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
[OLK-6.6] [Backport] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls
by Hui Tang 04 Aug '26
by Hui Tang 04 Aug '26
04 Aug '26
From: SeungJu Cheon <suunj1331(a)gmail.com>
mainline inclusion
from mainline-v7.1-rc2
commit 9ca7053d6215d89c33f28893bfd1625a32919d3f
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16200
CVE: CVE-2026-63871
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
iso_connect_bis(), iso_connect_cis(), iso_listen_bis(), and
iso_conn_big_sync() call hci_get_route() using iso_pi(sk)->dst,
iso_pi(sk)->src, and iso_pi(sk)->src_type without holding lock_sock().
These fields may be modified concurrently by connect() or setsockopt()
on the same socket, resulting in data-races reported by KCSAN.
Fix this by snapshotting the required fields under lock_sock() before
calling hci_get_route().
BUG: KCSAN: data-race in memcmp+0x45/0xb0
race at unknown origin, with read to 0xffff8880122135cf of 1 bytes
by task 333 on cpu 1:
memcmp+0x45/0xb0
hci_get_route+0x27e/0x490
iso_connect_cis+0x4c/0xa10
iso_sock_connect+0x60e/0xb30
__sys_connect_file+0xbd/0xe0
__sys_connect+0xe0/0x110
__x64_sys_connect+0x40/0x50
x64_sys_call+0xcad/0x1c60
do_syscall_64+0x133/0x590
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Signed-off-by: SeungJu Cheon <suunj1331(a)gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Conflicts:
net/bluetooth/iso.c
[Context conflicts due to backport]
Signed-off-by: Hui Tang <tanghui20(a)huawei.com>
---
net/bluetooth/iso.c | 55 +++++++++++++++++++++++++++++++++------------
1 file changed, 41 insertions(+), 14 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 78b0055f0aaf..bd83943d6f27 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -363,12 +363,19 @@ static int iso_connect_bis(struct sock *sk)
struct iso_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type;
int err;
- BT_DBG("%pMR", &iso_pi(sk)->src);
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ release_sock(sk);
+
+ BT_DBG("%pMR", &src);
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return -EHOSTUNREACH;
@@ -454,12 +461,19 @@ static int iso_connect_cis(struct sock *sk)
struct iso_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type;
int err;
- BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ release_sock(sk);
+
+ BT_DBG("%pMR -> %pMR", &src, &dst);
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return -EHOSTUNREACH;
@@ -1092,15 +1106,22 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr *addr,
static int iso_listen_bis(struct sock *sk)
{
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type, bc_sid;
int err = 0;
- BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
- &iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ bc_sid = iso_pi(sk)->bc_sid;
+ release_sock(sk);
+
+ BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &src, &dst, bc_sid);
write_lock(&iso_sk_list.lock);
- if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
- iso_pi(sk)->bc_sid))
+ if (__iso_get_sock_listen_by_sid(&src, &dst, bc_sid))
err = -EADDRINUSE;
write_unlock(&iso_sk_list.lock);
@@ -1108,8 +1129,7 @@ static int iso_listen_bis(struct sock *sk)
if (err)
return err;
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return -EHOSTUNREACH;
@@ -1357,9 +1377,16 @@ static void iso_conn_big_sync(struct sock *sk)
{
int err;
struct hci_dev *hdev;
+ bdaddr_t src, dst;
+ u8 src_type;
+
+ lock_sock(sk);
+ bacpy(&src, &iso_pi(sk)->src);
+ bacpy(&dst, &iso_pi(sk)->dst);
+ src_type = iso_pi(sk)->src_type;
+ release_sock(sk);
- hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
- iso_pi(sk)->src_type);
+ hdev = hci_get_route(&dst, &src, src_type);
if (!hdev)
return;
--
2.34.1
1
0
*** fix CVE-2026-64375 ***
Eric W. Biederman (1):
proc/fd: In proc_fd_link use fget_task
Jann Horn (1):
proc: protect ptrace_may_access() with exec_update_lock (FD links)
fs/proc/base.c | 119 ++++++++++++++++++---------------------------
fs/proc/fd.c | 34 +++++--------
fs/proc/internal.h | 2 +-
3 files changed, 59 insertions(+), 96 deletions(-)
--
2.34.1
2
3
[PATCH OLK-6.6] [Backport] nvmet-tcp: check INIT_FAILED before nvmet_req_uninit in digest error path
by Lu Chentao 04 Aug '26
by Lu Chentao 04 Aug '26
04 Aug '26
From: Shivam Kumar <kumar.shivam43666(a)gmail.com>
stable inclusion
from stable-v6.6.145
commit e602c93b25bda4a9d0ff1791a4bdbfdcbb074af1
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16831
CVE: CVE-2026-64534
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4606467a75cfc16721937272ed29462a750b60c8 upstream.
In nvmet_tcp_try_recv_ddgst(), when a data digest mismatch is detected,
nvmet_req_uninit() is called unconditionally. However, if the command
arrived via the nvmet_tcp_handle_req_failure() path, nvmet_req_init()
had returned false and percpu_ref_tryget_live() was never executed. The
unconditional percpu_ref_put() inside nvmet_req_uninit() then causes a
refcount underflow, leading to a WARNING in
percpu_ref_switch_to_atomic_rcu, a use-after-free diagnostic, and
eventually a permanent workqueue deadlock.
Check cmd->flags & NVMET_TCP_F_INIT_FAILED before calling
nvmet_req_uninit(), matching the existing pattern in
nvmet_tcp_execute_request().
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Signed-off-by: Shivam Kumar <kumar.shivam43666(a)gmail.com>
Signed-off-by: Keith Busch <kbusch(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Lu Chentao <luchentao1(a)huawei.com>
---
drivers/nvme/target/tcp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 6ec6912b2b47..e530eebf0bf2 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1288,11 +1288,12 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue)
if (queue->data_digest && cmd->exp_ddgst != cmd->recv_ddgst) {
pr_err("queue %d: cmd %d pdu (%d) data digest error: recv %#x expected %#x\n",
queue->idx, cmd->req.cmd->common.command_id,
queue->pdu.cmd.hdr.type, le32_to_cpu(cmd->recv_ddgst),
le32_to_cpu(cmd->exp_ddgst));
- nvmet_req_uninit(&cmd->req);
+ if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED))
+ nvmet_req_uninit(&cmd->req);
nvmet_tcp_free_cmd_buffers(cmd);
nvmet_tcp_fatal_error(queue);
ret = -EPROTO;
goto out;
}
--
2.52.0
2
1
[PATCH OLK-5.10] [Backport] nvmet-tcp: check INIT_FAILED before nvmet_req_uninit in digest error path
by Lu Chentao 04 Aug '26
by Lu Chentao 04 Aug '26
04 Aug '26
From: Shivam Kumar <kumar.shivam43666(a)gmail.com>
stable inclusion
from stable-v5.10.261
commit 22ec7a9fe9153d2737ee9b2fa6d2e43a1491decf
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16831
CVE: CVE-2026-64534
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4606467a75cfc16721937272ed29462a750b60c8 upstream.
In nvmet_tcp_try_recv_ddgst(), when a data digest mismatch is detected,
nvmet_req_uninit() is called unconditionally. However, if the command
arrived via the nvmet_tcp_handle_req_failure() path, nvmet_req_init()
had returned false and percpu_ref_tryget_live() was never executed. The
unconditional percpu_ref_put() inside nvmet_req_uninit() then causes a
refcount underflow, leading to a WARNING in
percpu_ref_switch_to_atomic_rcu, a use-after-free diagnostic, and
eventually a permanent workqueue deadlock.
Check cmd->flags & NVMET_TCP_F_INIT_FAILED before calling
nvmet_req_uninit(), matching the existing pattern in
nvmet_tcp_execute_request().
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Signed-off-by: Shivam Kumar <kumar.shivam43666(a)gmail.com>
Signed-off-by: Keith Busch <kbusch(a)kernel.org>
[shivam: inlined nvmet_tcp_finish_cmd() at the fix site for 5.10.y]
Signed-off-by: Shivam Kumar <kumar.shivam43666(a)gmail.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Lu Chentao <luchentao1(a)huawei.com>
---
drivers/nvme/target/tcp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 1f048ad19f6a..a2f6e75fd1bf 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1217,11 +1217,13 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue)
if (queue->data_digest && cmd->exp_ddgst != cmd->recv_ddgst) {
pr_err("queue %d: cmd %d pdu (%d) data digest error: recv %#x expected %#x\n",
queue->idx, cmd->req.cmd->common.command_id,
queue->pdu.cmd.hdr.type, le32_to_cpu(cmd->recv_ddgst),
le32_to_cpu(cmd->exp_ddgst));
- nvmet_tcp_finish_cmd(cmd);
+ if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED))
+ nvmet_req_uninit(&cmd->req);
+ nvmet_tcp_free_cmd_buffers(cmd);
nvmet_tcp_fatal_error(queue);
ret = -EPROTO;
goto out;
}
--
2.52.0
2
1
[PATCH OLK-6.6 0/2] CVE-2026-64079: fix NULL dereference in x_tables hook registration
by superdcc97@163.com 04 Aug '26
by superdcc97@163.com 04 Aug '26
04 Aug '26
From: Dong Chenchen <dongchenchen2(a)huawei.com>
This series backports the upstream fix for CVE-2026-64079 to OLK-6.6.
Patch 1 is the prerequisite that defers the audit register log message
until after hooks are wired up. Patch 2 moves hook ops allocation into
the xtables core so the table is never visible in the per-netns list
with ops=NULL, preventing a NULL dereference during concurrent netns
tear-down.
The main CVE patch adapts kmemdup_array() to kmemdup(), because
kmemdup_array() is not available in OLK-6.6.
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16469
Florian Westphal (2):
netfilter: x_tables: allow initial table replace without emitting
audit log message
netfilter: x_tables: allocate hook ops while under mutex
include/linux/netfilter/x_tables.h | 1 +
net/ipv4/netfilter/arp_tables.c | 35 ++------------
net/ipv4/netfilter/ip_tables.c | 41 ++--------------
net/ipv6/netfilter/ip6_tables.c | 38 ++-------------
net/netfilter/x_tables.c | 77 +++++++++++++++++++++++-------
5 files changed, 74 insertions(+), 118 deletions(-)
--
2.43.0
2
3
[PATCH] [Backport] nvmet-tcp: check INIT_FAILED before nvmet_req_uninit in digest error path
by Lu Chentao 04 Aug '26
by Lu Chentao 04 Aug '26
04 Aug '26
From: Shivam Kumar <kumar.shivam43666(a)gmail.com>
stable inclusion
from stable-v5.10.261
commit 22ec7a9fe9153d2737ee9b2fa6d2e43a1491decf
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16831
CVE: CVE-2026-64534
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4606467a75cfc16721937272ed29462a750b60c8 upstream.
In nvmet_tcp_try_recv_ddgst(), when a data digest mismatch is detected,
nvmet_req_uninit() is called unconditionally. However, if the command
arrived via the nvmet_tcp_handle_req_failure() path, nvmet_req_init()
had returned false and percpu_ref_tryget_live() was never executed. The
unconditional percpu_ref_put() inside nvmet_req_uninit() then causes a
refcount underflow, leading to a WARNING in
percpu_ref_switch_to_atomic_rcu, a use-after-free diagnostic, and
eventually a permanent workqueue deadlock.
Check cmd->flags & NVMET_TCP_F_INIT_FAILED before calling
nvmet_req_uninit(), matching the existing pattern in
nvmet_tcp_execute_request().
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Signed-off-by: Shivam Kumar <kumar.shivam43666(a)gmail.com>
Signed-off-by: Keith Busch <kbusch(a)kernel.org>
[shivam: inlined nvmet_tcp_finish_cmd() at the fix site for 5.10.y]
Signed-off-by: Shivam Kumar <kumar.shivam43666(a)gmail.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Lu Chentao <luchentao1(a)huawei.com>
---
drivers/nvme/target/tcp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 1f048ad19f6a..a2f6e75fd1bf 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1217,11 +1217,13 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue)
if (queue->data_digest && cmd->exp_ddgst != cmd->recv_ddgst) {
pr_err("queue %d: cmd %d pdu (%d) data digest error: recv %#x expected %#x\n",
queue->idx, cmd->req.cmd->common.command_id,
queue->pdu.cmd.hdr.type, le32_to_cpu(cmd->recv_ddgst),
le32_to_cpu(cmd->exp_ddgst));
- nvmet_tcp_finish_cmd(cmd);
+ if (!(cmd->flags & NVMET_TCP_F_INIT_FAILED))
+ nvmet_req_uninit(&cmd->req);
+ nvmet_tcp_free_cmd_buffers(cmd);
nvmet_tcp_fatal_error(queue);
ret = -EPROTO;
goto out;
}
--
2.52.0
1
0
[PATCH OLK-6.6 0/2] CVE-2026-64079: fix NULL dereference in x_tables hook registration
by superdcc97@163.com 04 Aug '26
by superdcc97@163.com 04 Aug '26
04 Aug '26
From: Dong Chenchen <dongchenchen2(a)huawei.com>
This series backports the upstream fix for CVE-2026-64079 to OLK-6.6.
Patch 1 is the prerequisite that defers the audit register log message
until after hooks are wired up. Patch 2 moves hook ops allocation into
the xtables core so the table is never visible in the per-netns list
with ops=NULL, preventing a NULL dereference during concurrent netns
tear-down.
The main CVE patch adapts kmemdup_array() to kmemdup(), because
kmemdup_array() is not available in OLK-6.6.
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16469
Florian Westphal (2):
netfilter: x_tables: allow initial table replace without emitting
audit log message
netfilter: x_tables: allocate hook ops while under mutex
include/linux/netfilter/x_tables.h | 1 +
net/ipv4/netfilter/arp_tables.c | 35 ++------------
net/ipv4/netfilter/ip_tables.c | 41 ++--------------
net/ipv6/netfilter/ip6_tables.c | 38 ++-------------
net/netfilter/x_tables.c | 77 +++++++++++++++++++++++-------
5 files changed, 74 insertions(+), 118 deletions(-)
--
2.43.0
2
3
*** BLURB HERE ***
Chen Jinghuang (3):
cpuset: Fix prefer_cpus ineffectiveness by tracking prefer_cpus
cgroup/cpuset.c: Comment out early when prefer_cpus cpumask equals
cgroup/cpuset.c: Adapt schduler dynamic affinity for hotplug scenarios
with cgroup v2
kernel/cgroup/cpuset.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
--
2.34.1
2
4
[PATCH OLK-5.10] [Backport] ksmbd: fix out-of-bounds read in smb_check_perm_dacl()
by Lu Chentao 04 Aug '26
by Lu Chentao 04 Aug '26
04 Aug '26
From: Hem Parekh <hemparekh1596(a)gmail.com>
mainline inclusion
from mainline-v7.2-rc1
commit 1ef06004ed4bd6d3ed8c840d9d1a376b66d4935b
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16110
CVE: CVE-2026-53390
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
The permission-check ACE walk in smb_check_perm_dacl() validates the ACE
header size and caps sid.num_subauth at SID_MAX_SUB_AUTHORITIES, but it
never checks that ace->size is actually large enough to contain
num_subauth sub-authorities before compare_sids() dereferences them.
CIFS_SID_BASE_SIZE covers the SID header up to but excluding the
sub_auth[] array, and offsetof(struct smb_ace, sid) is the ACE header,
so the existing guards only guarantee the 8-byte SID base, i.e. zero
sub-authorities. compare_sids() then reads ace->sid.sub_auth[i] for
i < min(local_sid->num_subauth, ace->sid.num_subauth). The local
comparison SIDs (sid_everyone, sid_unix_NFS_mode, and the id_to_sid()
result) always have at least one sub-authority, and an attacker controls
the ACE revision and authority bytes (which lie within the in-bounds SID
base), so they can match one of those SIDs and force the sub_auth read.
A crafted ACE with size == 16 and num_subauth >= 1 placed at the tail of
the security descriptor therefore causes a heap out-of-bounds read of up
to SID_MAX_SUB_AUTHORITIES * sizeof(__le32) bytes past the pntsd
allocation. The security descriptor is loaded by ksmbd_vfs_get_sd_xattr()
into a buffer sized exactly to the on-disk data (kzalloc(sd_size) in
ndr_decode_v4_ntacl()), so the read lands past the allocation. The
malformed descriptor can be stored verbatim via SMB2_SET_INFO (the DACL
is not normalised before being written to the security.NTACL xattr) and
the read fires on a subsequent SMB2_CREATE access check, making this
reachable by an authenticated client on a share that uses ACL xattrs.
Add the missing num_subauth-versus-ace_size check, mirroring the
identical guards already present in the sibling parsers parse_dacl() and
smb_inherit_dacl().
Fixes: d07b26f39246 ("ksmbd: require minimum ACE size in smb_check_perm_dacl()")
Cc: stable(a)vger.kernel.org
Signed-off-by: Hem Parekh <hemparekh1596(a)gmail.com>
Acked-by: Namjae Jeon <linkinjeon(a)kernel.org>
Signed-off-by: Steve French <stfrench(a)microsoft.com>
Signed-off-by: Lu Chentao <luchentao1(a)huawei.com>
---
fs/ksmbd/smbacl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c
index 692d063ef9be..bc54184e9216 100644
--- a/fs/ksmbd/smbacl.c
+++ b/fs/ksmbd/smbacl.c
@@ -1299,11 +1299,13 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
ace_size < offsetof(struct smb_ace, sid) +
CIFS_SID_BASE_SIZE)
break;
aces_size -= ace_size;
- if (ace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES)
+ if (ace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
+ ace_size < offsetof(struct smb_ace, sid) + CIFS_SID_BASE_SIZE +
+ sizeof(__le32) * ace->sid.num_subauth)
break;
if (!compare_sids(&sid, &ace->sid) ||
!compare_sids(&sid_unix_NFS_mode, &ace->sid)) {
found = 1;
--
2.52.0
2
14
From: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
driver inclusion
category: feature
bugzilla: https://atomgit.com/openeuler/kernel/issues/9708
CVE: NA
---------------------------------
Current hinic5 driver does not support PXE, this will causing timeout while boot from remote host.
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>>
---
.../ethernet/huawei/hinic5/GLOBAL_VERSION_NEW | 12 +
.../ethernet/huawei/hinic5/build/__init__.py | 3 +
.../huawei/hinic5/build/build_main.py | 166 +
.../huawei/hinic5/build/build_util.py | 105 +
.../net/ethernet/huawei/hinic5/build/env.py | 708 ++++
.../hinic5/build/host/linux/Makefile.ko | 123 +
.../hinic5/build/host/linux/__init__.py | 3 +
.../hinic5/build/host/linux/build_host.py | 99 +
.../hinic5/build/host/linux/kcompat-lib.sh | 300 ++
.../hinic5/build/host/linux/nic/__init__.py | 3 +
.../hinic5/build/host/linux/nic/build_nic.py | 182 +
.../host/linux/nic/nic-kcompat-generator.sh | 500 +++
.../hinic5/build/host/linux/roce/__init__.py | 3 +
.../build/host/linux/roce/build_roce.py | 567 ++++
.../host/linux/roce/roce_kcompat_generator.sh | 330 ++
.../hinic5/build/host/linux/sdk/__init__.py | 3 +
.../hinic5/build/host/linux/sdk/build_sdk.py | 207 ++
.../host/linux/sdk/sdk-kcompat-generator.sh | 308 ++
.../hinic5/build/host/linux/udma/__init__.py | 3 +
.../build/host/linux/udma/build_udma.py | 532 +++
.../hinic5/build/tools/build_log/build_log.sh | 95 +
.../cmake/huawei_secure_cConfig.cmake | 96 +
.../huawei_secure_c/include/securec.h | 676 ++++
.../huawei_secure_c/include/securectype.h | 613 ++++
.../adapt_implicit_fallthrough_level5.patch | 20 +
.../platform/huawei_secure_c/src/Makefile | 196 ++
.../platform/huawei_secure_c/src/fscanf_s.c | 52 +
.../platform/huawei_secure_c/src/fwscanf_s.c | 51 +
.../platform/huawei_secure_c/src/gets_s.c | 72 +
.../platform/huawei_secure_c/src/input.inl | 2482 ++++++++++++++
.../platform/huawei_secure_c/src/memcpy_s.c | 630 ++++
.../platform/huawei_secure_c/src/memmove_s.c | 122 +
.../platform/huawei_secure_c/src/memset_s.c | 583 ++++
.../platform/huawei_secure_c/src/output.inl | 1951 +++++++++++
.../platform/huawei_secure_c/src/scanf_s.c | 50 +
.../platform/huawei_secure_c/src/secinput.h | 193 ++
.../huawei_secure_c/src/securecutil.c | 82 +
.../huawei_secure_c/src/securecutil.h | 682 ++++
.../huawei_secure_c/src/secureinput_a.c | 37 +
.../huawei_secure_c/src/secureinput_w.c | 74 +
.../huawei_secure_c/src/secureprintoutput.h | 168 +
.../huawei_secure_c/src/secureprintoutput_a.c | 119 +
.../huawei_secure_c/src/secureprintoutput_w.c | 40 +
.../platform/huawei_secure_c/src/snprintf_s.c | 110 +
.../platform/huawei_secure_c/src/sprintf_s.c | 57 +
.../platform/huawei_secure_c/src/sscanf_s.c | 57 +
.../platform/huawei_secure_c/src/strcat_s.c | 103 +
.../platform/huawei_secure_c/src/strcpy_s.c | 392 +++
.../platform/huawei_secure_c/src/strncat_s.c | 121 +
.../platform/huawei_secure_c/src/strncpy_s.c | 157 +
.../platform/huawei_secure_c/src/strtok_s.c | 116 +
.../platform/huawei_secure_c/src/swprintf_s.c | 47 +
.../platform/huawei_secure_c/src/swscanf_s.c | 53 +
.../platform/huawei_secure_c/src/vfscanf_s.c | 63 +
.../platform/huawei_secure_c/src/vfwscanf_s.c | 66 +
.../platform/huawei_secure_c/src/vscanf_s.c | 62 +
.../huawei_secure_c/src/vsnprintf_s.c | 146 +
.../platform/huawei_secure_c/src/vsprintf_s.c | 69 +
.../platform/huawei_secure_c/src/vsscanf_s.c | 88 +
.../huawei_secure_c/src/vswprintf_s.c | 64 +
.../platform/huawei_secure_c/src/vswscanf_s.c | 79 +
.../platform/huawei_secure_c/src/vwscanf_s.c | 63 +
.../platform/huawei_secure_c/src/wcscat_s.c | 108 +
.../platform/huawei_secure_c/src/wcscpy_s.c | 87 +
.../platform/huawei_secure_c/src/wcsncat_s.c | 116 +
.../platform/huawei_secure_c/src/wcsncpy_s.c | 110 +
.../platform/huawei_secure_c/src/wcstok_s.c | 115 +
.../platform/huawei_secure_c/src/wmemcpy_s.c | 73 +
.../platform/huawei_secure_c/src/wmemmove_s.c | 72 +
.../platform/huawei_secure_c/src/wscanf_s.c | 51 +
.../drv_cfm_intf/hmm/hinic5_hmm.h | 101 +
.../drv_cfm_intf/hmm/hmm_buddy.h | 77 +
.../drv_cfm_intf/hmm/hmm_common.h | 577 ++++
.../drv_sdk_intf/hisdk/hinic5_cqm.h | 901 +++++
.../drv_sdk_intf/hisdk/hinic5_service.h | 590 ++++
.../drv_sdk_intf/hisdk/hinic5_vram_api.h | 50 +
.../drv_sdk_intf/ossl/ossl_user.h | 13 +
.../drv_sdk_intf/ossl/vbs_kcompat.h | 13 +
.../urts/arch/arm/udk_byteorder.h | 33 +
.../drv_sdk_intf/urts/arch/arm/udk_cycles.h | 35 +
.../drv_sdk_intf/urts/arch/arm/udk_io.h | 27 +
.../urts/arch/arm/udk_membarrier.h | 49 +
.../urts/arch/x86/udk_byteorder.h | 88 +
.../drv_sdk_intf/urts/arch/x86/udk_cycles.h | 33 +
.../drv_sdk_intf/urts/arch/x86/udk_io.h | 26 +
.../urts/arch/x86/udk_membarrier.h | 59 +
.../drv_sdk_intf/urts/udk_args.h | 93 +
.../drv_sdk_intf/urts/udk_atomic.h | 235 ++
.../drv_sdk_intf/urts/udk_byteorder.h | 79 +
.../drv_sdk_intf/urts/udk_common.h | 243 ++
.../drv_sdk_intf/urts/udk_cycles.h | 75 +
.../drv_sdk_intf/urts/udk_ethdev.h | 713 ++++
.../drv_sdk_intf/urts/udk_ether.h | 116 +
.../drv_sdk_intf/urts/udk_io.h | 23 +
.../drv_sdk_intf/urts/udk_log.h | 243 ++
.../drv_sdk_intf/urts/udk_malloc.h | 107 +
.../drv_sdk_intf/urts/udk_mbuf.h | 513 +++
.../drv_sdk_intf/urts/udk_membarrier.h | 17 +
.../drv_sdk_intf/urts/udk_mempool.h | 603 ++++
.../drv_sdk_intf/urts/udk_memzone.h | 121 +
.../drv_sdk_intf/urts/udk_ops.h | 113 +
.../drv_sdk_intf/urts/udk_pci.h | 46 +
.../drv_sdk_intf/urts/udk_ring.h | 249 ++
.../drv_sdk_intf/urts/udk_rwlock.h | 148 +
.../drv_sdk_intf/urts/udk_spinlock.h | 102 +
.../drv_sdk_intf/urts/udk_usrnl.h | 219 ++
.../drv_sdk_intf/urts/udk_vdev.h | 147 +
.../drv_srvc_intf/roce/hrn5_dfx_u_api.h | 60 +
.../drv_srvc_intf/roce/hrn5_u_api.h | 146 +
.../drv_srvc_intf/roce/hyper_roce_extend.h | 68 +
.../drv_srvc_intf/roce/roce_uld_kernel_api.h | 536 +++
.../drv_srvc_intf/roce/roce_uld_user_api.h | 209 ++
.../fw_msg_intf/ccp/ccp_algo_format.h | 398 +++
.../fw_msg_intf/cfm/hmm_cmd_defs.h | 259 ++
.../fw_msg_intf/cfm/qos_base_mpu_defs.h | 120 +
.../fw_msg_intf/cqm/cqm_npu_cmd.h | 23 +
.../fw_msg_intf/cqm/cqm_npu_cmd_defs.h | 82 +
.../fw_msg_intf/mag/eeprom_qsfp_defs.h | 440 +++
.../fw_msg_intf/mag/eeprom_sfp_defs.h | 209 ++
.../fw_msg_intf/mpu/mpu_outband_mctp_cmd.h | 44 +
.../mpu/mpu_outband_mctp_cmd_defs.h | 206 ++
.../fw_msg_intf/mpu/mpu_outband_ncsi_cmd.h | 239 ++
.../mpu/mpu_outband_ncsi_cmd_defs.h | 123 +
.../fw_msg_intf/mpu/mpu_outband_smbus_cmd.h | 134 +
.../mpu/mpu_outband_smbus_cmd_defs.h | 726 ++++
.../fw_msg_intf/nic/nic_mig_mpu_intf.h | 36 +
.../fw_msg_intf/nic/nic_mig_npu_intf.h | 175 +
.../fw_msg_intf/nic/nic_npu_cmd_defs.h | 200 ++
.../fw_msg_intf/nic/nic_npu_wqe_defs.h | 333 ++
.../fw_msg_intf/public/adm_dict.h | 78 +
.../fw_msg_intf/public/counter_dict.h | 31 +
.../fw_msg_intf/public/dfx_cap_pkt_cfg.h | 147 +
.../fw_msg_intf/public/hmm_context.h | 230 ++
.../fw_msg_intf/rdma/roce5_gid_type.h | 21 +
.../fw_msg_intf/rdma/roce_cqe_format.h | 159 +
.../rdma/roce_npu_cmd_ext_data_defs.h | 23 +
.../fw_msg_intf/rdma/roce_npu_cmd_type_defs.h | 71 +
.../fw_msg_intf/rdma/roce_wqe_opt_types.h | 43 +
.../fw_msg_intf/rdma/roce_wqe_ulp_task.h | 121 +
.../ubc_net/ubcnet_base_view_defs.h | 12 +
.../ubc_net/ubcnet_heartbeat_view_defs.h | 138 +
.../fw_msg_intf/ubc_net/ubcnet_mami_extend.h | 267 ++
.../fw_msg_intf/ubc_net/ubcnet_mpu_cmd.h | 54 +
.../fw_msg_intf/ubc_net/ubcnet_mpu_cmd_defs.h | 276 ++
.../fw_msg_intf/ubc_net/ubcnet_npu_cmd.h | 48 +
.../fw_msg_intf/ubc_net/ubcnet_npu_cmd_defs.h | 175 +
.../fw_msg_intf/ubc_net/ubcnet_rdma_extend.h | 89 +
.../ubc_net/ubcnet_rdma_view_defs.h | 112 +
.../host/cfm/hmm/hmm_buddy.c | 186 +
.../host/cfm/hmm/hmm_common.c | 798 +++++
.../host/cfm/hmm/hmm_em.c | 395 +++
.../host/cfm/hmm/hmm_em_inner.h | 76 +
.../host/cfm/hmm/hmm_init.c | 157 +
.../host/cfm/hmm/hmm_mpt.c | 60 +
.../host/cfm/hmm/hmm_mr.c | 397 +++
.../host/cfm/hmm/hmm_mtt.c | 586 ++++
.../host/cfm/hmm/hmm_umem.c | 404 +++
.../host/cfm/hmm/hmm_umem_inner.h | 98 +
.../host/cfm/rdma/rdma_bitmap.c | 148 +
.../host/cfm/rdma/rdma_bitmap.h | 40 +
.../include/sdk/knldk/hinic5_lld_common.h | 22 +
.../host/include/sdk/knldk/hinic5_vram.h | 34 +
.../host/include/sdk/knldk/vram_common.h | 182 +
.../cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.c | 89 +
.../cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.h | 41 +
.../cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.c | 87 +
.../cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.h | 54 +
.../host/sdk/knldk/cqm/cqm_bat_cla.c | 2745 +++++++++++++++
.../host/sdk/knldk/cqm/cqm_bat_cla.h | 256 ++
.../host/sdk/knldk/cqm/cqm_bitmap_table.c | 1807 ++++++++++
.../host/sdk/knldk/cqm/cqm_bitmap_table.h | 85 +
.../host/sdk/knldk/cqm/cqm_bloomfilter.c | 549 +++
.../host/sdk/knldk/cqm/cqm_bloomfilter.h | 54 +
.../host/sdk/knldk/cqm/cqm_cmd.c | 213 ++
.../host/sdk/knldk/cqm/cqm_cmd.h | 43 +
.../host/sdk/knldk/cqm/cqm_cmdq.h | 28 +
.../host/sdk/knldk/cqm/cqm_cmdq_adapt.c | 14 +
.../host/sdk/knldk/cqm/cqm_db.c | 571 ++++
.../host/sdk/knldk/cqm/cqm_db.h | 36 +
.../host/sdk/knldk/cqm/cqm_main.c | 2262 +++++++++++++
.../host/sdk/knldk/cqm/cqm_main.h | 520 +++
.../host/sdk/knldk/cqm/cqm_object.c | 1765 ++++++++++
.../host/sdk/knldk/cqm/cqm_object.h | 385 +++
.../host/sdk/knldk/cqm/cqm_object_intern.c | 1625 +++++++++
.../host/sdk/knldk/cqm/cqm_object_intern.h | 118 +
.../host/sdk/knldk/cqm/cqm_secure_mem.c | 253 ++
.../host/sdk/knldk/crm/hinic5_mgmt_msg.c | 817 +++++
.../host/sdk/knldk/include/hisdk5_hwif.h | 363 ++
.../host/sdk/knldk/include/hisdk5_typedef.h | 20 +
.../host/sdk/knldk/lld/CMakeLists.txt | 94 +
.../host/sdk/knldk/lld/Makefile | 185 +
.../host/sdk/knldk/vram/hinic5_vram.c | 309 ++
.../host/sdk/knldk/vram/vram_common.c | 224 ++
.../host/service/include/hinic5_rdma.h | 65 +
.../nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.c | 122 +
.../nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.h | 37 +
.../nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.c | 135 +
.../nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.h | 54 +
.../host/service/nic/ipxe/base/hinic5_cmd.h | 264 ++
.../host/service/nic/ipxe/base/hinic5_cmdq.c | 893 +++++
.../host/service/nic/ipxe/base/hinic5_cmdq.h | 250 ++
.../nic/ipxe/base/hinic5_cmdq_enhance.h | 168 +
.../service/nic/ipxe/base/hinic5_compat.h | 185 +
.../host/service/nic/ipxe/base/hinic5_csr.h | 118 +
.../nic/ipxe/base/hinic5_enhance_cmdq.c | 103 +
.../host/service/nic/ipxe/base/hinic5_eqs.c | 665 ++++
.../host/service/nic/ipxe/base/hinic5_eqs.h | 95 +
.../service/nic/ipxe/base/hinic5_hw_cfg.c | 228 ++
.../service/nic/ipxe/base/hinic5_hw_cfg.h | 121 +
.../service/nic/ipxe/base/hinic5_hw_comm.c | 459 +++
.../service/nic/ipxe/base/hinic5_hw_comm.h | 223 ++
.../host/service/nic/ipxe/base/hinic5_hwdev.c | 481 +++
.../host/service/nic/ipxe/base/hinic5_hwdev.h | 107 +
.../host/service/nic/ipxe/base/hinic5_hwif.c | 823 +++++
.../host/service/nic/ipxe/base/hinic5_hwif.h | 140 +
.../host/service/nic/ipxe/base/hinic5_mbox.c | 1236 +++++++
.../host/service/nic/ipxe/base/hinic5_mbox.h | 196 ++
.../host/service/nic/ipxe/base/hinic5_mgmt.c | 445 +++
.../host/service/nic/ipxe/base/hinic5_mgmt.h | 132 +
.../host/service/nic/ipxe/base/hinic5_wq.c | 144 +
.../host/service/nic/ipxe/base/hinic5_wq.h | 65 +
.../host/service/nic/ipxe/hinic5_mag_cfg.h | 209 ++
.../host/service/nic/ipxe/hinic5_main.c | 699 ++++
.../host/service/nic/ipxe/hinic5_nic_cfg.c | 1189 +++++++
.../host/service/nic/ipxe/hinic5_nic_cfg.h | 904 +++++
.../host/service/nic/ipxe/hinic5_nic_dev.h | 55 +
.../host/service/nic/ipxe/hinic5_nic_io.c | 633 ++++
.../host/service/nic/ipxe/hinic5_nic_io.h | 285 ++
.../host/service/nic/ipxe/hinic5_rx.c | 444 +++
.../host/service/nic/ipxe/hinic5_rx.h | 220 ++
.../host/service/nic/ipxe/hinic5_settings.c | 532 +++
.../host/service/nic/ipxe/hinic5_settings.h | 27 +
.../host/service/nic/ipxe/hinic5_tx.c | 498 +++
.../host/service/nic/ipxe/hinic5_tx.h | 224 ++
.../host/service/nic/ipxe/menu.ipxe | 25 +
.../host/service/nic/linux/CMakeLists.txt | 82 +
.../mpu/outband_mpu_ncsi_cmd_defs.h | 1641 +++++++++
.../drv_fw_msg/roce/hi182x/roce_mpu_cmd.h | 78 +
.../roce/hi182x/roce_mpu_cmd_defs.h | 543 +++
.../include/drv_fw_msg/roce/roce_aeq_format.h | 173 +
.../include/drv_fw_msg/roce/roce_cc_format.h | 238 ++
.../include/drv_fw_msg/roce/roce_cfg_format.h | 178 +
.../include/drv_fw_msg/roce/roce_ctx_format.h | 45 +
.../drv_fw_msg/roce/roce_hyper_npu_cmd.h | 211 ++
.../include/drv_fw_msg/roce/roce_npu_cmd.h | 146 +
.../drv_fw_msg/roce/roce_npu_cmd_cq_defs.h | 235 ++
.../drv_fw_msg/roce/roce_npu_cmd_defs.h | 318 ++
.../drv_fw_msg/roce/roce_npu_cmd_dfx_defs.h | 46 +
.../drv_fw_msg/roce/roce_npu_cmd_ext_defs.h | 115 +
.../drv_fw_msg/roce/roce_npu_cmd_gid_defs.h | 196 ++
.../drv_fw_msg/roce/roce_npu_cmd_mr_defs.h | 334 ++
.../drv_fw_msg/roce/roce_npu_cmd_qp_defs.h | 993 ++++++
.../drv_fw_msg/roce/roce_npu_cmd_srq_defs.h | 269 ++
.../drv_fw_msg/roce/roce_wqe_base_format.h | 565 ++++
.../include/drv_fw_msg/roce/roce_wqe_format.h | 316 ++
.../include/drv_fw_msg/roce/roce_xqe_format.h | 320 ++
.../include/drv_fw_msg/uboe/ub_aeqe.h | 356 ++
.../include/drv_fw_msg/uboe/ub_dw_index.h | 42 +
.../include/drv_fw_msg/uboe/ub_mpu_cmd.h | 117 +
.../include/drv_fw_msg/uboe/ub_mpu_cmd_defs.h | 937 +++++
.../drv_fw_msg/uboe/ub_mpu_dfx_cmd_defs.h | 337 ++
.../include/drv_fw_msg/uboe/ub_npu_base_cmd.h | 454 +++
.../include/drv_fw_msg/uboe/ub_npu_eid_cmd.h | 18 +
.../drv_fw_msg/uboe/ub_npu_eid_cmd_defs.h | 106 +
.../drv_fw_msg/uboe/ub_npu_event_cmd.h | 21 +
.../drv_fw_msg/uboe/ub_npu_event_cmd_defs.h | 53 +
.../drv_fw_msg/uboe/ub_npu_jetty_cmd.h | 49 +
.../drv_fw_msg/uboe/ub_npu_jetty_cmd_defs.h | 672 ++++
.../include/drv_fw_msg/uboe/ub_npu_jfc_cmd.h | 26 +
.../drv_fw_msg/uboe/ub_npu_jfc_cmd_defs.h | 198 ++
.../include/drv_fw_msg/uboe/ub_npu_jfr_cmd.h | 24 +
.../include/drv_fw_msg/uboe/ub_npu_jfrc_cmd.h | 26 +
.../drv_fw_msg/uboe/ub_npu_jfrc_cmd_defs.h | 105 +
.../include/drv_fw_msg/uboe/ub_npu_mapt_cmd.h | 30 +
.../drv_fw_msg/uboe/ub_npu_mapt_cmd_defs.h | 188 ++
.../include/drv_fw_msg/uboe/ub_npu_mig_cmd.h | 44 +
.../drv_fw_msg/uboe/ub_npu_mig_cmd_defs.h | 464 +++
.../include/drv_fw_msg/uboe/ub_npu_sip_cmd.h | 21 +
.../drv_fw_msg/uboe/ub_npu_sip_cmd_defs.h | 117 +
.../include/drv_fw_msg/uboe/ub_npu_srq_cmd.h | 24 +
.../drv_fw_msg/uboe/ub_npu_srq_cmd_defs.h | 242 ++
.../include/drv_fw_msg/uboe/ub_npu_tp_cmd.h | 60 +
.../drv_fw_msg/uboe/ub_npu_tp_cmd_defs.h | 1274 +++++++
.../include/drv_fw_msg/uboe/ub_npu_tpg_cmd.h | 25 +
.../drv_fw_msg/uboe/ub_npu_tpg_cmd_defs.h | 179 +
.../include/drv_fw_msg/uboe/ub_npu_upi_cmd.h | 16 +
.../drv_fw_msg/uboe/ub_npu_upi_cmd_defs.h | 146 +
.../drv_fw_msg/uboe/ub_npu_userctl_defs.h | 141 +
.../include/drv_fw_msg/uboe/ub_npu_utp_cmd.h | 18 +
.../drv_fw_msg/uboe/ub_npu_utp_cmd_defs.h | 161 +
.../include/drv_fw_msg/uboe/ub_npu_vtp_cmd.h | 26 +
.../drv_fw_msg/uboe/ub_npu_vtp_cmd_defs.h | 237 ++
.../drv_fw_msg/uboe/ub_ta_wqe_define.h | 3007 +++++++++++++++++
.../drv_fw_msg/uboe/ub_ta_wqe_format.h | 34 +
.../drv_fw_msg/uboe/ub_tp_wqe_define.h | 349 ++
.../drv_fw_msg/uboe/ub_tp_wqe_format.h | 20 +
.../include/drv_fw_msg/uboe/ub_wqe_format.h | 647 ++++
.../include/drv_fw_msg/uboe/ub_xqe_format.h | 498 +++
.../drv_fw_msg/uboe/uboe_pub_tbl_def.h | 52 +
.../include/drv_tool_msg/cfm_pub_cmd.h | 10 +
.../include/drv_tool_msg/hihtr_pub_cmd.h | 33 +
.../include/drv_tool_msg/hyper_roce_pub_cmd.h | 48 +
.../include/drv_tool_msg/mig_pub_cmd.h | 42 +
.../include/drv_tool_msg/roce_pub_cmd.h | 47 +
.../include/drv_tool_msg/ub_pub_cmd.h | 857 +++++
305 files changed, 82357 insertions(+)
create mode 100644 drivers/net/ethernet/huawei/hinic5/GLOBAL_VERSION_NEW
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/__init__.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/build_main.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/build_util.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/env.py
create mode 100644 drivers/net/ethernet/huawei/hinic5/build/host/linux/Makefile.ko
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/__init__.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/build_host.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/kcompat-lib.sh
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/__init__.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/build_nic.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/nic-kcompat-generator.sh
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/__init__.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/build_roce.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/roce_kcompat_generator.sh
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/__init__.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/build_sdk.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/sdk-kcompat-generator.sh
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/__init__.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/build_udma.py
create mode 100755 drivers/net/ethernet/huawei/hinic5/build/tools/build_log/build_log.sh
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/cmake/huawei_secure_cConfig.cmake
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securec.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securectype.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/patch/adapt_implicit_fallthrough_level5.patch
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/Makefile
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fwscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/gets_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/input.inl
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memcpy_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memmove_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memset_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/output.inl
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/scanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secinput.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_a.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_w.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_a.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_w.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/snprintf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sprintf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcat_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcpy_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncat_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncpy_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strtok_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swprintf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfwscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsnprintf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsprintf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswprintf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vwscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscat_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscpy_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncat_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncpy_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcstok_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemcpy_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemmove_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wscanf_s.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hinic5_hmm.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_buddy.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_common.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_cqm.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_service.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_vram_api.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_user.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/vbs_kcompat.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_byteorder.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_cycles.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_io.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_membarrier.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_byteorder.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_cycles.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_io.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_membarrier.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_args.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_atomic.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_byteorder.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_common.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_cycles.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ethdev.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ether.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_io.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_log.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_malloc.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mbuf.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_membarrier.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mempool.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_memzone.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ops.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_pci.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ring.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_rwlock.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_spinlock.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_usrnl.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_vdev.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_dfx_u_api.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_u_api.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hyper_roce_extend.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_kernel_api.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_user_api.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ccp/ccp_algo_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/hmm_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/qos_base_mpu_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_qsfp_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_sfp_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_mpu_intf.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_npu_intf.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_wqe_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/adm_dict.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/counter_dict.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/dfx_cap_pkt_cfg.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hmm_context.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce5_gid_type.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_cqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_ext_data_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_type_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_opt_types.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_ulp_task.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_base_view_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_heartbeat_view_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mami_extend.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_extend.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_view_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_buddy.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_common.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em_inner.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_init.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mpt.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mr.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mtt.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem_inner.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_lld_common.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/vram_common.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq_adapt.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_secure_mem.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_mgmt_msg.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_hwif.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_typedef.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/CMakeLists.txt
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/Makefile
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/hinic5_vram.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/vram_common.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_rdma.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq_enhance.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_compat.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_csr.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_enhance_cmdq.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_mag_cfg.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_main.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_dev.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.c
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.h
create mode 100755 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/menu.ipxe
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/CMakeLists.txt
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/outband_mpu_ncsi_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_aeq_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cc_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cfg_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_ctx_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_hyper_npu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_cq_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_dfx_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_ext_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_gid_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_mr_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_qp_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_srq_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_base_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_xqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_aeqe.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_dw_index.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_dfx_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_base_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfr_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_userctl_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_define.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_define.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_wqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_xqe_format.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/uboe_pub_tbl_def.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/cfm_pub_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hihtr_pub_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hyper_roce_pub_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/mig_pub_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/roce_pub_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/ub_pub_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic5/GLOBAL_VERSION_NEW b/drivers/net/ethernet/huawei/hinic5/GLOBAL_VERSION_NEW
new file mode 100644
index 000000000..679df7612
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/GLOBAL_VERSION_NEW
@@ -0,0 +1,12 @@
+dpu_dev_kit:1.0.0.2
+driver:21.0.10.1
+tool:21.0.10.1
+boot:21.0.10.1
+mpu:21.0.10.1
+npu:21.0.10.1
+smu_l0:21.0.10.1
+smu_l1:21.0.10.1
+cps_data:21.0.10.1
+cps:22.12.11
+roce_scc:21.0.10.1
+roce_imp:21.0.10.1
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/__init__.py b/drivers/net/ethernet/huawei/hinic5/build/__init__.py
new file mode 100755
index 000000000..cc0d19d0a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/__init__.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/build_main.py b/drivers/net/ethernet/huawei/hinic5/build/build_main.py
new file mode 100755
index 000000000..506017465
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/build_main.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+from time import time
+from multiprocessing import Pool
+import logging
+import env
+
+
+sys.path.append(env.HI1823_BUILD_HOST_DIR)
+import build_host
+
+hi1823_type = None
+chip_version = None
+
+hi1823_feature_dict = {
+ "sdk" : "SDK",
+ "SDK" : "SDK",
+ "sdk_ko" : "SDK_KO",
+ "SDK_KO" : "SDK_KO",
+ "nic" : "NIC",
+ "NIC" : "NIC",
+ "nic_ko" : "NIC_KO",
+ "NIC_KO" : "NIC_KO",
+ "roce" : "ROCE",
+ "ROCE" : "ROCE",
+ "udma" : "UDMA",
+ "UDMA" : "UDMA",
+}
+
+hi1823_type_dict = {
+ "driver" : "DRIVER",
+ "DRIVER" : "DRIVER",
+ "driver_ubus" : "DRIVER_UBUS",
+ "DRIVER_UBUS" : "DRIVER_UBUS",
+}
+
+hi1823_driver_type_dict = {
+ "kernel" : "KERNEL",
+ "KERNEL" : "KERNEL",
+ "kernel_arm" : "KERNEL",
+ "KERNEL_ARM" : "KERNEL",
+ "roce_compute" : "ROCE_COMPUTE",
+ "ROCE_COMPUTE" : "ROCE_COMPUTE",
+ "roce_standard_mlnx" : "ROCE_STANDARD_MLNX",
+ "ROCE_STANDARD_MLNX" : "ROCE_STANDARD_MLNX",
+}
+
+hi1823_fc_os_release_type_dict = {
+ "release" : "RELEASE",
+ "RELEASE" : "RELEASE",
+ "debug" : "DEBUG",
+ "DEBUG" : "DEBUG",
+ "loopback" : "LOOPBACK",
+ "LOOPBACK" : "LOOPBACK",
+}
+
+hi1823_env_type_dict = {
+ "ub_beta" : ("1650", "opensource/openeuler/kernel/olk-6.6", "kernel"),
+ "bigdipperv5r9" : ("1650", "open_source/2403_SP2", "ube/ubengine/ssapi/kernelspace"),
+}
+
+hi1823_driver_ubus_edition_dict = {
+ "b180" : "B180",
+ "B180" : "B180",
+ "b186" : "B186",
+ "B186" : "B186",
+ "b188" : "B188",
+ "B188" : "B188",
+}
+
+def manual():
+ logging.info(f"{sys.argv[0]} [feature] [type] [driver_type]:")
+ logging.info("[feature]:")
+ logging.info(" sdk | SDK | nic | NIC")
+ logging.info("[type]:")
+ logging.info(" driver | DRIVER | driver_ubus | DRIVER_UBUS")
+ logging.info("[driver_type]:")
+ logging.info(" kernel | KERNEL | user | USER")
+ logging.info("[ubus_edition_type]:")
+ logging.info(" b180 | b186 | b188")
+
+def get_hi1823_arg(arg):
+ if env.hi1823_feature == None:
+ env.hi1823_feature = hi1823_feature_dict.get(arg, None)
+ if env.hi1823_feature != None:
+ return 0
+
+ if env.hi1823_type == None:
+ env.hi1823_type = hi1823_type_dict.get(arg, None)
+ if env.hi1823_type != None:
+ return 0
+
+ if env.hi1823_driver_type == None:
+ env.hi1823_driver_type = hi1823_driver_type_dict.get(arg, None)
+ if env.hi1823_driver_type != None:
+ return 0
+
+ if env.hi1823_fc_os_release_type == None:
+ env.hi1823_fc_os_release_type = hi1823_fc_os_release_type_dict.get(arg, None)
+ if env.hi1823_fc_os_release_type != None:
+ return 0
+
+ if env.hi1823_ubus_driver_unified_compile_edition == None:
+ env.hi1823_ubus_driver_unified_compile_edition = hi1823_driver_ubus_edition_dict.get(arg, None)
+ if env.hi1823_ubus_driver_unified_compile_edition != None:
+ return 0
+
+ global chip_version
+ if chip_version == None:
+ arg_lower = arg.lower()
+ if arg_lower.startswith("hi") and "v" in arg_lower: # 芯片的型号为 hi1823v100,检测hi v
+ chip_version = arg_lower
+ if chip_version != None:
+ return 0
+
+ if env.hi1823_env_type == None:
+ for key,value in hi1823_env_type_dict.items():
+ if arg.startswith(key):
+ env.hi1823_env_type = value[0]
+ env.hi1823_os_path = value[1]
+ env.hi1823_component_path = value[2]
+ env.hi1823_1650_build_version = arg
+ return 0
+
+ logging.error(f"argument is unexpect. extras arg [{arg}]")
+ return 1
+
+if __name__ == "__main__":
+ count = 0
+
+ for arg in sys.argv:
+ if count == 0:
+ count += 1
+ continue
+ else:
+ print(f"arg = {arg}")
+ ret = get_hi1823_arg(arg)
+ count += 1
+ if ret:
+ logging.error(f"get argument fail")
+ manual()
+ sys.exit(1)
+
+ if chip_version == None:
+ chip_version = "hi1823v200"
+
+ os.putenv("CHIP_VERSION", chip_version)
+
+ logging.info(f"""env.hi1823_feature = {env.hi1823_feature}. hi1823_type = {env.hi1823_type}.
+env.hi1823_driver_type = {env.hi1823_driver_type}.""")
+
+ if env.hi1823_type == "DRIVER":
+ ret = build_host.build_host_main()
+ if ret:
+ sys.exit(1)
+ elif env.hi1823_type == "DRIVER_UBUS":
+ env.hi1823_ubus_driver_unified_compile = True
+ ret = build_host.build_host_main()
+ if ret:
+ sys.exit(1)
+ else:
+ logging.error(f"Unkown type, Please check your inputting! hi1823_type = {env.hi1823_type}")
diff --git a/drivers/net/ethernet/huawei/hinic5/build/build_util.py b/drivers/net/ethernet/huawei/hinic5/build/build_util.py
new file mode 100755
index 000000000..769323377
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/build_util.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved.
+
+import logging
+import os
+import subprocess
+import sys
+
+
+def _format_cmd(cmd):
+ if isinstance(cmd, list) or isinstance(cmd, tuple):
+ return ' '.join(cmd)
+ return cmd
+
+def _format_cmd_output(output: str):
+ append = '\n'
+ if output and output[-1] == '\n':
+ append = ''
+ return f'{"=" * 50} Output {"=" * 50}\n{output}{append}{"=" * 108}\n'
+
+def _subprocess_run_compat_args():
+ # capture output and decode output to text
+ if sys.version_info >= (3, 7):
+ return {
+ 'text': True,
+ # 'capture_output': True, # capture stdout and stderr into two separate pipes
+ 'stdout': subprocess.PIPE,
+ 'stderr': subprocess.STDOUT,
+ }
+ else:
+ return {
+ 'universal_newlines': True,
+ 'stdout': subprocess.PIPE,
+ 'stderr': subprocess.STDOUT,
+ }
+
+def do_cmd(*cmd, input=None, check=True, shell=False, verbose=False, silence=False, **kwargs):
+ """
+ Wrapper for subprocess.run()
+ """
+ if not verbose and not silence:
+ logging.info(f'EXEC: {_format_cmd(cmd)}')
+
+ try:
+ r = subprocess.run(list(cmd), input=input, check=check, shell=shell, errors='replace',
+ **_subprocess_run_compat_args(), **kwargs)
+ if verbose and not silence:
+ logging.info(f'EXEC: {_format_cmd(cmd)}, return {r.returncode}\n{_format_cmd_output(r.stdout)}')
+ return r
+ except subprocess.CalledProcessError as e:
+ if not silence:
+ logging.error(f'EXEC: {_format_cmd(cmd)}\n{e}\n{_format_cmd_output(e.stdout)}')
+ raise
+ except Exception as e:
+ logging.error(f'EXEC: {e}')
+ raise
+
+
+def try_run(*cmd, verbose=False, **kwargs):
+ """
+ Try runnnig a command, no errors will be printed
+ """
+ try:
+ if verbose:
+ return do_cmd(*cmd, verbose=True, **kwargs)
+ else:
+ return do_cmd(*cmd, silence=True, **kwargs)
+ except subprocess.CalledProcessError:
+ # ignore called error
+ return None
+
+
+def try_run_and_test(*cmd, verbose=False, **kwargs) -> bool:
+ """
+ Try runnnig a command, and return whether retcode is zero (success)
+ """
+ p = try_run(*cmd, verbose=verbose, **kwargs)
+ return p and p.returncode == 0
+
+
+def do_make(*make_args,
+ workdir='',
+ jobs=0, jobs_is_cpu_count=True,
+ verbose=True):
+ args = []
+ if workdir:
+ args += ['-C', workdir]
+ if jobs:
+ args += ['-j', str(jobs)]
+ elif jobs_is_cpu_count:
+ args += ['-j', str(os.cpu_count())]
+
+ do_cmd('make', *args, *make_args, verbose=verbose)
+
+
+def do_make_clean(workdir=''):
+ do_make('clean', workdir=workdir, jobs_is_cpu_count=False, verbose=False)
+
+
+def rpm_build(workdir, spec, arch):
+ cmd = ['rpmbuild', '--define', f'_topdir {workdir}', '-bb', spec]
+ if arch == 'aarch64':
+ cmd.append('--target=aarch64')
+ do_cmd(*cmd, cwd=f'{workdir}/SPECS')
diff --git a/drivers/net/ethernet/huawei/hinic5/build/env.py b/drivers/net/ethernet/huawei/hinic5/build/env.py
new file mode 100755
index 000000000..3be01f6e9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/env.py
@@ -0,0 +1,708 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+import shutil
+import logging
+import platform
+import subprocess
+from build_util import try_run_and_test
+
+logging.getLogger().setLevel(logging.INFO)
+DIR_HEAD = "/"
+
+HI1823_BUILD_DIR = os.path.dirname(__file__)
+HI1823_BUILD_HOST_DIR = f"{HI1823_BUILD_DIR}/host/linux"
+HI1823_TRUNK_DIR = os.path.split(HI1823_BUILD_DIR)[0]
+HI1823_BUILD_HINICADM_DIR = f"{HI1823_BUILD_DIR}/tools/linux/hinicadm"
+HI1823_BUILD_HINICADMDFX_DIR = f"{HI1823_BUILD_DIR}/tools/linux/hinicadmdfx"
+HI1823_BUILD_HIFCADMDFX_DIR = f"{HI1823_BUILD_DIR}/tools/linux/hifcadmdfx"
+HI1823_BUILD_UBTEST_DIR = f"{HI1823_BUILD_DIR}/tools/linux/ub-test"
+HI1823_BUILD_UBMAC_DIR = f"{HI1823_TRUNK_DIR}/test/at_test/ubmac"
+HI1823_BUILD_SDK_DIR = f"{HI1823_BUILD_DIR}/host/linux/sdk"
+HI1823_BUILD_LOG_PATH = f"{HI1823_BUILD_DIR}/tools/build_log"
+HI1823_LLD_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/knldk/lld"
+HI1823_RPM_BUILD_DIR = f"{HI1823_TRUNK_DIR}/rpmbuild"
+HI1823_DEB_BUILD_DIR = f"{HI1823_TRUNK_DIR}/debbuild"
+HI1823_BUILD_SSSDK_DIR = f"{HI1823_BUILD_DIR}/host/linux/sss"
+HI1823_HOTPATCH_BUILD_DIR = f"{HI1823_TRUNK_DIR}/../patch_build"
+HI1823_BUILD_NIC_DIR = f"{HI1823_BUILD_DIR}/host/linux/nic"
+HI1823_BUILD_IPSEC_DIR = f"{HI1823_BUILD_DIR}/host/linux/crypt"
+HI1872_BUILD_MACSEC_DIR = f"{HI1823_BUILD_DIR}/host/linux/macsec"
+HI1823_IPSEC_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/crypt"
+HI1872_MACSEC_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/macsec"
+HI1823_BUILD_PPA_DIR = f"{HI1823_BUILD_DIR}/host/linux/ppa"
+HI1823_OPENSOURCE_DIR = f"{HI1823_BUILD_DIR}/../../Opensource"
+HI1823_V100_TOP_DIR = f"{HI1823_BUILD_DIR}/../../Hi1823_chip_solution"
+HI1823_BUILD_DPDK_DIR = f"{HI1823_BUILD_DIR}/host/linux/dpdk"
+HI1823_BUILD_ROCE_DIR = f"{HI1823_BUILD_DIR}/host/linux/roce"
+HI1823_BUILD_UDMA_DIR = f"{HI1823_BUILD_DIR}/host/linux/udma"
+HI1823_BUILD_PLOG_DIR = f"{HI1823_BUILD_DIR}/host/linux/plog"
+HI1823_BUILD_OVS_DIR = f"{HI1823_BUILD_DIR}/host/linux/ovs"
+HI1872_BUILD_PFE_DIR = f"{HI1823_BUILD_DIR}/host/linux/pfe"
+HI1823_BUILD_HPD_DIR = f"{HI1823_BUILD_DIR}/host/linux/hpd"
+HI1823_BUILD_TOE_DIR = f"{HI1823_BUILD_DIR}/host/linux/toe"
+HI1823_BUILD_DTOE_DIR = f"{HI1823_BUILD_DIR}/host/linux/dtoe"
+HI1823_BUILD_VBS_DIR = f"{HI1823_BUILD_DIR}/host/linux/dsware"
+HI1823_BUILD_MIGRATE_DIR = f"{HI1823_BUILD_DIR}/host/linux/migrate"
+HI1823_BUILD_DMMU_DIR = f"{HI1823_BUILD_DIR}/host/linux/dmmu"
+HI1823_BUILD_JBOF_DIR = f"{HI1823_BUILD_DIR}/host/linux/jbof"
+HI1823_BUILD_DIST_QOS_DIR = f"{HI1823_BUILD_DIR}/host/linux/dist_qos"
+
+HI1823_BUILD_UBUS_KERNEL_DIR = f"{HI1823_BUILD_DIR}/../../../KunpengTrunk/open_source/2403_SP2"
+HI1823_BUILD_UBUS_DRIVER_MODULE_DIR = f"{HI1823_BUILD_DIR}/../../../KunpengTrunk/open_source/2403_SP2/ubus"
+
+hi1823_type = None
+hi1823_feature = None
+hi1823_driver_type = None
+hi1823_fc_os_release_type = None
+hi1823_env_type = None
+hi1823_os_path = None
+hi1823_component_path = None
+
+hi1823_1650_build_version = None
+hi1823_bin_dir = None
+hi1823_ci_lib_dir = None
+hi1823_nic_code_dir = None
+hi1823_dist_qos_code_dir = None
+hi1823_ppa_code_dir = None
+hi1823_dpdk_code_dir = None
+hi1823_ppa_usr_code_dir = None
+huawei_secure_code_dir = None
+hi1823_roce_knl_code_dir = None
+hi1823_roce_usr_code_dir = None
+hi1823_udma_knl_code_dir = None
+hi1823_udma_usr_code_dir = None
+hi1823_plog_code_dir = None
+hi1823_ovs_knl_code_dir = None
+hi1823_ovs_usr_code_dir = None
+hi1872_pfe_code_dir = None
+hi1823_hpd_code_dir = None
+hi1823_toecore_code_dir = None
+hi1823_tom_code_dir = None
+hi1823_vbs_knl_code_dir = None
+hi1823_vbs_usr_code_dir = None
+hi1823_migrvf_base_code_dir = None
+hi1823_migrvf_virtio_code_dir = None
+hi1823_migrvf_ub_code_dir = None
+hi1823_cloud_migration_dir = None
+hi1823_cloud_migration_fake_zero_dir = None
+hi1823_compute_migration_dir = None
+hi1823_dmmu_code_dir = None
+hi1823_jbof_usr_code_dir = None
+hi1823_jbof_usr_at_code_dir = None
+hi1823_tifoe_knl_code_dir = None
+hi1823_tifoe_usr_code_dir = None
+HI1823_FC_CODE_DIR = None
+
+hi1823_os_arch = None
+hi1823_complie_os_kver = None
+hi1823_complie_os_kver_underline = None
+hi1823_os_type = None
+hi1823_os_release = None
+hi1823_os_pkg_mgr = None
+hi1823_vpmd_code_dir = None
+
+build_roce_mode = None
+
+hi1823_ubus_driver_unified_compile = False
+hi1823_ubus_driver_unified_compile_edition = None
+
+def copy_file(srcfile, dstpath, dst_fname = None):
+ if not os.path.isfile(srcfile):
+ logging.error(f"{srcfile} not exist!")
+ return 1
+ else:
+ fpath, fname = os.path.split(srcfile)
+ if not os.path.exists(dstpath):
+ os.makedirs(dstpath)
+ if dst_fname:
+ shutil.copy(srcfile, f"{dstpath}/{dst_fname}")
+ else:
+ shutil.copy(srcfile, f"{dstpath}/{fname}")
+
+ return 0
+
+def copy_file_with_end(srcpath, dstpath, suffix):
+ if not os.path.exists(srcpath):
+ logging.error(f"{srcpath} not exist!")
+ return 1
+ else:
+ if not os.path.exists(dstpath):
+ os.makedirs(dstpath)
+ for file_name in os.listdir(srcpath):
+ if file_name.endswith(suffix):
+ ret = copy_file(f"{srcpath}/{file_name}", dstpath)
+ if ret:
+ return ret
+
+ return 0
+
+def copy_file_with_start(srcpath, dstpath, prefix):
+ if not os.path.exists(srcpath):
+ logging.error(f"{srcpath} not exist!")
+ return 1
+ else:
+ if not os.path.exists(dstpath):
+ os.makedirs(dstpath)
+ for file_name in os.listdir(srcpath):
+ if file_name.startswith(prefix):
+ ret = copy_file(f"{srcpath}/{file_name}", dstpath)
+ if ret:
+ return ret
+
+ return 0
+
+def copy_file_with_start_and_end(srcpath, dstpath, prefix, suffix):
+ if not os.path.exists(srcpath):
+ logging.error(f"{srcpath} not exist!")
+ return 1
+ else:
+ if not os.path.exists(dstpath):
+ os.makedirs(dstpath)
+ for file_name in os.listdir(srcpath):
+ if file_name.startswith(prefix) and file_name.endswith(suffix):
+ ret = copy_file(f"{srcpath}/{file_name}", dstpath)
+ if ret:
+ return ret
+
+ return 0
+
+def collect_build_info(path, dst_dir, suffix=None):
+ if suffix:
+ build_info = f"build_info_{suffix}.txt"
+ else:
+ build_info = "build_info.txt"
+
+ if os.path.isfile(f"{path}/{build_info}"):
+ if not os.path.isfile(f"{dst_dir}/{build_info}"):
+ logging.info(f"collect_build_info. path = [{path}], dst_dir = [{dst_dir}]")
+ build_file = f"{dst_dir}/{build_info}"
+ cmd = ["cat", f"{path}/{build_info}"]
+ try:
+ with open(build_file, 'wb') as fp:
+ rslt = subprocess.run(cmd, shell=False, check=True, stdout=fp, stderr=subprocess.PIPE)
+ except Exception as e:
+ logging.error(f"exec cmd fail:{e}. error = [{rslt.stderr}]")
+ return 1
+
+ return 0
+
+def set_env():
+ os.environ['HI1823_TRUNK_DIR'] = HI1823_TRUNK_DIR
+ os.environ['HI1823_BUILD_DIR'] = HI1823_BUILD_DIR
+ os.environ['HI1823_BIN_DIR'] = hi1823_bin_dir
+ if not hi1823_os_type:
+ logging.warning("hi1823_os_type is none. not set env")
+ else:
+ os.environ['HI1823_OS_TYPE'] = hi1823_os_type
+ if not hi1823_os_release:
+ logging.warning("hi1823_os_release is none. not set env")
+ else:
+ os.environ['HI1823_OS_RELEASE'] = hi1823_os_release
+ if not HI1823_FC_CODE_DIR:
+ logging.warning("HI1823_FC_CODE_DIR is none. not set env")
+ else:
+ os.environ['HI1823_FC_CODE_DIR'] = HI1823_FC_CODE_DIR
+
+ if hi1823_ubus_driver_unified_compile == True:
+ os.environ['CONFIG_UB_UNIFIED_UBUS'] = "y"
+ if not HI1823_BUILD_UBUS_DRIVER_MODULE_DIR:
+ logging.warning("HI1823_BUILD_UBUS_DRIVER_MODULE_DIR is none. not set env")
+ else:
+ os.environ['UBUS_MODULE_DIR'] = HI1823_BUILD_UBUS_DRIVER_MODULE_DIR
+
+ if not HI1823_BUILD_UBUS_KERNEL_DIR:
+ logging.warning("HI1823_BUILD_UBUS_KERNEL_DIR is none. not set env")
+ else:
+ os.environ['UBUS_BUILD_KERNEL_DIR'] = HI1823_BUILD_UBUS_KERNEL_DIR
+
+ if hi1823_ubus_driver_unified_compile_edition == "B188":
+ os.environ['CONFIG_UB_UBUS_B188'] = "y"
+ else:
+ os.environ['CONFIG_UB_UBUS_B188'] = "n"
+
+def dir_define():
+ global hi1823_bin_dir
+ global hi1823_ci_lib_dir
+ global hi1823_nic_code_dir
+ global hi1823_dist_qos_code_dir
+ global hi1823_ppa_code_dir
+ global hi1823_dpdk_code_dir
+ global hi1823_ppa_usr_code_dir
+ global huawei_secure_code_dir
+ global hi1823_roce_knl_code_dir
+ global hi1823_roce_usr_code_dir
+ global hi1823_udma_knl_code_dir
+ global hi1823_udma_usr_code_dir
+ global hi1823_plog_code_dir
+ global hi1823_ovs_knl_code_dir
+ global hi1823_ovs_usr_code_dir
+ global hi1872_pfe_code_dir
+ global hi1823_hpd_code_dir
+ global hi1823_toecore_code_dir
+ global hi1823_tom_code_dir
+ global hi1823_vbs_knl_code_dir
+ global hi1823_vbs_usr_code_dir
+ global hi1823_migrvf_base_code_dir
+ global hi1823_migrvf_virtio_code_dir
+ global hi1823_migrvf_ub_code_dir
+ global hi1823_cloud_migration_dir
+ global hi1823_cloud_migration_fake_zero_dir
+ global hi1823_compute_migration_dir
+ global hi1823_dmmu_code_dir
+ global hi1823_jbof_usr_code_dir
+ global hi1823_jbof_usr_at_code_dir
+ global hi1823_vpmd_code_dir
+ global hi1823_tifoe_knl_code_dir
+ global hi1823_tifoe_usr_code_dir
+ global HI1823_FC_CODE_DIR
+
+ #Directories must define in this function, because HI1823_TRUNK_DIR may be change in cross compile conditions.
+ hi1823_nic_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/nic/linux"
+ hi1823_dpdk_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/nic/dpdk"
+ hi1823_dist_qos_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/dist_qos/kernel"
+ hi1823_ppa_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/ppa/kernel"
+ hi1823_ppa_usr_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/ppa/usr"
+ HI1823_CRYPT_CODE_DIR = f"{HI1823_TRUNK_DIR}/test/crypt"
+ HI1823_FC_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/fc/linux"
+ HI1823_FC_TGT_DIR = f"{HI1823_TRUNK_DIR}/test/fc_tgt"
+ hi1823_plog_code_dir = f"{HI1823_TRUNK_DIR}/test/chip_level_test/plog_at_src"
+ hi1823_ovs_knl_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/ovs/linux/kernel"
+ hi1823_ovs_usr_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/ovs/linux/user"
+ # hi1872_pfe_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/pfe"
+ hi1872_pfe_code_dir = f"{HI1823_TRUNK_DIR}/test/non_product/pfe"
+ hi1823_hpd_code_dir = f"{HI1823_TRUNK_DIR}/test/samples/sdi/hpd"
+ HI1823_ISN_USR_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/driver/linux/isn/lib"
+ HI1823_ISN_APP_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/driver/linux/isn/app"
+ HI1823_ISN_KNL_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/driver/linux/isn/kernel"
+ hi1823_vbs_knl_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/vbs/kernel"
+ hi1823_vbs_usr_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/vbs/user"
+ hi1823_jbof_usr_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/jbof/user"
+ hi1823_jbof_usr_at_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/jbof/user_at"
+ hi1823_vpmd_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/usrdk/vpmd"
+ HI1823_SDK_CODE_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/knldk/"
+ hi1823_bin_dir = f"{HI1823_TRUNK_DIR}/bin"
+ hi1823_ci_lib_dir = f"{HI1823_TRUNK_DIR}/ci/lib"
+ hi1823_roce_knl_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/roce/linux/kernel"
+ hi1823_roce_usr_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/roce/linux/user"
+ HI1823_ROCE_HW_VERBS_EXT_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_extended_library/roce/hw_verbs_ext"
+ HI1823_ROCE_HW_ROCE_EXT_DIR = f"{HI1823_TRUNK_DIR}/src/dpu_extended_library/roce/hw_roce_ext"
+ hi1823_udma_knl_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/udma/kernel"
+ hi1823_udma_usr_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/udma/user"
+ huawei_secure_code_dir = f"{HI1823_TRUNK_DIR}/platform/huawei_secure_c/"
+ HI1823_CI_BUILD_DIR = f"{HI1823_TRUNK_DIR}/ci/build"
+ HI1823_TOE_CODE_DIR = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/toe"
+ hi1823_tom_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/toe/toecode"
+ hi1823_toecore_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/toe/toecore"
+ HI1823_TOEDFX_CODE_DIR = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/toe/dfx"
+ hi1823_tifoe_knl_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/toe_tifoe_test/kernel"
+ hi1823_tifoe_usr_code_dir = f"{HI1823_TRUNK_DIR}/test/at_test/host/service/toe_tifoe_test/user"
+ hi1823_migrvf_base_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/migrate/base"
+ hi1823_migrvf_virtio_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/migrate/virtio"
+ hi1823_migrvf_ub_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/migrate/ub"
+ hi1823_cloud_migration_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/migrate"
+ hi1823_cloud_migration_fake_zero_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/migrate/zero"
+ hi1823_compute_migration_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/migrate/virtio_product/computing"
+ hi1823_dmmu_code_dir = f"{HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/dmmu"
+
+def get_package_manager_type():
+ """
+ Checks if the Linux system uses RPM or DEB based package management.
+ Returns 'rpm', 'deb', or 'unknown' if neither is detected.
+ """
+ if try_run_and_test('test', '-f', '/etc/redhat-release', verbose=True):
+ return 'rpm'
+ if try_run_and_test('test', '-f', '/etc/debian_version', verbose=True):
+ return 'deb'
+ if try_run_and_test('which', 'rpm', verbose=True):
+ return 'rpm'
+ if try_run_and_test('which', 'dpkg', verbose=True):
+ return 'deb'
+ return 'unknown'
+
+def get_driver_output_path(driver_type):
+ global hi1823_bin_dir, hi1823_os_arch, hi1823_os_release
+ if hi1823_os_arch == 'x86_64':
+ return f'{hi1823_bin_dir}/driver/linux/{driver_type}/{hi1823_os_release}'
+ return f'{hi1823_bin_dir}/driver/linux/{driver_type}/arm/{hi1823_os_release}'
+
+def get_os_info_by_eulerlinux():
+ global hi1823_os_type
+ global hi1823_os_release
+ hi1823_diff_id = os.getenv('HI1823_DIFF_ID', None)
+ with open("/etc/EulerLinux.conf", 'r') as file:
+ os_file_info = file.read()
+ if (re.search("pangea", os_file_info, re.IGNORECASE) or \
+ re.search("storage", os_file_info, re.IGNORECASE)):
+ hi1823_os_type = "PANGEA"
+ cmd = f"cat {DIR_HEAD}etc/EulerLinux.conf | grep -iE 'version=euleros' | awk -F '=' '{{print $2}}' |\
+ sed 's/_/ /g' | grep -o V.* | awk '{{print $1}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"PANGEA_{version}"
+ elif re.search("uvp", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "UVP"
+ cmd = f"cat {DIR_HEAD}etc/EulerLinux.conf | grep -iE 'uvp_version' | awk -F '=' '{{print $2}}' | sed 's/-/_/g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ if hi1823_diff_id:
+ hi1823_os_release = f"{version}_{hi1823_diff_id}"
+ else:
+ hi1823_os_release = version
+ elif (re.search("EulerOS", os_file_info, re.IGNORECASE) and \
+ re.search("storage", hi1823_complie_os_kver, re.IGNORECASE)) or \
+ hi1823_complie_os_kver == "4.1.18-vhulk3.3.5.aarch64":
+ hi1823_os_type = "EULEROS_PANGEA"
+ cmd = f"cat {DIR_HEAD}etc/EulerLinux.conf | grep -iE 'version' | awk -F '=' '{{print $2}}' |\
+ awk -F '-' '{{print $1}}' | tr 'a-z' 'A-Z'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ if hi1823_diff_id:
+ hi1823_os_release = f"{version}_{hi1823_diff_id}"
+ else:
+ hi1823_os_release = version
+ elif re.search("EulerOS", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "EULEROS"
+ cmd = f"cat {DIR_HEAD}etc/EulerLinux.conf | grep -iE 'version' | awk -F '=' '{{print $2}}' |\
+ awk -F '-' '{{print $1}}' | tr 'a-z' 'A-Z'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ if hi1823_diff_id:
+ hi1823_os_release = f"{version}_{hi1823_diff_id}"
+ else:
+ hi1823_os_release = version
+ elif re.search("HyperStack", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "HyperStack"
+ cmd = f"cat {DIR_HEAD}etc/EulerLinux.conf | grep -iE 'version' | awk -F '=' '{{print $2}}' |\
+ awk -F '-' '{{print $1}}' | tr 'a-z' 'A-Z'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = version
+ elif re.search("HCE", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "HCE"
+ cmd = f"cat {DIR_HEAD}etc/EulerLinux.conf | grep -iE 'version' | awk -F '=' '{{print $2}}' |\
+ sed 's/-/_/g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ if hi1823_diff_id:
+ hi1823_os_release = f"{version}_{hi1823_diff_id}"
+ else:
+ hi1823_os_release = version
+
+ return 0
+
+def get_os_info_by_euleros_latest():
+ global hi1823_os_type
+ global hi1823_os_release
+ with open("/etc/euleros-latest", 'r') as file:
+ os_file_info = file.read()
+ if (re.search("pangea", os_file_info, re.IGNORECASE) or \
+ re.search("storage", os_file_info, re.IGNORECASE)):
+ hi1823_os_type = "PANGEA"
+ cmd = f"cat {DIR_HEAD}etc/euleros-latest | grep -iE 'version=euleros' | awk -F '=' '{{print $2}}' |\
+ sed 's/_/ /g' | grep -o V.* | awk '{{print $1}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"PANGEA_{version}"
+ elif re.search("uvp", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "UVP"
+ cmd = f"cat {DIR_HEAD}etc/euleros-latest | grep -iE 'uvp_version' | awk -F '=' '{{print $2}}' | sed 's/-/_/g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = version
+ elif re.search("EulerOS", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "EULEROS"
+ cmd = f"cat {DIR_HEAD}etc/euleros-latest | grep -iE 'eulerversion' | awk -F '=' '{{print $2}}' |\
+ awk -F '-' '{{print $1}}' | tr 'a-z' 'A-Z'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = version
+
+ return 0
+
+def _os_release_row_parser(row):
+ m = re.match('(\w+)="(.*)"', row)
+ return m.group(1), m.group(2)
+
+def get_os_info_for_alinux():
+ if not os.path.exists("/etc/os-release"):
+ raise Exception("no /etc/os-release for alinux")
+
+ with open("/etc/os-release", 'r') as file:
+ items = [_os_release_row_parser(row) for row in file]
+ os_info = dict(items)
+
+ os_id = os_info['ID'].upper()
+ os_ver_id = os_info['VERSION_ID']
+ os_var_id = os_info.get('VARIANT_ID')
+
+ if os_id == 'ALINUX':
+ # OpenAnolis
+ if os_var_id == 'openanolis':
+ alinux_minor = os_info['ALINUX_MINOR_ID']
+ alinux_update = os_info['ALINUX_UPDATE_ID']
+ os_ver = f'{os_ver_id}_{alinux_minor}_U{alinux_update}_{os_var_id.upper()}'
+ # No variant
+ else:
+ alinux_update = os_info['UPDATE_ID']
+ os_ver = f'{os_ver_id}_U{alinux_update}'
+ else:
+ raise Exception(f'unknown OS ID "{os_id}" for alinux')
+
+ global hi1823_os_type, hi1823_os_release
+ hi1823_os_type = os_id
+ hi1823_os_release = f'{os_id}_{os_ver}'
+
+def get_os_info_by_os_release():
+ global hi1823_os_type, hi1823_os_release, hi1823_complie_os_kver_underline, hi1823_os_arch
+ with open("/etc/os-release", 'r') as file:
+ os_file_info = file.read()
+ if re.search("kylin", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "KYLIN"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION_ID' | awk -F '=' '{{print $2}}' | sed 's/\"//g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ if re.search("Tercel", os_file_info, re.IGNORECASE):
+ global hi1823_complie_os_kver
+ if "23.8.v2101.ky10" in hi1823_complie_os_kver:
+ hi1823_os_release = f"Kylin{version}SP1_BUILD20"
+ else:
+ hi1823_os_release = f"Kylin{version}SP1"
+ elif re.search("Sword", os_file_info, re.IGNORECASE):
+ hi1823_os_release = f"Kylin{version}SP2"
+ else:
+ hi1823_os_release = f"Kylin{version}"
+ elif re.search("UnionTech", os_file_info, re.IGNORECASE) or re.search("UOS", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "UOS"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION_ID' | awk -F '=' '{{print $2}}' | sed 's/\"//g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"UOS{version}"
+ elif re.search("ctyun", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "ctyun"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION_ID' | awk -F '=' '{{print $2}}' | sed 's/\"//g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"ctyun{version}"
+ elif re.search("anolis", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "anolis"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION_ID' | awk -F '=' '{{print $2}}' | sed 's/\"//g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"anolis{version}"
+ elif re.search("sles", os_file_info, re.IGNORECASE):
+ hi1823_os_type = "SUSE"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -wE 'VERSION' | awk -F '=' '{{print $2}}' | sed 's/\"//g' | sed 's/-//g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"SuSE{version}"
+ else:
+ hi1823_os_type = "Ubuntu"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -wE 'VERSION' | awk -F '=' '{{print $2}}' | sed 's/\"//g' |\
+ sed 's/-//g' | awk '{{print $1}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"ubuntu{version}_{hi1823_complie_os_kver_underline}_{hi1823_os_arch}"
+
+ return 0
+
+def get_os_info():
+ global hi1823_os_arch, hi1823_os_pkg_mgr
+ global hi1823_complie_os_kver, hi1823_complie_os_kver_underline
+ global hi1823_os_type, hi1823_os_release
+ hi1823_os_arch = platform.machine()
+ hi1823_os_pkg_mgr = get_package_manager_type()
+
+ cmd = "uname -r"
+ global hi1823_complie_os_kver
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ hi1823_complie_os_kver = output
+ hi1823_complie_os_kver_underline = output.replace('-', '_')
+
+ logging.info(f'hi1823_os_arch {hi1823_os_arch}')
+ logging.info(f'hi1823_os_pkg_mgr {hi1823_os_pkg_mgr}')
+ logging.info(f'hi1823_complie_os_kver {hi1823_complie_os_kver}')
+ logging.info(f'hi1823_complie_os_kver_underline {hi1823_complie_os_kver_underline}')
+
+ if os.path.isfile("/etc/EulerLinux.conf"):
+ return get_os_info_by_eulerlinux()
+
+ if os.path.isfile("/etc/euleros-latest"):
+ return get_os_info_by_euleros_latest()
+
+ if os.path.isfile("/etc/os-release"):
+ with open("/etc/os-release", "r") as f:
+ for line in f:
+ if line.startswith("NAME="):
+ os_name = line.strip().split("=")[1].strip('"')
+ break
+ if "Red Hat" in os_name:
+ hi1823_os_type = "REDHAT"
+ if os.path.isfile("/etc/os-release"):
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION_ID' | awk -F '=' '{{print $2}}' | sed 's/\"//g'"
+ else:
+ cmd = f"cat {DIR_HEAD}etc/redhat-release | awk -F 'release' '{{print $2}}' | sed 's/ //g' | awk -F '(' '{{print $1}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"RedHat{version}"
+ return 0
+
+ if os.path.isfile("/etc/bclinux-release"):
+ hi1823_os_type = "BCLINUX"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION_ID' | awk -F '=' '{{print $2}}' | sed 's/\"//g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"BCLinux{version}"
+ return 0
+
+ # Alibaba Cloud Linux
+ if os.path.exists('/etc/alinux-release'):
+ return get_os_info_for_alinux()
+
+ if os.path.isfile("/etc/centos-release") and not os.path.exists("/etc/euleros-release") and\
+ not os.path.exists("/etc/redflag-release"):
+ hi1823_os_type = "CENTOS"
+ cmd = f"cat {DIR_HEAD}etc/centos-release | grep -E 'release' | awk -F 'release ' '{{print $2}}' |\
+ awk -F \" \" '{{print $1}}'|awk -F \".\" '{{print $1\".\"$2}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"CentOS{version}"
+ return 0
+
+ if os.path.isfile("/etc/openEuler-release"):
+ hi1823_os_type = "openEuler"
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION=' | awk -F '[\" ]' '{{print $2}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version1 = output
+ cmd = f"cat {DIR_HEAD}etc/os-release | grep -E 'VERSION=' | awk -F '[-)\"]' '{{print $3}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version2 = output
+ hi1823_os_release = f"openEuler{version1}{version2}"
+ return 0
+
+ if os.path.isfile("/etc/hce-release"):
+ hi1823_os_type = "HCE"
+ cmd = f"cat {DIR_HEAD}etc/hce-latest | grep -iE 'hceversion' | awk -F '=' '{{print $2}}' | sed 's/-/_/g' | tr 'a-z' 'A-Z'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = version
+ return 0
+
+ if os.path.isfile("/etc/VesselOS-release"):
+ hi1823_os_type = "VesselOS"
+ cmd = f"cat {DIR_HEAD}etc/VesselOS-release | grep -E 'release' | awk -F 'release ' '{{print $2}}' |\
+ awk -F \" \" '{{print $1}}'|awk -F \".\" '{{print $1\".\"$2}}'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version = output
+ hi1823_os_release = f"VesselOS{version}"
+ return 0
+
+ if os.path.isfile("/etc/SuSE-release"):
+ hi1823_os_type = "SUSE"
+ cmd = f"cat {DIR_HEAD}etc/SuSE-release | grep -E 'VERSION' | awk -F '=' '{{print $2}}' | sed 's/ //g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version1 = output
+ cmd = f"cat {DIR_HEAD}etc/SuSE-release | grep -E 'PATCHLEVEL' | awk -F '=' '{{print $2}}' | sed 's/ //g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ version2 = output
+ hi1823_os_release = f"SuSE{version1}SP{version2}"
+
+ if os.path.isfile("/etc/os-release"):
+ return get_os_info_by_os_release()
+
+ return 0
+
+def get_global_version(type):
+ version_file = f"{HI1823_TRUNK_DIR}/src/GLOBAL_VERSION_NEW"
+ try:
+ with open(version_file) as file:
+ lines = file.readlines()
+ for line in lines:
+ ver_type = line.split(":")[0]
+ if ver_type == type:
+ value = line.split(":")[1]
+ return value.strip('\n')
+ except Exception as e:
+ logging.error(f"get global version [{type}] in [{version_file}] fail. error: {e} ")
+ return None
+
+ logging.error(f"no support global version [{type}] in [{version_file}].")
+ return None
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/Makefile.ko b/drivers/net/ethernet/huawei/hinic5/build/host/linux/Makefile.ko
new file mode 100644
index 000000000..88a56b175
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/Makefile.ko
@@ -0,0 +1,123 @@
+ccflags-y += -Wframe-larger-than=2048
+ccflags-y += -Wno-implicit-fallthrough
+
+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)\"
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface
+
+$(warning cflags, $(ccflags-y))
+V ?= 0
+
+
+ifeq ($(HI1823_RELEASE_TYPE), LLT)
+ ccflags-y += -D_LLT_TEST_
+else
+ ccflags-y += -DHW_CONVERT_ENDIAN
+endif
+
+ccflags-y += -D__LINUX__
+
+ifeq ($(HI1823_OS_TYPE), EULEROS)
+EXTRA_CFLAGS += -DOS_EULER
+endif
+ifeq ($(HI1823_OS_TYPE), openEuler)
+EXTRA_CFLAGS += -DOS_OPENEULER
+endif
+ifeq ($(HI1823_OS_TYPE), HCE)
+EXTRA_CFLAGS += -DOS_HCE
+endif
+ifeq ($(HI1823_OS_TYPE), Ubuntu)
+EXTRA_CFLAGS += -DOS_UBUNTU
+endif
+
+EXTRA_CFLAGS += -DSECUREC_EXPORT_KERNEL_SYMBOL=0
+
+KERNEL_VER ?= $(shell uname -r 2>/dev/null)
+
+ifeq ($(CONFIG_UB_UNIFIED_UBUS), y)
+KERNEL_DIR ?= $(UBUS_BUILD_KERNEL_DIR)
+DEFAULT_KERNEL_DIR ?= $(UBUS_BUILD_KERNEL_DIR)
+# 目前build_cache里的内核是6.6的,KERNEL_VER不影响功能,暂时写死
+KERNEL_VER ?= 6.6.0-132.0.0.111.oe2403sp3.aarch64
+else
+KERNEL_DIR ?= /lib/modules/$(KERNEL_VER)/build
+DEFAULT_KERNEL_DIR ?= /lib/modules/$(KERNEL_VER)/build
+endif
+
+OPTIONAL_FLAGS := -Wno-implicit-fallthrough -Wno-misleading-indentation -Wno-missing-prototypes -Wno-error=missing-declarations -Werror=date-time -Wno-missing-attributes -Wno-format-overflow -Wno-packed-not-aligned
+filter_unsupported_flag = \
+ $(eval support := $(call check_gcc_support, $(1))) \
+ $(if $(filter 0, $(support)), \
+ $(eval EXTRA_CFLAGS := $(filter-out $(1), $(EXTRA_CFLAGS))), \
+ $(eval EXTRA_CFLAGS += $(1)) \
+ ) \
+ $(if $(filter 0, $(support)), \
+ $(eval KBUILD_CFLAGS := $(filter-out $(1), $(KBUILD_CFLAGS))) \
+ )
+check_gcc_support = $(shell \
+ if echo "int main() { return 0; }" | gcc $(1) -c -x c -o /dev/null - 2>/dev/null; then \
+ gcc_support=1; \
+ else \
+ gcc_support=0; \
+ fi; \
+ \
+ if echo "int main() { return 0; }" | cc1 $(1) -x c - 2>/dev/null; then \
+ cc1_support=1; \
+ else \
+ cc1_support=0; \
+ fi; \
+ \
+ if command -v cc1 2>/dev/null; then \
+ if [ $$cc1_support -eq 1 ]; then \
+ echo 1; \
+ else \
+ echo 0; \
+ fi; \
+ else \
+ if [ $$gcc_support -eq 1 ]; then \
+ echo 1; \
+ else \
+ echo 0; \
+ fi; \
+ fi \
+)
+$(foreach flag, $(OPTIONAL_FLAGS), $(call filter_unsupported_flag, $(flag)))
+
+# CONFIG_FRAME_WARN
+CONFIG_FRAME := $(shell grep -q "CONFIG_FRAME_WARN=1024" $(KERNEL_DIR)/.config && echo 1)
+ifeq ($(CONFIG_FRAME),1)
+ EXTRA_CFLAGS += -Wframe-larger-than=2048
+endif
+
+# STACK_PROTECT
+NO_STACK_PROTECT := $(shell grep -q "STACKPROTECTOR_NONE=y" $(KERNEL_DIR)/.config && echo 1)
+STACK_PROTECT := $(shell grep -q "STACKPROTECTOR=y" $(KERNEL_DIR)/.config && echo 1)
+ifneq ($(NO_STACK_PROTECT),1)
+ ifeq ($(STACK_PROTECT),1)
+ EXTRA_CFLAGS += -fstack-protector-all
+ endif
+endif
+
+ifneq ($(KERNEL_DIR),$(DEFAULT_KERNEL_DIR))
+ # 尝试执行make kernelrelease
+ KERNEL_RELEASE := $(shell cd $(KERNEL_DIR) && make kernelrelease 2>/dev/null)
+
+ ifneq ($(KERNEL_RELEASE),)
+ # 如果执行成功,更新KERNEL_VER
+ KERNEL_VER := $(KERNEL_RELEASE)
+ $(info execute 'make kernelrelease' in $(KERNEL_DIR), using kernel version $(KERNEL_VER))
+ else
+ # 如果执行失败,保持原值并打印信息
+ $(warning Failed to execute 'make kernelrelease' in $(KERNEL_DIR), using default kernel version $(KERNEL_VER))
+ endif
+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
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/__init__.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/__init__.py
new file mode 100755
index 000000000..cc0d19d0a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/__init__.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/build_host.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/build_host.py
new file mode 100755
index 000000000..e11fbded3
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/build_host.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+import env
+import logging
+import subprocess
+from pathlib import Path
+import shutil, random, string
+
+sys.path.append(env.HI1823_BUILD_SDK_DIR)
+import build_sdk
+sys.path.append(env.HI1823_BUILD_NIC_DIR)
+import build_nic
+sys.path.append(env.HI1823_BUILD_ROCE_DIR)
+import build_roce
+sys.path.append(env.HI1823_BUILD_UDMA_DIR)
+import build_udma
+
+def build_host_main():
+ # In order to adapt cross compile conditions.
+ env.dir_define()
+ ret = env.get_os_info()
+ if ret:
+ return ret
+ # set env for make cmd
+ env.set_env()
+
+ # Generating sdk compilation header file sdk_kcompat.h
+ sdk_kcompat_generator_path = Path(f"{env.HI1823_BUILD_SDK_DIR}/sdk-kcompat-generator.sh").resolve()
+ sdk_kcompat_path = f"{env.HI1823_TRUNK_DIR}/src/dpu_develop_interface/drv_sdk_intf/ossl/sdk_kcompat.h"
+
+ nic_kcompat_generator_path = Path(f"{env.HI1823_BUILD_NIC_DIR}/nic-kcompat-generator.sh").resolve()
+ nic_kcompat_generator_path_tmp = None
+ nic_kcompat_path = f"{env.HI1823_TRUNK_DIR}/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h"
+
+ if env.hi1823_ubus_driver_unified_compile == False:
+ subprocess.run(
+ [ "bash", "-c",
+ f"source {sdk_kcompat_generator_path} && gen_sdk_kcompat '{sdk_kcompat_path}'"
+ ],
+ check=True
+ )
+ else:
+ subprocess.run(
+ [ "bash", "-c",
+ f"source {sdk_kcompat_generator_path} && gen_sdk_kcompat '{sdk_kcompat_path}' '{env.HI1823_BUILD_UBUS_KERNEL_DIR}'"
+ ],
+ check=True
+ )
+
+ # Nic drv适配1650
+ ksrc = env.HI1823_BUILD_UBUS_KERNEL_DIR
+ nic_kcompat_generator_path_tmp = str(nic_kcompat_generator_path).replace(".sh", f"_{random.randint(1000, 9999)}.sh")
+ shutil.copy(nic_kcompat_generator_path, nic_kcompat_generator_path_tmp)
+
+ with open(nic_kcompat_generator_path_tmp, 'r') as f:
+ content = f.read().replace("KERN_VER=$(uname -r)", "KERN_VER=NULL")
+ content = content.replace('KSRC=""', f'KSRC="{ksrc}"')
+ with open(nic_kcompat_generator_path_tmp, 'w') as f:
+ f.write(content)
+ nic_kcompat_generator_path = nic_kcompat_generator_path_tmp
+
+ # Generating NIC compilation header file nic_kcompat.h
+ subprocess.run(
+ [ "bash", "-c",
+ f"source {nic_kcompat_generator_path} && gen_nic_kcompat '{nic_kcompat_path}'"
+ ],
+ check=True
+ )
+ if nic_kcompat_generator_path_tmp and os.path.exists(nic_kcompat_generator_path_tmp):
+ os.remove(nic_kcompat_generator_path_tmp)
+ print(f"nic_kcompat header file generated: {os.path.exists(nic_kcompat_path)}")
+
+ ret = 0
+ if env.hi1823_feature == "SDK":
+ ret = build_sdk.build_sdk()
+ elif env.hi1823_feature == "SDK_KO":
+ ret = build_sdk.build_sdk_ko()
+ elif env.hi1823_feature == "NIC":
+ ret = build_sdk.build_sdk()
+ if ret:
+ return ret
+ ret = build_nic.build_nic()
+ elif env.hi1823_feature == "NIC_KO":
+ ret = build_sdk.build_sdk_ko()
+ if ret:
+ return ret
+ ret = build_nic.build_nic_ko()
+ elif env.hi1823_feature == "ROCE":
+ ret = build_roce.build_roce()
+ elif env.hi1823_feature == "UDMA":
+ ret = build_udma.build_udma()
+ else:
+ logging.error("Unkown Feature, Please check your inputting!")
+
+ return ret
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/kcompat-lib.sh b/drivers/net/ethernet/huawei/hinic5/build/host/linux/kcompat-lib.sh
new file mode 100755
index 000000000..dcaa778c4
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/kcompat-lib.sh
@@ -0,0 +1,300 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright(c) 2025 Huawei Technologies Co., Ltd
+
+# Example of using the gen function
+# Required Field []
+# Optional Items ()
+# gen DEFINE if [fun|enum|struct|macro|typedef|symbol] NAME (absent) in <list-of-files>
+# gen DEFINE if [fun|enum|struct|macro|typedef|symbol] NAME [matches|lacks] PATTERN in <list-of-files>
+# gen DEFINE if [fun] NAME [countparam] [number] in <list-of-files>
+# gen DEFINE if [method] method_name of NAME [matches|lacks] PATTERN in <list-of-files>
+# gen DEFINE if [method] method_name of NAME [matches|lacks] (fun_param|return_type) PATTERN in <list-of-files>
+# gen DEFINE if [method] method_name of NAME (absent) in <list-of-files>
+# gen DEFINE if [method] method_name of NAME [countparam] [number] in <list-of-files>
+
+set -e
+
+function g_log_err() {
+ local log_time=$(date +"%Y-%m-%d %H:%M:%S")
+ echo >&2 "$log_time $@"
+ exit 10
+}
+
+WB='[ \t\n]'
+NI='[^A-Za-z0-9_]'
+# Return to function context, don't pass return type in $1
+# looks only in files specified (files[@], struct_context)
+function find_fun_context() {
+ test $# -ge 1
+ local start1 end1
+ start1="/$WB*([(]\*)?($NI|^)$1$WB*($|[()])/"
+ end1='/\);?$/'
+ shift
+ awk "
+ /^$WB*\*/ {next}
+ $start1, $end1
+ " "$@"
+}
+
+# Return to enum context
+function find_enum_context() {
+ test $# -ge 2
+ local start2 end2
+ start2="/^$WB*enum$WB+$1"' \{$/'
+ end2='/\};$/'
+ awk "
+ /^$WB*\*/ {next}
+ $start2, $end2
+ " ${files[@]}
+}
+
+# Return to struct context
+function find_struct_context() {
+ test $# -ge 2
+ local start3 end3
+ start3="/^$WB*struct$WB+$1"' \{$/'
+ end3='/^\};$/'
+ awk "
+ /^$WB*\*/ {next}
+ $start3, $end3
+ " ${files[@]}
+}
+
+# Return to first line of macro definition
+function find_macro_context() {
+ test $# -ge 2
+ local start4 end4
+ # Match only unindented macro definitions
+ start4="/^#define$WB+$1"'([ \t\(]|$)/'
+ end4=1 # Extract only the first row of the matched range.
+ awk "
+ /^$WB*\*/ {next}
+ $start4, $end4
+ " ${files[@]}
+}
+
+# Return to first line of $1 typedef definition
+# This only handles typedefs where the name is on first line
+function find_typedef_context() {
+ test $# -ge 2
+ local start5 end5
+ start5="/^typedef$WB.*$1"'[\(\); \t\n]/'
+ end5='/;$/'
+ awk "
+ /^$WB*\*/ {next}
+ $start5, $end5
+ " ${files[@]}
+}
+
+# Return to symbol line from Module.symvers
+function find_symbol_context() {
+ test $# -ge 2
+ local start6 end6
+ start6="/^0x[0-9a-f]+\t$1\t/"
+ end6=1 # only one line
+ awk "
+ /^$WB*\*/ {next}
+ $start6, $end6
+ " ${files[@]}
+}
+
+# Return the number of function parameters
+function count_fun_params() {
+ local context="$1"
+ local count=0
+
+ local params=$(echo "$context" | awk 'BEGIN{ORS=" "} {print}' | sed -n 's/.*(\(.*\)).*/\1/p' | xargs)
+ if [ -n "$params" ] && [ "$params" != "void" ]; then
+ IFS=',' read -ra param_array <<< "$params"
+ for param in "${param_array[@]}"; do
+ if [ -n "$(echo "$param" | tr -d '[:space:]')" ]; then
+ ((count+=1))
+ fi
+ done
+ else
+ count=0
+ fi
+ echo $count
+}
+
+function gen() {
+ test $# -ge 6 || g_log_err "$src_line: too few arguments"
+ local define="" struct_name="" member_name="" func_name=""
+ local src_line="${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
+ files=()
+ local context=""
+ local pattern='.'
+ local seen_in=0
+ local define="$1"
+ local param_count=""
+ [ "$2" != "if" ] && g_log_err "$src_line: 'if' keyword expected"
+ local kind="$3"
+ shift 3
+ if [ "$kind" = "string" ]; then
+ given_value="$1"
+ keyword="$2"
+ expected_value="$3"
+ found_fmt="#define %s 1\n"
+ if [ "${given_value}" = "${expected_value}" ]; then
+ printf -- "$found_fmt" "$define"
+ fi
+ return 0
+ fi
+ for arg in "$@"; do
+ if [ "$arg" = "in" ]; then
+ seen_in=1
+ continue
+ fi
+ if [ $seen_in -eq 1 ] && [ -e "$arg" ] ; then
+ files+=("$arg")
+ fi
+ done
+ if [ ${#files[@]} -eq 0 ]; then
+ echo >&2 "[INFO] ${BASH_LINENO[0]} gen invoked, but input file is missing."
+ return 0
+ fi
+
+ for f in "${files[@]}"; do
+ if [[ -e "$f" ]]; then
+ file_desc=$(file "$f")
+ # linux 下ASCII CRLF 文件匹配错误,需要告警退出
+ if [[ "$file_desc" == *"with CRLF line terminators"* ]]; then
+ echo >&2 "[ERROR] ${BASH_SOURCE[0]}:${BASH_LINENO[0]}: CRLF line endings detected in '$f'"
+ echo >&2 " This may cause parsing errors. Please convert to LF (Unix) line endings."
+ echo >&2 " Hint: run 'dos2unix \"$f\"' or 'sed -i \"s/\\r\$//\" \"$f\"'"
+ return 0
+ fi
+ fi
+ done
+
+ case "$kind" in
+ fun|enum|struct|macro|typedef|symbol)
+ test $# -ge 2 || g_log_err "$src_line: too few arguments"
+ name="$1"
+ shift
+ if [[ "$1" == "matches" || "$1" == "lacks" ]]; then
+ test $# -ge 2 || g_log_err "$src_line: too few arguments"
+ modelops="$1"
+ pattern="$2"
+ elif [[ "$1" == "absent" ]]; then
+ test $# -ge 2 || g_log_err "$src_line: too few arguments"
+ modelops="$1"
+ elif [[ "$1" == "countparam" ]]; then
+ test $# -ge 2 || g_log_err "$src_line: too few arguments"
+ modelops="$1"
+ param_count="$2"
+ else
+ modelops=matches
+ fi
+ context="$(find_${kind}_context "$name" "${files[@]}")"
+ process_context "$context" "$define" "$pattern" "$modelops" "$param_count"
+ ;;
+ method)
+ test $# -ge 5 || g_log_err "$src_line: too few arguments"
+ member_name="$1"
+ pattern="$1"
+ [ "$2" != of ] && g_log_err "$src_line: 'of' keyword expected"
+ struct_name="$3"
+ shift 3
+ if [[ "$1" == "matches" || "$1" == "lacks" ]]; then
+ modelops="$1"
+ pattern="$2"
+ if [[ "$2" == "return_type" || "$2" == "fun_param" ]]; then
+ pattern="$3"
+ fi
+ elif [[ "$1" == "countparam" ]]; then
+ modelops="$1"
+ param_count="$2"
+ elif [[ "$1" == "absent" ]]; then
+ modelops="$1"
+ else
+ modelops=matches
+ fi
+ local struct_context=""
+ struct_context="$(find_struct_context "$struct_name" "${files[@]}")"
+ context="$(find_fun_context "$member_name" <<< "$struct_context")"
+ process_context "$context" "$define" "$pattern" "$modelops" "$param_count"
+ ;;
+ *)
+ g_log_err "$src_line: unknown kind" ;;
+ esac
+}
+
+process_context() {
+ local context="$1" define="$2" pattern="$3" modelops="$4" param_count="$5"
+ local found=0 not_empty=0
+ if [ "$modelops" = "countparam" ]; then
+ local actual_param_count=$(count_fun_params "$context")
+ if [[ "$param_count" =~ ^[0-9]+$ ]] && [ "$actual_param_count" -eq "$param_count" ]; then
+ found=1
+ fi
+ else
+ # Use awk to check whether the given pattern matches in $context
+ read found not_empty <<< "$(awk -v pattern="$pattern" '
+ BEGIN {
+ NI = "[^A-Za-z0-9_]"
+ if (!match(pattern, NI "$"))
+ pattern = pattern "(" NI "|$)"
+ pattern = "(^|" NI ")" pattern
+ found = 0
+ not_empty = 0
+ }
+ /./ { not_empty = 1 } # mark context as non-empty
+ $0 ~ pattern { found = 1 } # mark if the pattern matches
+ END {
+ print found, not_empty
+ }
+ ' <<< "$context")"
+ fi
+ format_result "$define" "$found" "$not_empty" "$modelops"
+}
+
+format_result() {
+ local define="$1" found="$2" not_empty="$3" modelops="$4"
+ local found_fmt_tmp
+
+ found_fmt_tmp="#define %s 1\n";
+
+ if { [ "$modelops" = lacks ] && [ "$found" -eq 0 ] && [ "$not_empty" -eq 1 ]; } ||
+ { [ "$modelops" = matches ] && [ "$found" -eq 1 ]; } ||
+ { [ "$modelops" = absent ] && [ "$found" -eq 0 ]; } ||
+ { [ "$modelops" = countparam ] && [ "$found" -eq 1 ]; }
+ then
+ printf "$found_fmt_tmp" "$define"
+ fi
+}
+
+find_config_net_devlink() {
+ local -a config_files=( config_files
+ "$KOBJ/include/generated/autoconf.h"
+ "$KOBJ/include/linux/autoconf.h"
+ "$KOBJ/.config"
+ )
+ local file
+
+ echo >&2 "${KSRC-}"
+ if ! [ -d "${KSRC-}" ]; then
+ echo >&2 "Error: KSRC not valid"
+ exit 13
+ fi
+
+ for file in "${config_files[@]}"; do
+ if [ -f "$file" ]; then
+ echo >&2 "find config file: $file"
+ config_file=$(realpath "${file-}")
+ if grep -qE "^(#define )?CONFIG_NET_DEVLINK((_MODULE)? 1|=m|=y)$" "$config_file"; then
+ echo >&2 "CONFIG_NET_DEVLINK Found"
+ return 0
+ else
+ return 1
+ fi
+ fi
+ done
+ return 1
+}
+
+# return true/false instead of generating output.
+function check() {
+ [[ "$(gen CHECK if "$@")" = "#define CHECK 1" ]]
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/__init__.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/__init__.py
new file mode 100755
index 000000000..cc0d19d0a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/__init__.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/build_nic.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/build_nic.py
new file mode 100755
index 000000000..0f646b143
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/build_nic.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+import env
+import logging
+import shutil
+import subprocess
+from build_util import do_cmd, do_make, do_make_clean, rpm_build
+
+
+NIC_RPM_BUILD_DIR = f"{env.HI1823_BUILD_DIR}/host/linux/nic/nic_rpm_build/"
+nic_kcompat_file = f"{env.HI1823_TRUNK_DIR}/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h"
+
+def save_output(path):
+ shutil.rmtree(path, ignore_errors=True)
+ os.makedirs(path, exist_ok=True)
+ env.copy_file(f"{env.hi1823_nic_code_dir}/hinic5.ko", path)
+ env.copy_file(nic_kcompat_file, path)
+
+ # get build info
+ cmd = ["sh", f"{env.HI1823_BUILD_LOG_PATH}/build_log.sh", f"{env.hi1823_nic_code_dir}/build", path, "hinic5.ko"]
+ do_cmd(*cmd)
+
+ ret = env.collect_build_info(path, f"{env.hi1823_bin_dir}/driver/linux/nic")
+ if ret:
+ raise Exception('env.collect_build_info failed')
+
+ # strip debug info of ko for release rpm or deb package
+ cmd = ["strip", "--strip-debug", f"{path}/hinic5.ko", "-o", f"{path}/hinic5_tmp.ko"]
+ do_cmd(*cmd)
+
+
+def build_clean():
+ module_file = f"{env.hi1823_ci_lib_dir}/NIC_Module.symvers"
+ if os.path.isfile(module_file):
+ os.remove(module_file)
+ env.copy_file(f"{env.hi1823_nic_code_dir}/Module.symvers", env.hi1823_ci_lib_dir, "NIC_Module.symvers")
+
+ # make clean
+ do_make_clean(workdir=env.hi1823_nic_code_dir)
+
+ cmd = ["find", f"{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/knldk", "-name", "*.o",
+ "-o", "-name", "*.cmd", "-o", "-name", "*.mod"]
+ result = do_cmd(*cmd)
+ do_cmd('xargs', 'rm', '-f', input=result.stdout)
+
+ cmd = ["find", f"{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/ossl", "-name", "*.o",
+ "-o", "-name", "*.cmd"]
+ result = do_cmd(*cmd)
+ do_cmd('xargs', 'rm', '-f', input=result.stdout)
+
+ cmd = ["find", f"{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/nic", "-name", "*.o",
+ "-o", "-name", "*.cmd", "-o", "-name", "*.mod"]
+ result = do_cmd(*cmd)
+ do_cmd('xargs', 'rm', '-f', input=result.stdout)
+
+
+def build_deb_package(arch):
+ workdir = f'{env.HI1823_BUILD_DIR}/host/linux/nic/nic_deb_build/'
+ kernel_release = env.hi1823_complie_os_kver
+ driver_version = env.get_global_version('driver')
+
+ if arch == "x86_64":
+ distname = "amd64"
+ else:
+ distname = "arm64"
+
+ distdir = f'{workdir}/{distname}'
+ modules_dir = f"{distdir}/lib/modules/"
+ modules_load_dir = f"{distdir}/lib/modules-load.d/"
+ ko_dir = f'{modules_dir}/{kernel_release}/updates/hinic5/'
+
+ shutil.rmtree(modules_dir, ignore_errors=True)
+ os.makedirs(ko_dir)
+
+ # prepare hinic5
+ nic_output = env.get_driver_output_path('nic')
+ shutil.move(f'{nic_output}/hinic5_tmp.ko', f'{ko_dir}/hinic5.ko')
+ env.copy_file(f"{workdir}/hinic5-modules.conf", modules_load_dir)
+
+ do_cmd('sed', '-i', f'/^Version/c Version: {driver_version}', f'{distdir}/DEBIAN/control')
+ do_cmd('chmod', '-R', '775', f'{distdir}/DEBIAN/')
+
+ # build deb
+ deb_file = f"hinic5-{driver_version}-{env.hi1823_complie_os_kver_underline}.{arch}.deb"
+ cmd = ["dpkg", "-b", distname, deb_file]
+ do_cmd(*cmd, cwd=workdir)
+
+ shutil.move(f'{workdir}/{deb_file}', nic_output)
+
+
+def get_rpm_spec(os_type, arch):
+ if os_type == 'UVP':
+ spec = 'hinic5_uvp.spec'
+ else:
+ spec = 'hinic5.spec'
+ return spec
+
+
+def build_rpm_package(arch):
+ os_type = env.hi1823_os_type
+ workdir = env.HI1823_RPM_BUILD_DIR
+
+ shutil.rmtree(workdir, ignore_errors=True)
+ cmd = [
+ 'mkdir', '-pv', '-m', '777',
+ f'{workdir}/BUILD',
+ f'{workdir}/BUILDROOT',
+ f'{workdir}/RPMS',
+ f'{workdir}/SOURCES',
+ f'{workdir}/SPECS',
+ f'{workdir}/SRPMS'
+ ]
+ do_cmd(*cmd)
+
+ env.copy_file(f'{env.HI1823_TRUNK_DIR}/src/GLOBAL_VERSION_NEW', f'{workdir}/SOURCES')
+
+ # prepare hinic5
+ nic_output = env.get_driver_output_path('nic')
+
+ shutil.move(f'{nic_output}/hinic5_tmp.ko', f'{workdir}/SOURCES/hinic5.ko')
+ env.copy_file(f'{NIC_RPM_BUILD_DIR}/hinic5-modules.conf', f'{workdir}/SOURCES')
+
+ # prepare OS
+ if os_type == 'UVP':
+ env.copy_file(f'{NIC_RPM_BUILD_DIR}hinic5-dracut.conf', f'{workdir}/SOURCES')
+
+ # prepare rpm spec
+ spec = get_rpm_spec(os_type, arch)
+ if not spec:
+ raise Exception(f'no spec to build rpm. OS type {os_type}, arch {arch}')
+ env.copy_file(f'{NIC_RPM_BUILD_DIR}/{spec}', f'{workdir}/SPECS')
+
+ # build rpm
+ rpm_build(workdir=workdir, spec=spec, arch=arch)
+
+ # copy rpm to output dir
+ rpm_dir = f'{workdir}/RPMS/{arch}'
+ env.copy_file_with_end(rpm_dir, nic_output, ".rpm")
+
+
+def build_package(pkg_type, arch):
+ if pkg_type == "rpm":
+ return build_rpm_package(arch=arch)
+ if pkg_type == "deb":
+ return build_deb_package(arch=arch)
+ raise Exception(f'unknown package manager type {pkg_type}')
+
+
+def build_nic_rpm_deb():
+ try:
+ build_package(
+ pkg_type=env.hi1823_os_pkg_mgr,
+ arch=env.hi1823_os_arch,
+ )
+ return 0
+ except Exception as e:
+ logging.exception(f'build package failed')
+ return 1
+
+
+def build_nic_ko():
+ srcdir = env.hi1823_nic_code_dir
+ outdir = env.get_driver_output_path('nic')
+
+ try:
+ # make
+ do_make_clean(workdir=srcdir)
+ do_make(workdir=srcdir)
+
+ save_output(outdir)
+ build_clean()
+ return 0
+ except Exception as e:
+ logging.exception(f'build ko failed')
+ return 1
+
+def build_nic():
+ return build_nic_ko()
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/nic-kcompat-generator.sh b/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/nic-kcompat-generator.sh
new file mode 100755
index 000000000..62ba8da23
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/nic/nic-kcompat-generator.sh
@@ -0,0 +1,500 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2025 Huawei Technologies Co., Ltd
+
+# This file is used to automatically generate HAVE_ and NEED_ macros
+# for the current or incoming kernel.
+#
+# It is primarily implemented by invoking the 'gen' function in the kcompat-lib.sh file
+# (you can refer to the main part of 'gen_xx' for details).
+# The 'gen' tool can search for declarations of various types in kernel header files to generate macros.
+# For example, search for a function in a specified file and check whether the given function exists.
+# Please refer to the comments above the 'gen' function in kcompat-lib.sh.
+
+# End of intro.
+# The implementation is in kcompat-lib.sh, and below is an example of the 'gen' invocation.
+
+set -e
+
+echo "curr bash script file name: $(basename "${BASH_SOURCE[0]}")"
+export LC_ALL=C
+SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
+ORIG_CWD="$(pwd)"
+trap 'rc=$?; echo >&2 "$(realpath "$ORIG_CWD/${BASH_SOURCE[0]}"):$LINENO: failed with rc: $rc"' ERR
+
+# shellcheck source=kcompat-lib.sh
+CURR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+KCOMPAT_LIB="${CURR_DIR}/../kcompat-lib.sh"
+
+if [ -f "$KCOMPAT_LIB" ]; then
+ echo "$KCOMPAT_LIB file is exist"
+else
+ echo "$KCOMPAT_LIB file is not exist"
+fi
+source "$KCOMPAT_LIB"
+
+ARCH=$(uname -m)
+IS_ARM=""
+if [ "$ARCH" == aarch64 ]; then
+ IS_ARM=1
+fi
+
+function ready_gen()
+{
+ KERN_VER=$(uname -r)
+ KSRC=""
+
+ if [ -e /usr/src/kernels/linux-"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/linux-"$KERN_VER"/"
+ elif [ -e /usr/src/kernels/"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/"$KERN_VER"/"
+ elif [ -e /lib/modules/"$KERN_VER"/build/include/config ]; then
+ KSRC="/lib/modules/"$KERN_VER"/build/"
+ fi
+
+ if [ -z "$KSRC" ]; then
+ KERN_VER=$(uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/')
+ if [ -e /usr/src/kernels/linux-"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/linux-"$KERN_VER"/"
+ elif [ -e /usr/src/kernels/"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/"$KERN_VER"/"
+ elif [ -e /lib/modules/"$KERN_VER"/build/include/config ]; then
+ KSRC="/lib/modules/"$KERN_VER"/build/"
+ fi
+ fi
+
+ if [ -z "$KSRC" ]; then
+ echo "Invalid kernel src. Expected: ${KERN_VER}. Please check if kernel-devel(for other OS) or linux-headers(for debian) installed"
+ KSOURCES=$(ls -w 1 /usr/src/kernels/ ; ls -w 1 /lib/modules/)
+ echo "Found: ${KSOURCES}"
+ exit 1
+ fi
+ KOBJ=$KSRC
+
+ if [ ! -d "${KSRC}"/include/linux ]; then
+ echo "Detect other Debian/SLES include directory using KSRC..."
+ # detect other SLES include directory using KSRC
+ t=$(dirname "$KSRC")/$(basename "$KSRC")
+ if [ -L "$t" ]; then
+ # a symlink
+ t=$(readlink -f $t)
+ fi
+ # SLES
+ t=${t%-obj*}
+ # LinxOS
+ t=${t/-linx-security-arm64/-common-linx-security}
+ # Debian
+ t=${t/-amd64/-common}
+ t=${t/-arm64/-common}
+ if [ -d "${t}"/include/linux ]; then
+ KSRC=$t
+ fi
+ fi
+ echo "nic-kcompat-generator.sh -> KERN_VER: ${KERN_VER}"
+ echo "nic-kcompat-generator.sh -> KSRC: ${KSRC}"
+ export KSRC KOBJ
+}
+
+function gen_devres() {
+ dvh='include/linux/device.h'
+ ddrh='include/linux/device/devres.h'
+ # gen NEED_DEVM_KASPRINTF if fun devm_kasprintf absent in "$dvh" "$ddrh"
+ # gen NEED_DEVM_KCALLOC if fun devm_kcalloc absent in "$dvh" "$ddrh" -- delete
+ # gen NEED_DEVM_KFREE if fun devm_kfree absent in "$dvh" "$ddrh"
+ # gen NEED_DEVM_KMEMDUP if fun devm_kmemdup absent in "$dvh" "$ddrh"
+ # gen NEED_DEVM_KSTRDUP if fun devm_kstrdup absent in "$dvh" "$ddrh"
+ # gen NEED_DEVM_KVASPRINTF if fun devm_kvasprintf absent in "$dvh" "$ddrh"
+ # gen NEED_DEVM_KZALLOC if fun devm_kzalloc absent in "$dvh" "$ddrh"
+}
+
+function gen_dma() {
+ dma='include/linux/dma-mapping.h'
+ da='include/linux/dma-attrs.h'
+ # gen HAVE_DMA_SET_MASK if fun dma_set_mask in "$dma"
+ # gen NEED_DMA_ZALLOC_COHERENT if fun dma_zalloc_coherent absent in "$dma"
+ # gen NEED_DMA_SET_MASK_AND_COHERENT if fun dma_set_mask_and_coherent absent in "$dma"
+ # gen HAVE_STRUCT_DMA_ATTRS if struct dma_attrs in "$da"
+ HAVE_DMA_ATTR_WRITE_BARRIER=0
+ if check enum dma_attr matches DMA_ATTR_WRITE_BARRIER in "$da" ||
+ check macro DMA_ATTR_WRITE_BARRIER in "$dma"; then
+ HAVE_DMA_ATTR_WRITE_BARRIER=1
+ fi
+ # gen HAVE_DMA_ATTR_WRITE_BARRIER if string "$HAVE_DMA_ATTR_WRITE_BARRIER" equals 1
+}
+
+function gen_ethtool() {
+ eth='include/linux/ethtool.h'
+ ueth='include/uapi/linux/ethtool.h'
+ gen HAVE_ETHTOOL_COALESCE_EXTACK if method get_coalesce of ethtool_ops matches 'struct kernel_ethtool_coalesce \\*' in "$eth"
+ gen HAVE_ETHTOOL_EXTENDED_RINGPARAMS if method get_ringparam of ethtool_ops matches 'struct kernel_ethtool_ringparam \\*' in "$eth"
+ gen HAVE_RXFH_HASHFUNC if method get_rxfh of ethtool_ops matches hfunc in "$eth"
+ # gen HAVE_RXFH_PARAM if method get_rxfh of ethtool_ops matches 'struct ethtool_rxfh_param \\*' in "$eth"
+ # gen HAVE_ETHTOOL_GET_RXNFC_U32_RULELOCS if method get_rxnfc of ethtool_ops matches 'u32 \\*rule_locs' in "$eth"
+
+ gen HAVE_ETHTOOL_GET_RXNFC_VOID_RULELOCS if method get_rxnfc of ethtool_ops matches 'void \\*rule_locs' in "$eth"
+ gen HAVE_ETHTOOL_GET_RXFH_INDIR_SIZE if method get_rxfh_indir_size of ethtool_ops in "$eth"
+ gen HAVE_ETHTOOL_GET_MODULE_EEPROM_BY_PAGE if method get_module_eeprom_by_page of ethtool_ops in "$eth"
+ gen HAVE_ETHTOOL_RXFH_INDIR_STRUCT_RXFH_INDIR if method set_rxfh_indir of ethtool_ops matches 'struct ethtool_rxfh_indir \\*' in "$eth"
+ gen SUPPORTED_COALESCE_PARAMS if struct ethtool_ops matches supported_coalesce_params in "$eth"
+ gen HAVE_ETHTOOL_SET_PHYS_ID if method set_phys_id of ethtool_ops in "$eth"
+ gen HAVE_ETHTOOL_OPS_EXT if struct ethtool_ops_ext in "$eth"
+ gen NEED_DEFINE_SPEED_20000 if macro SPEED_20000 absent in "$eth"
+ gen NEED_DEFINE_SPEED_25000 if macro SPEED_25000 absent in "$eth"
+ gen NEED_DEFINE_SPEED_40000 if macro SPEED_40000 absent in "$eth"
+ gen NEED_DEFINE_SPEED_100000 if macro SPEED_100000 absent in "$eth"
+ gen NEED_DEFINE_ETH_MODULE_SFF_8636 if macro ETH_MODULE_SFF_8636 absent in "$ueth"
+ gen NEED_DEFINE_ETH_MODULE_SFF_8636_LEN if macro ETH_MODULE_SFF_8636_LEN absent in "$ueth"
+ gen NEED_DEFINE_ETH_MODULE_SFF_8436 if macro ETH_MODULE_SFF_8436 absent in "$ueth"
+ gen NEED_DEFINE_ETH_MODULE_SFF_8436_LEN if macro ETH_MODULE_SFF_8436_LEN absent in "$ueth"
+ gen HAVE_ETHTOOL_GLINKSETTINGS if macro ETHTOOL_GLINKSETTINGS in "$ueth"
+ gen NEED_ENUM_ETHTOOL_LINK_MODE_25000baseCR_Full_BIT if enum ethtool_link_mode_bit_indices lacks ETHTOOL_LINK_MODE_25000baseCR_Full_BIT in "$ueth"
+ gen NEED_ENUM_ETHTOOL_LINK_MODE_25000baseKR_Full_BIT if enum ethtool_link_mode_bit_indices lacks ETHTOOL_LINK_MODE_25000baseKR_Full_BIT in "$ueth"
+ gen NEED_ENUM_ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT if enum ethtool_link_mode_bit_indices lacks ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT in "$ueth"
+ gen NEED_ENUM_ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT if enum ethtool_link_mode_bit_indices lacks ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT in "$ueth"
+
+ HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY=0
+ if check method get_settings of ethtool_ops absent in "$eth" &&
+ check method get_link_ksettings of ethtool_ops in "$eth"; then
+ HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY=1
+ fi
+ gen HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY if string "$HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY" equals 1
+
+ gen HAVE_KERNEL_ETHTOOL_TS_INFO if struct kernel_ethtool_ts_info in "$eth"
+ gen HAVE_ETHTOOL_RXFH_PARAM if struct ethtool_rxfh_param in "$eth"
+ gen NEED_ETHTOOL_COALESCE_USECS_LOW_HIGH if macro ETHTOOL_COALESCE_USECS_LOW_HIGH absent in "$eth"
+ gen NEED_ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH if macro ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH absent in "$eth"
+ gen NEED_ETHTOOL_COALESCE_PKT_RATE_RX_USECS if macro ETHTOOL_COALESCE_PKT_RATE_RX_USECS absent in "$eth"
+}
+
+function gen_filter() {
+ fh='include/linux/filter.h'
+ gen HAVE_NETDEV_PROG_XDP_WARN_ACTION if fun bpf_warn_invalid_xdp_action matches 'struct net_device \\*' in "$fh"
+ # gen NEED_DEFINE_XDP_DO_FLUSH_MAP if macro xdp_do_flush_map absent in "$fh"
+ gen HAVE_XDP_DO_FLUSH_MAP if fun xdp_do_flush_map in "$fh"
+}
+
+function gen_netdevice() {
+ ndh='include/linux/netdevice.h'
+ nddh='include/linux/net_debug.h'
+ gen NEED_NETIF_NAPI_ADD_NO_WEIGHT if fun netif_napi_add matches 'int weight' in "$ndh"
+ gen HAVE_NETIF_NAPI_NO_WEIGHT if fun netif_napi_add lacks 'int weight' in "$ndh"
+ gen HAVE_NETIF_NAPI_ADD_WEIGHT if fun netif_napi_add_weight in "$ndh"
+ gen HAVE_NDO_TX_TIMEOUT_TXQ if method ndo_tx_timeout of net_device_ops matches txqueue in "$ndh"
+ gen HAVE_NDO_XDP if method ndo_xdp of net_device_ops in "$ndh"
+ gen HAVE_NDO_BPF if method ndo_bpf of net_device_ops in "$ndh"
+ gen HAVE_XDP_XDP_QUERY_PROG if enum xdp_netdev_command matches XDP_QUERY_PROG in "$ndh"
+ gen HAVE_BPF_XDP_QUERY_PROG if enum bpf_netdev_command matches XDP_QUERY_PROG in "$ndh"
+ gen HAVE_NDO_GET_STATS64 if method ndo_get_stats64 of net_device_ops in "$ndh"
+ gen HAVE_NDO_DO_IOCTL if method ndo_do_ioctl of net_device_ops in "$ndh"
+
+ gen HAVE_VOID_NDO_GET_STATS64 if method ndo_get_stats64 of net_device_ops matches 'void[ \t]*\\(\\*' in "$ndh"
+ gen HAVE_NDO_SET_FEATURES if method ndo_set_features of net_device_ops in "$ndh"
+ gen HAVE_NDO_SET_U32_FEATURES if method ndo_set_features of net_device_ops matches 'u32 features' in "$ndh"
+ gen HAVE_NAPI_GRO_FLUSH_OLD if fun napi_gro_flush matches 'bool flush_old' in "$ndh"
+ gen HAVE_NDO_UDP_TUNNEL_ADD if method ndo_udp_tunnel_add of net_device_ops in "$ndh"
+ gen HAVE_VF_SPOOFCHK_CONFIGURE if method ndo_set_vf_spoofchk of net_device_ops in "$ndh"
+ gen HAVE_NDO_SET_VF_TRUST if method ndo_set_vf_trust of net_device_ops in "$ndh"
+ gen HAVE_NDO_SET_VF_MIN_MAX_TX_RATE if method ndo_set_vf_rate of net_device_ops in "$ndh"
+ # gen HAVE_NETDEV_LEVEL_ONCE if macro netdev_warn_once in "$ndh" "$nddh"
+ # gen HAVE_DEV_OPEN_EXTACK if fun dev_open matches extack in "$ndh"
+ gen HAVE_NETDEVICE_MIN_MAX_MTU if struct net_device matches min_mtu in "$ndh"
+ gen HAVE_NETDEV_STATS_IN_NETDEV if struct net_device matches 'struct net_device_stats[ \t]*stats' in "$ndh"
+ gen HAVE_NETDEVICE_MACSEC_OPS if struct net_device matches 'const struct macsec_ops[ \t]*\\*macsec_ops' in "$ndh"
+ # gen NEED_DEFINE_NAPI_POLL_WEIGHT if macro NAPI_POLL_WEIGHT absent in "$ndh"
+ gen HAVE_NDO_SET_VF_LINK_STATE if method ndo_set_vf_link_state of net_device_ops in "$ndh"
+ gen HAVE_NDO_SELECT_QUEUE_FALLBACK if method ndo_select_queue of net_device_ops matches fallback in "$ndh"
+ gen HAVE_NDO_SELECT_QUEUE_SB_DEV if method ndo_select_queue of net_device_ops matches sb_dev in "$ndh"
+ gen HAVE_NDO_SELECT_QUEUE_ACCEL if method ndo_select_queue of net_device_ops matches accel_priv in "$ndh"
+ gen NEED_NETDEV_NOTIFIER_INFO_TO_DEV if fun netdev_notifier_info_to_dev absent in "$ndh"
+ # exception centos7.9 x86 os
+ # (Un)registration functions for the notifiers that takes 'struct netdev_notifier_info *' as parameter in register_netdevice_notifier_rh
+ # gen HAVE_REGISTER_NETDEVICE_NOTIFIER_RH if fun register_netdevice_notifier_rh in "$ndh"
+ gen HAVE_NET_DEVICE_OPS_EXT if struct net_device_ops_ext in "$ndh"
+ gen HAVE_NET_DEVICE_OPS_EXTENDED if struct net_device_ops_extended in "$ndh"
+ gen HAVE_NET_DEV_OPS_EXT_NDO_SET_VF_VLAN if method ndo_set_vf_vlan of net_device_ops_extended in "$ndh"
+ gen HAVE_NET_DEV_OPS_EXT_NDO_CHANGE_MTU if method ndo_change_mtu of net_device_ops_extended in "$ndh"
+ gen HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU if struct net_device_extended matches min_mtu in "$ndh"
+ gen NEED_NETDEV_PHYS_ITEM_ID if struct netdev_phys_item_id absent in "$ndh"
+ gen NEED_DEFINE_NETDEV_RSS_KEY_LEN if macro NETDEV_RSS_KEY_LEN absent in "$ndh"
+ gen NEED_NAPI_SCHEDULE_IRQOFF if fun napi_schedule_irqoff absent in "$ndh"
+ # gen NEED_DEFINE_NETDEV_HW_ADDR_LIST_FOR_EACH if macro netdev_hw_addr_list_for_each absent in "$ndh"
+ # gen HAVE_NDO_XDP_XMIT if method ndo_xdp_xmit of net_device_ops in "$ndh"
+ gen HAVE_NETDEV_CHANGEUPPER if enum netdev_cmd matches NETDEV_CHANGEUPPER in "$ndh"
+ gen HAVE_NETDEV_CHANGEUPPER if macro NETDEV_CHANGEUPPER in "$ndh"
+}
+
+function gen_pci() {
+ pcih='include/linux/pci.h'
+ pdch='include/linux/pci-dma-compat.h'
+ # gen NEED_DEFINE_PCI_POOL_ALLOC if macro pci_pool_alloc absent in "$pcih"
+ # gen NEED_DEFINE_PCI_POOL_FREE if macro pci_pool_free absent in "$pcih"
+ # gen NEED_DEFINE_PCI_POOL if macro pci_pool absent in "$pcih"
+ # gen NEED_DEFINE_PCI_DMA_BIDIRECTIONAL if macro PCI_DMA_BIDIRECTIONAL absent in "$pcih" "$pdch"
+ # gen NEED_PCI_SRIOV_GET_TOTALVFS if fun pci_sriov_get_totalvfs absent in "$pcih"
+ # gen NEED_DEFINE_PCI_DEVID if macro PCI_DEVID absent in "$pcih"
+ # gen NEED_PCI_ENABLE_MSIX_RANGE if fun pci_enable_msix_range absent in "$pcih"
+ # gen HAVE_SRIOV_CONFIGURE if method sriov_configure of pci_driver in "$pcih"
+ # gen HAVE_PCI_DEV_FLAGS_ASSIGNED if enum pci_dev_flags matches PCI_DEV_FLAGS_ASSIGNED in "$pcih"
+ # gen NEED_PCI_VFS_ASSIGNED if fun pci_vfs_assigned absent in "$pcih"
+}
+
+function gen_limits() {
+ lih='include/linux/limits.h'
+ kh='include/linux/kernel.h'
+ gen NEED_DEFINE_U16_MAX if macro U16_MAX absent in "$lih" "$kh"
+ gen NEED_DEFINE_U32_MAX if macro U32_MAX absent in "$lih" "$kh"
+}
+
+function gen_skbuff() {
+ skbh='include/linux/skbuff.h'
+ gen HAVE_SKB_RECV_DATAGRAM_NOBLOCK if fun skb_recv_datagram matches 'int noblock' in "$skbh"
+ # gen NEED_PLT_HASH_TYPES if enum pkt_hash_types absent in "$skbh"
+ gen NEED_SKB_SET_HASH if fun skb_set_hash absent in "$skbh"
+ gen HAVE_SK_BUFF_ENCAPSULATION if struct sk_buff matches encapsulation in "$skbh"
+ gen NEED_SKB_FRAG_OFF_ADD if fun skb_frag_off_add absent in "$skbh"
+ gen HAVE_TYPEDEF_SKB_FRAG_T_BIOVEC if typedef skb_frag_t matches bio_vec in "$skbh"
+ gen HAVE_SKB_L4_RXHASH if struct sk_buff matches l4_rxhash in "$skbh"
+ # gen NEED_DEFINE_DEV_ALLOC_PAGES if macro dev_alloc_pages absent in "$skbh"
+ # gen NEED_DEFINE_DEV_ALLOC_PAGE if macro dev_alloc_page absent in "$skbh"
+ gen HAVE_SKBUFF_CSUM_LEVEL if struct sk_buff matches csum_level in "$skbh"
+ # gen NEED___SKB_PUT_DATA if fun __skb_put_data absent in "$skbh"
+}
+
+function gen_list() {
+ lh='include/linux/list.h'
+ gen NEED_DEFINE_LIST_FIRST_ENTRY_OR_NULL if macro list_first_entry_or_null absent in "$lh"
+ gen NEED_DEFINE_LIST_NEXT_ENTRY if macro list_next_entry absent in "$lh"
+ gen NEED_DEFINE_LIST_PREV_ENTRY if macro list_prev_entry absent in "$lh"
+}
+
+function gen_ether() {
+ edh='include/linux/etherdevice.h'
+ ieh='include/uapi/linux/if_ether.h'
+ gen HAVE_ETH_GET_HEADLEN_NET_DEVICE_ARG if fun eth_get_headlen matches 'struct net_device \\*' in "$edh"
+ gen HAVE_ETH_HW_ADDR_SET if fun eth_hw_addr_set in "$edh"
+ # gen HAVE_ETH_MAC_ADDR if fun eth_mac_addr in "$edh"
+ gen NEED_ETHER_ADDR_COPY if fun ether_addr_copy absent in "$edh"
+ gen HAVE_ETH_GET_HEADLEN_FUNC if fun eth_get_headlen in "$edh"
+ gen NEED_ETH_P_8021AD if macro ETH_P_8021AD absent in "$edh"
+ # gen NEED_ETHER_ZERO_ADDR if fun eth_zero_addr absent in "$edh"
+}
+
+function gen_mm() {
+ mm='include/linux/mm.h'
+ mmt='include/linux/mm_types.h'
+ gen HAVE_VM_FLAGS_SET if fun vm_flags_set in include/linux/mm.h
+ # gen HAVE_GET_USER_PAGES_GUP_FLAGS if fun get_user_pages matches gup_flags in "$mm"
+ # gen HAVE_GET_USER_PAGES_VMAS if fun get_user_pages matches vmas in "$mm"
+ # gen HAVE_GET_USER_PAGES_LONGTERM if fun get_user_pages_longterm in "$mm"
+ # gen HAVE_PINNED_VM_TYPE_ATOMIC64_T if struct mm_struct matches 'atomic64_t[ \t]*pinned_vm;' in "$mmt"
+ # gen HAVE_GET_USER_PAGES_8_PARAMS if fun get_user_pages countparam 8 in "$mm"
+}
+
+function gen_mmap_lock() {
+ mml='include/linux/mmap_lock.h'
+ # gen HAVE_MMAP_WRITE_LOCK if fun mmap_write_lock in "$mml"
+}
+
+function gen_time() {
+ tih='include/linux/time.h'
+ utih='include/uapi/linux/time.h'
+ tp32h='include/linux/timekeeping32.h'
+ # gen NEED_DO_GETTIMEOFDAY if fun do_gettimeofday absent in "$tih" "$tp32h"
+
+ NEED_STRUCT_TIMEVAL=0
+ if grep -q "^#ifndef __KERNEL__" "${KSRC%/}/$tih" || grep -q "^#ifndef __KERNEL__" "${KSRC%/}/$utih"; then
+ NEED_STRUCT_TIMEVAL=1
+ fi
+ # gen NEED_STRUCT_TIMEVAL if string "$NEED_STRUCT_TIMEVAL" equals 1
+}
+
+function gen_kobject() {
+ obh='include/linux/kobject.h'
+ gen HAVE_KOBJ_TYPE_DEFAULT_GROUPS if struct kobj_type matches 'const struct attribute_group \\*' in "$obh"
+ gen HAVE_KOBJ_TYPE_DEFAULT_ATTRS if struct kobj_type matches 'struct attribute \\*' in "$obh"
+}
+
+function gen_other() {
+ pciaerh='include/linux/aer.h'
+ ush='include/linux/u64_stats_sync.h'
+ gfp='include/linux/gfp.h'
+ # gen HAVE_PCI_ENABLE_PCIE_ERROR_REPORTING if fun pci_enable_pcie_error_reporting in "$pciaerh"
+ # gen HAVE_PCI_DISABLE_PCIE_ERROR_REPORTING if fun pci_disable_pcie_error_reporting in "$pciaerh"
+ # gen NEED_PCI_CLEANUP_AER_UNCORRECT_ERROR_STATUS if fun pci_cleanup_aer_uncorrect_error_status absent in "$pciaerh"
+ # gen HAVE_TIMER_SETUP if fun timer_setup in include/linux/timer.h
+ # gen NEED_TIMER_SETUP if fun timer_setup absent in include/linux/timer.h
+ gen NEED_PDE_DATA if fun PDE_DATA absent in include/linux/proc_fs.h
+ gen HAVE_PDE_DATA_LOWERCASE if fun pde_data in include/linux/proc_fs.h
+ # gen HAVE_PROC_OPS if struct proc_ops in include/linux/proc_fs.h
+ # gen NEED_PROC_OPS if struct proc_ops absent in include/linux/proc_fs.h
+ gen NEED_NETIF_F_SCTP_CRC if macro NETIF_F_SCTP_CRC absent in include/linux/netdev_features.h
+ # gen NEED_DEFINE_NETIF_F_GSO_UDP_TUNNEL_CSUM if macro NETIF_F_GSO_UDP_TUNNEL_CSUM absent in include/linux/netdev_features.h
+ gen HAVE_NETIF_F_RXHASH if macro NETIF_F_RXHASH in include/linux/netdev_features.h
+ gen HAVE_SOCK_CREATE_KERN_NET if fun sock_create_kern matches 'struct net \\*' in include/linux/net.h
+ gen HAVE_SK_DATE_READY_BYTES if method sk_data_ready of sock matches 'int bytes' in include/net/sock.h
+ gen HAVE_UDP_TUNNEL_NIC_INFO if struct udp_tunnel_nic_info in include/net/udp_tunnel.h
+ # gen HAVE_VLAN_FIND_DEV_DEEP_RCU if fun __vlan_find_dev_deep_rcu in include/linux/if_vlan.h
+ gen NEED_DEFINE_SKB_VLAN_TAG_PRESENT if macro skb_vlan_tag_present absent in include/linux/if_vlan.h
+ gen NEED___vlan_get_protocol if fun __vlan_get_protocol absent in include/linux/if_vlan.h
+ gen NEED_DEFINE_FIELD_SIZEOF if macro FIELD_SIZEOF absent in include/linux/kernel.h
+ # gen NEED_RTC_TIME_TO_TM if fun rtc_time_to_tm absent in include/linux/rtc.h
+ gen NEED_STRLCPY if fun strlcpy absent in include/linux/string.h
+ # gen NEED_CPUMASK_LOCAL_SPREAD if fun cpumask_local_spread absent in include/linux/cpumask.h
+ # gen HAVE_GENL_OPS_FIELD_VALIDATE if struct genl_ops matches validate in include/net/genetlink.h
+ # gen NEED_DEFINE_GET_DS if macro get_ds absent in include/asm-generic/uaccess.h
+ # gen NEED_BITMAP_ZALLOC if fun bitmap_zalloc absent in include/linux/bitmap.h
+ # gen HAVE_MACRO_VM_FAULT_T if typedef vm_fault_t in include/linux/mm_types.h
+ # gen NEED_CSUM_REPLACE_BY_DIFF if fun csum_replace_by_diff absent in include/net/checksum.h
+ # gen NEED_DEFINE_KFREE_RCU if macro kfree_rcu absent in include/linux/rcupdate.h
+ # gen NEED_DEFINE_U64_STATS_INIT if macro u64_stats_init absent in include/linux/u64_stats_sync.h
+ # gen NEED_DEFINE_BIT_ULL if macro BIT_ULL absent in include/linux/bitops.h include/linux/bits.h
+ gen NEED_DEFINE_DMA_RMB if macro dma_rmb absent in include/asm-generic/barrier.h
+ gen HAVE_XDP_SUPPORT if macro __LINUX_NET_XDP_H__ in include/net/xdp.h
+ # gen HAVE_XDP_FRAME_SZ if struct xdp_buff matches frame_sz in include/net/xdp.h
+ gen HAVE_XDP_DATA_META if fun xdp_set_data_meta_invalid in include/net/xdp.h
+ gen HAVE_XDP_RXQ_INFO_REG_NAPI_ID if fun xdp_rxq_info_reg matches napi_id in include/net/xdp.h
+ # only declared in some EulerOS version, like EulerV2R12, only used in SDI scenarios
+ # gen HAVE_KALLSYMS_LOOKUP_NAME_WRAP if fun kallsyms_lookup_name_wrap in include/linux/kallsyms.h
+ # gen NEED_KREF_READ if fun kref_read absent in include/linux/kref.h
+ # gen HAVE_BPF_TRACE_H if macro __LINUX_BPF_TRACE_H__ in include/linux/bpf_trace.h
+ gen HAVE_NETDEV_XDP_ACT_NDO_XMIT if enum netdev_xdp_act matches NETDEV_XDP_ACT_NDO_XMIT in include/uapi/linux/netdev.h
+ NEED_KMALLOC_ARRAY=0
+ if check fun kmalloc_array absent in include/linux/slab.h &&
+ check macro kmalloc_array absent in include/linux/slab.h; then
+ NEED_KMALLOC_ARRAY=1
+ fi
+ # gen NEED_KMALLOC_ARRAY if string "$NEED_KMALLOC_ARRAY" equals 1
+ gen HAVE_PAGE_POOL_SUPPORT if fun alloc_pages_bulk_array_node in "$gfp"
+
+ ppl1='include/net/page_pool.h'
+ ppl2='include/net/page_pool/types.h'
+ ppl3='include/net/page_pool/helpers.h'
+
+ if [[ -e "$ppl1" ]]; then
+ gen HAVE_PAGE_POOL_OLD if fun page_pool_alloc_frag in "$ppl1"
+ fi
+ if [[ -e "$ppl2" && -e "$ppl3" ]]; then
+ gen HAVE_PAGE_POOL_NEW if fun page_pool_alloc_frag in "$ppl2" "$ppl3"
+ fi
+
+ gen HAVE_PP_FLAG_PAGE_FRAG if macro PP_FLAG_PAGE_FRAG in "$ppl1" "$ppl2" "$ppl3"
+ gen HAVE_FLOW_ACTION_PRIORITY if enum flow_action_id matches FLOW_ACTION_PRIORITY in include/net/flow_offload.h
+
+ tinfo='arch/arm64/include/asm/thread_info.h'
+ processor='arch/x86/include/asm/processor.h'
+ uaccess='include/linux/uaccess.h'
+ gen HAVE_MM_SEGMENT_T if typedef mm_segment_t in "$tinfo" "$processor" "$uaccess"
+}
+
+function gen_symbol() {
+ module_symvers='Module.symvers'
+
+ # only used in SDI scenarios, some special OS which kernel version < 5.7 but have not
+ # exported function kallsyms_lookup_name
+ HAVE_KALLSYMS_LOOKUP_NAME_EXPORTED=0
+ if grep -q "kallsyms_lookup_name" "${KSRC%/}/$module_symvers"; then
+ HAVE_KALLSYMS_LOOKUP_NAME_EXPORTED=1
+ fi
+ # gen HAVE_KALLSYMS_LOOKUP_NAME_EXPORTED if string "$HAVE_KALLSYMS_LOOKUP_NAME_EXPORTED" equals 1
+}
+
+# all the generations, extracted from main() to keep normal code and various
+# prep separated
+function gen_all() {
+ gen_netdevice
+ # code above is covered by unit_tests/test_gold.sh
+ if [ -n "${JUST_UNIT_TESTING-}" ]; then
+ return
+ fi
+ gen_devres
+ gen_dma
+ gen_ethtool
+ gen_filter
+ gen_pci
+ gen_limits
+ gen_skbuff
+ gen_list
+ gen_ether
+ gen_mm
+ gen_mmap_lock
+ # gen_time
+ gen_other
+ #gen_symbol
+ gen_kobject
+}
+
+function gen_nic_kcompat() {
+ ready_gen
+ local out=$1
+ if ! [ -d "${KSRC-}" ]; then
+ echo >&2 "env KSRC=${KSRC-} does not exist or is not a directory"
+ exit 11
+ fi
+
+ # Assume KOBJ is the same as KSRC if not set.
+ if [ -z "${KOBJ-}" ]; then
+ KOBJ="${KSRC-}"
+ fi
+
+ # check if caller (like our makefile) wants to redirect output to file
+ if [ -n "${out-}" ]; then
+
+ # in case out exists, we don't want to overwrite it, instead
+ # write to a temporary copy.
+ if [ -s "${out}" ]; then
+ TMP_OUT="$(mktemp "${out}.XXX")"
+ trap "rm -f '${TMP_OUT}'" EXIT
+
+ REAL_OUT="${out}"
+ out="${TMP_OUT}"
+ fi
+
+ exec 3>&1
+ exec > "$out"
+ # all stdout goes to out since now
+ echo "/* uname=$(uname -r) Autogenerated for KSRC=${KSRC-} via $(basename "$0") */"
+ fi
+
+ cd "${KSRC}"
+
+
+ # check if KSRC was ok/if we are in proper place to look for headers
+ if [ ! -e include/linux/kernel.h ]; then
+ echo >&2 "seems that there are no kernel includes placed in KSRC=${KSRC}
+ pwd=$(pwd); ls -l:"
+ ls -l >&2
+ exit 8
+ fi
+
+ echo "#ifndef NIC_KCOMPAT_H"
+ echo "#define NIC_KCOMPAT_H"
+
+ set +x
+ gen_all
+ set -x
+
+ echo "#endif /* NIC_KCOMPAT_H */"
+ exec >&3
+ if [ -n "${out-}" ]; then
+ cd "$ORIG_CWD"
+
+ # Compare and see if anything changed. This avoids updating
+ # mtime of the file.
+ if [ -n "${REAL_OUT-}" ]; then
+ if cmp --silent "${REAL_OUT}" "${TMP_OUT}"; then
+ # exit now, skipping print of the output since
+ # there were no changes. the trap should
+ # cleanup TMP_OUT
+ return 0
+ fi
+
+ mv -f "${TMP_OUT}" "${REAL_OUT}"
+ out="${REAL_OUT}"
+ fi
+ fi
+ cat -n "$out" >&2
+}
+
+if [ "$1" = "--gen_nic_kcompat" ]; then
+ gen_nic_kcompat "$2"
+fi
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/__init__.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/__init__.py
new file mode 100755
index 000000000..cc0d19d0a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/__init__.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/build_roce.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/build_roce.py
new file mode 100755
index 000000000..0c7041744
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/build_roce.py
@@ -0,0 +1,567 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+import env
+import logging
+import shutil
+import glob
+import platform
+import subprocess
+import build_sdk
+import build_nic
+from pathlib import Path
+
+def run_shell_cmd(cmd, output=True):
+ rslt = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail:{' '.join(cmd)}. status = [{rslt.returncode}]. output:[{rslt.stdout}]")
+ return 1
+ if output:
+ logging.info(f"output = [{rslt.stdout}]")
+ return 0
+
+def copy_dir(source_dir, target_dir):
+ if not os.path.exists(target_dir):
+ os.makedirs(target_dir)
+ for root, dirs, files in os.walk(source_dir):
+ target_root = os.path.join(target_dir, os.path.relpath(root, source_dir))
+ for file in files:
+ source_file = os.path.join(root, file)
+ target_file = os.path.join(target_root, file)
+ shutil.copy(source_file, target_file)
+
+def get_roce_build_info(copy_dir):
+ cmd = ['cp', f'{env.hi1823_roce_knl_code_dir}/Makefile', f'{copy_dir}/Makefile_bak']
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ returncode = 0
+ while True:
+ cmd = ['sed', '-i', "/Makefile.ko$/d", f"{env.hi1823_roce_knl_code_dir}/Makefile"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ break
+
+ cmd = ['sed', '-i', "s/ifeq ($(KERNELRELEASE), )/ifneq ($(KERNELRELEASE), )/g", f"{env.hi1823_roce_knl_code_dir}/Makefile"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ break
+
+ cmd = ['make', '-C', env.hi1823_roce_knl_code_dir, 'build_info']
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ break
+
+ if True:
+ break
+
+ cmd = ['cp', f'{copy_dir}/Makefile_bak', f'{env.hi1823_roce_knl_code_dir}/Makefile']
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ os.remove(f'{copy_dir}/Makefile_bak')
+
+ return returncode
+
+def build_roce_knl_6_6_git_apply(is_reverse: bool = False):
+ project_name = "ChipSolution"
+ current_dir = os.getcwd()
+ project_dir = current_dir.split(project_name)[0] + project_name
+ file = "/etc/os-release"
+ with open(file, 'r') as f:
+ os_release_lines = f.readlines()
+ version_line = [os_release_line for os_release_line in os_release_lines if "VERSION_ID" in os_release_line]
+
+ version = int(version_line[0].split('"')[1].split(".")[0])
+ if version >= 22:
+ os.chdir(project_dir)
+ cmd = []
+ if is_reverse == True:
+ cmd = ["git", "apply", "--reverse", "build/host/linux/sdk/patch_code/knl6_6_compile.patch"]
+ else:
+ cmd = ["git", "apply", "build/host/linux/sdk/patch_code/knl6_6_compile.patch"]
+
+ subprocess.run(cmd, shell=False, check=True, capture_output=True)
+ os.chdir(current_dir)
+
+def build_roce_recurec_git_apply(is_reverse: bool = False):
+ project_name = "ChipSolution"
+ current_dir = os.getcwd()
+ project_dir = current_dir.split(project_name)[0] + project_name
+
+ os.chdir(project_dir)
+ cmd = []
+ if is_reverse == True:
+ cmd = ["git", "apply", "--reverse", "platform/huawei_secure_c/patch/adapt_implicit_fallthrough_level5.patch"]
+ else:
+ cmd = ["git", "apply", "platform/huawei_secure_c/patch/adapt_implicit_fallthrough_level5.patch"]
+
+ subprocess.run(cmd, shell=False, check=True, capture_output=True)
+ os.chdir(current_dir)
+
+def build_roce_kernel():
+ OFED_TYPE = "KERNEL"
+
+ cmd = ["kmod", "list"]
+ kmod_list = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
+ if 'hiroce5' in kmod_list.stdout:
+ cmd = ["sudo", "rmmod", "hiroce5"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ if 'hinic5' in kmod_list.stdout:
+ cmd = ["sudo", "rmmod", "hinic5"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ if not os.path.exists(f"{env.HI1823_TRUNK_DIR}/pangea"):
+ build_sdk.build_sdk()
+ build_nic.build_nic()
+
+ if not env.hi1823_driver_type:
+ ROCE_KRN_DRIVER_TYPE = "ROCE_STANDARD"
+ elif env.hi1823_driver_type == "ROCE_STANDARD_MLNX":
+ ROCE_KRN_DRIVER_TYPE = "ROCE_STANDARD"
+ OFED_TYPE = "MLNX_OFED"
+ else:
+ ROCE_KRN_DRIVER_TYPE = env.hi1823_driver_type
+
+ cmd = ["sh", "-x", f"{env.HI1823_BUILD_ROCE_DIR}/roce_kcompat_generator.sh", f"{env.hi1823_roce_knl_code_dir}/include", "", f"{OFED_TYPE}"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ cmd = ["cat", f"{env.hi1823_roce_knl_code_dir}/include/roce_kernel_compat_gen.h"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ logging.info("build roce clean")
+ cmd = ["make", "-C", env.hi1823_roce_knl_code_dir, "clean"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ if not env.hi1823_fc_os_release_type:
+ # build release version by default
+ ROCE_ENABLE_DEBUG = "OFF"
+ else:
+ if env.hi1823_fc_os_release_type == "RELEASE":
+ ROCE_ENABLE_DEBUG = "OFF"
+ elif env.hi1823_fc_os_release_type == "DEBUG":
+ ROCE_ENABLE_DEBUG = "ON"
+ else:
+ logging.error(f"unsupported fc os release type:{env.hi1823_fc_os_release_type}")
+ return 1
+
+ env.build_roce_mode = os.getenv("build_roce_mode")
+ if not env.build_roce_mode:
+ # not build hyper roce perftest by default
+ BUILD_HYPER_ROCE = "OFF"
+ else:
+ if env.build_roce_mode == "roce":
+ BUILD_HYPER_ROCE = "OFF"
+ elif env.build_roce_mode == "hyperroce":
+ BUILD_HYPER_ROCE = "ON"
+ else:
+ logging.error(f"unsupported perftest type:{env.build_roce_mode}")
+ return 1
+
+ logging.info("build roce kernel")
+ cmd = ['make', '-C', env.hi1823_roce_knl_code_dir, f'VERSION={ROCE_KRN_DRIVER_TYPE}', f'OFED_VERSION={OFED_TYPE}', f'ENABLE_DEBUG={ROCE_ENABLE_DEBUG}',
+ f'ENABLE_HYPER_ROCE={BUILD_HYPER_ROCE}', '-j', '16']
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ KRN_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{ROCE_KRN_DRIVER_TYPE}/kernel"
+ if os.path.exists(KRN_OUTPUT_DIR):
+ shutil.rmtree(KRN_OUTPUT_DIR)
+ KRN_OUTPUT_DIR_WIETH_DGB = f"{KRN_OUTPUT_DIR}/debug"
+
+ os.makedirs(KRN_OUTPUT_DIR)
+ os.makedirs(KRN_OUTPUT_DIR_WIETH_DGB)
+
+ env.copy_file(f"{env.hi1823_roce_knl_code_dir}/hiroce5.ko", KRN_OUTPUT_DIR_WIETH_DGB)
+
+ cmd = ["strip", "-g", f"{env.hi1823_roce_knl_code_dir}/hiroce5.ko"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ env.copy_file(f"{env.hi1823_roce_knl_code_dir}/hiroce5.ko", KRN_OUTPUT_DIR)
+
+ # get build info
+ logging.info("build roce build_info")
+ returncode = get_roce_build_info(KRN_OUTPUT_DIR)
+ if returncode:
+ return returncode
+
+ cmd = ["sh", f"{env.HI1823_BUILD_LOG_PATH}/build_log.sh", f"{env.hi1823_roce_knl_code_dir}/build", KRN_OUTPUT_DIR, "hiroce5.ko"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ ret = env.collect_build_info(KRN_OUTPUT_DIR, f"{env.hi1823_bin_dir}/driver/linux/roce")
+ if ret:
+ return ret
+
+ env.copy_file(f"{env.hi1823_roce_knl_code_dir}/Module.symvers", env.hi1823_ci_lib_dir, "ROCE_Module.symvers")
+
+ cmd = ["make", "-C", env.hi1823_roce_knl_code_dir, "clean"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ return 0
+
+def build_huawei_securec():
+ os.chdir(f"{env.huawei_secure_code_dir}/src")
+
+ cmd = ["make", "clean"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ output_dir = f"{env.hi1823_ci_lib_dir}/huawei_securec/{env.hi1823_os_release}"
+ os.makedirs(output_dir, exist_ok=True)
+
+ cmd = ['make', '-C', f'{env.huawei_secure_code_dir}/src']
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ cmd = ['make', '-C', f'{env.huawei_secure_code_dir}/src', 'lib']
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ env.copy_file(f"{env.huawei_secure_code_dir}/lib/libsecurec.so", output_dir)
+
+ cmd = ["make", "clean"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ return 0
+
+def build_roce_user():
+ build_roce_knl_6_6_git_apply(is_reverse = True)
+
+ ret = build_huawei_securec()
+ if ret:
+ return ret
+
+ # Generating roce user compilation header file roce_kcompat.h
+ roce_usr_compat_generator_path = Path(f"{env.HI1823_BUILD_ROCE_DIR}/roce_user_compat_generator.sh").resolve()
+ roce_usr_kcompat_path = f"{env.hi1823_roce_usr_code_dir}/libhiroce-1.0.0/include/roce_user_kcompat.h"
+
+ top_dir = f"{env.HI1823_TRUNK_DIR}"
+ subprocess.run(
+ [
+ "bash", "-cx",
+ f"source {roce_usr_compat_generator_path} && gen_roce_user_kcompat '{roce_usr_kcompat_path}' '{top_dir}' "
+ ],
+ check=True
+ )
+
+ if not env.hi1823_driver_type:
+ ROCE_USR_DRIVER_TYPE = "ROCE_STANDARD"
+ elif env.hi1823_driver_type == "ROCE_STANDARD_MLNX":
+ ROCE_USR_DRIVER_TYPE = "ROCE_STANDARD"
+ else:
+ ROCE_USR_DRIVER_TYPE = env.hi1823_driver_type
+
+ # build so/a
+ ROCE_BUILD_DIR = f"{env.hi1823_roce_usr_code_dir}/build"
+ ROCE_OUTPUT_DIR = f"{env.hi1823_roce_usr_code_dir}/output"
+
+ ROCE_MODIFY_SRQ_SGE_EN = "on"
+
+ if not env.hi1823_fc_os_release_type:
+ # build release version by default
+ ROCE_ENABLE_DEBUG = "OFF"
+ else:
+ if env.hi1823_fc_os_release_type == "RELEASE":
+ ROCE_ENABLE_DEBUG = "OFF"
+ elif env.hi1823_fc_os_release_type == "DEBUG":
+ ROCE_ENABLE_DEBUG = "ON"
+ else:
+ logging.error(f"unsupported fc os release type:{env.hi1823_fc_os_release_type}")
+ return 1
+
+ env.build_roce_mode = os.getenv("build_roce_mode")
+ if not env.build_roce_mode:
+ # not build hyper roce perftest by default
+ BUILD_HYPER_ROCE = "OFF"
+ else:
+ if env.build_roce_mode == "roce":
+ BUILD_HYPER_ROCE = "OFF"
+ elif env.build_roce_mode == "hyperroce":
+ BUILD_HYPER_ROCE = "ON"
+ else:
+ logging.error(f"unsupported perftest type:{env.build_roce_mode}")
+ return 1
+
+ cmd = [
+ 'cmake',
+ f'-B{ROCE_BUILD_DIR}',
+ f'-DROOT_PROJECT_DIR={env.HI1823_TRUNK_DIR}',
+ f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={ROCE_OUTPUT_DIR}',
+ f'-DTYPE={ROCE_USR_DRIVER_TYPE}',
+ f'-DROCE_MODIFY_SRQ_SGE_EN={ROCE_MODIFY_SRQ_SGE_EN}',
+ f'-DENABLE_DEBUG={ROCE_ENABLE_DEBUG}',
+ f'-DENABLE_HYPER_ROCE={BUILD_HYPER_ROCE}',
+ env.hi1823_roce_usr_code_dir
+ ]
+ returncode = run_shell_cmd(cmd, output=True)
+ if returncode:
+ return returncode
+
+ cmd = ['cmake', '--build', ROCE_BUILD_DIR, '--', '-j16']
+ returncode = run_shell_cmd(cmd, output=True)
+ if returncode:
+ return returncode
+
+ USR_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{ROCE_USR_DRIVER_TYPE}/user"
+ if os.path.exists(USR_OUTPUT_DIR):
+ shutil.rmtree(USR_OUTPUT_DIR)
+
+ os.makedirs(USR_OUTPUT_DIR)
+
+ libh_list = glob.glob(f'{ROCE_OUTPUT_DIR}/libh*.so')
+ for item in libh_list:
+ try:
+ shutil.copy(item, USR_OUTPUT_DIR)
+ except Exception as e:
+ logging.error(f'copy {item} to {USR_OUTPUT_DIR} failed: {e}')
+ return 1
+
+ env.copy_file(f"{roce_usr_kcompat_path}", USR_OUTPUT_DIR)
+
+ # get build info
+ if 'CentOS' not in env.hi1823_os_release:
+ cmd = ["sh", f"{env.HI1823_BUILD_LOG_PATH}/build_log.sh", f"{env.hi1823_roce_usr_code_dir}/build", USR_OUTPUT_DIR, "libhrn5-rdmav34.so", "user"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ ret = env.collect_build_info(USR_OUTPUT_DIR, f"{env.hi1823_bin_dir}/driver/linux/roce", "user")
+ if ret:
+ return ret
+
+ build_roce_knl_6_6_git_apply()
+ logging.info("compile roce user complete.")
+
+ return 0
+
+def build_roce():
+ if not env.hi1823_os_release:
+ env.hi1823_os_release = platform.uname().release.replace('-', '_')
+ elif env.hi1823_os_release == "EULEROS_SERVER_V200R010C00SPC300B560":
+ env.hi1823_os_release = f"{env.hi1823_os_release}_{env.hi1823_os_arch}"
+
+ # kernel
+ ret = build_roce_kernel()
+ if ret:
+ return ret
+
+ return ret
+
+def collect_common_file(roce_rpm_type):
+ shutil.rmtree(env.HI1823_RPM_BUILD_DIR, ignore_errors=True)
+ cmd = ["mkdir", "-pv", "-m", "777", f"{env.HI1823_RPM_BUILD_DIR}/BUILD", f"{env.HI1823_RPM_BUILD_DIR}/BUILDROOT",
+ f"{env.HI1823_RPM_BUILD_DIR}/RPMS", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES", f"{env.HI1823_RPM_BUILD_DIR}/SPECS",
+ f"{env.HI1823_RPM_BUILD_DIR}/SRPMS"]
+ returncode = run_shell_cmd(cmd)
+ if returncode:
+ return returncode
+
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/src/GLOBAL_VERSION_NEW", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES")
+
+ src_build_dir = f"{env.HI1823_TRUNK_DIR}/build/host/linux/roce/hiroce_rpm_build"
+ env.copy_file_with_end(src_build_dir, f"{env.HI1823_RPM_BUILD_DIR}/SPECS", "spec")
+
+ returncode = copy_dir(src_build_dir, f'{env.HI1823_RPM_BUILD_DIR}/SOURCES')
+ if returncode:
+ return returncode
+
+ src_bin_dir = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{roce_rpm_type}"
+ env.copy_file_with_end(f"{src_bin_dir}/user", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES", "so")
+ env.copy_file_with_end(f"{src_bin_dir}/kernel", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES", "ko")
+
+ return 0
+
+def collect_vbs_extern_file(roce_rpm_type):
+ src_bin_dir = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{roce_rpm_type}"
+
+ returncode = copy_dir(f"{src_bin_dir}/hw_verbs_ext", f'{env.HI1823_RPM_BUILD_DIR}/SOURCES')
+ if returncode:
+ return returncode
+
+ returncode = copy_dir(f"{src_bin_dir}/hw_roce_ext", f'{env.HI1823_RPM_BUILD_DIR}/SOURCES')
+ if returncode:
+ return returncode
+
+ return 0
+
+def build_roce_rpm():
+ VBS_EXT = 0
+
+ if not env.hi1823_driver_type:
+ ROCE_RPM_TYPE = "ROCE_STANDARD"
+ elif env.hi1823_driver_type == "ROCE_VBS":
+ ROCE_RPM_TYPE = env.hi1823_driver_type
+ elif env.hi1823_driver_type == "CHIP_TEST" or env.hi1823_driver_type == "ROCE_COMPUTE":
+ ROCE_RPM_TYPE = env.hi1823_driver_type
+ elif env.hi1823_driver_type == "ROCE_VROCE":
+ ROCE_RPM_TYPE = env.hi1823_driver_type
+ else:
+ logging.error(f"not support rpm type: [{env.hi1823_driver_type}]")
+ return 1
+
+ ret = collect_common_file(ROCE_RPM_TYPE)
+ if ret:
+ return ret
+
+ os.chdir(f"{env.HI1823_RPM_BUILD_DIR}/SPECS")
+
+ cmd = [
+ "rpmbuild", "--define", f'_topdir {env.HI1823_RPM_BUILD_DIR}', '-bb', 'hiroce5.spec',
+ "--define", f'vbs_ext {VBS_EXT}'
+ ]
+ returncode = run_shell_cmd(cmd, output=False)
+ if returncode:
+ return returncode
+
+ src_dir = f"{env.HI1823_RPM_BUILD_DIR}/RPMS/{env.hi1823_os_arch}"
+ dst_dir = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{ROCE_RPM_TYPE}"
+ env.copy_file_with_end(src_dir, dst_dir, ".rpm")
+
+ return 0
+
+def build_roce_deb():
+ """基于1825 rpm配置变量生成deb包"""
+
+ # 确定ROCE_DEB_TYPE(参考rpm中的逻辑)
+ if not env.hi1823_driver_type:
+ ROCE_DEB_TYPE = "ROCE_STANDARD"
+ elif env.hi1823_driver_type == "ROCE_VBS":
+ ROCE_DEB_TYPE = env.hi1823_driver_type
+ elif env.hi1823_driver_type == "CHIP_TEST" or env.hi1823_driver_type == "ROCE_COMPUTE":
+ ROCE_DEB_TYPE = env.hi1823_driver_type
+ elif env.hi1823_driver_type == "ROCE_VROCE":
+ ROCE_DEB_TYPE = env.hi1823_driver_type
+ else:
+ logging.error(f"not support deb type: [{env.hi1823_driver_type}]")
+ return 1
+
+ # 设置输出目录
+ KRN_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{ROCE_DEB_TYPE}/kernel"
+ USR_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/roce/{env.hi1823_os_release}/{ROCE_DEB_TYPE}/user"
+
+ # 检查支持的OS类型
+ if env.hi1823_os_type not in ["Ubuntu", "Linx"]:
+ logging.error(f"OS type {env.hi1823_os_type} not supported for deb packaging")
+ return 1
+
+ # 获取版本信息
+ version_var = ""
+ try:
+ with open(f"{env.HI1823_TRUNK_DIR}/src/GLOBAL_VERSION_NEW", 'r') as f:
+ for line in f:
+ if 'driver' in line:
+ version_var = line.split(':')[1].strip()
+ break
+ except Exception as e:
+ logging.error(f"Failed to read version file: {e}")
+ return 1
+
+ lower_os_type = env.hi1823_os_type.lower()
+ arch_dir = "arm64" if env.hi1823_os_arch == "aarch64" else "amd64"
+ lib_dir = "aarch64-linux-gnu" if env.hi1823_os_arch == "aarch64" else "x86_64-linux-gnu"
+
+ # 清理并创建构建目录
+ deb_build_base = f"{env.HI1823_BUILD_DIR}/host/linux/roce/hiroce_deb_build"
+ arch_build_dir = f"{deb_build_base}/{arch_dir}"
+
+ # 清理目录
+ shutil.rmtree(f"{arch_build_dir}/lib/modules", ignore_errors=True)
+
+ # 创建目录结构
+ dirs_to_create = [
+ f"{arch_build_dir}/lib/modules/{env.hi1823_complie_os_kver}/updates/hiroce5",
+ f"{arch_build_dir}/usr/lib/{lib_dir}",
+ f"{arch_build_dir}/etc/modules-load.d",
+ f"{arch_build_dir}/etc/libibverbs.d",
+ f"{arch_build_dir}/etc/logrotate.d"
+ ]
+
+ for directory in dirs_to_create:
+ os.makedirs(directory, exist_ok=True, mode=0o755)
+
+ # 复制内核模块
+ ko_src = f"{KRN_OUTPUT_DIR}/hiroce5.ko"
+ ko_dst = f"{arch_build_dir}/lib/modules/{env.hi1823_complie_os_kver}/updates/hiroce5/hiroce5.ko"
+ if not os.path.exists(ko_src):
+ logging.error(f"Kernel module not found: {ko_src}")
+ return 1
+ shutil.copy2(ko_src, ko_dst)
+
+ # 复制用户态库
+ for so_file in glob.glob(f"{USR_OUTPUT_DIR}/*.so"):
+ shutil.copy2(so_file, f"{arch_build_dir}/usr/lib/{lib_dir}/")
+
+ # 更新control文件版本
+ control_file = f"{arch_build_dir}/DEBIAN/control"
+ if os.path.exists(control_file):
+ with open(control_file, 'r') as f:
+ content = f.read()
+ content = re.sub(r'^Version:.*$', f'Version: {version_var}', content, flags=re.MULTILINE)
+ with open(control_file, 'w') as f:
+ f.write(content)
+
+ # 复制配置文件
+ config_files = {
+ "hrn5.driver": f"{arch_build_dir}/etc/libibverbs.d/",
+ "hiroce5-modules.conf": f"{arch_build_dir}/etc/modules-load.d/",
+ "libroce5": f"{arch_build_dir}/etc/logrotate.d/"
+ }
+
+ config_source_dir = f"{env.HI1823_BUILD_DIR}/host/linux/roce/hiroce_rpm_build"
+ for config_file, dest_dir in config_files.items():
+ src_path = f"{config_source_dir}/{config_file}"
+ if os.path.exists(src_path):
+ shutil.copy2(src_path, dest_dir)
+
+ # 设置DEBIAN目录权限
+ debian_dir = f"{arch_build_dir}/DEBIAN"
+ if os.path.exists(debian_dir):
+ for file in os.listdir(debian_dir):
+ file_path = os.path.join(debian_dir, file)
+ os.chmod(file_path, 0o775)
+
+ # 构建deb包
+ os.chdir(deb_build_base)
+ kver_underline = env.hi1823_complie_os_kver.replace('.', '_')
+ deb_name = f"hiroce5-{version_var}-{kver_underline}.{lower_os_type}.{env.hi1823_os_arch}.deb"
+
+ cmd = ["dpkg-deb", "--build", arch_dir, deb_name]
+ returncode = run_shell_cmd(cmd, output=False)
+ if returncode:
+ return returncode
+
+ # 移动deb包到输出目录
+ deb_src = f"{deb_build_base}/{deb_name}"
+ deb_dst = f"{KRN_OUTPUT_DIR}/{deb_name}"
+ shutil.move(deb_src, deb_dst)
+
+ logging.info(f"DEB package generated: {deb_dst}")
+ return 0
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/roce_kcompat_generator.sh b/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/roce_kcompat_generator.sh
new file mode 100755
index 000000000..335cae74b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/roce/roce_kcompat_generator.sh
@@ -0,0 +1,330 @@
+#!/bin/bash
+
+# SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
+#!/bin/bash
+# Copyright(c) 2026 Huawei Technologies Co., Ltd
+
+# This file is used to automatically generate HAVE_ and NEED_ macros
+# for the current or incoming kernel.
+#
+# It is primarily implemented by invoking the 'gen' function in the kcompat-lib.sh file
+# (you can refer to the main part of 'gen_xx' for details).
+# The 'gen' tool can search for declarations of various types in kernel header files to generate macros.
+# For example, search for a function in a specified file and check whether the given function exists.
+# Please refer to the comments above the 'gen' function in kcompat-lib.sh.
+
+# End of intro.
+# The implementation is in kcompat-lib.sh, and below is an example of the 'gen' invocation.
+
+set -e
+
+export LC_ALL=C
+
+SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
+ORIG_CWD="$(pwd)"
+ROCE_INCLUDE_DIR=""
+KSRC=""
+OUT=""
+
+trap 'rc=$?; echo >&2 "$(realpath "$ORIG_CWD/${BASH_SOURCE[0]}"):$LINENO: failed with rc: $rc"' ERR
+
+# shellcheck source=kcompat-lib.sh
+if [[ -f "$SCRIPT_DIR/kcompat-lib.sh" ]]; then
+ source "$SCRIPT_DIR/kcompat-lib.sh"
+elif [[ -f "$SCRIPT_DIR/../kcompat-lib.sh" ]]; then
+ source "$SCRIPT_DIR/../kcompat-lib.sh"
+else
+ echo "Error: kcompat-lib.sh not found."
+ exit 1
+fi
+
+function ready_gen()
+{
+ if [ -z "$KSRC" ]; then
+ BUILD_KERNEL=$(uname -r)
+ if [ -e "/usr/src/kernels/linux-$BUILD_KERNEL/include/config" ]; then
+ KSRC="/usr/src/kernels/linux-$BUILD_KERNEL/"
+ elif [ -e "/usr/src/kernels/$BUILD_KERNEL/include/config" ]; then
+ KSRC="/usr/src/kernels/$BUILD_KERNEL/"
+ elif [ -e "/lib/modules/$BUILD_KERNEL/build/include/config" ]; then
+ KSRC="/lib/modules/$BUILD_KERNEL/build/"
+ fi
+ fi
+
+ if [ -z "$KSRC" ]; then
+ BUILD_KERNEL=$(uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/')
+ if [ -e "/usr/src/kernels/linux-$BUILD_KERNEL/include/config" ]; then
+ KSRC="/usr/src/kernels/linux-$BUILD_KERNEL/"
+ elif [ -e "/usr/src/kernels/$BUILD_KERNEL/include/config" ]; then
+ KSRC="/usr/src/kernels/$BUILD_KERNEL/"
+ elif [ -e "/lib/modules/$BUILD_KERNEL/build/include/config" ]; then
+ KSRC="/lib/modules/$BUILD_KERNEL/build/"
+ fi
+ fi
+
+ if [ -z "$KSRC" ]; then
+ echo "Invalid kernel src. Expected: $BUILD_KERNEL"
+ KSOURCES=$(ls -w 1 /usr/src/kernels/ ; ls -w 1 /lib/modules/)
+ echo "Found: $KSOURCES"
+ exit 1
+ fi
+
+ # Generate roce_kernel_compat_gen.h
+ GSRC=$KSRC
+ if [ ! -d "$KSRC/include/rdma" ]; then
+ echo "Detect other Debian/SLES include directory using KSRC..."
+ # detect other SLES include directory using KSRC
+ t=$(dirname $KSRC)/$(basename $KSRC)
+ if [ -L "$t" ]; then
+ # a symlink
+ t=$(readlink -f $t)
+ fi
+ # SLES
+ t=${t%-obj*}
+ # Debian
+ t=${t/-amd64/-common}
+ t=${t/-arm64/-common}
+ if [ -d "$t/include/rdma" ]; then
+ GSRC=$t
+ fi
+ fi
+
+ echo "KSRC: $KSRC"
+ echo "GSRC: $GSRC"
+
+ OUT=$ROCE_INCLUDE_DIR/roce_kernel_compat_gen.h KSRC=$GSRC QUIET_COMPAT=1
+}
+# DO NOT break gen calls below (via \), to make our compat code more grep-able,
+# keep them also grouped, first by feature (like DEVLINK), then by .h filename
+# finally, keep them sorted within a group (sort by flag name)
+
+# handy line of DOC copy-pasted form kcompat-lib.sh:
+# gen DEFINE if (KIND [METHOD of]) NAME [(matches|lacks) PATTERN|absent] in <list-of-files>
+
+function gen_rdma_ib_umem() {
+ um='include/rdma/ib_umem.h'
+ kernel_um=$KSRC/include/rdma/ib_umem.h
+ gen HAVE_IB_UMEM_NUM_DMA_BLOCKS if fun ib_umem_num_dma_blocks in "$um"
+ gen HAVE_RDMA_UMEM_FOR_EACH_DMA_BLOCK if macro rdma_umem_for_each_dma_block in "$um"
+ gen IB_UMEM_HAVE_SG_APPEND_TABLE if struct ib_umem matches 'sg_append_table' in "$kernel_um"
+ gen UMEM_HAVE_PAGE_SHIFT if struct ib_umem matches 'int[ \t]*page_shift' in "$um"
+ gen IB_UMEM_GET_HAVE_IB_DEVICE if fun ib_umem_get matches 'struct ib_device \\*' in "$um"
+ gen IB_UMEM_GET_HAVE_IB_UCONTEXT if fun ib_umem_get matches 'struct ib_ucontext \\*' in "$um"
+ gen HAVE_IB_UMEM_PAGE_COUNT if fun ib_umem_page_count in "$um"
+ gen HAVE_IB_UMEM_NUM_PAGES if fun ib_umem_num_pages in "$um"
+
+ gen IB_UMEM_GET_PEER if fun ib_umem_get_peer in "$um"
+ gen IB_UMEM_GET_PEER_HAVE_IBDEVICE if fun ib_umem_get_peer matches 'struct ib_device \\*' in "$um"
+ gen IB_UMEM_NEED_IB_UMEM_FIND_BEST_PGSZ if fun ib_umem_find_best_pgsz absent in "$um"
+}
+
+function gen_rdma_ib_verbs() {
+ iv='include/rdma/ib_verbs.h'
+
+ gen IB_MODIFY_QP_IS_OK_HAVE_RDMA_LINK_LAYER if fun ib_modify_qp_is_ok matches 'enum rdma_link_layer' in "$iv"
+ gen HAVE_RDMA_AH_INIT_ATTR if struct rdma_ah_init_attr in "$iv"
+ gen IB_REG_DEV_HAVE_PORT_CALLBACK if fun ib_register_device matches 'int \\(\\*port_callback' in "$iv"
+ gen IB_REG_DEV_HAVE_NAME if fun ib_register_device matches 'char \\*name' in "$iv"
+ gen IB_REG_DEV_HAVE_DEVICE if fun ib_register_device matches 'struct device \\*' in "$iv"
+ gen IB_SRQ_HAVE_UOBJECT if struct ib_srq matches 'struct ib_uobject[ \t]*\\*'
+ gen IB_CQ_HAVE_UOBJECT if struct ib_cq matches 'struct ib_uobject[ \t]*\\*'
+ gen IB_DEV_HAVE_UVERBS_EX_CMD_MASK if struct ib_device matches 'uverbs_ex_cmd_mask' in "$iv"
+ gen IB_DEV_ATTR_HAVE_MAX_FMR if struct ib_device_attr matches 'max_fmr' in "$iv"
+ gen IB_DEV_ATTR_HAVE_MAX_MAP_PER_FMR if struct ib_device_attr matches 'max_map_per_fmr' in "$iv"
+ gen HAVE__IB_ALLOC_DEVICE if fun _ib_alloc_device in "$iv"
+ gen IB_WR_OPCODE_HAVE_BIND_MW if enum ib_wr_opcode matches IB_WR_BIND_MW in "$iv"
+ gen IB_QP_CREATE_FLAGS_HAVE_INTEGRITY_EN if enum ib_qp_create_flags matches IB_QP_CREATE_INTEGRITY_EN in "$iv"
+ gen HAVE_IB_DEVICE_OPS if struct ib_device_ops in "$iv"
+ gen ROCE_CREATE_QP_INT if method create_qp of ib_device_ops matches 'int[ \t]*\\(\\*' in "$iv"
+ gen ROCE_CREATE_QP_IB_QP if method create_qp of ib_device_ops matches 'struct ib_qp[ \t]*\\*\\(\\*' in "$iv"
+ gen IB_DEVICE_OPS_HAVE_CREATE_USER_AH if method create_user_ah of ib_device_ops in "$iv"
+ gen HAVE_ALL_ROCE_FUNCS_U8_PORT if method query_port of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen HAVE_ALL_ROCE_FUNCS_U32_PORT if method query_port of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen GET_LINK_LAYER_HAVE_U8_PORT if method get_link_layer of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen GET_LINK_LAYER_HAVE_U32_PORT if method get_link_layer of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen QUERY_GID_HAVE_U8_PORT if method query_gid of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen QUERY_GID_HAVE_U32_PORT if method query_gid of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen QUERY_PKEY_HAVE_U8_PORT if method query_pkey of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen QUERY_PKEY_HAVE_U32_PORT if method query_pkey of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen MODIFY_PORT_HAVE_U8_PORT if method modify_port of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen MODIFY_PORT_HAVE_U32_PORT if method modify_port of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen GET_PORT_IMMUTABLE_HAVE_U8_PORT if method get_port_immutable of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen GET_PORT_IMMUTABLE_HAVE_U32_PORT if method get_port_immutable of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen GET_NETDEV_HAVE_U8_PORT if method get_netdev of ib_device_ops matches 'u8 port_num' in "$iv"
+ gen GET_NETDEV_HAVE_U32_PORT if method get_netdev of ib_device_ops matches 'u32 port_num' in "$iv"
+ gen IB_DEVICE_OPS_HAVE_IB_QP_OBJ if struct ib_device_ops matches 'DECLARE_RDMA_OBJ_SIZE\\(ib_qp\\)' in "$iv"
+ gen HAVE_IB_DEVICE_LOCAL_DMA_LKEY if enum ib_device_cap_flags matches IB_DEVICE_LOCAL_DMA_LKEY in "$iv"
+ gen HAVE_IB_KERNEL_CAP_FLAGS if enum ib_kernel_cap_flags in "$iv"
+ gen IB_QUERY_PORT_HAVE_U8_PORT if fun ib_query_port matches 'u8 port_num' in "$iv"
+ gen IB_QUERY_PORT_HAVE_U32_PORT if fun ib_query_port matches 'u32 port_num' in "$iv"
+ gen IB_MR_TYPE_HAVE_USER if enum ib_mr_type matches IB_MR_TYPE_USER in "$iv"
+ gen IB_MR_TYPE_HAVE_INTEGRITY if enum ib_mr_type matches IB_MR_TYPE_INTEGRITY in "$iv"
+}
+
+function gen_rdma_ib_addr() {
+ ia='include/rdma/ib_addr.h'
+
+ gen RDMA_RESOLVE_IP_HAVE_GID_ATTR if fun rdma_resolve_ip matches 'bool resolve_by_gid_attr' in "$ia"
+}
+
+function gen_rdma_uverbs_ioctl() {
+ ui='include/rdma/uverbs_ioctl.h'
+
+ gen UVERBS_IOCTL_HAVE_RDMA_UDATA_TO_DRV_CONTEXT if macro rdma_udata_to_drv_context in "$ui"
+ gen UVERBS_IOCTL_HAVE_DECLARE_UVERBS_WRITE_EX if macro DECLARE_UVERBS_WRITE_EX in "$ui"
+}
+
+function gen_rdma_netlink() {
+ nl=$KSRC/include/net/netlink.h
+
+ gen NLA_POLICY_HAVE_MIN_MAX if struct nla_policy matches 's16 min, max' in "$nl"
+}
+
+function gen_rdma_mmu_notifier() {
+ # mlnx ofed defines MMU_INTERVAL_NOTIFIER based on the kernel mmu_notifier.h
+ mmu_notifier=${KSRC}/include/linux/mmu_notifier.h
+
+ gen MMU_INTERVAL_NOTIFIER if struct mmu_interval_notifier in "$mmu_notifier"
+}
+
+function gen_rdma_inetdevice() {
+ inetdev=$KSRC/include/linux/inetdevice.h
+ ndh='include/linux/netdevice.h'
+
+ gen INETDEV_HAVE_FOR_IFA if macro for_ifa in "$inetdev"
+
+ # exception centos7.9 x86 os
+ # (Un)registration functions for the notifiers that takes 'struct netdev_notifier_info *' as parameter in register_netdevice_notifier_rh
+ if [[ -z "${MLNX_OFED_DIR:-}" ]]; then
+ gen HAVE_REGISTER_NETDEVICE_NOTIFIER_RH if fun register_netdevice_notifier_rh in "$ndh"
+ fi
+}
+
+function gen_rdma_kobjtype() {
+ kobject=$KSRC/include/linux/kobject.h
+
+ gen KBOJ_TYPE_HAVE_ATTRS_GROUP if struct kobj_type matches 'const struct attribute_group \\*' in "$kobject"
+}
+
+function gen_rdma() {
+ # Distinguish the mlnx and native rdma-core packages that use the same image for Kylin V10SP3/SP2
+ if [[ -n "${MLNX_OFED_DIR:-}" && -d "$MLNX_OFED_DIR" ]]; then
+ cd $MLNX_OFED_DIR
+ else
+ cd .
+ fi
+
+ gen_rdma_ib_umem
+ gen_rdma_ib_verbs
+ gen_rdma_ib_addr
+ gen_rdma_uverbs_ioctl
+ gen_rdma_mmu_notifier
+ gen_rdma_inetdevice
+ gen_rdma_netlink
+ gen_rdma_kobjtype
+
+ cd - > /dev/null
+}
+
+# all the generations, extracted from main() to keep normal code and various
+# prep separated
+function gen_all() {
+ CHECK_DIR=(/opt/buildtools)
+ if [[ "$OFED_TYPE" == "MLNX_OFED" ]]; then
+ modfile=$(find ${CHECK_DIR[0]} -maxdepth 2 -name Module.symvers | grep mlnx-ofa_kernel)
+ if [ -n "$modfile" ] && [ -f "$modfile" ]; then
+ MLNX_OFED_DIR=$(dirname "$modfile")
+ fi
+ fi
+ gen_rdma
+}
+
+function gen_roce_kcompat() {
+ ready_gen
+ # check if caller (like our makefile) wants to redirect output to file
+ OUT_DEFINE=_ROCE_KCOMPAT_GEN_H_
+ if [ -n "${OUT-}" ]; then
+ OUT_DEFINE="$(basename $OUT .h)"
+ OUT_DEFINE="_${OUT_DEFINE^^}_H_"
+
+ # in case OUT exists, we don't want to overwrite it, instead
+ # write to a temporary copy.
+ if [ -s "$OUT" ]; then
+ TMP_OUT="$(mktemp "$OUT.XXX")"
+ trap "rm -f '$TMP_OUT'" EXIT
+
+ REAL_OUT="$OUT"
+ OUT="$TMP_OUT"
+ fi
+
+ ls -l $ROCE_INCLUDE_DIR
+ exec > "$OUT"
+ # all stdout goes to OUT since now
+ echo "/* Autogenerated for KSRC=${KSRC-} via $(basename "$0") */"
+ fi
+ if [ -d "${KSRC-}" ]; then
+ cd $KSRC
+ fi
+
+ # check if KSRC was ok/if we are in proper place to look for headers
+ if [ ! -e include/linux/kernel.h ]; then
+ echo >&2 "seems that there are no kernel includes placed in KSRC=$KSRC
+ pwd=$(pwd); ls -l:"
+ ls -l >&2
+ exit 8
+ fi
+
+ echo "#ifndef $OUT_DEFINE"
+ echo "#define $OUT_DEFINE"
+ gen_all
+ echo "#endif /* $OUT_DEFINE */"
+
+ if [ -n "${OUT-}" ]; then
+ cd "$ORIG_CWD"
+
+ # Compare and see if anything changed. This avoids updating
+ # mtime of the file.
+ if [ -n "${REAL_OUT-}" ]; then
+ if cmp --silent "$REAL_OUT" "$TMP_OUT"; then
+ # exit now, skipping print of the output since
+ # there were no changes. the trap should
+ # cleanup TMP_OUT
+ exit 0
+ fi
+
+ mv -f "$TMP_OUT" "$REAL_OUT"
+ OUT="$REAL_OUT"
+ fi
+
+ # dump output, will be visible in CI
+ if [ -n "${JUST_UNIT_TESTING-}${QUIET_COMPAT-}" ]; then
+ return
+ fi
+ cat -n "$OUT" >&2
+ fi
+}
+
+if [[ -z ${1:-} ]]; then
+ echo "Not set roce kernel source path"
+ exit 1
+fi
+
+ROCE_INCLUDE_DIR=$1
+
+if [[ -n "$2" ]]; then
+ KSRC="$2"
+fi
+
+if [ "$CONFIG_UB_UNIFIED_UBUS" = "y" ]; then
+ KSRC=$UBUS_BUILD_KERNEL_DIR
+fi
+
+if [[ -n "$3" ]]; then
+ OFED_TYPE="$3"
+fi
+
+gen_roce_kcompat
+if [ $? -ne 0 ]; then
+ echo "Failed to generate $ROCE_INCLUDE_DIR/roce_kernel_compat_gen.h"
+ exit 1
+fi
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/__init__.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/__init__.py
new file mode 100755
index 000000000..cc0d19d0a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/__init__.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/build_sdk.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/build_sdk.py
new file mode 100755
index 000000000..652894f23
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/build_sdk.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+import env
+import logging
+import shutil
+import subprocess
+from build_util import do_cmd, do_make, do_make_clean, rpm_build
+
+SDK_RPM_BUILD_DIR = f'{env.HI1823_BUILD_DIR}/host/linux/sdk/sdk_rpm_build/'
+
+
+def save_output(path):
+ shutil.rmtree(path, ignore_errors=True)
+ os.makedirs(path, exist_ok=True)
+ env.copy_file(f"{env.HI1823_LLD_CODE_DIR}/hisdk5.ko", path)
+
+ # get build info
+ cmd = ["sh", f"{env.HI1823_BUILD_LOG_PATH}/build_log.sh", f"{env.HI1823_LLD_CODE_DIR}/build", path, "hisdk5.ko"]
+ do_cmd(*cmd)
+
+ ret = env.collect_build_info(path, f"{env.hi1823_bin_dir}/driver/linux/sdk")
+ if ret:
+ raise Exception('env.collect_build_info failed')
+
+ # strip debug info of ko for release rpm or deb package
+ cmd = ["strip", "--strip-debug", f"{path}/hisdk5.ko", "-o", f"{path}/hisdk5_tmp.ko"]
+ do_cmd(*cmd)
+
+
+def build_clean():
+ module_file = f"{env.hi1823_ci_lib_dir}/SDK_Module.symvers"
+ if os.path.isfile(module_file):
+ os.remove(module_file)
+ env.copy_file(f"{env.HI1823_LLD_CODE_DIR}/Module.symvers", env.hi1823_ci_lib_dir, "SDK_Module.symvers")
+
+ # make clean
+ do_make_clean(workdir=env.HI1823_LLD_CODE_DIR)
+
+ cmd = ["find", f"{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/knldk",
+ "-name", "*.o", "-o", "-name", "*.cmd", "-o", "-name", "*.mod"]
+ result = do_cmd(*cmd)
+ do_cmd('xargs', 'rm', '-f', input=result.stdout)
+
+ cmd = ["find", f"{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/sdk/ossl",
+ "-name", "*.o", "-o", "-name", "*.cmd"]
+ result = do_cmd(*cmd)
+ do_cmd('xargs', 'rm', '-f', input=result.stdout)
+
+
+def build_deb_package(arch):
+ workdir = f'{env.HI1823_BUILD_DIR}/host/linux/sdk/sdk_deb_build/'
+ kernel_release = env.hi1823_complie_os_kver
+ driver_version = env.get_global_version('driver')
+
+ if arch == "x86_64":
+ distname = "amd64"
+ else:
+ distname = "arm64"
+
+ distdir = f'{workdir}/{distname}'
+ modules_dir = f"{distdir}/lib/modules/"
+ modules_load_dir = f"{distdir}/lib/modules-load.d/"
+ ko_dir = f'{modules_dir}/{kernel_release}/updates/hisdk5/'
+
+ shutil.rmtree(modules_dir, ignore_errors=True)
+ os.makedirs(ko_dir)
+
+ # prepare hisdk5
+ sdk_output = env.get_driver_output_path('sdk')
+ shutil.move(f'{sdk_output}/hisdk5_tmp.ko', f'{ko_dir}/hisdk5.ko')
+ env.copy_file(f"{workdir}/hisdk5-modules.conf", modules_load_dir)
+
+ do_cmd('sed', '-i', f'/^Version/c Version: {driver_version}', f'{distdir}/DEBIAN/control')
+ do_cmd('chmod', '-R', '775', f'{distdir}/DEBIAN/')
+
+ # build deb
+ deb_file = f"hisdk5-{driver_version}-{env.hi1823_complie_os_kver_underline}.{arch}.deb"
+ cmd = ["dpkg", "-b", distname, deb_file]
+ do_cmd(*cmd, cwd=workdir)
+
+ shutil.move(f'{workdir}/{deb_file}', sdk_output)
+
+
+def get_rpm_spec(os_type, arch):
+ if os_type == 'UVP':
+ spec = 'hisdk5_uvp.spec'
+ else:
+ spec = 'hisdk5.spec'
+ return spec
+
+
+def build_rpm_package(arch):
+ os_type = env.hi1823_os_type
+ workdir = env.HI1823_RPM_BUILD_DIR
+
+ shutil.rmtree(workdir, ignore_errors=True)
+ cmd = [
+ 'mkdir', '-pv', '-m', '777',
+ f'{workdir}/BUILD',
+ f'{workdir}/BUILDROOT',
+ f'{workdir}/RPMS',
+ f'{workdir}/SOURCES',
+ f'{workdir}/SPECS',
+ f'{workdir}/SRPMS'
+ ]
+ do_cmd(*cmd)
+
+ env.copy_file(f'{env.HI1823_TRUNK_DIR}/src/GLOBAL_VERSION_NEW', f'{workdir}/SOURCES')
+
+ # prepare hisdk5
+ sdk_output = env.get_driver_output_path('sdk')
+
+ shutil.move(f'{sdk_output}/hisdk5_tmp.ko', f'{workdir}/SOURCES/hisdk5.ko')
+ env.copy_file(f'{SDK_RPM_BUILD_DIR}/hisdk5-modules.conf', f'{workdir}/SOURCES')
+
+ # prepare OS
+ if os_type == 'UVP':
+ env.copy_file(f'{SDK_RPM_BUILD_DIR}hisdk5-dracut.conf', f'{workdir}/SOURCES')
+
+ # prepare rpm spec
+ spec = get_rpm_spec(os_type, arch)
+ if not spec:
+ raise Exception(f'no spec to build rpm. OS type {os_type}, arch {arch}')
+ env.copy_file(f'{SDK_RPM_BUILD_DIR}/{spec}', f'{workdir}/SPECS')
+
+ # build rpm
+ rpm_build(workdir=workdir, spec=spec, arch=arch)
+
+ # copy rpm to output dir
+ rpm_dir = f'{workdir}/RPMS/{arch}'
+ env.copy_file_with_end(rpm_dir, sdk_output, ".rpm")
+
+
+def build_package(pkg_type, arch):
+ if pkg_type == "rpm":
+ return build_rpm_package(arch=arch)
+ if pkg_type == "deb":
+ return build_deb_package(arch=arch)
+ raise Exception(f'unknown package manager type {pkg_type}')
+
+
+def build_sdk_rpm_deb():
+ try:
+ build_package(
+ pkg_type=env.hi1823_os_pkg_mgr,
+ arch=env.hi1823_os_arch,
+ )
+ return 0
+ except Exception as e:
+ logging.exception(f'build package failed')
+ return 1
+
+def sdk_dfx_ko_build(workdir, outdir, solo=False):
+ logging.info(f'\n{"↓" * 60} Build SDK DFX ko {"↓" * 60}')
+
+ mod_name = 'hidfx3'
+ make_args = []
+ if solo:
+ logging.info(f'solo dfx driver : {solo}')
+ mod_name = 'hidfx3solo'
+ make_args = ['CONFIG_DFX_SOLO=y']
+
+ try:
+ do_make_clean(workdir)
+ do_make(*make_args, workdir=workdir)
+
+ # save output
+ env.copy_file(f"{workdir}/{mod_name}.ko", outdir)
+ do_cmd("strip", "--strip-debug", f"{outdir}/{mod_name}.ko", "-o", f"{outdir}/{mod_name}.strip.ko")
+
+ do_make_clean(workdir)
+ logging.info(f'Build SDK DFX ko success')
+ except Exception as e:
+ logging.error(f'Build SDK DFX ko failed: {e}')
+ raise
+ finally:
+ logging.info(f'\n{"↑" * 60} Build SDK DFX ko {"↑" * 60}')
+
+def build_sdk_ko():
+ srcdir = env.HI1823_LLD_CODE_DIR
+ outdir = env.get_driver_output_path('sdk')
+ sdk_dfx_dir = f'{env.HI1823_TRUNK_DIR}/tools/dfx_driver/src'
+
+ try:
+ # make
+ do_make_clean(workdir=srcdir)
+ do_make(workdir=srcdir)
+
+ save_output(outdir)
+ build_clean()
+
+ # build hidfx3.ko
+ if os.getenv('BUILD_SDK_DFX') == 'y':
+ sdk_dfx_ko_build(sdk_dfx_dir, outdir)
+ sdk_dfx_ko_build(sdk_dfx_dir, outdir, solo=True)
+ return 0
+ except Exception as e:
+ logging.exception(f'build ko failed')
+ return 1
+
+
+def build_sdk():
+ return build_sdk_ko()
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/sdk-kcompat-generator.sh b/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/sdk-kcompat-generator.sh
new file mode 100755
index 000000000..e2fbd51d9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/sdk/sdk-kcompat-generator.sh
@@ -0,0 +1,308 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2025 Huawei Technologies Co., Ltd
+
+# This file is used to automatically generate HAVE_ and NEED_ macros
+# for the current or incoming kernel.
+#
+# It is primarily implemented by invoking the 'gen' function in the kcompat-lib.sh file
+# (you can refer to the main part of 'gen_xx' for details).
+# The 'gen' tool can search for declarations of various types in kernel header files to generate macros.
+# For example, search for a function in a specified file and check whether the given function exists.
+# Please refer to the comments above the 'gen' function in kcompat-lib.sh.
+
+# End of intro.
+# The implementation is in kcompat-lib.sh, and below is an example of the 'gen' invocation.
+
+set -e
+
+echo "curr bash script file name: $(basename "${BASH_SOURCE[0]}")"
+export LC_ALL=C
+SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
+ORIG_CWD="$(pwd)"
+trap 'rc=$?; echo >&2 "$(realpath "$ORIG_CWD/${BASH_SOURCE[0]}"):$LINENO: failed with rc: $rc"' ERR
+
+# shellcheck source=kcompat-lib.sh
+CURR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+KCOMPAT_LIB="${CURR_DIR}/../kcompat-lib.sh"
+
+if [ -f "$KCOMPAT_LIB" ]; then
+ echo "$KCOMPAT_LIB file is exist"
+else
+ echo "$KCOMPAT_LIB file is not exist"
+fi
+source "$KCOMPAT_LIB"
+
+ARCH=$(uname -m)
+IS_ARM=""
+if [ "$ARCH" == aarch64 ]; then
+ IS_ARM=1
+fi
+
+function ready_gen()
+{
+ KERN_VER=$(uname -r)
+ KSRC=""
+
+ if [ -e /usr/src/kernels/linux-"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/linux-"$KERN_VER"/"
+ elif [ -e /usr/src/kernels/"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/"$KERN_VER"/"
+ elif [ -e /lib/modules/"$KERN_VER"/build/include/config ]; then
+ KSRC="/lib/modules/"$KERN_VER"/build/"
+ fi
+
+ if [ -z "$KSRC" ]; then
+ KERN_VER=$(uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/')
+ if [ -e /usr/src/kernels/linux-"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/linux-"$KERN_VER"/"
+ elif [ -e /usr/src/kernels/"$KERN_VER"/include/config ]; then
+ KSRC="/usr/src/kernels/"$KERN_VER"/"
+ elif [ -e /lib/modules/"$KERN_VER"/build/include/config ]; then
+ KSRC="/lib/modules/"$KERN_VER"/build/"
+ fi
+ fi
+
+ if [ -z "$KSRC" ]; then
+ echo "Invalid kernel src. Expected: ${KERN_VER}"
+ echo "Please check if kernel-devel(for other OS) or linux-headers(for debian) installed"
+ KSOURCES=$(ls -w 1 /usr/src/kernels/ ; ls -w 1 /lib/modules/)
+ echo "Found: ${KSOURCES}"
+ exit 1
+ fi
+ KOBJ=$KSRC
+
+ if [ ! -d "${KSRC}"/include/linux ]; then
+ echo "Detect other Debian/SLES include directory using KSRC..."
+ # detect other SLES include directory using KSRC
+ t=$(dirname "$KSRC")/$(basename "$KSRC")
+ if [ -L "$t" ]; then
+ # a symlink
+ t=$(readlink -f $t)
+ fi
+ # SLES
+ t=${t%-obj*}
+ # LinxOS
+ t=${t/-linx-security-arm64/-common-linx-security}
+ # Debian
+ t=${t/-amd64/-common}
+ t=${t/-arm64/-common}
+ if [ -d "${t}"/include/linux ]; then
+ KSRC=$t
+ fi
+ fi
+
+ if [ -d "$1" ]; then
+ KSRC=$1
+ # 目前build_cache里的内核是6.6的,KERNEL_VER不影响功能,暂时写死
+ KERN_VER="6.6.0-132.0.0.111.oe2403sp3.aarch64"
+ fi
+ echo "sdk-kcompat-generator.sh -> KERN_VER: ${KERN_VER}"
+ echo "sdk-kcompat-generator.sh -> KSRC: ${KSRC}"
+ export KSRC KOBJ
+}
+
+# 解决在linux 内核头文件中未定义的语法说明
+#eg. gen DEFINE if [fun|enum|struct|macro|typedef|symbol] NAME (absent) in <list-of-files>
+# 解决在linux 内核头文件中有多种格式定义的语法说明
+# matches PATTERN:定义中存在这个字符pattern. lacks PATTERN:定义中存在这个字符pattern: 定义中没有这个pattern
+#eg. gen DEFINE if [fun|enum|struct|macro|typedef|symbol] NAME [matches|lacks] PATTERN in <list-of-files>
+function gen_pci() {
+ pci_h='include/linux/pci.h'
+ pdc_h='include/linux/pci-dma-compat.h'
+
+ gen NEED_PCI_DOMAIN_NR if fun pci_domain_nr absent in "$pci_h"
+ gen NEED_DEFINE_PCI_DMA_COMPAT if macro PCI_DMA_BIDIRECTIONAL absent in "$pdc_h"
+ gen HAVE_PCIE_RESET_DONE if struct pci_error_handlers matches reset_done in "$pci_h"
+ gen NEED_PCI_SRIOV_GET_TOTALVFS if fun pci_sriov_get_totalvfs absent in "$pci_h"
+}
+
+function gen_sysfs() {
+ sysfs_h='include/linux/sysfs.h'
+
+ gen NEED_PDE_DATA if fun PDE_DATA absent in include/linux/proc_fs.h
+ gen HAVE_PDE_DATA_LOWERCASE if fun pde_data in include/linux/proc_fs.h
+ gen NEED_SYSFS_EMIT if fun sysfs_emit absent in "$sysfs_h"
+}
+
+function gen_ptp_clock_kernel() {
+ ptp_clock_kernel_h='include/linux/ptp_clock_kernel.h'
+
+ gen NEED_PTP_ADJUST_BY_SCALED_PPM if fun adjust_by_scaled_ppm absent in "$ptp_clock_kernel_h"
+}
+
+function gen_math64() {
+ math64_h='include/linux/math64.h'
+
+ gen NEED_MATH64_MUL_U64_U64_DIV_U64 if fun mul5_u64_u64_div_u64 absent in "$math64_h"
+}
+
+function gen_timer() {
+ timer_h='include/linux/timer.h'
+
+ gen HAVE_TIMER_SETUP if fun timer_setup in "$timer_h"
+}
+
+function gen_cpumask() {
+ cpumask_h='include/linux/cpumask.h'
+
+ gen NEED_CPUMASK_LOCAL_SPREAD if fun cpumask_local_spread absent in "$cpumask_h"
+}
+
+function gen_etherdevice() {
+ etherdevice_h='include/linux/etherdevice.h'
+
+ gen HAVE_ETH_HW_ADDR_SET if fun eth_hw_addr_set in "$etherdevice_h"
+ gen NEED_ETH_ZERO_ADDR if fun eth_zero_addr absent in "$etherdevice_h"
+}
+
+function gen_devlink() {
+ devlink_h='include/net/devlink.h'
+ gen HAVE_DEVLINK_H if macro _NET_DEVLINK_H_ in "$devlink_h"
+
+ gen HAVE_DEVLINK_FLASH_UPDATE_METHOD if struct devlink_ops matches flash_update in "$devlink_h"
+ gen HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY if fun devlink_flash_update_begin_notify in "$devlink_h"
+ gen HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FW if struct devlink_flash_update_params matches 'struct firmware \\*fw' in "$devlink_h"
+ gen HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FILE_NAME if struct devlink_flash_update_params matches file_name in "$devlink_h"
+ gen HAVE_DEVLINK_OPS_FLASH_UPDATE_HAVE_PARAMS if method flash_update of devlink_ops matches devlink_flash_update_params in "$devlink_h"
+
+ gen HAVE_DEVLINK_PARAMS_PUBLISH if fun devlink_params_publish in "$devlink_h"
+ gen HAVE_DEVLINK_PARAMS_UNPUBLISH if fun devlink_params_unpublish in "$devlink_h"
+
+ gen HAVE_DEVLINK_ALLOC_SET_DEV if fun devlink_alloc matches 'struct device' in "$devlink_h"
+ gen HAVE_DEVLINK_ALLOC if fun devlink_alloc in "$devlink_h"
+
+ gen HAVE_DEVLINK_REGISTER if fun devlink_register in "$devlink_h"
+ gen HAVE_DEVLINK_REGISTER_SET_DEV if fun devlink_register matches 'struct device' in "$devlink_h"
+ gen HAVE_DEVLINK_REGISTER_HAVE_RET if fun devlink_register matches 'int devlink_register' in "$devlink_h"
+
+ gen HAVE_DEVLINK_PARAM_SET_EXTACK if method set of devlink_param matches 'struct netlink_ext_ack' in "$devlink_h"
+}
+
+function gen_uaccess() {
+ uaccess_h='include/linux/uaccess.h'
+ asm_generic_uaccess_h='include/asm-generic/uaccess.h'
+
+ gen NEED_FORCE_UACCESS_BEGIN if fun force_uaccess_begin absent in "$uaccess_h"
+ gen NEED_FORCE_UACCESS_END if fun force_uaccess_end absent in "$uaccess_h"
+ gen NEED_GET_FS if macro get_fs absent in "$asm_generic_uaccess_h"
+ gen NEED_SET_FS if fun set_fs absent in "$asm_generic_uaccess_h"
+}
+
+function gen_aer() {
+ aer_h='include/linux/aer.h'
+
+ gen NEED_PCI_ENABLE_PCIE_ERROR_REPORTING if fun pci_enable_pcie_error_reporting absent in "$aer_h"
+ gen NEED_PCI_DISABLE_PCIE_ERROR_REPORTING if fun pci_disable_pcie_error_reporting absent in "$aer_h"
+}
+
+function gen_gnss() {
+ class_h='include/linux/device/class.h'
+ device_h='include/linux/device.h'
+ class2_h='include/linux/class.h'
+
+ gen HAVE_DEVNODE_CONST_DEV if method devnode of class matches '(const|RH_KABI_CONST) struct device' in "$class_h" "$device_h" "$class2_h"
+
+ NEED_CLASS_CREATE=0
+ if check fun class_create matches 'owner' in "$class_h" "$device_h" "$class2_h" ||
+ check macro class_create matches 'owner' in "$class_h" "$device_h" "$class2_h" ; then
+ NEED_CLASS_CREATE=1
+ fi
+ gen HAVE_CLASS_CREATE_OWNER if string "$NEED_CLASS_CREATE" equals 1
+
+}
+
+# all the generations, extracted from main() to keep normal code and various
+# prep separated
+function gen_all() {
+ gen_pci
+ gen_sysfs
+ gen_ptp_clock_kernel
+ gen_math64
+ gen_timer
+ gen_cpumask
+ gen_etherdevice
+ gen_devlink
+ gen_uaccess
+ gen_aer
+ gen_gnss
+}
+
+function gen_sdk_kcompat() {
+ local ubus_build_kernel_dir=$2
+
+ echo >&2 "gen_sdk_kcompat ubus_build_kernel_dir=${ubus_build_kernel_dir}"
+ if [ -d "$ubus_build_kernel_dir" ]; then
+ ready_gen "$ubus_build_kernel_dir"
+ else
+ ready_gen
+ fi
+
+ local out=$1
+ if ! [ -d "${KSRC-}" ]; then
+ echo >&2 "env KSRC=${KSRC-} does not exist or is not a directory"
+ exit 11
+ fi
+
+ # check if caller (like our makefile) wants to redirect output to file
+ if [ -n "${out-}" ]; then
+
+ # in case out exists, we don't want to overwrite it, instead
+ # write to a temporary copy.
+ if [ -s "${out}" ]; then
+ TMP_OUT="$(mktemp "${out}.XXX")"
+ trap "rm -f '${TMP_OUT}'" EXIT
+
+ REAL_OUT="${out}"
+ out="${TMP_OUT}"
+ fi
+
+ exec 3>&1
+ exec > "$out"
+ # all stdout goes to out since now
+ echo "/* uname=$(uname -r) Autogenerated for KSRC=${KSRC-} via $(basename "$0") */"
+ fi
+
+ cd "${KSRC}"
+
+
+ # check if KSRC was ok/if we are in proper place to look for headers
+ if [ ! -e include/linux/kernel.h ]; then
+ echo >&2 "seems that there are no kernel includes placed in KSRC=${KSRC}
+ pwd=$(pwd); ls -l:"
+ ls -l >&2
+ exit 8
+ fi
+
+ echo "#ifndef SDK_KCOMPAT_H"
+ echo "#define SDK_KCOMPAT_H"
+
+ set +x
+ gen_all
+ set -x
+
+ echo "#endif /* SDK_KCOMPAT_H */"
+ exec >&3
+ if [ -n "${out-}" ]; then
+ cd "$ORIG_CWD"
+
+ # Compare and see if anything changed. This avoids updating
+ # mtime of the file.
+ if [ -n "${REAL_OUT-}" ]; then
+ if cmp --silent "${REAL_OUT}" "${TMP_OUT}"; then
+ # exit now, skipping print of the output since
+ # there were no changes. the trap should
+ # cleanup TMP_OUT
+ return 0
+ fi
+
+ mv -f "${TMP_OUT}" "${REAL_OUT}"
+ out="${REAL_OUT}"
+ fi
+ fi
+ cat -n "$out" >&2
+}
+
+if [ "$1" = "--gen_sdk_kcompat" ]; then
+ gen_sdk_kcompat "$2"
+fi
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/__init__.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/__init__.py
new file mode 100755
index 000000000..cc0d19d0a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/__init__.py
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/build_udma.py b/drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/build_udma.py
new file mode 100755
index 000000000..1bc135990
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/host/linux/udma/build_udma.py
@@ -0,0 +1,532 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+import os
+import re
+import sys
+import env
+import logging
+import shutil
+import subprocess
+import build_sdk
+import build_nic
+
+UDMA_DRIVER_TYPE = None
+KRN_OUTPUT_DIR = None
+KRN_OUTPUT_DIR_WIETH_DGB = None
+USR_OUTPUT_DIR = None
+USR_OUTPUT_DIR_WIETH_DGB = None
+KRN_OUTPUT_DIR_V100 = None
+KRN_OUTPUT_DIR_WIETH_DGB_V100 = None
+USR_OUTPUT_DIR_V100 = None
+USR_OUTPUT_DIR_WIETH_DGB_V100 = None
+URMA_KRN_OUTPUT_DIR = None
+URMA_KRN_OUTPUT_DIR_WIETH_DBG = None
+URMA_USR_OUTPUT_DIR = None
+URMA_USR_OUTPUT_DIR_WIETH_DBG = None
+RPM_OUTPUT_DIR = None
+
+HI1823_1650_BUILD_DIR = None
+KDIR = None
+UBUS_UBC_BUILD_DIR = None
+HISDK5_BUILD_DIR = None
+HINIC5_BUILD_DIR = None
+BUILD_KERNEL_DIR = None
+
+HI1823_UMDK_CODE_DIR = f"{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/UMDK"
+HI1823_UMDK_SPEC_FILE_NAME = 'umdk.spec'
+HI1823_UMDK_SPEC_FILE_PATHNAME = f'{env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/UMDK/{HI1823_UMDK_SPEC_FILE_NAME}'
+HI1823_UMDK_TAR_FILE_VERSION = 'umdk-25.12.0'
+HI1823_UMDK_RPM_OPTION = '--with ubagg_disable --with urma'
+HI1823_UMDK_LIB_URMA_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/lib/urma/core'
+HI1823_UMDK_LIB_TPSA_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/lib/uvs/core'
+HI1823_UMDK_LIB_URMA_COMM_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/common'
+HI1823_UMDK_UBCORE_SYMVERS_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/kmod/drivers/ub/urma/ubcore'
+HI1823_UMDK_UBCORE_KO_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/kmod/drivers/ub/urma/ubcore'
+HI1823_UMDK_UBURMA_SYMVERS_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/kmod/drivers/ub/urma/uburma'
+HI1823_UMDK_UBURMA_KO_DIR = f'{HI1823_UMDK_CODE_DIR}/build/urma/kmod/drivers/ub/urma/uburma'
+
+def build_rpm_prepare():
+ if not env.hi1823_os_release:
+ cmd = "echo -n $(uname -r) | sed -e 's/-/_/g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ env.hi1823_os_release = output
+
+ global UDMA_DRIVER_TYPE
+ if not env.hi1823_driver_type:
+ UDMA_DRIVER_TYPE = "UDMA_STANDARD"
+
+ global KRN_OUTPUT_DIR
+ global KRN_OUTPUT_DIR_WIETH_DGB
+ global USR_OUTPUT_DIR
+ global USR_OUTPUT_DIR_WIETH_DGB
+ global RPM_OUTPUT_DIR
+ KRN_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/udma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}/kernel"
+ KRN_OUTPUT_DIR_WIETH_DGB = f"{KRN_OUTPUT_DIR}/debug"
+ USR_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/udma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}/user"
+ USR_OUTPUT_DIR_WIETH_DGB = f"{USR_OUTPUT_DIR}/debug"
+ RPM_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/udma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}"
+
+ return 0
+
+def build_prepare():
+ if not env.hi1823_os_release:
+ cmd = "echo -n $(uname -r) | sed -e 's/-/_/g'"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ env.hi1823_os_release = output
+
+ global UDMA_DRIVER_TYPE
+ if not env.hi1823_driver_type:
+ UDMA_DRIVER_TYPE = "UDMA_STANDARD"
+
+ global KRN_OUTPUT_DIR
+ global KRN_OUTPUT_DIR_WIETH_DGB
+ global USR_OUTPUT_DIR
+ global USR_OUTPUT_DIR_WIETH_DGB
+ global RPM_OUTPUT_DIR
+ KRN_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/udma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}/kernel"
+ KRN_OUTPUT_DIR_WIETH_DGB = f"{KRN_OUTPUT_DIR}/debug"
+ USR_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/udma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}/user"
+ USR_OUTPUT_DIR_WIETH_DGB = f"{USR_OUTPUT_DIR}/debug"
+ RPM_OUTPUT_DIR = f"{env.hi1823_bin_dir}/driver/linux/udma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}"
+
+ global URMA_KRN_OUTPUT_DIR
+ global URMA_KRN_OUTPUT_DIR_WIETH_DBG
+ global URMA_USR_OUTPUT_DIR
+ global URMA_USR_OUTPUT_DIR_WIETH_DBG
+ URMA_KRN_OUTPUT_DIR = f"{env.HI1823_TRUNK_DIR}/platform/bin/driver/linux/urma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}/kernel"
+ URMA_KRN_OUTPUT_DIR_WIETH_DBG = f"{URMA_KRN_OUTPUT_DIR}/debug"
+ URMA_USR_OUTPUT_DIR = f"{env.HI1823_TRUNK_DIR}/platform/bin/driver/linux/urma/{env.hi1823_os_release}/{UDMA_DRIVER_TYPE}/user"
+ URMA_USR_OUTPUT_DIR_WIETH_DBG = f"{URMA_USR_OUTPUT_DIR}/debug"
+
+ if os.path.isdir(KRN_OUTPUT_DIR):
+ shutil.rmtree(KRN_OUTPUT_DIR)
+ if os.path.isdir(USR_OUTPUT_DIR):
+ shutil.rmtree(USR_OUTPUT_DIR)
+ if os.path.isdir(URMA_KRN_OUTPUT_DIR):
+ shutil.rmtree(URMA_KRN_OUTPUT_DIR)
+ if os.path.isdir(URMA_USR_OUTPUT_DIR):
+ shutil.rmtree(URMA_USR_OUTPUT_DIR)
+
+ os.makedirs(KRN_OUTPUT_DIR)
+ os.makedirs(KRN_OUTPUT_DIR_WIETH_DGB)
+ os.makedirs(USR_OUTPUT_DIR)
+ os.makedirs(USR_OUTPUT_DIR_WIETH_DGB)
+
+ os.makedirs(URMA_KRN_OUTPUT_DIR)
+ os.makedirs(URMA_KRN_OUTPUT_DIR_WIETH_DBG)
+ os.makedirs(URMA_USR_OUTPUT_DIR)
+ os.makedirs(URMA_USR_OUTPUT_DIR_WIETH_DBG)
+
+ global BUILD_KERNEL_DIR
+ BUILD_KERNEL_DIR = env.hi1823_udma_knl_code_dir
+ if (env.hi1823_env_type == "1650"):
+ global HI1823_1650_BUILD_DIR
+ global KDIR
+ global UBUS_UBC_BUILD_DIR
+ global HISDK5_BUILD_DIR
+ global HINIC5_BUILD_DIR
+ HI1823_1650_BUILD_DIR = f"{env.HI1823_TRUNK_DIR}/../build_cache/{env.hi1823_1650_build_version}"
+ KDIR = f"{HI1823_1650_BUILD_DIR}/{env.hi1823_os_path}"
+ UBUS_UBC_BUILD_DIR = f"{HI1823_1650_BUILD_DIR}/cmake/component/{env.hi1823_component_path}/ubus"
+ HISDK5_BUILD_DIR = f"{HI1823_1650_BUILD_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/sdk/knldk/lld"
+ HINIC5_BUILD_DIR = f"{HI1823_1650_BUILD_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/service/nic/linux"
+ BUILD_KERNEL_DIR = f"{HI1823_1650_BUILD_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/service/udma/kernel"
+
+ if env.hi1823_ubus_driver_unified_compile == True:
+ KDIR = env.HI1823_BUILD_UBUS_KERNEL_DIR
+ UBUS_UBC_BUILD_DIR = env.HI1823_BUILD_UBUS_DRIVER_MODULE_DIR
+ HISDK5_BUILD_DIR = f"{env.HI1823_BUILD_DIR}/../src/dpu_platform_library/host/sdk/knldk/lld"
+ HINIC5_BUILD_DIR = f"{env.HI1823_BUILD_DIR}/../src/dpu_platform_library/host/service/nic/linux"
+ BUILD_KERNEL_DIR = f"{env.HI1823_BUILD_DIR}/../src/dpu_platform_library/host/service/udma/kernel"
+
+ return 0
+
+def copy_umdk():
+ env.copy_file(f"{HI1823_UMDK_UBCORE_KO_DIR}/ubcore.ko", URMA_KRN_OUTPUT_DIR_WIETH_DBG)
+ env.copy_file(f"{HI1823_UMDK_UBCORE_KO_DIR}/ubcore.ko", URMA_KRN_OUTPUT_DIR)
+ env.copy_file(f"{HI1823_UMDK_UBCORE_SYMVERS_DIR}/Module.symvers", env.hi1823_ci_lib_dir, "UBCORE_Module.symvers")
+ cmd = f"strip -g {URMA_KRN_OUTPUT_DIR}/ubcore.ko"
+ logging.info(f"exec cmd :[{cmd}]")
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ env.copy_file(f"{HI1823_UMDK_UBURMA_KO_DIR}/uburma.ko", URMA_KRN_OUTPUT_DIR_WIETH_DBG)
+ env.copy_file(f"{HI1823_UMDK_UBURMA_KO_DIR}/uburma.ko", URMA_KRN_OUTPUT_DIR)
+ env.copy_file(f"{HI1823_UMDK_UBURMA_SYMVERS_DIR}/Module.symvers", env.hi1823_ci_lib_dir, "UBURMA_Module.symvers")
+ cmd = f"strip -g {URMA_KRN_OUTPUT_DIR}/uburma.ko"
+ logging.info(f"exec cmd :[{cmd}]")
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ # Copy user library
+ logging.info("Copy user library")
+ env.copy_file_with_start(f"{HI1823_UMDK_LIB_URMA_DIR}", URMA_USR_OUTPUT_DIR_WIETH_DBG, "liburma")
+ env.copy_file_with_start(f"{HI1823_UMDK_LIB_URMA_DIR}", URMA_USR_OUTPUT_DIR, "liburma")
+ cmd = f"strip -s {URMA_USR_OUTPUT_DIR}/liburma*"
+ logging.info(f"exec cmd :[{cmd}]")
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ logging.info("Copy libtpsa")
+ env.copy_file_with_start(f"{HI1823_UMDK_LIB_TPSA_DIR}", URMA_USR_OUTPUT_DIR_WIETH_DBG, "libtpsa")
+ env.copy_file_with_start(f"{HI1823_UMDK_LIB_TPSA_DIR}", URMA_USR_OUTPUT_DIR, "libtpsa")
+ cmd = f"strip -s {URMA_USR_OUTPUT_DIR}/libtpsa*"
+ logging.info(f"exec cmd :[{cmd}]")
+ status, output = subprocess.getstatusoutput(cmd)
+ logging.info(f"exec cmd :status:[{status}]. output:[{output}]")
+
+ logging.info("Copy liburma_common*")
+ env.copy_file_with_start(f"{HI1823_UMDK_LIB_URMA_COMM_DIR}", URMA_USR_OUTPUT_DIR_WIETH_DBG, "liburma_common")
+ env.copy_file_with_start(f"{HI1823_UMDK_LIB_URMA_COMM_DIR}", URMA_USR_OUTPUT_DIR, "liburma_common")
+ cmd = f"strip -s {URMA_USR_OUTPUT_DIR}/liburma_common*"
+ logging.info(f"exec cmd :[{cmd}]")
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/uvs_admin/uvs_admin", URMA_USR_OUTPUT_DIR_WIETH_DBG)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/uvs_admin/uvs_admin", URMA_USR_OUTPUT_DIR)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/urma_admin/urma_admin", URMA_USR_OUTPUT_DIR_WIETH_DBG)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/urma_admin/urma_admin", URMA_USR_OUTPUT_DIR)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/urma_perftest/urma_perftest", URMA_USR_OUTPUT_DIR_WIETH_DBG)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/urma_perftest/urma_perftest", URMA_USR_OUTPUT_DIR)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/transport_service/tpsa_daemon", URMA_USR_OUTPUT_DIR_WIETH_DBG)
+ env.copy_file(f"{HI1823_UMDK_CODE_DIR}/build/urma/tools/transport_service/tpsa_daemon", URMA_USR_OUTPUT_DIR)
+
+def build_umdk():
+ shutil.rmtree(f"{HI1823_UMDK_CODE_DIR}/build", ignore_errors=True)
+
+ tmp_ops = ""
+ if (env.hi1823_env_type == "1650"):
+ cmd = f"cp -rf {HI1823_UMDK_CODE_DIR}/huawei_secure_c/include/*.h {env.HI1823_TRUNK_DIR}/../{env.hi1823_os_path}/include/linux/"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ cmd = f"sed -i 's|#include <stdarg.h>|#include <linux/stdarg.h>|g' {env.HI1823_TRUNK_DIR}/../{env.hi1823_os_path}/include/linux/securec.h"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ cmd = f"cp -rf {env.HI1823_TRUNK_DIR}/../{env.hi1823_os_path}/include/linux/stdarg.h {env.HI1823_TRUNK_DIR}/../{env.hi1823_os_path}/include/"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ cmd = f"\cp -rf {env.HI1823_TRUNK_DIR}/src/dpu_platform_library/host/service/UMDK/src/urma/kmod/include/ub {env.HI1823_TRUNK_DIR}/../open_source/2403_SP2/include/"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ tmp_ops = f"-DKERNEL_PATH={KDIR} -DSECUREC_COMPILE=enable -DBUILD_DLOCK=disable -DBUILD_URPC=disable -DBUILD_UMS=disable -DBUILD_URMA=enable -DBUILD_ALL=disable -DBUILD_UDMA=disable"
+
+ if env.hi1823_ubus_driver_unified_compile == True:
+ if os.path.isdir(f'{KDIR}/include/ub/urma'):
+ shutil.rmtree(f'{KDIR}/include/ub/urma')
+
+ tmp_ops = f"-DKERNEL_PATH={KDIR} -DSECUREC_COMPILE=enable -DBUILD_DLOCK=disable -DBUILD_URPC=disable -DBUILD_UMS=disable -DBUILD_URMA=enable -DBUILD_ALL=disable -DBUILD_UDMA=disable"
+
+ if "eulerosv2r9" in str(env.hi1823_complie_os_kver) or env.hi1823_env_type == "1650" or (env.hi1823_ubus_driver_unified_compile == True):
+ cmd = f"cmake {HI1823_UMDK_CODE_DIR}/src -B {HI1823_UMDK_CODE_DIR}/build -DURMA_OVER_IB=disable {tmp_ops}"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ logging.info(f"cmd:[{cmd}], output:[{output}]")
+
+ cmd = f"make -j16 -C {HI1823_UMDK_CODE_DIR}/build"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ logging.info(f"cmd:[{cmd}], output = [{output}]")
+ else:
+ logging.info("Copy urma spec file to rpmbuild dir...")
+ env.copy_file(HI1823_UMDK_SPEC_FILE_PATHNAME, f"{env.HI1823_RPM_BUILD_DIR}/SPECS")
+
+ logging.info("Tar urma files...")
+ cmd = f"cd {HI1823_UMDK_CODE_DIR};tar -czf {env.HI1823_RPM_BUILD_DIR}/SOURCES/{HI1823_UMDK_TAR_FILE_VERSION}.tar.gz ./*"
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout.decode()}]. stderr:[{rslt.stderr.decode()}]")
+ return 1
+ logging.info("Excute rpmbuild rdma rpm package...")
+ cmd = f"rpmbuild --noclean --define \"_topdir {env.HI1823_RPM_BUILD_DIR}\" -ba {env.HI1823_RPM_BUILD_DIR}/SPECS/{HI1823_UMDK_SPEC_FILE_NAME} {HI1823_UMDK_RPM_OPTION}"
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout.decode()}]. stderr:[{rslt.stderr.decode()}]")
+ return 1
+ logging.info(f"output = [{rslt.stdout.decode()}]")
+
+ cmd = f'cd {env.HI1823_RPM_BUILD_DIR}/BUILD/{HI1823_UMDK_TAR_FILE_VERSION}/src/urma/kmod; sh build.sh'
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout.decode()}]. stderr:[{rslt.stderr.decode()}]")
+ return 1
+ logging.info(f"output = [{rslt.stdout.decode()}]")
+
+ # copy rpmbuild files to HI1823_UMDK_CODE_DIR/build
+ cmd = f"mkdir -pv -m 777 {HI1823_UMDK_CODE_DIR}/build; cp -rf {env.HI1823_RPM_BUILD_DIR}/BUILD/{HI1823_UMDK_TAR_FILE_VERSION}/* {HI1823_UMDK_CODE_DIR}/build/"
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ logging.info(f"exec cmd :[{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout.decode()}]. stderr:[{rslt.stderr.decode()}]")
+
+ # copy rpms to output dir
+ env.copy_file_with_start_and_end(f"{env.HI1823_RPM_BUILD_DIR}/RPMS/{env.hi1823_os_arch}", RPM_OUTPUT_DIR, "umdk", ".rpm")
+ env.copy_file_with_start_and_end(f"{env.HI1823_RPM_BUILD_DIR}/SRPMS", RPM_OUTPUT_DIR, "umdk", ".rpm")
+
+ copy_umdk()
+ # build clean
+ cmd = f"find {HI1823_UMDK_CODE_DIR}/build -name '*.o' -o -name '*.cmd' -o -name '*.mod'|xargs rm -f"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ return 0
+
+def build_udma_kernel():
+ cmd = f"make -C {env.hi1823_udma_knl_code_dir} clean"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ if env.hi1823_ubus_driver_unified_compile == True:
+ cmd = f"sed -i 's|#include <stddef.h>|#include <linux/stddef.h>|g' {BUILD_KERNEL_DIR}/../base/udma_base_sq.c"
+ status, output = subprocess.getstatusoutput(cmd)
+
+ if env.hi1823_env_type == "1650":
+ cmd = f"cp -rf {env.HI1823_TRUNK_DIR}/../{env.hi1823_os_path}/include/linux/stddef.h {env.HI1823_TRUNK_DIR}/../{env.hi1823_os_path}/include/"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ cmd = f"make -C {env.hi1823_udma_knl_code_dir} UMDK_DIR={HI1823_UMDK_CODE_DIR} VERSION={UDMA_DRIVER_TYPE} -j16"
+ if env.hi1823_env_type == "1650":
+ cmd = f"make -j64 -C {KDIR} M={BUILD_KERNEL_DIR} src={env.hi1823_udma_knl_code_dir} UMDK_DIR={HI1823_UMDK_CODE_DIR} VERSION={UDMA_DRIVER_TYPE} UBUS_UBC_BUILD_DIR={UBUS_UBC_BUILD_DIR} HI1823_TRUNK_DIR={env.HI1823_TRUNK_DIR} HI1823_BUILD_DIR={env.HI1823_TRUNK_DIR}/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"
+ else:
+ cmd = f"make -C {env.hi1823_udma_knl_code_dir} UMDK_DIR={HI1823_UMDK_CODE_DIR} VERSION={UDMA_DRIVER_TYPE} -j16"
+
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout}] err:{rslt.stderr.decode()}")
+ return 1
+ logging.info(f"output = [{rslt.stdout.decode()}]")
+ os.chmod(f"{BUILD_KERNEL_DIR}/hiudma5.ko", 0o644)
+ env.copy_file(f"{BUILD_KERNEL_DIR}/hiudma5.ko", KRN_OUTPUT_DIR_WIETH_DGB)
+ env.copy_file(f"{BUILD_KERNEL_DIR}/hiudma5.ko", KRN_OUTPUT_DIR)
+ env.copy_file(f"{BUILD_KERNEL_DIR}/Module.symvers", env.hi1823_ci_lib_dir, "UBUDMA_Module.symvers")
+
+ cmd = f"strip -g {KRN_OUTPUT_DIR}/hiudma5.ko"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ # get build info
+ cmd = f"sh {env.HI1823_BUILD_LOG_PATH}/build_log.sh {BUILD_KERNEL_DIR}/build {KRN_OUTPUT_DIR} hiudma5.ko"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ ret = env.collect_build_info(KRN_OUTPUT_DIR, f"{env.hi1823_bin_dir}/driver/linux/udma")
+ if ret:
+ return ret
+
+ cmd = f"make -C {env.hi1823_udma_knl_code_dir} clean"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ # build clean
+ cmd = f"find {env.hi1823_udma_knl_code_dir} -name '*.o' -o -name '*.cmd' -o -name '*.mod'|xargs rm -f"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ return 0
+
+def build_huawei_securec():
+ os.chdir(f"{env.huawei_secure_code_dir}/src")
+
+ cmd = ["make", "clean"]
+ try:
+ subprocess.run(cmd, shell=False, check=True, capture_output=True)
+ except Exception as e:
+ logging.error(f"exec cmd fail:{e}. error = [{e.stderr}]")
+ return 1
+
+ output_dir = f"{env.hi1823_ci_lib_dir}/huawei_securec/{env.hi1823_os_release}"
+ os.makedirs(output_dir, exist_ok=True)
+
+ cmd = f"make -C {env.huawei_secure_code_dir}/src"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ logging.info(f"output = [{output}]")
+
+ cmd = f"make -C {env.huawei_secure_code_dir}/src lib"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ logging.info(f"output = [{output}]")
+
+ env.copy_file(f"{env.huawei_secure_code_dir}/lib/libsecurec.so", output_dir)
+
+ cmd = ["make", "clean"]
+ try:
+ subprocess.run(cmd, shell=False, check=True, capture_output=True)
+ except Exception as e:
+ logging.error(f"exec cmd fail:{e}. error = [{e.stderr}]")
+ return 1
+
+ return 0
+
+def build_udma_user():
+ ret = build_huawei_securec()
+ if ret:
+ return ret
+ shutil.rmtree(f"{env.hi1823_udma_usr_code_dir}/build", ignore_errors=True)
+
+ logging.info(env.hi1823_udma_usr_code_dir)
+ cmd = f"ls -l {env.hi1823_udma_usr_code_dir}"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ file_list = output
+ logging.info(file_list)
+
+ if env.hi1823_ubus_driver_unified_compile == True:
+ cmd = f"sed -i 's|#include <linux/stddef.h>|#include <stddef.h>|g' {BUILD_KERNEL_DIR}/../base/udma_base_sq.c"
+ status, output = subprocess.getstatusoutput(cmd)
+
+ cmd = f"cmake {env.hi1823_udma_usr_code_dir} -B {env.hi1823_udma_usr_code_dir}/build -DUMDK_CODE_DIR={HI1823_UMDK_CODE_DIR}"
+
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ cmd = f"make -C {env.hi1823_udma_usr_code_dir}/build -j16"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+ logging.info(f"output = [{output}]")
+
+ build_info_lines = [
+ 'Source 0', 'OpenSource 0', 'ThirdParty 0', 'Tool 0', 'RealTarget 1', 'liburma.so', 'CMTarget 1', 'liburma.so'
+ ]
+ with open(f'{USR_OUTPUT_DIR}/build_info_user.txt', 'w') as f:
+ for line in build_info_lines:
+ f.write(f'{line}\n')
+
+ ret = env.collect_build_info(USR_OUTPUT_DIR, f"{env.hi1823_bin_dir}/driver/linux/udma", "user")
+ if ret:
+ return ret
+
+ env.copy_file_with_start(f"{env.hi1823_udma_usr_code_dir}/build", USR_OUTPUT_DIR_WIETH_DGB, "liburma")
+ env.copy_file_with_start(f"{env.hi1823_udma_usr_code_dir}/build", USR_OUTPUT_DIR, "liburma")
+
+ cmd = f"strip -s {USR_OUTPUT_DIR}/liburma*"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ os.chmod(f"{USR_OUTPUT_DIR}/liburma_hiudma5.so", 0o550)
+ os.chmod(f"{USR_OUTPUT_DIR_WIETH_DGB}/liburma_hiudma5.so", 0o550)
+
+ cmd = f"make -C {env.hi1823_udma_usr_code_dir}/build clean"
+ status, output = subprocess.getstatusoutput(cmd)
+ if status:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{status}]. output:[{output}]")
+ return 1
+
+ return 0
+
+def build_udma_rpm():
+ logging.info("*********************Start build udma rpm *********************")
+ ret = build_rpm_prepare()
+ if ret:
+ return ret
+
+ shutil.rmtree(env.HI1823_RPM_BUILD_DIR, ignore_errors=True)
+ cmd = f"mkdir -pv -m 777 {env.HI1823_RPM_BUILD_DIR}/{{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}}"
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout.decode()}]. stderr:[{rslt.stderr.decode()}]")
+ return 1
+
+ env.copy_file(f"{KRN_OUTPUT_DIR}/hiudma5.ko", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES/")
+ env.copy_file(f"{USR_OUTPUT_DIR}/liburma_hiudma5.so", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES/")
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/ci/tool/hiudma5_udk_log/hiudma5", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES")
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/ci/tool/hiudma5_udk_log/hiudma5.conf", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES")
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/ci/tool/hiudma5_udk_log/hiudma5logdump.conf", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES")
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/src/GLOBAL_VERSION_NEW", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES")
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/build/host/linux/udma/udma_rpm_build/udma-modules.conf", f"{env.HI1823_RPM_BUILD_DIR}/SOURCES")
+ env.copy_file(f"{env.HI1823_TRUNK_DIR}/build/host/linux/udma/udma_rpm_build/udma.spec", f"{env.HI1823_RPM_BUILD_DIR}/SPECS")
+
+ cmd = f"rpmbuild --define \"_topdir {env.HI1823_RPM_BUILD_DIR}\" -bb {env.HI1823_RPM_BUILD_DIR}/SPECS/udma.spec --target={env.hi1823_os_arch}"
+ rslt = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if rslt.returncode:
+ logging.error(f"exec cmd fail. [{cmd}] status:[{rslt.returncode}]. output:[{rslt.stdout.decode()}]. stderr:[{rslt.stderr.decode()}]")
+ return 1
+
+ env.copy_file_with_start_and_end(f"{env.HI1823_RPM_BUILD_DIR}/RPMS/{env.hi1823_os_arch}", RPM_OUTPUT_DIR, "hiudma5", ".rpm")
+
+ os.system(f"chmod 644 {RPM_OUTPUT_DIR}/hiudma5*")
+
+ logging.info("*********************build udma rpm success*********************")
+
+ return 0
+
+def build_udma():
+ ret = build_prepare()
+ if ret:
+ return ret
+
+ if env.hi1823_env_type != "1650":
+ logging.info("*********************Start build sdk & nic*********************")
+ build_sdk.build_sdk()
+ build_nic.build_nic()
+
+ logging.info("*********************Start build umdk*********************")
+ # build UMDK(urma). Temporarily, the UMDK is ultimately delivered upstream as a binary
+ ret = build_umdk()
+ if ret:
+ return ret
+
+ logging.info("*********************Start build udma kernel*********************")
+ ret = build_udma_kernel()
+ if ret:
+ return ret
+
+ logging.info("*********************Start build udma user*********************")
+ ret = build_udma_user()
+
+ return ret
diff --git a/drivers/net/ethernet/huawei/hinic5/build/tools/build_log/build_log.sh b/drivers/net/ethernet/huawei/hinic5/build/tools/build_log/build_log.sh
new file mode 100755
index 000000000..617003fcd
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/build/tools/build_log/build_log.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+# Perform hot backups of Oracle databases.
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+set -e
+set +e
+CUR_DIR=$PWD
+SOURCE_DIR=$1
+TARGET_DIR=$2
+CMTARGET=$3
+INFO_SUFFIX=$4
+
+if [ ! -z "$INFO_SUFFIX" ]; then
+ BUILD_INFO_FILE="$TARGET_DIR/build_info_$INFO_SUFFIX.txt"
+else
+ BUILD_INFO_FILE=$TARGET_DIR/build_info.txt
+fi
+
+cd $SOURCE_DIR
+# Source
+if [ -e "build_src.txt" ]; then
+ sed -i "s/ /\n/g" build_src.txt
+ count=0
+ for line in $(cat build_src.txt)
+ do
+ let count++
+ done
+ if [ -e "$BUILD_INFO_FILE" ];then
+ echo "" >> $BUILD_INFO_FILE
+ echo "Source $count" >> $BUILD_INFO_FILE
+ else
+ echo "Source $count" > $BUILD_INFO_FILE
+ fi
+ cat build_src.txt >> $BUILD_INFO_FILE
+else
+ echo "Source 0" > $BUILD_INFO_FILE
+fi
+
+# OpenSource
+if [ -e "build_opensrc.txt" ]; then
+ sed -i "s/ /\n/g" build_opensrc.txt
+ count=0
+ for line in $(cat build_opensrc.txt)
+ do
+ let count++
+ done
+ echo "OpenSource $count" >> $BUILD_INFO_FILE
+ cat build_opensrc.txt >> $BUILD_INFO_FILE
+else
+ echo "OpenSource 0" >> $BUILD_INFO_FILE
+fi
+
+# ThirdParty
+if [ -e "build_third_party.txt" ]; then
+ sed -i "s/ /\n/g" build_third_party.txt
+ count=0
+ for line in $(cat build_third_party.txt)
+ do
+ let count++
+ done
+ echo "ThirdParty $count" >> $BUILD_INFO_FILE
+ cat build_third_party.txt >> $BUILD_INFO_FILE
+else
+ echo "ThirdParty 0" >> $BUILD_INFO_FILE
+fi
+
+# Tool
+if [ -e "build_tool.txt" ]; then
+ sed -i "s/ /\n/g" build_tool.txt
+ count=0
+ for line in $(cat build_tool.txt)
+ do
+ let count++
+ done
+ echo "Tool $count" >> $BUILD_INFO_FILE
+ cat build_tool.txt >> $BUILD_INFO_FILE
+else
+ echo "Tool 0" >> $BUILD_INFO_FILE
+fi
+
+# Target
+count=0
+target_suffix=".bin\|.ko\|.so\|hinicadm"
+for line in $(ls $TARGET_DIR | grep $target_suffix)
+do
+ let count++
+done
+echo "RealTarget $count" >> $BUILD_INFO_FILE
+ls $TARGET_DIR | grep $target_suffix >> $BUILD_INFO_FILE
+
+# CM Target
+count=1
+echo "CMTarget $count" >> $BUILD_INFO_FILE
+echo $CMTARGET >> $BUILD_INFO_FILE
+
+
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/cmake/huawei_secure_cConfig.cmake b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/cmake/huawei_secure_cConfig.cmake
new file mode 100644
index 000000000..f91007059
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/cmake/huawei_secure_cConfig.cmake
@@ -0,0 +1,96 @@
+# Generated by CMake
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
+ message(FATAL_ERROR "CMake >= 2.6.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6...3.17)
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_targetsDefined)
+set(_targetsNotDefined)
+set(_expectedTargets)
+foreach(_expectedTarget Hisec::huawei_secure_c)
+ list(APPEND _expectedTargets ${_expectedTarget})
+ if(NOT TARGET ${_expectedTarget})
+ list(APPEND _targetsNotDefined ${_expectedTarget})
+ endif()
+ if(TARGET ${_expectedTarget})
+ list(APPEND _targetsDefined ${_expectedTarget})
+ endif()
+endforeach()
+if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
+ unset(_targetsDefined)
+ unset(_targetsNotDefined)
+ unset(_expectedTargets)
+ set(CMAKE_IMPORT_FILE_VERSION)
+ cmake_policy(POP)
+ return()
+endif()
+if(NOT "${_targetsDefined}" STREQUAL "")
+ message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
+endif()
+unset(_targetsDefined)
+unset(_targetsNotDefined)
+unset(_expectedTargets)
+
+
+# Compute the installation prefix relative to this file.
+get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+if(_IMPORT_PREFIX STREQUAL "/")
+ set(_IMPORT_PREFIX "")
+endif()
+
+# Create imported target Hisec::huawei_secure_c
+add_library(Hisec::huawei_secure_c INTERFACE IMPORTED)
+
+set_target_properties(Hisec::huawei_secure_c PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
+)
+
+if(CMAKE_VERSION VERSION_LESS 3.0.0)
+ message(FATAL_ERROR "This file relies on consumers using CMake 3.0.0 or greater.")
+endif()
+
+# Load information for each installed configuration.
+get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+file(GLOB CONFIG_FILES "${_DIR}/huawei_secure_cConfig-*.cmake")
+foreach(f ${CONFIG_FILES})
+ include(${f})
+endforeach()
+
+# Cleanup temporary variables.
+set(_IMPORT_PREFIX)
+
+# Loop over all imported files and verify that they actually exist
+foreach(target ${_IMPORT_CHECK_TARGETS} )
+ foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
+ if(NOT EXISTS "${file}" )
+ message(FATAL_ERROR "The imported target \"${target}\" references the file
+ \"${file}\"
+but this file does not exist. Possible reasons include:
+* The file was deleted, renamed, or moved to another location.
+* An install or uninstall procedure did not complete successfully.
+* The installation package was faulty and contained
+ \"${CMAKE_CURRENT_LIST_FILE}\"
+but not all the files it references.
+")
+ endif()
+ endforeach()
+ unset(_IMPORT_CHECK_FILES_FOR_${target})
+endforeach()
+unset(_IMPORT_CHECK_TARGETS)
+
+# This file does not depend on other imported targets which have
+# been exported from the same project but in a separate export set.
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securec.h b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securec.h
new file mode 100644
index 000000000..a5d275c99
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securec.h
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: The user of this secure c library should include this header file in you source code.
+ * This header file declare all supported API prototype of the library,
+ * such as memcpy_s, strcpy_s, wcscpy_s,strcat_s, strncat_s, sprintf_s, scanf_s, and so on.
+ * Create: 2014-02-25
+ * Notes: Do not modify this file by yourself.
+ */
+
+#ifndef SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27
+#define SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27
+
+#include "securectype.h"
+#ifndef SECUREC_HAVE_STDARG_H
+#define SECUREC_HAVE_STDARG_H 1
+#endif
+
+#if SECUREC_HAVE_STDARG_H
+#include <linux/version.h>
+#ifdef _LINUX_STDARG_H
+#include <linux/stdarg.h>
+#else
+#include <stdarg.h>
+#endif
+
+#endif
+
+#ifndef SECUREC_HAVE_ERRNO_H
+#define SECUREC_HAVE_ERRNO_H 1
+#endif
+
+/* EINVAL ERANGE may defined in errno.h */
+#if SECUREC_HAVE_ERRNO_H
+#if SECUREC_IN_KERNEL
+#include <linux/errno.h>
+#else
+#include <errno.h>
+#endif
+#endif
+
+/* Define error code */
+#if defined(SECUREC_NEED_ERRNO_TYPE) || !defined(__STDC_WANT_LIB_EXT1__) || \
+ (defined(__STDC_WANT_LIB_EXT1__) && (!__STDC_WANT_LIB_EXT1__))
+#ifndef SECUREC_DEFINED_ERRNO_TYPE
+#define SECUREC_DEFINED_ERRNO_TYPE
+/* Just check whether macrodefinition exists. */
+#ifndef errno_t
+typedef int errno_t;
+#endif
+#endif
+#endif
+
+/* Success */
+#ifndef EOK
+#define EOK 0
+#endif
+
+#ifndef EINVAL
+/* The src buffer is not correct and destination buffer can not be reset */
+#define EINVAL 22
+#endif
+
+#ifndef EINVAL_AND_RESET
+/* Once the error is detected, the dest buffer must be reset! Value is 22 or 128 */
+#define EINVAL_AND_RESET 150
+#endif
+
+#ifndef ERANGE
+/* The destination buffer is not long enough and destination buffer can not be reset */
+#define ERANGE 34
+#endif
+
+#ifndef ERANGE_AND_RESET
+/* Once the error is detected, the dest buffer must be reset! Value is 34 or 128 */
+#define ERANGE_AND_RESET 162
+#endif
+
+#ifndef EOVERLAP_AND_RESET
+/* Once the buffer overlap is detected, the dest buffer must be reset! Value is 54 or 128 */
+#define EOVERLAP_AND_RESET 182
+#endif
+
+/* If you need export the function of this library in Win32 dll, use __declspec(dllexport) */
+#ifndef SECUREC_API
+#if defined(SECUREC_DLL_EXPORT)
+#if defined(_MSC_VER)
+#define SECUREC_API __declspec(dllexport)
+#else /* build for linux */
+#define SECUREC_API __attribute__((visibility("default")))
+#endif /* end of _MSC_VER and SECUREC_DLL_EXPORT */
+#elif defined(SECUREC_DLL_IMPORT)
+#if defined(_MSC_VER)
+#define SECUREC_API __declspec(dllimport)
+#else
+#define SECUREC_API
+#endif /* end of _MSC_VER and SECUREC_DLL_IMPORT */
+#else
+/*
+ * Standardized function declaration. If a security function is declared in the your code,
+ * it may cause a compilation alarm,Please delete the security function you declared.
+ * Adding extern under windows will cause the system to have inline functions to expand,
+ * so do not add the extern in default
+ */
+#if defined(_MSC_VER)
+#define SECUREC_API
+#else
+#define SECUREC_API extern
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Description: The GetHwSecureCVersion function get SecureC Version string and version number.
+ * Parameter: verNumber - to store version number (for example value is 0x500 | 0xa)
+ * Return: version string
+ */
+SECUREC_API const char *GetHwSecureCVersion(unsigned short *verNumber);
+
+#if SECUREC_ENABLE_MEMSET
+/*
+ * Description: The memset_s function copies the value of c (converted to an unsigned char) into each of
+ * the first count characters of the object pointed to by dest.
+ * Parameter: dest - destination address
+ * Parameter: destMax - The maximum length of destination buffer
+ * Parameter: c - the value to be copied
+ * Parameter: count - copies count bytes of value to dest
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t memset_s(void *dest, size_t destMax, int c, size_t count);
+#endif
+
+#ifndef SECUREC_ONLY_DECLARE_MEMSET
+#define SECUREC_ONLY_DECLARE_MEMSET 0
+#endif
+
+#if !SECUREC_ONLY_DECLARE_MEMSET
+
+#if SECUREC_ENABLE_MEMMOVE
+/*
+ * Description: The memmove_s function copies n characters from the object pointed to by src
+ * into the object pointed to by dest.
+ * Parameter: dest - destination address
+ * Parameter: destMax - The maximum length of destination buffer
+ * Parameter: src - source address
+ * Parameter: count - copies count bytes from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t memmove_s(void *dest, size_t destMax, const void *src,
+ size_t count);
+#endif
+
+#if SECUREC_ENABLE_MEMCPY
+/*
+ * Description: The memcpy_s function copies n characters from the object pointed to
+ * by src into the object pointed to by dest.
+ * Parameter: dest - destination address
+ * Parameter: destMax - The maximum length of destination buffer
+ * Parameter: src - source address
+ * Parameter: count - copies count bytes from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t memcpy_s(void *dest, size_t destMax, const void *src,
+ size_t count);
+#endif
+
+#if SECUREC_ENABLE_STRCPY
+/*
+ * Description: The strcpy_s function copies the string pointed to by strSrc (including
+ * the terminating null character) into the array pointed to by strDest
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)
+ * Parameter: strSrc - source address
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc);
+#endif
+
+#if SECUREC_ENABLE_STRNCPY
+/*
+ * Description: The strncpy_s function copies not more than n successive characters (not including
+ * the terminating null character) from the array pointed to by strSrc to the array pointed to by strDest.
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)
+ * Parameter: strSrc - source address
+ * Parameter: count - copies count characters from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc,
+ size_t count);
+#endif
+
+#if SECUREC_ENABLE_STRCAT
+/*
+ * Description: The strcat_s function appends a copy of the string pointed to by strSrc (including
+ * the terminating null character) to the end of the string pointed to by strDest.
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character)
+ * Parameter: strSrc - source address
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc);
+#endif
+
+#if SECUREC_ENABLE_STRNCAT
+/*
+ * Description: The strncat_s function appends not more than n successive characters (not including
+ * the terminating null character)
+ * from the array pointed to by strSrc to the end of the string pointed to by strDest.
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)
+ * Parameter: strSrc - source address
+ * Parameter: count - copies count characters from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc,
+ size_t count);
+#endif
+
+#if SECUREC_ENABLE_VSPRINTF
+/*
+ * Description: The vsprintf_s function is equivalent to the vsprintf function except for the parameter destMax
+ * and the explicit runtime-constraints violation
+ * Parameter: strDest - produce output according to a format,write to the character string strDest.
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character)
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of characters printed(not including the terminating null byte '\0'),
+ * If an error occurred Return: -1.
+ */
+SECUREC_API int vsprintf_s(char *strDest, size_t destMax, const char *format,
+ va_list argList) SECUREC_ATTRIBUTE(3, 0);
+#endif
+
+#if SECUREC_ENABLE_SPRINTF
+/*
+ * Description: The sprintf_s function is equivalent to the sprintf function except for the parameter destMax
+ * and the explicit runtime-constraints violation
+ * Parameter: strDest - produce output according to a format ,write to the character string strDest.
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0')
+ * Parameter: format - format string
+ * Return: the number of characters printed(not including the terminating null byte '\0'),
+ * If an error occurred Return: -1.
+*/
+SECUREC_API int sprintf_s(char *strDest, size_t destMax, const char *format,
+ ...) SECUREC_ATTRIBUTE(3, 4);
+#endif
+
+#if SECUREC_ENABLE_VSNPRINTF
+/*
+ * Description: The vsnprintf_s function is equivalent to the vsnprintf function except for
+ * the parameter destMax/count and the explicit runtime-constraints violation
+ * Parameter: strDest - produce output according to a format ,write to the character string strDest.
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0')
+ * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0')
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of characters printed(not including the terminating null byte '\0'),
+ * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs.
+ */
+SECUREC_API int vsnprintf_s(char *strDest, size_t destMax, size_t count,
+ const char *format, va_list argList)
+ SECUREC_ATTRIBUTE(4, 0);
+#endif
+
+#if SECUREC_ENABLE_SNPRINTF
+/*
+ * Description: The snprintf_s function is equivalent to the snprintf function except for
+ * the parameter destMax/count and the explicit runtime-constraints violation
+ * Parameter: strDest - produce output according to a format ,write to the character string strDest.
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0')
+ * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0')
+ * Parameter: format - format string
+ * Return: the number of characters printed(not including the terminating null byte '\0'),
+ * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs.
+ */
+SECUREC_API int snprintf_s(char *strDest, size_t destMax, size_t count,
+ const char *format, ...) SECUREC_ATTRIBUTE(4, 5);
+#endif
+
+#if SECUREC_SNPRINTF_TRUNCATED
+/*
+ * Description: The vsnprintf_truncated_s function is equivalent to the vsnprintf_s function except
+ * no count parameter and return value
+ * Parameter: strDest - produce output according to a format ,write to the character string strDest
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0')
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of characters printed(not including the terminating null byte '\0'),
+ * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs
+*/
+SECUREC_API int vsnprintf_truncated_s(char *strDest, size_t destMax,
+ const char *format, va_list argList)
+ SECUREC_ATTRIBUTE(3, 0);
+
+/*
+ * Description: The snprintf_truncated_s function is equivalent to the snprintf_s function except
+ * no count parameter and return value
+ * Parameter: strDest - produce output according to a format,write to the character string strDest.
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0')
+ * Parameter: format - format string
+ * Return: the number of characters printed(not including the terminating null byte '\0'),
+ * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs.
+ */
+SECUREC_API int snprintf_truncated_s(char *strDest, size_t destMax,
+ const char *format, ...)
+ SECUREC_ATTRIBUTE(3, 4);
+#endif
+
+#if SECUREC_ENABLE_SCANF
+/*
+ * Description: The scanf_s function is equivalent to fscanf_s with the argument stdin
+ * interposed before the arguments to scanf_s
+ * Parameter: format - format string
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int scanf_s(const char *format, ...);
+#endif
+
+#if SECUREC_ENABLE_VSCANF
+/*
+ * Description: The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int vscanf_s(const char *format, va_list argList);
+#endif
+
+#if SECUREC_ENABLE_SSCANF
+/*
+ * Description: The sscanf_s function is equivalent to fscanf_s, except that input is obtained from a
+ * string (specified by the argument buffer) rather than from a stream
+ * Parameter: buffer - read character from buffer
+ * Parameter: format - format string
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int sscanf_s(const char *buffer, const char *format, ...);
+#endif
+
+#if SECUREC_ENABLE_VSSCANF
+/*
+ * Description: The vsscanf_s function is equivalent to sscanf_s, with the variable argument list
+ * replaced by argList
+ * Parameter: buffer - read character from buffer
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int vsscanf_s(const char *buffer, const char *format,
+ va_list argList);
+#endif
+
+#if SECUREC_ENABLE_FSCANF
+/*
+ * Description: The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers
+ * apply to a pair of arguments (unless assignment suppression is indicated by a *)
+ * Parameter: stream - stdio file stream
+ * Parameter: format - format string
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int fscanf_s(FILE *stream, const char *format, ...);
+#endif
+
+#if SECUREC_ENABLE_VFSCANF
+/*
+ * Description: The vfscanf_s function is equivalent to fscanf_s, with the variable argument list
+ * replaced by argList
+ * Parameter: stream - stdio file stream
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int vfscanf_s(FILE *stream, const char *format, va_list argList);
+#endif
+
+#if SECUREC_ENABLE_STRTOK
+/*
+ * Description: The strtok_s function parses a string into a sequence of strToken,
+ * replace all characters in strToken string that match to strDelimit set with 0.
+ * On the first call to strtok_s the string to be parsed should be specified in strToken.
+ * In each subsequent call that should parse the same string, strToken should be NULL
+ * Parameter: strToken - the string to be delimited
+ * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string
+ * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function
+ * Return: On the first call returns the address of the first non \0 character, otherwise NULL is returned.
+ * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call,
+ * return NULL if the *context string length is equal 0, otherwise return *context.
+ */
+SECUREC_API char *strtok_s(char *strToken, const char *strDelimit,
+ char **context);
+#endif
+
+#if SECUREC_ENABLE_GETS && !SECUREC_IN_KERNEL
+/*
+ * Description: The gets_s function reads at most one less than the number of characters specified
+ * by destMax from the stream pointed to by stdin, into the array pointed to by buffer
+ * Parameter: buffer - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)
+ * Return: buffer if there was no runtime-constraint violation,If an error occurred Return: NULL.
+ */
+SECUREC_API char *gets_s(char *buffer, size_t destMax);
+#endif
+
+#if SECUREC_ENABLE_WCHAR_FUNC
+#if SECUREC_ENABLE_MEMCPY
+/*
+ * Description: The wmemcpy_s function copies n successive wide characters from the object pointed to
+ * by src into the object pointed to by dest.
+ * Parameter: dest - destination address
+ * Parameter: destMax - The maximum length of destination buffer
+ * Parameter: src - source address
+ * Parameter: count - copies count wide characters from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src,
+ size_t count);
+#endif
+
+#if SECUREC_ENABLE_MEMMOVE
+/*
+ * Description: The wmemmove_s function copies n successive wide characters from the object
+ * pointed to by src into the object pointed to by dest.
+ * Parameter: dest - destination address
+ * Parameter: destMax - The maximum length of destination buffer
+ * Parameter: src - source address
+ * Parameter: count - copies count wide characters from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t wmemmove_s(wchar_t *dest, size_t destMax,
+ const wchar_t *src, size_t count);
+#endif
+
+#if SECUREC_ENABLE_STRCPY
+/*
+ * Description: The wcscpy_s function copies the wide string pointed to by strSrc(including the terminating
+ * null wide character) into the array pointed to by strDest
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer
+ * Parameter: strSrc - source address
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t wcscpy_s(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc);
+#endif
+
+#if SECUREC_ENABLE_STRNCPY
+/*
+ * Description: The wcsncpy_s function copies not more than n successive wide characters (not including the
+ * terminating null wide character) from the array pointed to by strSrc to the array pointed to by strDest
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character)
+ * Parameter: strSrc - source address
+ * Parameter: count - copies count wide characters from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t wcsncpy_s(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc, size_t count);
+#endif
+
+#if SECUREC_ENABLE_STRCAT
+/*
+ * Description: The wcscat_s function appends a copy of the wide string pointed to by strSrc (including the
+ * terminating null wide character) to the end of the wide string pointed to by strDest
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character)
+ * Parameter: strSrc - source address
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t wcscat_s(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc);
+#endif
+
+#if SECUREC_ENABLE_STRNCAT
+/*
+ * Description: The wcsncat_s function appends not more than n successive wide characters (not including the
+ * terminating null wide character) from the array pointed to by strSrc to the end of the wide string pointed to
+ * by strDest.
+ * Parameter: strDest - destination address
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character)
+ * Parameter: strSrc - source address
+ * Parameter: count - copies count wide characters from the src
+ * Return: EOK if there was no runtime-constraint violation
+ */
+SECUREC_API errno_t wcsncat_s(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc, size_t count);
+#endif
+
+#if SECUREC_ENABLE_STRTOK
+/*
+ * Description: The wcstok_s function is the wide-character equivalent of the strtok_s function
+ * Parameter: strToken - the string to be delimited
+ * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string
+ * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function
+ * Return: a pointer to the first character of a token, or a null pointer if there is no token
+ * or there is a runtime-constraint violation.
+ */
+SECUREC_API wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit,
+ wchar_t **context);
+#endif
+
+#if SECUREC_ENABLE_VSPRINTF
+/*
+ * Description: The vswprintf_s function is the wide-character equivalent of the vsprintf_s function
+ * Parameter: strDest - produce output according to a format,write to the character string strDest
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null)
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of characters printed(not including the terminating null wide character),
+ * If an error occurred Return: -1.
+ */
+SECUREC_API int vswprintf_s(wchar_t *strDest, size_t destMax,
+ const wchar_t *format, va_list argList);
+#endif
+
+#if SECUREC_ENABLE_SPRINTF
+/*
+ * Description: The swprintf_s function is the wide-character equivalent of the sprintf_s function
+ * Parameter: strDest - produce output according to a format,write to the character string strDest
+ * Parameter: destMax - The maximum length of destination buffer(including the terminating null)
+ * Parameter: format - format string
+ * Return: the number of characters printed(not including the terminating null wide character),
+ * If an error occurred Return: -1.
+ */
+SECUREC_API int swprintf_s(wchar_t *strDest, size_t destMax,
+ const wchar_t *format, ...);
+#endif
+
+#if SECUREC_ENABLE_FSCANF
+/*
+ * Description: The fwscanf_s function is the wide-character equivalent of the fscanf_s function
+ * Parameter: stream - stdio file stream
+ * Parameter: format - format string
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int fwscanf_s(FILE *stream, const wchar_t *format, ...);
+#endif
+
+#if SECUREC_ENABLE_VFSCANF
+/*
+ * Description: The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function
+ * Parameter: stream - stdio file stream
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int vfwscanf_s(FILE *stream, const wchar_t *format,
+ va_list argList);
+#endif
+
+#if SECUREC_ENABLE_SCANF
+/*
+ * Description: The wscanf_s function is the wide-character equivalent of the scanf_s function
+ * Parameter: format - format string
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int wscanf_s(const wchar_t *format, ...);
+#endif
+
+#if SECUREC_ENABLE_VSCANF
+/*
+ * Description: The vwscanf_s function is the wide-character equivalent of the vscanf_s function
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int vwscanf_s(const wchar_t *format, va_list argList);
+#endif
+
+#if SECUREC_ENABLE_SSCANF
+/*
+ * Description: The swscanf_s function is the wide-character equivalent of the sscanf_s function
+ * Parameter: buffer - read character from buffer
+ * Parameter: format - format string
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...);
+#endif
+
+#if SECUREC_ENABLE_VSSCANF
+/*
+ * Description: The vswscanf_s function is the wide-character equivalent of the vsscanf_s function
+ * Parameter: buffer - read character from buffer
+ * Parameter: format - format string
+ * Parameter: argList - instead of a variable number of arguments
+ * Return: the number of input items assigned, If an error occurred Return: -1.
+ */
+SECUREC_API int vswscanf_s(const wchar_t *buffer, const wchar_t *format,
+ va_list argList);
+#endif
+#endif /* SECUREC_ENABLE_WCHAR_FUNC */
+#endif
+
+/* Those functions are used by macro,must declare hare, also for without function declaration warning */
+extern errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc,
+ size_t count);
+extern errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc);
+
+#if SECUREC_WITH_PERFORMANCE_ADDONS
+/* Those functions are used by macro */
+extern errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count);
+extern errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count);
+extern errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src,
+ size_t count);
+extern errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src,
+ size_t count);
+
+/* The strcpy_sp is a macro, not a function in performance optimization mode. */
+#define strcpy_sp(dest, destMax, src) \
+ ((__builtin_constant_p((destMax)) && __builtin_constant_p((src))) ? \
+ SECUREC_STRCPY_SM((dest), (destMax), (src)) : \
+ strcpy_s((dest), (destMax), (src)))
+
+/* The strncpy_sp is a macro, not a function in performance optimization mode. */
+#define strncpy_sp(dest, destMax, src, count) \
+ ((__builtin_constant_p((count)) && __builtin_constant_p((destMax)) && \
+ __builtin_constant_p((src))) ? \
+ SECUREC_STRNCPY_SM((dest), (destMax), (src), (count)) : \
+ strncpy_s((dest), (destMax), (src), (count)))
+
+/* The strcat_sp is a macro, not a function in performance optimization mode. */
+#define strcat_sp(dest, destMax, src) \
+ ((__builtin_constant_p((destMax)) && __builtin_constant_p((src))) ? \
+ SECUREC_STRCAT_SM((dest), (destMax), (src)) : \
+ strcat_s((dest), (destMax), (src)))
+
+/* The strncat_sp is a macro, not a function in performance optimization mode. */
+#define strncat_sp(dest, destMax, src, count) \
+ ((__builtin_constant_p((count)) && __builtin_constant_p((destMax)) && \
+ __builtin_constant_p((src))) ? \
+ SECUREC_STRNCAT_SM((dest), (destMax), (src), (count)) : \
+ strncat_s((dest), (destMax), (src), (count)))
+
+/* The memcpy_sp is a macro, not a function in performance optimization mode. */
+#define memcpy_sp(dest, destMax, src, count) \
+ (__builtin_constant_p((count)) ? \
+ (SECUREC_MEMCPY_SM((dest), (destMax), (src), (count))) : \
+ (__builtin_constant_p((destMax)) ? \
+ (((size_t)(destMax) > 0 && \
+ (((unsigned long long)(destMax) & \
+ (unsigned long long)(-2)) < \
+ SECUREC_MEM_MAX_LEN)) ? \
+ memcpy_sOptTc((dest), (destMax), (src), \
+ (count)) : \
+ ERANGE) : \
+ memcpy_sOptAsm((dest), (destMax), (src), (count))))
+
+/* The memset_sp is a macro, not a function in performance optimization mode. */
+#define memset_sp(dest, destMax, c, count) \
+ (__builtin_constant_p((count)) ? \
+ (SECUREC_MEMSET_SM((dest), (destMax), (c), (count))) : \
+ (__builtin_constant_p((destMax)) ? \
+ (((((unsigned long long)(destMax) & \
+ (unsigned long long)(-2)) < \
+ SECUREC_MEM_MAX_LEN)) ? \
+ memset_sOptTc((dest), (destMax), (c), \
+ (count)) : \
+ ERANGE) : \
+ memset_sOptAsm((dest), (destMax), (c), (count))))
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securectype.h b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securectype.h
new file mode 100644
index 000000000..bf13f1556
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/include/securectype.h
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Define internal used macro and data type. The marco of SECUREC_ON_64BITS
+ * will be determined in this header file, which is a switch for part
+ * of code. Some macro are used to suppress warning by MS compiler.
+ * Create: 2014-02-25
+ * Notes: User can change the value of SECUREC_STRING_MAX_LEN and SECUREC_MEM_MAX_LEN
+ * macro to meet their special need, but The maximum value should not exceed 2G.
+ */
+/*
+ * [Standardize-exceptions]: Performance-sensitive
+ * [reason]: Strict parameter verification has been done before use
+ */
+
+#ifndef SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7
+#define SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7
+
+#ifndef SECUREC_USING_STD_SECURE_LIB
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#if defined(__STDC_WANT_SECURE_LIB__) && (!__STDC_WANT_SECURE_LIB__)
+/* Security functions have been provided since vs2005, default use of system library functions */
+#define SECUREC_USING_STD_SECURE_LIB 0
+#else
+#define SECUREC_USING_STD_SECURE_LIB 1
+#endif
+#else
+#define SECUREC_USING_STD_SECURE_LIB 0
+#endif
+#endif
+
+/* Compatibility with older Secure C versions, shielding VC symbol redefinition warning */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!SECUREC_USING_STD_SECURE_LIB)
+#ifndef SECUREC_DISABLE_CRT_FUNC
+#define SECUREC_DISABLE_CRT_FUNC 1
+#endif
+#ifndef SECUREC_DISABLE_CRT_IMP
+#define SECUREC_DISABLE_CRT_IMP 1
+#endif
+#else /* MSC VER */
+#ifndef SECUREC_DISABLE_CRT_FUNC
+#define SECUREC_DISABLE_CRT_FUNC 0
+#endif
+#ifndef SECUREC_DISABLE_CRT_IMP
+#define SECUREC_DISABLE_CRT_IMP 0
+#endif
+#endif
+
+#if SECUREC_DISABLE_CRT_FUNC
+#ifdef __STDC_WANT_SECURE_LIB__
+#undef __STDC_WANT_SECURE_LIB__
+#endif
+#define __STDC_WANT_SECURE_LIB__ 0
+#endif
+
+#if SECUREC_DISABLE_CRT_IMP
+#ifdef _CRTIMP_ALTERNATIVE
+#undef _CRTIMP_ALTERNATIVE
+#endif
+#define _CRTIMP_ALTERNATIVE /* Comment Microsoft *_s function */
+#endif
+
+/* Compile in kernel under macro control */
+#ifndef SECUREC_IN_KERNEL
+#ifdef __KERNEL__
+#define SECUREC_IN_KERNEL 1
+#else
+#define SECUREC_IN_KERNEL 0
+#endif
+#endif
+
+/* make kernel symbols of functions available to loadable modules */
+#ifndef SECUREC_EXPORT_KERNEL_SYMBOL
+#if SECUREC_IN_KERNEL
+#define SECUREC_EXPORT_KERNEL_SYMBOL 1
+#else
+#define SECUREC_EXPORT_KERNEL_SYMBOL 0
+#endif
+#endif
+
+#if SECUREC_IN_KERNEL
+#ifndef SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_SCANF_FILE 0
+#endif
+#ifndef SECUREC_ENABLE_WCHAR_FUNC
+#define SECUREC_ENABLE_WCHAR_FUNC 0
+#endif
+#else /* SECUREC_IN_KERNEL */
+#ifndef SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_SCANF_FILE 1
+#endif
+#ifndef SECUREC_ENABLE_WCHAR_FUNC
+#define SECUREC_ENABLE_WCHAR_FUNC 1
+#endif
+#endif
+
+/* Default secure function declaration, default declarations for non-standard functions */
+#ifndef SECUREC_SNPRINTF_TRUNCATED
+#define SECUREC_SNPRINTF_TRUNCATED 1
+#endif
+
+#if SECUREC_USING_STD_SECURE_LIB
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+/* Declare secure functions that are not available in the VS compiler */
+#ifndef SECUREC_ENABLE_MEMSET
+#define SECUREC_ENABLE_MEMSET 1
+#endif
+/* VS 2005 have vsnprintf_s function */
+#ifndef SECUREC_ENABLE_VSNPRINTF
+#define SECUREC_ENABLE_VSNPRINTF 0
+#endif
+#ifndef SECUREC_ENABLE_SNPRINTF
+/* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security function */
+#define snprintf_s _snprintf_s
+#define SECUREC_ENABLE_SNPRINTF 0
+#endif
+/* Before VS 2010 do not have v functions */
+#if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS)
+#ifndef SECUREC_ENABLE_VFSCANF
+#define SECUREC_ENABLE_VFSCANF 1
+#endif
+#ifndef SECUREC_ENABLE_VSCANF
+#define SECUREC_ENABLE_VSCANF 1
+#endif
+#ifndef SECUREC_ENABLE_VSSCANF
+#define SECUREC_ENABLE_VSSCANF 1
+#endif
+#endif
+
+#else /* MSC VER */
+#ifndef SECUREC_ENABLE_MEMSET
+#define SECUREC_ENABLE_MEMSET 0
+#endif
+#ifndef SECUREC_ENABLE_SNPRINTF
+#define SECUREC_ENABLE_SNPRINTF 0
+#endif
+#ifndef SECUREC_ENABLE_VSNPRINTF
+#define SECUREC_ENABLE_VSNPRINTF 0
+#endif
+#endif
+
+#ifndef SECUREC_ENABLE_MEMMOVE
+#define SECUREC_ENABLE_MEMMOVE 0
+#endif
+#ifndef SECUREC_ENABLE_MEMCPY
+#define SECUREC_ENABLE_MEMCPY 0
+#endif
+#ifndef SECUREC_ENABLE_STRCPY
+#define SECUREC_ENABLE_STRCPY 0
+#endif
+#ifndef SECUREC_ENABLE_STRNCPY
+#define SECUREC_ENABLE_STRNCPY 0
+#endif
+#ifndef SECUREC_ENABLE_STRCAT
+#define SECUREC_ENABLE_STRCAT 0
+#endif
+#ifndef SECUREC_ENABLE_STRNCAT
+#define SECUREC_ENABLE_STRNCAT 0
+#endif
+#ifndef SECUREC_ENABLE_SPRINTF
+#define SECUREC_ENABLE_SPRINTF 0
+#endif
+#ifndef SECUREC_ENABLE_VSPRINTF
+#define SECUREC_ENABLE_VSPRINTF 0
+#endif
+#ifndef SECUREC_ENABLE_SSCANF
+#define SECUREC_ENABLE_SSCANF 0
+#endif
+#ifndef SECUREC_ENABLE_VSSCANF
+#define SECUREC_ENABLE_VSSCANF 0
+#endif
+#ifndef SECUREC_ENABLE_SCANF
+#define SECUREC_ENABLE_SCANF 0
+#endif
+#ifndef SECUREC_ENABLE_VSCANF
+#define SECUREC_ENABLE_VSCANF 0
+#endif
+
+#ifndef SECUREC_ENABLE_FSCANF
+#define SECUREC_ENABLE_FSCANF 0
+#endif
+#ifndef SECUREC_ENABLE_VFSCANF
+#define SECUREC_ENABLE_VFSCANF 0
+#endif
+#ifndef SECUREC_ENABLE_STRTOK
+#define SECUREC_ENABLE_STRTOK 0
+#endif
+#ifndef SECUREC_ENABLE_GETS
+#define SECUREC_ENABLE_GETS 0
+#endif
+
+#else /* SECUREC USE STD SECURE LIB */
+
+#ifndef SECUREC_ENABLE_MEMSET
+#define SECUREC_ENABLE_MEMSET 1
+#endif
+#ifndef SECUREC_ENABLE_MEMMOVE
+#define SECUREC_ENABLE_MEMMOVE 1
+#endif
+#ifndef SECUREC_ENABLE_MEMCPY
+#define SECUREC_ENABLE_MEMCPY 1
+#endif
+#ifndef SECUREC_ENABLE_STRCPY
+#define SECUREC_ENABLE_STRCPY 1
+#endif
+#ifndef SECUREC_ENABLE_STRNCPY
+#define SECUREC_ENABLE_STRNCPY 1
+#endif
+#ifndef SECUREC_ENABLE_STRCAT
+#define SECUREC_ENABLE_STRCAT 1
+#endif
+#ifndef SECUREC_ENABLE_STRNCAT
+#define SECUREC_ENABLE_STRNCAT 1
+#endif
+#ifndef SECUREC_ENABLE_SPRINTF
+#define SECUREC_ENABLE_SPRINTF 1
+#endif
+#ifndef SECUREC_ENABLE_VSPRINTF
+#define SECUREC_ENABLE_VSPRINTF 1
+#endif
+#ifndef SECUREC_ENABLE_SNPRINTF
+#define SECUREC_ENABLE_SNPRINTF 1
+#endif
+#ifndef SECUREC_ENABLE_VSNPRINTF
+#define SECUREC_ENABLE_VSNPRINTF 1
+#endif
+#ifndef SECUREC_ENABLE_SSCANF
+#define SECUREC_ENABLE_SSCANF 1
+#endif
+#ifndef SECUREC_ENABLE_VSSCANF
+#define SECUREC_ENABLE_VSSCANF 1
+#endif
+#ifndef SECUREC_ENABLE_SCANF
+#if SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_SCANF 1
+#else
+#define SECUREC_ENABLE_SCANF 0
+#endif
+#endif
+#ifndef SECUREC_ENABLE_VSCANF
+#if SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_VSCANF 1
+#else
+#define SECUREC_ENABLE_VSCANF 0
+#endif
+#endif
+
+#ifndef SECUREC_ENABLE_FSCANF
+#if SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_FSCANF 1
+#else
+#define SECUREC_ENABLE_FSCANF 0
+#endif
+#endif
+#ifndef SECUREC_ENABLE_VFSCANF
+#if SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_VFSCANF 1
+#else
+#define SECUREC_ENABLE_VFSCANF 0
+#endif
+#endif
+
+#ifndef SECUREC_ENABLE_STRTOK
+#define SECUREC_ENABLE_STRTOK 1
+#endif
+#ifndef SECUREC_ENABLE_GETS
+#define SECUREC_ENABLE_GETS 1
+#endif
+#endif /* SECUREC_USE_STD_SECURE_LIB */
+
+#if !SECUREC_ENABLE_SCANF_FILE
+#if SECUREC_ENABLE_FSCANF
+#undef SECUREC_ENABLE_FSCANF
+#define SECUREC_ENABLE_FSCANF 0
+#endif
+#if SECUREC_ENABLE_VFSCANF
+#undef SECUREC_ENABLE_VFSCANF
+#define SECUREC_ENABLE_VFSCANF 0
+#endif
+#if SECUREC_ENABLE_SCANF
+#undef SECUREC_ENABLE_SCANF
+#define SECUREC_ENABLE_SCANF 0
+#endif
+#if SECUREC_ENABLE_FSCANF
+#undef SECUREC_ENABLE_FSCANF
+#define SECUREC_ENABLE_FSCANF 0
+#endif
+
+#endif
+
+#if SECUREC_IN_KERNEL
+#include <linux/kernel.h>
+#include <linux/module.h>
+#else
+#ifndef SECUREC_HAVE_STDIO_H
+#define SECUREC_HAVE_STDIO_H 1
+#endif
+#ifndef SECUREC_HAVE_STRING_H
+#define SECUREC_HAVE_STRING_H 1
+#endif
+#ifndef SECUREC_HAVE_STDLIB_H
+#define SECUREC_HAVE_STDLIB_H 1
+#endif
+#if SECUREC_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if SECUREC_HAVE_STRING_H
+#include <string.h>
+#endif
+#if SECUREC_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#endif
+
+/*
+ * If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS macro, default is enable.
+ * The macro is automatically closed on the windows platform and linux kernel
+ */
+#ifndef SECUREC_WITH_PERFORMANCE_ADDONS
+#if SECUREC_IN_KERNEL
+#define SECUREC_WITH_PERFORMANCE_ADDONS 0
+#else
+#define SECUREC_WITH_PERFORMANCE_ADDONS 1
+#endif
+#endif
+
+/* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */
+#if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && \
+ !defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
+#ifndef SECUREC_COMPATIBLE_WIN_FORMAT
+#define SECUREC_COMPATIBLE_WIN_FORMAT
+#endif
+#endif
+
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+/* On windows platform, can't use optimized function for there is no __builtin_constant_p like function */
+/* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */
+#ifdef SECUREC_WITH_PERFORMANCE_ADDONS
+#undef SECUREC_WITH_PERFORMANCE_ADDONS
+#define SECUREC_WITH_PERFORMANCE_ADDONS 0
+#endif
+#endif
+
+#if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || \
+ defined(_VXWORKS_PLATFORM_) || defined(SECUREC_VXWORKS_VERSION_5_4)
+#ifndef SECUREC_VXWORKS_PLATFORM
+#define SECUREC_VXWORKS_PLATFORM
+#endif
+#endif
+
+/* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */
+#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && \
+ !defined(SECUREC_VXWORKS_PLATFORM)
+#ifndef SECUREC_COMPATIBLE_LINUX_FORMAT
+#define SECUREC_COMPATIBLE_LINUX_FORMAT
+#endif
+#endif
+
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+#ifndef SECUREC_HAVE_STDDEF_H
+#define SECUREC_HAVE_STDDEF_H 1
+#endif
+/* Some system may no stddef.h */
+#if SECUREC_HAVE_STDDEF_H
+#if !SECUREC_IN_KERNEL
+#include <stddef.h>
+#endif
+#endif
+#endif
+
+/*
+ * Add the -DSECUREC_SUPPORT_FORMAT_WARNING=1 compiler option to supoort -Wformat=2.
+ * Default does not check the format is that the same data type in the actual code.
+ * In the product is different in the original data type definition of VxWorks and Linux.
+ */
+#ifndef SECUREC_SUPPORT_FORMAT_WARNING
+#define SECUREC_SUPPORT_FORMAT_WARNING 0
+#endif
+
+#if SECUREC_SUPPORT_FORMAT_WARNING
+#define SECUREC_ATTRIBUTE(x, y) __attribute__((format(printf, (x), (y))))
+#else
+#define SECUREC_ATTRIBUTE(x, y)
+#endif
+
+/*
+ * Add the -DSECUREC_SUPPORT_BUILTIN_EXPECT=0 compiler option, if compiler can not support __builtin_expect.
+ */
+#ifndef SECUREC_SUPPORT_BUILTIN_EXPECT
+#define SECUREC_SUPPORT_BUILTIN_EXPECT 1
+#endif
+
+#if SECUREC_SUPPORT_BUILTIN_EXPECT && defined(__GNUC__) && \
+ ((__GNUC__ > 3) || \
+ (defined(__GNUC_MINOR__) && (__GNUC__ == 3 && __GNUC_MINOR__ > 3)))
+/*
+ * This is a built-in function that can be used without a declaration, if warning for declaration not found occurred,
+ * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to compiler options
+ */
+#ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE
+long __builtin_expect(long exp, long c);
+#endif
+
+#define SECUREC_LIKELY(x) __builtin_expect(!!(x), 1)
+#define SECUREC_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define SECUREC_LIKELY(x) (x)
+#define SECUREC_UNLIKELY(x) (x)
+#endif
+
+/* Define the max length of the string */
+#ifndef SECUREC_STRING_MAX_LEN
+#define SECUREC_STRING_MAX_LEN 0x7fffffffUL
+#endif
+#define SECUREC_WCHAR_STRING_MAX_LEN (SECUREC_STRING_MAX_LEN / sizeof(wchar_t))
+
+/* Add SECUREC_MEM_MAX_LEN for memcpy and memmove */
+#ifndef SECUREC_MEM_MAX_LEN
+#define SECUREC_MEM_MAX_LEN 0x7fffffffUL
+#endif
+#define SECUREC_WCHAR_MEM_MAX_LEN (SECUREC_MEM_MAX_LEN / sizeof(wchar_t))
+
+#if SECUREC_STRING_MAX_LEN > 0x7fffffffUL
+#error "max string is 2G"
+#endif
+
+#if (defined(__GNUC__) && defined(__SIZEOF_POINTER__))
+#if (__SIZEOF_POINTER__ != 4) && (__SIZEOF_POINTER__ != 8)
+#error "unsupported system"
+#endif
+#endif
+
+#if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64)
+#define SECUREC_ON_64BITS
+#endif
+
+#if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && \
+ defined(__SIZEOF_POINTER__))
+#if __SIZEOF_POINTER__ == 8
+#define SECUREC_ON_64BITS
+#endif
+#endif
+
+#if defined(__SVR4) || defined(__svr4__)
+#define SECUREC_ON_SOLARIS
+#endif
+
+#if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS))
+#define SECUREC_ON_UNIX
+#endif
+
+/*
+ * Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknown system on default,
+ * and strtold.
+ * The function strtold is referenced first at ISO9899:1999(C99), and some old compilers can
+ * not support these functions. Here provides a macro to open these functions:
+ * SECUREC_SUPPORT_STRTOLD -- If defined, strtold will be used
+ */
+#ifndef SECUREC_SUPPORT_STRTOLD
+#define SECUREC_SUPPORT_STRTOLD 0
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT))
+#if defined(__USE_ISOC99) || (defined(_AIX) && defined(_ISOC99_SOURCE)) || \
+ (defined(__hpux) && defined(__ia64)) || \
+ (defined(SECUREC_ON_SOLARIS) && \
+ (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
+ defined(_STDC_C99) || defined(__EXTENSIONS__))
+#undef SECUREC_SUPPORT_STRTOLD
+#define SECUREC_SUPPORT_STRTOLD 1
+#endif
+#endif
+#if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_)))
+#undef SECUREC_SUPPORT_STRTOLD
+#define SECUREC_SUPPORT_STRTOLD 0
+#endif
+#endif
+
+#if SECUREC_WITH_PERFORMANCE_ADDONS
+
+#ifndef SECUREC_TWO_MIN
+#define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* For strncpy_s performance optimization */
+#define SECUREC_STRNCPY_SM(dest, destMax, src, count) \
+ (((void *)(dest) != NULL && (const void *)(src) != NULL && \
+ (size_t)(destMax) > 0 && \
+ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < \
+ SECUREC_STRING_MAX_LEN) && \
+ (SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= \
+ (size_t)(destMax)) ? \
+ (((size_t)(count) < strlen(src)) ? \
+ (memcpy((dest), (src), (count)), \
+ *((char *)(dest) + (count)) = '\0', EOK) : \
+ (memcpy((dest), (src), strlen(src) + 1), EOK)) : \
+ (strncpy_error((dest), (destMax), (src), (count))))
+
+#define SECUREC_STRCPY_SM(dest, destMax, src) \
+ (((void *)(dest) != NULL && (const void *)(src) != NULL && \
+ (size_t)(destMax) > 0 && \
+ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < \
+ SECUREC_STRING_MAX_LEN) && \
+ (strlen(src) + 1) <= (size_t)(destMax)) ? \
+ (memcpy((dest), (src), strlen(src) + 1), EOK) : \
+ (strcpy_error((dest), (destMax), (src))))
+
+/* For strcat_s performance optimization */
+#if defined(__GNUC__)
+#define SECUREC_STRCAT_SM(dest, destMax, src) \
+ ({ \
+ int catRet_ = EOK; \
+ if ((void *)(dest) != NULL && (const void *)(src) != NULL && \
+ (size_t)(destMax) > 0 && \
+ (((unsigned long long)(destMax) & \
+ (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \
+ char *catTmpDst_ = (char *)(dest); \
+ size_t catRestSize_ = (destMax); \
+ while (catRestSize_ > 0 && *catTmpDst_ != '\0') { \
+ ++catTmpDst_; \
+ --catRestSize_; \
+ } \
+ if (catRestSize_ == 0) { \
+ catRet_ = EINVAL; \
+ } else if ((strlen(src) + 1) <= catRestSize_) { \
+ memcpy(catTmpDst_, (src), strlen(src) + 1); \
+ catRet_ = EOK; \
+ } else { \
+ catRet_ = ERANGE; \
+ } \
+ if (catRet_ != EOK) { \
+ catRet_ = strcat_s((dest), (destMax), (src)); \
+ } \
+ } else { \
+ catRet_ = strcat_s((dest), (destMax), (src)); \
+ } \
+ catRet_; \
+ })
+#else
+#define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src))
+#endif
+
+/* For strncat_s performance optimization */
+#if defined(__GNUC__)
+#define SECUREC_STRNCAT_SM(dest, destMax, src, count) \
+ ({ \
+ int ncatRet_ = EOK; \
+ if ((void *)(dest) != NULL && (const void *)(src) != NULL && \
+ (size_t)(destMax) > 0 && \
+ (((unsigned long long)(destMax) & \
+ (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \
+ (((unsigned long long)(count) & \
+ (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \
+ char *ncatTmpDest_ = (char *)(dest); \
+ size_t ncatRestSize_ = (size_t)(destMax); \
+ while (ncatRestSize_ > 0 && *ncatTmpDest_ != '\0') { \
+ ++ncatTmpDest_; \
+ --ncatRestSize_; \
+ } \
+ if (ncatRestSize_ == 0) { \
+ ncatRet_ = EINVAL; \
+ } else if ((SECUREC_TWO_MIN((count), strlen(src)) + \
+ 1) <= ncatRestSize_) { \
+ if ((size_t)(count) < strlen(src)) { \
+ memcpy(ncatTmpDest_, (src), (count)); \
+ *(ncatTmpDest_ + (count)) = '\0'; \
+ } else { \
+ memcpy(ncatTmpDest_, (src), \
+ strlen(src) + 1); \
+ } \
+ } else { \
+ ncatRet_ = ERANGE; \
+ } \
+ if (ncatRet_ != EOK) { \
+ ncatRet_ = strncat_s((dest), (destMax), (src), \
+ (count)); \
+ } \
+ } else { \
+ ncatRet_ = \
+ strncat_s((dest), (destMax), (src), (count)); \
+ } \
+ ncatRet_; \
+ })
+#else
+#define SECUREC_STRNCAT_SM(dest, destMax, src, count) \
+ strncat_s((dest), (destMax), (src), (count))
+#endif
+
+/* This macro do not check buffer overlap by default */
+#define SECUREC_MEMCPY_SM(dest, destMax, src, count) \
+ (!(((size_t)(destMax) == 0) || \
+ (((unsigned long long)(destMax) & (unsigned long long)(-2)) > \
+ SECUREC_MEM_MAX_LEN) || \
+ ((size_t)(count) > (size_t)(destMax)) || \
+ ((void *)(dest)) == NULL || ((const void *)(src) == NULL)) ? \
+ (memcpy((dest), (src), (count)), EOK) : \
+ (memcpy_s((dest), (destMax), (src), (count))))
+
+#define SECUREC_MEMSET_SM(dest, destMax, c, count) \
+ (!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > \
+ SECUREC_MEM_MAX_LEN) || \
+ ((void *)(dest) == NULL) || \
+ ((size_t)(count) > (size_t)(destMax))) ? \
+ (memset((dest), (c), (count)), EOK) : \
+ (memset_s((dest), (destMax), (c), (count))))
+
+#endif
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/patch/adapt_implicit_fallthrough_level5.patch b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/patch/adapt_implicit_fallthrough_level5.patch
new file mode 100644
index 000000000..cbd74bd8d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/patch/adapt_implicit_fallthrough_level5.patch
@@ -0,0 +1,20 @@
+diff --git a/platform/huawei_secure_c/src/securecutil.h b/platform/huawei_secure_c/src/securecutil.h
+index 459647ec2ab..b624e6e575a 100644
+--- a/platform/huawei_secure_c/src/securecutil.h
++++ b/platform/huawei_secure_c/src/securecutil.h
+@@ -553,15 +553,11 @@ typedef struct {
+ #define SECUREC_ERROR_BUFFER_OVERLAP(msg)
+ #endif
+
+-#if defined(__clang__)
+ #ifndef fallthrough
+ #define FALLTHROUGH __attribute__((fallthrough))
+ #else
+ #define FALLTHROUGH fallthrough
+ #endif
+-#else
+-#define FALLTHROUGH
+-#endif /* __clang__ */
+
+ #ifdef __cplusplus
+ extern "C" {
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/Makefile b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/Makefile
new file mode 100644
index 000000000..6513bc423
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/Makefile
@@ -0,0 +1,196 @@
+######
+### This is a sample file for linux platform, please write the Makefile according to the actual situation of the product
+### If you want to create a shared library, use the command:"make"
+### If you want to create a static library, use the command:"make lib"
+### If you want to create a .ko file, use the command:"make kernel"
+### If you want to filter out unsupported compiler options, add the command:"CHECK_OPTION=check"
+######
+
+PROJECT=libsecurec.so
+#if you need a debug version library, use "-g" instead of "-s -DNDEBUG -O2".
+# If you compiler report a warning on "break strict-aliasing rules", there is no problem. If you need to clear all warnings, you can add "-fno-strict-aliasing" option to your compiler, but this will impact the performance a little.
+CC?=gcc
+
+#for linux secure compile options from stdandard 2018.8
+SECURE_CFLAG_FOR_SHARED_LIBRARY = -fPIC
+SECURE_LDFLAG_FOR_SHARED_LIBRARY += -s
+SECURE_LDFLAG_FOR_SHARED_LIBRARY += -Wl,-z,relro,-z,now,-z,noexecstack
+#This option ensure forced links to functions in the library. If these functions are already contained in other libraries, cross-calls will occur
+#SECURE_LDFLAG_FOR_SHARED_LIBRARY += -Wl,-Bsymbolic
+
+
+GCC_HAVE_STRONG=$(shell $(CC) -fstack-protector-strong -E -dM - < /dev/null 2>&1 |grep -- "fstack-protector-strong" >/dev/null ;if [ $$? -ne 0 ] ;then echo yes;fi)
+ifeq ($(GCC_HAVE_STRONG),yes)
+SECURE_CFLAG_FOR_SHARED_LIBRARY += -fstack-protector-strong
+else
+SECURE_CFLAG_FOR_SHARED_LIBRARY += -fstack-protector-all
+endif
+
+
+#-fvisibility=hidden need modify source code
+#SECURE_CFLAG_FOR_SHARED_LIBRARY_OPTIONAL += -fvisibility=hidden
+
+#-ftrapv -D_FORTIFY_SOURCE=2 -fstack-check May result in performance degradation after opening
+SECURE_CFLAG_FOR_SHARED_LIBRARY_OPTIONAL += -D_FORTIFY_SOURCE=2 -O2
+#SECURE_CFLAG_FOR_SHARED_LIBRARY_OPTIONAL += -ftrapv
+#SECURE_CFLAG_FOR_SHARED_LIBRARY_OPTIONAL += -fstack-check
+
+
+SECURE_CFLAG_FOR_SHARED_LIBRARY_OPTIONAL += -Wformat=2 -Wfloat-equal -Wshadow
+# about pie option , We compiled a dynamic library, so we did not use it. ,If you want to compile executable files, please open this option
+#SECURE_CFLAG_FOR_EXE = -fPIE -pie
+
+
+
+## code standard options
+SECUREC_CODE_STANDARD_OPTION = -Wconversion
+SECUREC_CODE_STANDARD_OPTION += -Wformat-security
+SECUREC_CODE_STANDARD_OPTION += -Wextra
+SECUREC_CODE_STANDARD_OPTION += --param ssp-buffer-size=4
+
+#repeat options
+#SECUREC_CODE_STANDARD_OPTION += -D_FORTIFY_SOURCE=2
+#SECUREC_CODE_STANDARD_OPTION += -Wl,-z,relro,-z,now
+#SECUREC_CODE_STANDARD_OPTION += -fstack-protector
+
+#from product options
+PRODUCT_OPTION_FOR_SELECTION = -Warray-bounds
+PRODUCT_OPTION_FOR_SELECTION += -Wpointer-arith
+PRODUCT_OPTION_FOR_SELECTION += -Wcast-qual
+PRODUCT_OPTION_FOR_SELECTION += -Wstrict-prototypes
+PRODUCT_OPTION_FOR_SELECTION += -Wmissing-prototypes
+PRODUCT_OPTION_FOR_SELECTION += -Wstrict-overflow=1
+PRODUCT_OPTION_FOR_SELECTION += -Wstrict-aliasing=2
+PRODUCT_OPTION_FOR_SELECTION += -Wswitch -Wswitch-default
+PRODUCT_OPTION_FOR_SELECTION += -Wdate-time
+PRODUCT_OPTION_FOR_SELECTION += -Wdisabled-optimization
+PRODUCT_OPTION_FOR_SELECTION += -Wduplicated-branches
+PRODUCT_OPTION_FOR_SELECTION += -Wduplicated-cond
+PRODUCT_OPTION_FOR_SELECTION += -Wignored-qualifiers
+PRODUCT_OPTION_FOR_SELECTION += -Wimplicit-fallthrough=3
+PRODUCT_OPTION_FOR_SELECTION += -Wmissing-include-dirs
+PRODUCT_OPTION_FOR_SELECTION += -Wshift-negative-value
+PRODUCT_OPTION_FOR_SELECTION += -Wsign-compare
+PRODUCT_OPTION_FOR_SELECTION += -Wtrampolines
+PRODUCT_OPTION_FOR_SELECTION += -Wtype-limits
+PRODUCT_OPTION_FOR_SELECTION += -Wwrite-strings
+PRODUCT_OPTION_FOR_SELECTION += -Werror
+PRODUCT_OPTION_FOR_SELECTION += -Wunused-macros
+PRODUCT_OPTION_FOR_SELECTION += -Wshift-overflow=2
+PRODUCT_OPTION_FOR_SELECTION += -Wnested-externs
+PRODUCT_OPTION_FOR_SELECTION += -Wlogical-op
+PRODUCT_OPTION_FOR_SELECTION += -Wjump-misses-init
+PRODUCT_OPTION_FOR_SELECTION += -Wvla
+PRODUCT_OPTION_FOR_SELECTION += -Wframe-larger-than=4096
+PRODUCT_OPTION_FOR_SELECTION += -Wsuggest-attribute=format
+PRODUCT_OPTION_FOR_SELECTION += -Wmissing-format-attribute
+PRODUCT_OPTION_FOR_SELECTION += # -fno-inline-small-functions -fno-indirect-inlining -fno-inline-functions-called-once -fno-early-inlining -fno-inline
+PRODUCT_OPTION_FOR_SELECTION += # -ftrapv
+
+ifeq ($(CHECK_OPTION),check)
+PRODUCT_OPTION := $(shell touch tmp.c; echo "int main(void){return 0;}" > tmp.c; \
+ for loop in $(PRODUCT_OPTION_FOR_SELECTION); \
+ do err=$$({ `$(CC) $$loop -I../include -c tmp.c >/dev/null`; } 2>&1);\
+ echo $${err} | grep ^clang:.w.*ted\]$$ > /dev/null 2>&1;\
+ if [ $$? = 0 ] || [ "X$${err}" = "X" ];then echo "$$loop";fi;\
+ done;\
+ if [ -f tmp.o ];then rm tmp.o;fi;\
+ if [ -f tmp.c ];then rm tmp.c;fi;)
+else
+PRODUCT_OPTION := $(PRODUCT_OPTION_FOR_SELECTION)
+endif
+
+CFLAG = -Wall -DNDEBUG -O2 $(SECURE_CFLAG_FOR_SHARED_LIBRARY) $(SECURE_CFLAG_FOR_EXE) $(SECURE_CFLAG_FOR_SHARED_LIBRARY_OPTIONAL) $(SECUREC_CODE_STANDARD_OPTION) $(PRODUCT_OPTION)
+#CFLAG += -DSECUREC_VXWORKS_PLATFORM
+#CFLAG += -DSECUREC_SUPPORT_STRTOLD
+#CFLAG += -DSECUREC_VXWORKS_VERSION_5_4
+#CFLAG += -D__STDC_WANT_LIB_EXT1__=0
+CFLAG += $(CFLAG_EXT)
+
+ARCH:=$(shell getconf LONG_BIT)
+
+ifeq ($(MAKECMDGOALS),lib)
+#Set static library related options
+CFLAG :=$(filter-out "xxxxx",$(CFLAG))
+endif
+
+#SOURCES=$(wildcard *.c)
+SOURCES = fscanf_s.c gets_s.c memcpy_s.c memmove_s.c memset_s.c scanf_s.c securecutil.c secureinput_a.c secureprintoutput_a.c snprintf_s.c sprintf_s.c sscanf_s.c strcat_s.c strcpy_s.c strncat_s.c strncpy_s.c strtok_s.c vfscanf_s.c vscanf_s.c vsnprintf_s.c vsprintf_s.c vsscanf_s.c
+
+SOURCES += fwscanf_s.c secureinput_w.c secureprintoutput_w.c swprintf_s.c swscanf_s.c vfwscanf_s.c vswprintf_s.c vswscanf_s.c vwscanf_s.c wcscat_s.c wcscpy_s.c wcsncat_s.c wcsncpy_s.c wcstok_s.c wmemcpy_s.c wmemmove_s.c wscanf_s.c
+
+OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
+
+.PHONY:clean lib kernel
+
+ENABLE_SCANF_FILE=$(findstring SECUREC_ENABLE_SCANF_FILE=0,$(CFLAG))
+ifeq ($(ENABLE_SCANF_FILE),SECUREC_ENABLE_SCANF_FILE=0)
+OBJECTS:=$(filter-out fscanf_s.o vfscanf_s.o vscanf_s.o scanf_s.o vwscanf_s.o wscanf_s.o fwscanf_s.o vfwscanf_s.o,$(OBJECTS))
+endif
+
+
+ifneq ($(CFLAGS),)
+CFLAG :=$(CFLAGS)
+endif
+CFLAG += -I../include
+LD_FLAG ?= $(SECURE_LDFLAG_FOR_SHARED_LIBRARY) $(SECURE_CFLAG_FOR_SHARED_LIBRARY)
+AR ?=ar
+RANLIB ?=ranlib
+
+$(PROJECT): note_msg $(OBJECTS)
+ @mkdir -p ../obj
+ mkdir -p ../lib
+ $(CC) -shared -o ../lib/$@ $(patsubst %.o,../obj/%.o,$(OBJECTS)) $(LD_FLAG)
+ @echo "finish $(PROJECT)"
+ #you may add you custom commands here
+
+lib: note_msg $(OBJECTS)
+ $(AR) crv libsecurec.a $(patsubst %.o,../obj/%.o,$(OBJECTS))
+ $(RANLIB) libsecurec.a
+ -mkdir -p ../lib
+ -cp libsecurec.a ../lib
+ @echo "finish libsecurec.a"
+ #you may add you custom commands here
+.c.o:
+ @mkdir -p ../obj
+ $(CC) -c $< $(CFLAG) -o ../obj/$(patsubst %.c,%.o,$<)
+
+EXTRA_CFLAGS += -I$(INCDIR) -fstack-protector $(CFLAG_EXT)
+
+# provide the default value to module name and ccflags-y
+ifeq ($(MODULE),)
+ MODULE := ksecurec
+endif
+ifeq ($(DEBUG),y)
+ ccflags-y += -DDEBUG
+endif
+
+ifneq ($(KERNELRELEASE),)
+ obj-m := ksecurec.o
+ifeq ($(SECUREC_KERNEL_ALL),)
+ #ksecurec-objs := memcpy_s.o memmove_s.o memset_s.o securecutil.o strcat_s.o strcpy_s.o strncat_s.o strncpy_s.o
+ ksecurec-objs := memcpy_s.o memmove_s.o memset_s.o securecutil.o strcat_s.o strcpy_s.o strncat_s.o strncpy_s.o sprintf_s.o vsprintf_s.o snprintf_s.o vsnprintf_s.o secureprintoutput_a.o sscanf_s.o vsscanf_s.o secureinput_a.o strtok_s.o
+else
+ ksecurec-objs := memcpy_s.o memmove_s.o memset_s.o securecutil.o strcat_s.o strcpy_s.o strncat_s.o strncpy_s.o sprintf_s.o vsprintf_s.o snprintf_s.o vsnprintf_s.o secureprintoutput_a.o sscanf_s.o vsscanf_s.o secureinput_a.o strtok_s.o
+endif
+else
+ KERNELDIR := /lib/modules/$(shell uname -r)/build
+ PWD := $(shell pwd)
+kernel: note_msg
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) INCDIR=$(PWD)/../include modules
+endif
+
+NOTE_MSG:='\n'
+NOTE_MSG+='---------------------------------------------------------\n'
+NOTE_MSG+='+ This Makefile is a sample file, do not use in product +\n'
+NOTE_MSG+='---------------------------------------------------------\n'
+
+note_msg:
+ -@echo -e $(NOTE_MSG)
+
+clean:
+ @echo "cleaning ...."
+ -rm modules.order Module.symvers $(MODULE).ko $(MODULE).mod.c $(MODULE).mod.o $(MODULE).o *.o
+ -rm -rf ../obj ../lib
+ @echo "clean up"
+
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fscanf_s.c
new file mode 100644
index 000000000..05e1e724c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fscanf_s.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: fscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The fscanf_s function is equivalent to fscanf except that the c, s,
+ * and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a*)
+ * The fscanf function reads data from the current position of stream into
+ * the locations given by argument (if any). Each argument must be a pointer
+ * to a variable of a type that corresponds to a type specifier in format.
+ * format controls the interpretation of the input fields and has the same
+ * form and function as the format argument for scanf.
+ *
+ * <INPUT PARAMETERS>
+ * stream Pointer to FILE structure.
+ * format Format control string, see Format Specifications.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * ... The converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned. A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int fscanf_s(FILE *stream, const char *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vfscanf_s(stream, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fwscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fwscanf_s.c
new file mode 100644
index 000000000..aa2b9e5ac
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/fwscanf_s.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: fwscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The fwscanf_s function is the wide-character equivalent of the fscanf_s function
+ * The fwscanf_s function reads data from the current position of stream into
+ * the locations given by argument (if any). Each argument must be a pointer
+ * to a variable of a type that corresponds to a type specifier in format.
+ * format controls the interpretation of the input fields and has the same
+ * form and function as the format argument for scanf.
+ *
+ * <INPUT PARAMETERS>
+ * stream Pointer to FILE structure.
+ * format Format control string, see Format Specifications.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * ... The converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned. A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int fwscanf_s(FILE *stream, const wchar_t *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vfwscanf_s(stream, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/gets_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/gets_s.c
new file mode 100644
index 000000000..c83eb76eb
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/gets_s.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: gets_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+/*
+ * The parameter size is buffer size in byte
+ */
+SECUREC_INLINE void SecTrimCRLF(char *buffer, size_t size)
+{
+ size_t len = strlen(buffer);
+ --len; /* Unsigned integer wrapping is accepted and is checked afterwards */
+ while (len < size && (buffer[len] == '\r' || buffer[len] == '\n')) {
+ buffer[len] = '\0';
+ --len; /* Unsigned integer wrapping is accepted and is checked next loop */
+ }
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The gets_s function reads at most one less than the number of characters
+ * specified by destMax from the std input stream, into the array pointed to by buffer
+ * The line consists of all characters up to and including
+ * the first newline character ('\n'). gets_s then replaces the newline
+ * character with a null character ('\0') before returning the line.
+ * If the first character read is the end-of-file character, a null character
+ * is stored at the beginning of buffer and NULL is returned.
+ *
+ * <INPUT PARAMETERS>
+ * buffer Storage location for input string.
+ * destMax The size of the buffer.
+ *
+ * <OUTPUT PARAMETERS>
+ * buffer is updated
+ *
+ * <RETURN VALUE>
+ * buffer Successful operation
+ * NULL Improper parameter or read fail
+ */
+char *gets_s(char *buffer, size_t destMax)
+{
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+ size_t bufferSize =
+ ((destMax == (size_t)(-1)) ? SECUREC_STRING_MAX_LEN : destMax);
+#else
+ size_t bufferSize = destMax;
+#endif
+
+ if (buffer == NULL || bufferSize == 0 ||
+ bufferSize > SECUREC_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_PARAMTER("gets_s");
+ return NULL;
+ }
+
+ if (fgets(buffer, (int)bufferSize, SECUREC_STREAM_STDIN) != NULL) {
+ SecTrimCRLF(buffer, bufferSize);
+ return buffer;
+ }
+
+ return NULL;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/input.inl b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/input.inl
new file mode 100644
index 000000000..2e47e088e
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/input.inl
@@ -0,0 +1,2482 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Used by secureinput_a.c and secureinput_w.c to include.
+ * This file provides a template function for ANSI and UNICODE compiling by
+ * different type definition. The functions of SecInputS or
+ * SecInputSW provides internal implementation for scanf family API, such as sscanf_s, fscanf_s.
+ * Create: 2014-02-25
+ * Notes: The formatted input processing results of integers on different platforms are different.
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Performance-sensitive
+ * [reason] Always used in the performance critical path,
+ * and sufficient input validation is performed before calling
+ */
+#ifndef INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27
+#define INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27
+
+#if SECUREC_IN_KERNEL
+#if !defined(SECUREC_CTYPE_MACRO_ADAPT)
+#include <linux/ctype.h>
+#endif
+#else
+#if !defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT)
+#include <ctype.h>
+#ifdef SECUREC_FOR_WCHAR
+#include <wctype.h> /* For iswspace */
+#endif
+#endif
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+#define SECUREC_NUM_WIDTH_SHORT 0
+#define SECUREC_NUM_WIDTH_INT 1
+#define SECUREC_NUM_WIDTH_LONG 2
+#define SECUREC_NUM_WIDTH_LONG_LONG 3 /* Also long double */
+
+#define SECUREC_BUFFERED_BLOK_SIZE 1024U
+
+#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(va_copy) && \
+ !defined(__va_copy)
+/* The name is the same as system macro. */
+#define __va_copy(dest, src) \
+ do { \
+ size_t destSize_ = (size_t)sizeof(dest); \
+ size_t srcSize_ = (size_t)sizeof(src); \
+ if (destSize_ != srcSize_) { \
+ SECUREC_MEMCPY_WARP_OPT((dest), (src), \
+ sizeof(va_list)); \
+ } else { \
+ SECUREC_MEMCPY_WARP_OPT(&(dest), &(src), \
+ sizeof(va_list)); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+#endif
+
+#define SECUREC_MULTI_BYTE_MAX_LEN 6
+
+/* Compatibility macro name cannot be modifie */
+#ifndef UNALIGNED
+#if !(defined(_M_IA64)) && !(defined(_M_AMD64))
+#define UNALIGNED
+#else
+#define UNALIGNED __unaligned
+#endif
+#endif
+
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+/* Max 64bit value is 0xffffffffffffffff */
+#define SECUREC_MAX_64BITS_VALUE 18446744073709551615ULL
+#define SECUREC_MAX_64BITS_VALUE_DIV_TEN 1844674407370955161ULL
+#define SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT 18446744073709551610ULL
+#define SECUREC_MIN_64BITS_NEG_VALUE 9223372036854775808ULL
+#define SECUREC_MAX_64BITS_POS_VALUE 9223372036854775807ULL
+#define SECUREC_MIN_32BITS_NEG_VALUE 2147483648UL
+#define SECUREC_MAX_32BITS_POS_VALUE 2147483647UL
+#define SECUREC_MAX_32BITS_VALUE 4294967295UL
+#define SECUREC_MAX_32BITS_VALUE_INC 4294967296UL
+#define SECUREC_MAX_32BITS_VALUE_DIV_TEN 429496729UL
+#define SECUREC_LONG_BIT_NUM ((unsigned int)(sizeof(long) << 3U))
+/* Use ULL to clean up cl6x compilation alerts */
+#define SECUREC_MAX_LONG_POS_VALUE \
+ ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)) - 1)
+#define SECUREC_MIN_LONG_NEG_VALUE \
+ ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)))
+
+/* Covert to long long to clean up cl6x compilation alerts */
+#define SECUREC_LONG_HEX_BEYOND_MAX(number) \
+ (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 4U)) > 0)
+#define SECUREC_LONG_OCTAL_BEYOND_MAX(number) \
+ (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 3U)) > 0)
+
+#define SECUREC_QWORD_HEX_BEYOND_MAX(number) (((number) >> (64U - 4U)) > 0)
+#define SECUREC_QWORD_OCTAL_BEYOND_MAX(number) (((number) >> (64U - 3U)) > 0)
+
+#define SECUREC_LP64_BIT_WIDTH 64
+#define SECUREC_LP32_BIT_WIDTH 32
+
+#define SECUREC_CONVERT_IS_SIGNED(conv) ((conv) == 'd' || (conv) == 'i')
+#endif
+
+#define SECUREC_BRACE '{' /* [ to { */
+#define SECUREC_FILED_WIDTH_ENOUGH(spec) \
+ ((spec)->widthSet == 0 || (spec)->width > 0)
+#define SECUREC_FILED_WIDTH_DEC(spec) \
+ do { \
+ if ((spec)->widthSet != 0) { \
+ --(spec)->width; \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+#ifdef SECUREC_FOR_WCHAR
+/* Bits for all wchar, size is 65536/8, only supports wide characters with a maximum length of two bytes */
+#define SECUREC_BRACKET_TABLE_SIZE 8192
+#define SECUREC_EOF WEOF
+#define SECUREC_MB_LEN 16 /* Max. # bytes in multibyte char ,see MB_LEN_MAX */
+#else
+/* Bits for all char, size is 256/8 */
+#define SECUREC_BRACKET_TABLE_SIZE 32
+#define SECUREC_EOF EOF
+#endif
+
+#if SECUREC_HAVE_WCHART
+#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) \
+ ((spec).arrayWidth == 0 || \
+ ((spec).isWCharOrLong <= 0 && \
+ (spec).arrayWidth > SECUREC_STRING_MAX_LEN) || \
+ ((spec).isWCharOrLong > 0 && \
+ (spec).arrayWidth > SECUREC_WCHAR_STRING_MAX_LEN))
+#else
+#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) \
+ ((spec).arrayWidth == 0 || (spec).arrayWidth > SECUREC_STRING_MAX_LEN)
+#endif
+
+#ifdef SECUREC_ON_64BITS
+/* Use 0xffffffffUL mask to pass integer as array length */
+#define SECUREC_GET_ARRAYWIDTH(argList) \
+ (((size_t)va_arg((argList), size_t)) & 0xffffffffUL)
+#else /* !SECUREC_ON_64BITS */
+#define SECUREC_GET_ARRAYWIDTH(argList) ((size_t)va_arg((argList), size_t))
+#endif
+
+typedef struct {
+#ifdef SECUREC_FOR_WCHAR
+ unsigned char *table; /* Default NULL */
+#else
+ unsigned char table
+ [SECUREC_BRACKET_TABLE_SIZE]; /* Array length is large enough in application scenarios */
+#endif
+ unsigned char mask; /* Default 0 */
+} SecBracketTable;
+
+#ifdef SECUREC_FOR_WCHAR
+#define SECUREC_INIT_BRACKET_TABLE \
+ { \
+ NULL, 0 \
+ }
+#else
+#define SECUREC_INIT_BRACKET_TABLE \
+ { \
+ { 0 }, 0 \
+ }
+#endif
+
+#if SECUREC_ENABLE_SCANF_FLOAT
+typedef struct {
+ size_t floatStrTotalLen; /* Initialization must be length of buffer in charater */
+ size_t floatStrUsedLen; /* Store float string len */
+ SecChar *floatStr; /* Initialization must point to buffer */
+ SecChar *allocatedFloatStr; /* Initialization must be NULL to store alloced point */
+ SecChar buffer[SECUREC_FLOAT_BUFSIZE + 1];
+} SecFloatSpec;
+#endif
+
+#define SECUREC_NUMBER_STATE_DEFAULT 0U
+#define SECUREC_NUMBER_STATE_STARTED 1U
+
+typedef struct {
+ SecInt ch; /* Char read from input */
+ int charCount; /* Number of characters processed */
+ void *argPtr; /* Variable parameter pointer, point to the end of the string */
+ size_t arrayWidth; /* Length of pointer Variable parameter, in charaters */
+ SecUnsignedInt64 number64; /* Store input number64 value */
+ unsigned long number; /* Store input number32 value */
+ int numberWidth; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */
+ int numberArgType; /* 1 for 64-bit integer, 0 otherwise. use it as decode function index */
+ unsigned int negative; /* 0 is positive */
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ unsigned int beyondMax; /* Non-zero means beyond */
+#endif
+ unsigned int
+ numberState; /* Identifies whether to start processing numbers, 1 is can input number */
+ int width; /* Width number in format */
+ int widthSet; /* 0 is not set width in format */
+ int convChr; /* Lowercase format conversion characters */
+ int oriConvChr; /* Store original format conversion, convChr may change when parsing integers */
+ signed char
+ isWCharOrLong; /* -1/0 not wchar or long, 1 for wchar or long */
+ unsigned char suppress; /* 0 is not have %* in format */
+} SecScanSpec;
+
+#ifdef SECUREC_FOR_WCHAR
+#define SECUREC_GETC fgetwc
+#define SECUREC_UN_GETC ungetwc
+/* Only supports wide characters with a maximum length of two bytes in format string */
+#define SECUREC_BRACKET_CHAR_MASK 0xffffU
+#else
+#define SECUREC_GETC fgetc
+#define SECUREC_UN_GETC ungetc
+#define SECUREC_BRACKET_CHAR_MASK 0xffU
+#endif
+
+#define SECUREC_CHAR_SIZE ((unsigned int)(sizeof(SecChar)))
+/* To avoid 648, mask high bit: 0x00ffffff 0x0000ffff or 0x00000000 */
+#define SECUREC_CHAR_MASK_HIGH \
+ (((((((((unsigned int)(-1) >> SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE) >> \
+ SECUREC_CHAR_SIZE)
+
+/* For char is 0xff, wcahr_t is 0xffff or 0xffffffff. */
+#define SECUREC_CHAR_MASK \
+ (~((((((((((unsigned int)(-1) & SECUREC_CHAR_MASK_HIGH) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE) \
+ << SECUREC_CHAR_SIZE))
+
+/* According wchar_t has multiple bytes, so use sizeof */
+#define SECUREC_GET_CHAR(stream, outCh) \
+ do { \
+ if ((stream)->count >= sizeof(SecChar)) { \
+ *(outCh) = \
+ (SecInt)(SECUREC_CHAR_MASK & \
+ (unsigned int)(int)(*( \
+ (const SecChar \
+ *)(const void \
+ *)(stream) \
+ ->cur))); \
+ (stream)->cur += sizeof(SecChar); \
+ (stream)->count -= sizeof(SecChar); \
+ } else { \
+ *(outCh) = SECUREC_EOF; \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+#define SECUREC_UN_GET_CHAR(stream) \
+ do { \
+ if ((stream)->cur > (stream)->base) { \
+ (stream)->cur -= sizeof(SecChar); \
+ (stream)->count += sizeof(SecChar); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+/* Convert wchar_t to int and then to unsigned int to keep data clearing warning */
+#define SECUREC_TO_LOWERCASE(chr) \
+ ((int)((unsigned int)(int)(chr) | (unsigned int)('a' - 'A')))
+
+/* Record a flag for each bit */
+#define SECUREC_BRACKET_INDEX(x) ((unsigned int)(x) >> 3U)
+#define SECUREC_BRACKET_VALUE(x) ((unsigned char)(1U << ((unsigned int)(x)&7U)))
+#if SECUREC_IN_KERNEL
+#define SECUREC_CONVERT_IS_UNSIGNED(conv) \
+ ((conv) == 'x' || (conv) == 'o' || (conv) == 'u')
+#endif
+
+/*
+ * Set char in %[xxx] into table, only supports wide characters with a maximum length of two bytes
+ */
+SECUREC_INLINE void SecBracketSetBit(unsigned char *table, SecUnsignedChar ch)
+{
+ unsigned int tableIndex = SECUREC_BRACKET_INDEX(
+ ((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
+ unsigned int tableValue = SECUREC_BRACKET_VALUE(
+ ((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
+ /* Do not use |= optimize this code, it will cause compiling warning */
+ table[tableIndex] = (unsigned char)(table[tableIndex] | tableValue);
+}
+
+SECUREC_INLINE void SecBracketSetBitRange(unsigned char *table,
+ SecUnsignedChar startCh,
+ SecUnsignedChar endCh)
+{
+ SecUnsignedChar expCh;
+ /* %[a-z] %[a-a] Format %[a-\xff] end is 0xFF, condition (expCh <= endChar) cause dead loop */
+ for (expCh = startCh; expCh < endCh; ++expCh) {
+ SecBracketSetBit(table, expCh);
+ }
+ SecBracketSetBit(table, endCh);
+}
+/*
+ * Determine whether the expression can be satisfied
+ */
+SECUREC_INLINE int SecCanInputForBracket(int convChr, SecInt ch,
+ const SecBracketTable *bracketTable)
+{
+ unsigned int tableIndex = SECUREC_BRACKET_INDEX(
+ ((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
+ unsigned int tableValue = SECUREC_BRACKET_VALUE(
+ ((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
+#ifdef SECUREC_FOR_WCHAR
+ if (((unsigned int)(int)ch & (~(SECUREC_BRACKET_CHAR_MASK))) != 0) {
+ /* The value of the wide character exceeds the size of two bytes */
+ return 0;
+ }
+ return (int)(convChr == SECUREC_BRACE &&
+ (((unsigned int)bracketTable->table[tableIndex] ^
+ (unsigned int)bracketTable->mask) &
+ tableValue) != 0);
+#else
+ return (int)(convChr == SECUREC_BRACE &&
+ (((unsigned int)bracketTable->table[tableIndex] ^
+ (unsigned int)bracketTable->mask) &
+ tableValue) != 0);
+#endif
+}
+
+/*
+ * String input ends when blank character is encountered
+ */
+SECUREC_INLINE int SecCanInputString(int convChr, SecInt ch)
+{
+ return (int)(convChr == 's' &&
+ (!(ch >= SECUREC_CHAR('\t') && ch <= SECUREC_CHAR('\r')) &&
+ ch != SECUREC_CHAR(' ')));
+}
+
+/*
+ * Can input a character when format is %c
+ */
+SECUREC_INLINE int SecCanInputCharacter(int convChr)
+{
+ return (int)(convChr == 'c');
+}
+
+/*
+ * Determine if it is a 64-bit pointer function
+ * Return 0 is not ,1 is 64bit pointer
+ */
+SECUREC_INLINE int SecNumberArgType(size_t sizeOfVoidStar)
+{
+ /* Point size is 4 or 8 , Under the 64 bit system, the value not 0 */
+ /* To clear e778 */
+ if ((sizeOfVoidStar & sizeof(SecInt64)) != 0) {
+ return 1;
+ }
+ return 0;
+}
+SECUREC_INLINE int SecIsDigit(SecInt ch);
+SECUREC_INLINE int SecIsXdigit(SecInt ch);
+SECUREC_INLINE int SecIsSpace(SecInt ch);
+SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter);
+SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter);
+SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream,
+ int *counter);
+
+#if SECUREC_ENABLE_SCANF_FLOAT
+
+/*
+ * Convert a floating point string to a floating point number
+ */
+SECUREC_INLINE int SecAssignNarrowFloat(const char *floatStr,
+ const SecScanSpec *spec)
+{
+ char *endPtr = NULL;
+ double d;
+#if SECUREC_SUPPORT_STRTOLD
+ if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG_LONG) {
+ long double d2 = strtold(floatStr, &endPtr);
+ if (endPtr == floatStr) {
+ return -1;
+ }
+ *(long double UNALIGNED *)(spec->argPtr) = d2;
+ return 0;
+ }
+#endif
+ d = strtod(floatStr, &endPtr);
+ /* cannot detect if endPtr points to the end of floatStr,because strtod handles only two characters for 1.E */
+ if (endPtr == floatStr) {
+ return -1;
+ }
+ if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) {
+ *(double UNALIGNED *)(spec->argPtr) = (double)d;
+ } else {
+ *(float UNALIGNED *)(spec->argPtr) = (float)d;
+ }
+ return 0;
+}
+
+#ifdef SECUREC_FOR_WCHAR
+/*
+ * Convert a floating point wchar string to a floating point number
+ * Success ret 0
+ */
+SECUREC_INLINE int SecAssignWideFloat(const SecFloatSpec *floatSpec,
+ const SecScanSpec *spec)
+{
+ int retVal;
+ /* Convert float string */
+ size_t mbsLen;
+ size_t tempFloatStrLen =
+ (size_t)(floatSpec->floatStrUsedLen + 1) * sizeof(wchar_t);
+ char *tempFloatStr = (char *)SECUREC_MALLOC(tempFloatStrLen);
+ if (tempFloatStr == NULL) {
+ return -1;
+ }
+ tempFloatStr[0] = '\0';
+ SECUREC_MASK_MSVC_CRT_WARNING
+ mbsLen = wcstombs(tempFloatStr, floatSpec->floatStr,
+ tempFloatStrLen - 1);
+ SECUREC_END_MASK_MSVC_CRT_WARNING
+ /* This condition must satisfy mbsLen is not -1 */
+ if (mbsLen >= tempFloatStrLen) {
+ SECUREC_FREE(tempFloatStr);
+ return -1;
+ }
+ tempFloatStr[mbsLen] = '\0';
+ retVal = SecAssignNarrowFloat(tempFloatStr, spec);
+ SECUREC_FREE(tempFloatStr);
+ return retVal;
+}
+#endif
+
+SECUREC_INLINE int SecAssignFloat(const SecFloatSpec *floatSpec,
+ const SecScanSpec *spec)
+{
+#ifdef SECUREC_FOR_WCHAR
+ return SecAssignWideFloat(floatSpec, spec);
+#else
+ return SecAssignNarrowFloat(floatSpec->floatStr, spec);
+#endif
+}
+
+/*
+ * Init SecFloatSpec before parse format
+ */
+SECUREC_INLINE void SecInitFloatSpec(SecFloatSpec *floatSpec)
+{
+ floatSpec->floatStr = floatSpec->buffer;
+ floatSpec->allocatedFloatStr = NULL;
+ floatSpec->floatStrTotalLen =
+ sizeof(floatSpec->buffer) / sizeof(floatSpec->buffer[0]);
+ floatSpec->floatStrUsedLen = 0;
+}
+
+SECUREC_INLINE void SecFreeFloatSpec(SecFloatSpec *floatSpec, int *doneCount)
+{
+ /* 2014.3.6 add, clear the stack data */
+ if (memset_s(floatSpec->buffer, sizeof(floatSpec->buffer), 0,
+ sizeof(floatSpec->buffer)) != EOK) {
+ *doneCount =
+ 0; /* This code just to meet the coding requirements */
+ }
+ /* The pFloatStr can be alloced in SecExtendFloatLen function, clear and free it */
+ if (floatSpec->allocatedFloatStr != NULL) {
+ size_t bufferSize =
+ floatSpec->floatStrTotalLen * sizeof(SecChar);
+ if (memset_s(floatSpec->allocatedFloatStr, bufferSize, 0,
+ bufferSize) != EOK) {
+ *doneCount =
+ 0; /* This code just to meet the coding requirements */
+ }
+ SECUREC_FREE(floatSpec->allocatedFloatStr);
+ floatSpec->allocatedFloatStr = NULL;
+ floatSpec->floatStr = NULL;
+ }
+}
+
+/*
+ * Splice floating point string
+ * Return 0 OK
+ */
+SECUREC_INLINE int SecExtendFloatLen(SecFloatSpec *floatSpec)
+{
+ if (floatSpec->floatStrUsedLen >= floatSpec->floatStrTotalLen) {
+ /* Buffer size is len x sizeof(SecChar) */
+ size_t oriSize = floatSpec->floatStrTotalLen * sizeof(SecChar);
+ /* Add one character to clear tool warning */
+ size_t nextSize =
+ (oriSize * 2) +
+ sizeof(SecChar); /* Multiply 2 to extend buffer size */
+
+ /* Prevents integer overflow, the maximum length of SECUREC_MAX_WIDTH_LEN is enough */
+ if (nextSize <= (size_t)SECUREC_MAX_WIDTH_LEN) {
+ void *nextBuffer = (void *)SECUREC_MALLOC(nextSize);
+ if (nextBuffer == NULL) {
+ return -1;
+ }
+ if (memcpy_s(nextBuffer, nextSize, floatSpec->floatStr,
+ oriSize) != EOK) {
+ SECUREC_FREE(
+ nextBuffer); /* This is a dead code, just to meet the coding requirements */
+ return -1;
+ }
+ /* Clear old buffer memory */
+ if (memset_s(floatSpec->floatStr, oriSize, 0,
+ oriSize) != EOK) {
+ SECUREC_FREE(
+ nextBuffer); /* This is a dead code, just to meet the coding requirements */
+ return -1;
+ }
+ /* Free old allocated buffer */
+ if (floatSpec->allocatedFloatStr != NULL) {
+ SECUREC_FREE(floatSpec->allocatedFloatStr);
+ }
+ floatSpec->allocatedFloatStr =
+ (SecChar *)(nextBuffer); /* Use to clear free on stack warning */
+ floatSpec->floatStr = (SecChar *)(nextBuffer);
+ floatSpec->floatStrTotalLen =
+ nextSize /
+ sizeof(SecChar); /* Get buffer total len in character */
+ return 0;
+ }
+ return -1; /* Next size is beyond max */
+ }
+ return 0;
+}
+
+/* Do not use localeconv()->decimal_pointif onlay support '.' */
+SECUREC_INLINE int SecIsFloatDecimal(SecChar ch)
+{
+ return (int)(ch == SECUREC_CHAR('.'));
+}
+
+SECUREC_INLINE int SecInputFloatSign(SecFileStream *stream, SecScanSpec *spec,
+ SecFloatSpec *floatSpec)
+{
+ if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ return 0;
+ }
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) {
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Make sure the count after un get char is correct */
+ if (spec->ch == SECUREC_CHAR('-')) {
+ floatSpec->floatStr[floatSpec->floatStrUsedLen] =
+ SECUREC_CHAR('-');
+ ++floatSpec->floatStrUsedLen;
+ if (SecExtendFloatLen(floatSpec) != 0) {
+ return -1;
+ }
+ }
+ } else {
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ }
+ return 0;
+}
+
+SECUREC_INLINE int SecInputFloatDigit(SecFileStream *stream, SecScanSpec *spec,
+ SecFloatSpec *floatSpec)
+{
+ /* Now get integral part */
+ while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ if (SecIsDigit(spec->ch) == 0) {
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ return 0;
+ }
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Must be behind un get char, otherwise the logic is incorrect */
+ spec->numberState = SECUREC_NUMBER_STATE_STARTED;
+ floatSpec->floatStr[floatSpec->floatStrUsedLen] =
+ (SecChar)spec->ch;
+ ++floatSpec->floatStrUsedLen;
+ if (SecExtendFloatLen(floatSpec) != 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+* Scan value of exponent.
+* Return 0 OK
+*/
+SECUREC_INLINE int SecInputFloatE(SecFileStream *stream, SecScanSpec *spec,
+ SecFloatSpec *floatSpec)
+{
+ if (SecInputFloatSign(stream, spec, floatSpec) == -1) {
+ return -1;
+ }
+ if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+SECUREC_INLINE int SecInputFloatFractional(SecFileStream *stream,
+ SecScanSpec *spec,
+ SecFloatSpec *floatSpec)
+{
+ if (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ if (SecIsFloatDecimal((SecChar)spec->ch) == 0) {
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ return 0;
+ }
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Must be behind un get char, otherwise the logic is incorrect */
+ /* Now check for decimal */
+ floatSpec->floatStr[floatSpec->floatStrUsedLen] =
+ (SecChar)spec->ch;
+ ++floatSpec->floatStrUsedLen;
+ if (SecExtendFloatLen(floatSpec) != 0) {
+ return -1;
+ }
+ if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+SECUREC_INLINE int SecInputFloatExponent(SecFileStream *stream,
+ SecScanSpec *spec,
+ SecFloatSpec *floatSpec)
+{
+ /* Now get exponent part */
+ if (spec->numberState == SECUREC_NUMBER_STATE_STARTED &&
+ SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ if (spec->ch != SECUREC_CHAR('e') &&
+ spec->ch != SECUREC_CHAR('E')) {
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ return 0;
+ }
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Must be behind un get char, otherwise the logic is incorrect */
+ floatSpec->floatStr[floatSpec->floatStrUsedLen] =
+ SECUREC_CHAR('e');
+ ++floatSpec->floatStrUsedLen;
+ if (SecExtendFloatLen(floatSpec) != 0) {
+ return -1;
+ }
+ if (SecInputFloatE(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+* Scan %f.
+* Return 0 OK
+*/
+SECUREC_INLINE int SecInputFloat(SecFileStream *stream, SecScanSpec *spec,
+ SecFloatSpec *floatSpec)
+{
+ floatSpec->floatStrUsedLen = 0;
+
+ /* The following code sequence is strict */
+ if (SecInputFloatSign(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+ if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+ if (SecInputFloatFractional(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+ if (SecInputFloatExponent(stream, spec, floatSpec) != 0) {
+ return -1;
+ }
+
+ /* Make sure have a string terminator, buffer is large enough */
+ floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('\0');
+ if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) {
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+#if (!defined(SECUREC_FOR_WCHAR) && SECUREC_HAVE_WCHART && \
+ SECUREC_HAVE_MBTOWC) || \
+ (!defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION))
+/* only multi-bytes string need isleadbyte() function */
+SECUREC_INLINE int SecIsLeadByte(SecInt ch)
+{
+ unsigned int c = (unsigned int)ch;
+#if !(defined(_MSC_VER) || defined(_INC_WCTYPE))
+ return (int)(c &
+ 0x80U); /* Use bitwise operation to check if the most significant bit is 1 */
+#else
+ return (int)isleadbyte((
+ int)(c &
+ 0xffU)); /* Use bitwise operations to limit character values to valid ranges */
+#endif
+}
+#endif
+
+/*
+ * Parsing whether it is a wide character
+ */
+SECUREC_INLINE void SecUpdateWcharFlagByType(SecUnsignedChar ch,
+ SecScanSpec *spec)
+{
+ if (spec->isWCharOrLong != 0) {
+ /* Wide character identifiers have been explicitly set by l or h flag */
+ return;
+ }
+
+ /* Set default flag */
+#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ spec->isWCharOrLong =
+ 1; /* On windows wide char version %c %s %[ is wide char */
+#else
+ spec->isWCharOrLong =
+ -1; /* On linux all version %c %s %[ is multi char */
+#endif
+
+ if (ch == SECUREC_CHAR('C') || ch == SECUREC_CHAR('S')) {
+#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ spec->isWCharOrLong =
+ -1; /* On windows wide char version %C %S is multi char */
+#else
+ spec->isWCharOrLong =
+ 1; /* On linux all version %C %S is wide char */
+#endif
+ }
+
+ return;
+}
+/*
+ * Decode %l %ll
+ */
+SECUREC_INLINE void SecDecodeScanQualifierL(const SecUnsignedChar **format,
+ SecScanSpec *spec)
+{
+ const SecUnsignedChar *fmt = *format;
+ if (*(fmt + 1) == SECUREC_CHAR('l')) {
+ spec->numberArgType = 1;
+ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
+ ++fmt;
+ } else {
+ spec->numberWidth = SECUREC_NUM_WIDTH_LONG;
+#if defined(SECUREC_ON_64BITS) && !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
+ /* On window 64 system sizeof long is 32bit */
+ spec->numberArgType = 1;
+#endif
+ spec->isWCharOrLong = 1;
+ }
+ *format = fmt;
+}
+
+/*
+ * Decode %I %I43 %I64 %Id %Ii %Io ...
+ * Set finishFlag to 1 finish Flag
+ */
+SECUREC_INLINE void SecDecodeScanQualifierI(const SecUnsignedChar **format,
+ SecScanSpec *spec, int *finishFlag)
+{
+ const SecUnsignedChar *fmt = *format;
+ if ((*(fmt + 1) == SECUREC_CHAR('6')) &&
+ (*(fmt + 2) == SECUREC_CHAR('4'))) { /* Offset 2 for I64 */
+ spec->numberArgType = 1;
+ *format =
+ *format +
+ 2; /* Add 2 to skip I64 point to '4' next loop will inc */
+ } else if ((*(fmt + 1) == SECUREC_CHAR('3')) &&
+ (*(fmt + 2) == SECUREC_CHAR('2'))) { /* Offset 2 for I32 */
+ *format =
+ *format +
+ 2; /* Add 2 to skip I32 point to '2' next loop will inc */
+ } else if ((*(fmt + 1) == SECUREC_CHAR('d')) ||
+ (*(fmt + 1) == SECUREC_CHAR('i')) ||
+ (*(fmt + 1) == SECUREC_CHAR('o')) ||
+ (*(fmt + 1) == SECUREC_CHAR('x')) ||
+ (*(fmt + 1) == SECUREC_CHAR('X'))) {
+ spec->numberArgType = SecNumberArgType(sizeof(void *));
+ } else {
+ /* For %I */
+ spec->numberArgType = SecNumberArgType(sizeof(void *));
+ *finishFlag = 1;
+ }
+}
+
+SECUREC_INLINE int SecDecodeScanWidth(const SecUnsignedChar **format,
+ SecScanSpec *spec)
+{
+ const SecUnsignedChar *fmt = *format;
+ while (SecIsDigit((SecInt)(int)(*fmt)) != 0) {
+ spec->widthSet = 1;
+ if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(spec->width)) {
+ return -1;
+ }
+ spec->width = (int)SECUREC_MUL_TEN((unsigned int)spec->width) +
+ (unsigned char)(*fmt - SECUREC_CHAR('0'));
+ ++fmt;
+ }
+ *format = fmt;
+ return 0;
+}
+
+/*
+ * Init default flags for each format. do not init ch this variable is context-dependent
+ */
+SECUREC_INLINE void SecSetDefaultScanSpec(SecScanSpec *spec)
+{
+ /* The ch and charCount member variables cannot be initialized here */
+ spec->argPtr = NULL;
+ spec->arrayWidth = 0;
+ spec->number64 = 0;
+ spec->number = 0;
+ spec->numberWidth =
+ SECUREC_NUM_WIDTH_INT; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */
+ spec->numberArgType = 0; /* 1 for 64-bit integer, 0 otherwise */
+ spec->width = 0;
+ spec->widthSet = 0;
+ spec->convChr = 0;
+ spec->oriConvChr = 0;
+ spec->isWCharOrLong = 0;
+ spec->suppress = 0;
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ spec->beyondMax = 0;
+#endif
+ spec->negative = 0;
+ spec->numberState = SECUREC_NUMBER_STATE_DEFAULT;
+}
+
+/*
+ * Decode qualifier %I %L %h ...
+ * Set finishFlag to 1 finish Flag
+ */
+SECUREC_INLINE void SecDecodeScanQualifier(const SecUnsignedChar **format,
+ SecScanSpec *spec, int *finishFlag)
+{
+ switch (**format) {
+ case SECUREC_CHAR('F'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('N'):
+ break;
+ case SECUREC_CHAR('h'):
+ --spec->numberWidth; /* The h for SHORT , hh for CHAR */
+ spec->isWCharOrLong = -1;
+ break;
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+ case SECUREC_CHAR('j'):
+ spec->numberWidth =
+ SECUREC_NUM_WIDTH_LONG_LONG; /* For intmax_t or uintmax_t */
+ spec->numberArgType = 1;
+ break;
+ case SECUREC_CHAR('t'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+#endif
+#if SECUREC_IN_KERNEL
+ case SECUREC_CHAR('Z'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+#endif
+ case SECUREC_CHAR('z'):
+#ifdef SECUREC_ON_64BITS
+ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
+ spec->numberArgType = 1;
+#else
+ spec->numberWidth = SECUREC_NUM_WIDTH_LONG;
+#endif
+ break;
+ case SECUREC_CHAR('L'):
+ FALLTHROUGH;
+ /* fall-through */ /* FALLTHRU */ /* For long double */
+ case SECUREC_CHAR('q'):
+ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
+ spec->numberArgType = 1;
+ break;
+ case SECUREC_CHAR('l'):
+ SecDecodeScanQualifierL(format, spec);
+ break;
+ case SECUREC_CHAR('w'):
+ spec->isWCharOrLong = 1;
+ break;
+ case SECUREC_CHAR('*'):
+ spec->suppress = 1;
+ break;
+ case SECUREC_CHAR('I'):
+ SecDecodeScanQualifierI(format, spec, finishFlag);
+ break;
+ default:
+ *finishFlag = 1;
+ break;
+ }
+}
+/*
+ * Decode width and qualifier in format
+ */
+SECUREC_INLINE int SecDecodeScanFlag(const SecUnsignedChar **format,
+ SecScanSpec *spec)
+{
+ const SecUnsignedChar *fmt = *format;
+ int finishFlag = 0;
+
+ do {
+ ++fmt; /* First skip % , next seek fmt */
+ /* May %*6d , so put it inside the loop */
+ if (SecDecodeScanWidth(&fmt, spec) != 0) {
+ return -1;
+ }
+ SecDecodeScanQualifier(&fmt, spec, &finishFlag);
+ } while (finishFlag == 0);
+ *format = fmt;
+ return 0;
+}
+
+/*
+ * Judging whether a zeroing buffer is needed according to different formats
+ */
+SECUREC_INLINE int SecDecodeClearFormat(const SecUnsignedChar *format,
+ int *convChr)
+{
+ const SecUnsignedChar *fmt = format;
+ /* To lowercase */
+ int ch = SECUREC_TO_LOWERCASE(*fmt);
+ if (!(ch == 'c' || ch == 's' || ch == SECUREC_BRACE)) {
+ return -1; /* First argument is not a string type */
+ }
+ if (ch == SECUREC_BRACE) {
+#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
+ if (*fmt == SECUREC_CHAR('{')) {
+ return -1;
+ }
+#endif
+ ++fmt;
+ if (*fmt == SECUREC_CHAR('^')) {
+ ++fmt;
+ }
+ if (*fmt == SECUREC_CHAR(']')) {
+ ++fmt;
+ }
+ while (*fmt != SECUREC_CHAR('\0') &&
+ *fmt != SECUREC_CHAR(']')) {
+ ++fmt;
+ }
+ if (*fmt == SECUREC_CHAR('\0')) {
+ return -1; /* Trunc'd format string */
+ }
+ }
+ *convChr = ch;
+ return 0;
+}
+
+/*
+ * Add L'\0' for wchar string , add '\0' for char string
+ */
+SECUREC_INLINE void SecAddEndingZero(void *ptr, const SecScanSpec *spec)
+{
+ if (spec->suppress == 0) {
+ *(char *)ptr = '\0';
+#if SECUREC_HAVE_WCHART
+ if (spec->isWCharOrLong > 0) {
+ *(wchar_t UNALIGNED *)ptr = L'\0';
+ }
+#endif
+ }
+}
+
+SECUREC_INLINE void SecDecodeClearArg(SecScanSpec *spec, va_list argList)
+{
+ va_list argListSave; /* Backup for argList value, this variable don't need initialized */
+ (void)SECUREC_MEMSET_FUNC_OPT(
+ &argListSave, 0,
+ sizeof(va_list)); /* To clear e530 argListSave not initialized */
+#if defined(va_copy)
+ va_copy(argListSave, argList);
+#elif defined(__va_copy) /* For vxworks */
+ __va_copy(argListSave, argList);
+#else
+ argListSave = argList;
+#endif
+ spec->argPtr = (void *)va_arg(argListSave, void *);
+ /* Get the next argument, size of the array in characters */
+ /* Use 0xffffffffUL mask to Support pass integer as array length */
+ spec->arrayWidth = ((size_t)(va_arg(argListSave, size_t))) &
+ 0xffffffffUL;
+ va_end(argListSave);
+ /* To clear e438 last value assigned not used , the compiler will optimize this code */
+ (void)argListSave;
+}
+
+#ifdef SECUREC_FOR_WCHAR
+/*
+ * Clean up the first %s %c buffer to zero for wchar version
+ */
+void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format,
+ va_list argList)
+#else
+/*
+ * Clean up the first %s %c buffer to zero for char version
+ */
+void SecClearDestBuf(const char *buffer, const char *format, va_list argList)
+#endif
+{
+ SecScanSpec spec;
+ int convChr = 0;
+ const SecUnsignedChar *fmt = (const SecUnsignedChar *)format;
+
+ /* Find first % */
+ while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR('%')) {
+ ++fmt;
+ }
+ if (*fmt == SECUREC_CHAR('\0')) {
+ return;
+ }
+
+ SecSetDefaultScanSpec(&spec);
+ if (SecDecodeScanFlag(&fmt, &spec) != 0) {
+ return;
+ }
+
+ /* Update wchar flag for %S %C */
+ SecUpdateWcharFlagByType(*fmt, &spec);
+ if (spec.suppress != 0) {
+ return;
+ }
+
+ if (SecDecodeClearFormat(fmt, &convChr) != 0) {
+ return;
+ }
+
+ if (*buffer != SECUREC_CHAR('\0') && convChr != 's') {
+ /*
+ * When buffer not empty just clear %s.
+ * Example call sscanf by argment of (" \n", "%s", s, sizeof(s))
+ */
+ return;
+ }
+
+ SecDecodeClearArg(&spec, argList);
+ /* There is no need to judge the upper limit */
+ if (spec.arrayWidth == 0 || spec.argPtr == NULL) {
+ return;
+ }
+ /* Clear one char */
+ SecAddEndingZero(spec.argPtr, &spec);
+ return;
+}
+
+/*
+ * Assign number to output buffer
+ */
+SECUREC_INLINE void SecAssignNumber(const SecScanSpec *spec)
+{
+ void *argPtr = spec->argPtr;
+ if (spec->numberArgType != 0) {
+#if defined(SECUREC_VXWORKS_PLATFORM)
+#if defined(SECUREC_VXWORKS_PLATFORM_COMP)
+ *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64);
+#else
+ /* Take number64 as unsigned number unsigned to int clear Compile warning */
+ *(SecInt64 UNALIGNED *)argPtr =
+ *(SecUnsignedInt64 *)(&(spec->number64));
+#endif
+#else
+ /* Take number64 as unsigned number */
+ *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64);
+#endif
+ return;
+ }
+ if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) {
+ /* Take number as unsigned number */
+ *(long UNALIGNED *)argPtr = (long)(spec->number);
+ } else if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {
+ *(int UNALIGNED *)argPtr = (int)(spec->number);
+ } else if (spec->numberWidth == SECUREC_NUM_WIDTH_SHORT) {
+ /* Take number as unsigned number */
+ *(short UNALIGNED *)argPtr = (short)(spec->number);
+ } else { /* < 0 for hh format modifier */
+ /* Take number as unsigned number */
+ *(char UNALIGNED *)argPtr = (char)(spec->number);
+ }
+}
+
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+/*
+ * Judge the long bit width
+ */
+SECUREC_INLINE int SecIsLongBitEqual(int bitNum)
+{
+ return (int)((unsigned int)bitNum == SECUREC_LONG_BIT_NUM);
+}
+#endif
+
+/*
+ * Convert hexadecimal characters to decimal value
+ */
+SECUREC_INLINE int SecHexValueOfChar(SecInt ch)
+{
+ /* Use isdigt Causing tool false alarms */
+ return (int)((ch >= '0' && ch <= '9') ?
+ ((unsigned char)ch - '0') :
+ ((((unsigned char)ch | (unsigned char)('a' - 'A')) -
+ ('a')) +
+ 10)); /* Adding 10 is to hex value */
+}
+
+/*
+ * Parse decimal character to integer for 32bit .
+ */
+static void SecDecodeNumberDecimal(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ unsigned long decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN;
+#ifdef SECUREC_ON_64BITS
+ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
+ decimalEdge = (unsigned long)SECUREC_MAX_64BITS_VALUE_DIV_TEN;
+ }
+#endif
+ if (spec->number > decimalEdge) {
+ spec->beyondMax = 1;
+ }
+#endif
+ spec->number = SECUREC_MUL_TEN(spec->number);
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (spec->number == SECUREC_MUL_TEN(decimalEdge)) {
+ /* This code is specially converted to unsigned long type for compatibility */
+ SecUnsignedInt64 number64As =
+ (unsigned long)SECUREC_MAX_64BITS_VALUE - spec->number;
+ if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch -
+ (SecUnsignedInt)SECUREC_CHAR('0')) {
+ spec->beyondMax = 1;
+ }
+ }
+#endif
+ spec->number += ((unsigned long)(SecUnsignedInt)spec->ch -
+ (SecUnsignedInt)SECUREC_CHAR('0'));
+}
+
+/*
+ * Parse Hex character to integer for 32bit .
+ */
+static void SecDecodeNumberHex(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (SECUREC_LONG_HEX_BEYOND_MAX(spec->number)) {
+ spec->beyondMax = 1;
+ }
+#endif
+ spec->number = SECUREC_MUL_SIXTEEN(spec->number);
+ spec->number +=
+ (unsigned long)(unsigned int)SecHexValueOfChar(spec->ch);
+}
+
+/*
+ * Parse Octal character to integer for 32bit .
+ */
+static void SecDecodeNumberOctal(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (SECUREC_LONG_OCTAL_BEYOND_MAX(spec->number)) {
+ spec->beyondMax = 1;
+ }
+#endif
+ spec->number = SECUREC_MUL_EIGHT(spec->number);
+ spec->number += ((unsigned long)(SecUnsignedInt)spec->ch -
+ (SecUnsignedInt)SECUREC_CHAR('0'));
+}
+
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+/* Compatible with integer negative values other than int */
+SECUREC_INLINE void SecFinishNumberNegativeOther(SecScanSpec *spec)
+{
+ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
+ if (spec->number > SECUREC_MIN_LONG_NEG_VALUE) {
+ spec->number = SECUREC_MIN_LONG_NEG_VALUE;
+ } else {
+ spec->number =
+ (unsigned long)(0U -
+ spec->number); /* Wrap with unsigned long numbers */
+ }
+ if (spec->beyondMax != 0) {
+ if (spec->numberWidth < SECUREC_NUM_WIDTH_INT) {
+ spec->number = 0;
+ }
+ if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG) {
+ spec->number = SECUREC_MIN_LONG_NEG_VALUE;
+ }
+ }
+ } else { /* For o, u, x, X, p */
+ spec->number =
+ (unsigned long)(0U -
+ spec->number); /* Wrap with unsigned long numbers */
+ if (spec->beyondMax != 0) {
+ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
+ }
+ }
+}
+/* Compatible processing of integer negative numbers */
+SECUREC_INLINE void SecFinishNumberNegativeInt(SecScanSpec *spec)
+{
+ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
+#ifdef SECUREC_ON_64BITS
+ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
+ if ((spec->number > SECUREC_MIN_64BITS_NEG_VALUE)) {
+ spec->number = 0;
+ } else {
+ spec->number =
+ (unsigned int)(0U -
+ (unsigned int)spec
+ ->number); /* Wrap with unsigned int numbers */
+ }
+ }
+#else
+ if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
+ if ((spec->number > SECUREC_MIN_32BITS_NEG_VALUE)) {
+ spec->number = SECUREC_MIN_32BITS_NEG_VALUE;
+ } else {
+ spec->number =
+ (unsigned int)(0U -
+ (unsigned int)spec
+ ->number); /* Wrap with unsigned int numbers */
+ }
+ }
+#endif
+ if (spec->beyondMax != 0) {
+#ifdef SECUREC_ON_64BITS
+ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
+ spec->number = 0;
+ }
+#else
+ if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
+ spec->number = SECUREC_MIN_32BITS_NEG_VALUE;
+ }
+#endif
+ }
+ } else { /* For o, u, x, X ,p */
+#ifdef SECUREC_ON_64BITS
+ if (spec->number > SECUREC_MAX_32BITS_VALUE_INC) {
+ spec->number = SECUREC_MAX_32BITS_VALUE;
+ } else {
+ spec->number =
+ (unsigned int)(0U -
+ (unsigned int)spec
+ ->number); /* Wrap with unsigned int numbers */
+ }
+#else
+ spec->number =
+ (unsigned int)(0U -
+ (unsigned int)spec
+ ->number); /* Wrap with unsigned int numbers */
+#endif
+ if (spec->beyondMax != 0) {
+ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
+ }
+ }
+}
+
+/* Compatible with integer positive values other than int */
+SECUREC_INLINE void SecFinishNumberPositiveOther(SecScanSpec *spec)
+{
+ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
+ if (spec->number > SECUREC_MAX_LONG_POS_VALUE) {
+ spec->number = SECUREC_MAX_LONG_POS_VALUE;
+ }
+ if ((spec->beyondMax != 0 &&
+ spec->numberWidth < SECUREC_NUM_WIDTH_INT)) {
+ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
+ }
+ if (spec->beyondMax != 0 &&
+ spec->numberWidth == SECUREC_NUM_WIDTH_LONG) {
+ spec->number = SECUREC_MAX_LONG_POS_VALUE;
+ }
+ } else {
+ if (spec->beyondMax != 0) {
+ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
+ }
+ }
+}
+
+/* Compatible processing of integer positive numbers */
+SECUREC_INLINE void SecFinishNumberPositiveInt(SecScanSpec *spec)
+{
+ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
+#ifdef SECUREC_ON_64BITS
+ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
+ if (spec->number > SECUREC_MAX_64BITS_POS_VALUE) {
+ spec->number =
+ (unsigned long)SECUREC_MAX_64BITS_VALUE;
+ }
+ }
+ if (spec->beyondMax != 0 &&
+ SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
+ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
+ }
+#else
+ if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
+ if (spec->number > SECUREC_MAX_32BITS_POS_VALUE) {
+ spec->number = SECUREC_MAX_32BITS_POS_VALUE;
+ }
+ }
+ if (spec->beyondMax != 0 &&
+ SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
+ spec->number = SECUREC_MAX_32BITS_POS_VALUE;
+ }
+#endif
+ } else { /* For o,u,x,X,p */
+ if (spec->beyondMax != 0) {
+ spec->number = SECUREC_MAX_32BITS_VALUE;
+ }
+ }
+}
+
+#endif
+
+/*
+ * Parse decimal character to integer for 64bit .
+ */
+static void SecDecodeNumber64Decimal(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (spec->number64 > SECUREC_MAX_64BITS_VALUE_DIV_TEN) {
+ spec->beyondMax = 1;
+ }
+#endif
+ spec->number64 = SECUREC_MUL_TEN(spec->number64);
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (spec->number64 == SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT) {
+ SecUnsignedInt64 number64As =
+ (SecUnsignedInt64)SECUREC_MAX_64BITS_VALUE -
+ spec->number64;
+ if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch -
+ (SecUnsignedInt)SECUREC_CHAR('0')) {
+ spec->beyondMax = 1;
+ }
+ }
+#endif
+ spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch -
+ (SecUnsignedInt)SECUREC_CHAR('0'));
+}
+
+/*
+ * Parse Hex character to integer for 64bit .
+ */
+static void SecDecodeNumber64Hex(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (SECUREC_QWORD_HEX_BEYOND_MAX(spec->number64)) {
+ spec->beyondMax = 1;
+ }
+#endif
+ spec->number64 = SECUREC_MUL_SIXTEEN(spec->number64);
+ spec->number64 +=
+ (SecUnsignedInt64)(unsigned int)SecHexValueOfChar(spec->ch);
+}
+
+/*
+ * Parse Octal character to integer for 64bit .
+ */
+static void SecDecodeNumber64Octal(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (SECUREC_QWORD_OCTAL_BEYOND_MAX(spec->number64)) {
+ spec->beyondMax = 1;
+ }
+#endif
+ spec->number64 = SECUREC_MUL_EIGHT(spec->number64);
+ spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch -
+ (SecUnsignedInt)SECUREC_CHAR('0'));
+}
+
+#define SECUREC_DECODE_NUMBER_FUNC_NUM 2
+
+/*
+ * Parse 64-bit integer formatted input, return 0 when ch is a number.
+ */
+SECUREC_INLINE int SecDecodeNumber(SecScanSpec *spec)
+{
+ /* Function name cannot add address symbol, causing 546 alarm */
+ static void (*const secDecodeNumberHex[SECUREC_DECODE_NUMBER_FUNC_NUM])(
+ SecScanSpec * spec) = { SecDecodeNumberHex,
+ SecDecodeNumber64Hex };
+ static void (*const secDecodeNumberOctal[SECUREC_DECODE_NUMBER_FUNC_NUM])(
+ SecScanSpec * spec) = { SecDecodeNumberOctal,
+ SecDecodeNumber64Octal };
+ static void (*const secDecodeNumberDecimal
+ [SECUREC_DECODE_NUMBER_FUNC_NUM])(
+ SecScanSpec * spec) = { SecDecodeNumberDecimal,
+ SecDecodeNumber64Decimal };
+ if (spec->convChr == 'x' || spec->convChr == 'p') {
+ if (SecIsXdigit(spec->ch) != 0) {
+ (*secDecodeNumberHex[spec->numberArgType])(spec);
+ } else {
+ return -1;
+ }
+ return 0;
+ }
+ if (SecIsDigit(spec->ch) == 0) {
+ return -1;
+ }
+ if (spec->convChr == 'o') {
+ if (spec->ch <
+ SECUREC_CHAR('8')) { /* Octal maximum limit '8' */
+ (*secDecodeNumberOctal[spec->numberArgType])(spec);
+ } else {
+ return -1;
+ }
+ } else { /* The convChr is 'd' */
+ (*secDecodeNumberDecimal[spec->numberArgType])(spec);
+ }
+ return 0;
+}
+
+/*
+ * Complete the final 32-bit integer formatted input
+ */
+static void SecFinishNumber(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (spec->negative != 0) {
+ if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {
+ SecFinishNumberNegativeInt(spec);
+ } else {
+ SecFinishNumberNegativeOther(spec);
+ }
+ } else {
+ if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {
+ SecFinishNumberPositiveInt(spec);
+ } else {
+ SecFinishNumberPositiveOther(spec);
+ }
+ }
+#else
+ if (spec->negative != 0) {
+#if defined(__hpux)
+ if (spec->oriConvChr != 'p') {
+ spec->number =
+ (unsigned long)(0U -
+ spec->number); /* Wrap with unsigned long numbers */
+ }
+#else
+ spec->number =
+ (unsigned long)(0U -
+ spec->number); /* Wrap with unsigned long numbers */
+#endif
+ }
+#endif
+ return;
+}
+
+/*
+ * Complete the final 64-bit integer formatted input
+ */
+static void SecFinishNumber64(SecScanSpec *spec)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
+ if (spec->negative != 0) {
+ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
+ if (spec->number64 > SECUREC_MIN_64BITS_NEG_VALUE) {
+ spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;
+ } else {
+ spec->number64 =
+ (SecUnsignedInt64)(0U -
+ spec->number64); /* Wrap with unsigned int64 numbers */
+ }
+ if (spec->beyondMax != 0) {
+ spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;
+ }
+ } else { /* For o, u, x, X, p */
+ spec->number64 =
+ (SecUnsignedInt64)(0U -
+ spec->number64); /* Wrap with unsigned int64 numbers */
+ if (spec->beyondMax != 0) {
+ spec->number64 = SECUREC_MAX_64BITS_VALUE;
+ }
+ }
+ } else {
+ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
+ if (spec->number64 > SECUREC_MAX_64BITS_POS_VALUE) {
+ spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;
+ }
+ if (spec->beyondMax != 0) {
+ spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;
+ }
+ } else {
+ if (spec->beyondMax != 0) {
+ spec->number64 = SECUREC_MAX_64BITS_VALUE;
+ }
+ }
+ }
+#else
+ if (spec->negative != 0) {
+#if defined(__hpux)
+ if (spec->oriConvChr != 'p') {
+ spec->number64 =
+ (SecUnsignedInt64)(0U -
+ spec->number64); /* Wrap with unsigned int64 numbers */
+ }
+#else
+ spec->number64 =
+ (SecUnsignedInt64)(0U -
+ spec->number64); /* Wrap with unsigned int64 numbers */
+#endif
+ }
+#endif
+ return;
+}
+
+#if SECUREC_ENABLE_SCANF_FILE
+
+/*
+ * Adjust the pointer position of the file stream
+ */
+SECUREC_INLINE void SecSeekStream(SecFileStream *stream)
+{
+ if (stream->count == 0) {
+ if (feof(stream->pf) != 0) {
+ /* File pointer at the end of file, don't need to seek back */
+ stream->base[0] = '\0';
+ return;
+ }
+ }
+ /* Seek to original position, for file read, but nothing to input */
+ if (fseek(stream->pf, stream->oriFilePos, SEEK_SET) != 0) {
+ /* Seek failed, ignore it */
+ stream->oriFilePos = 0;
+ return;
+ }
+
+ if (stream->fileRealRead > 0) { /* Do not seek without input data */
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ size_t residue =
+ stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE;
+ size_t loops;
+ for (loops = 0; loops < (stream->fileRealRead /
+ SECUREC_BUFFERED_BLOK_SIZE);
+ ++loops) {
+ if (fread(stream->base,
+ (size_t)SECUREC_BUFFERED_BLOK_SIZE, (size_t)1,
+ stream->pf) != (size_t)1) {
+ break;
+ }
+ }
+ if (residue != 0) {
+ long curFilePos;
+ if (fread(stream->base, residue, (size_t)1,
+ stream->pf) != (size_t)1) {
+ return;
+ }
+ curFilePos = ftell(stream->pf);
+ if (curFilePos < stream->oriFilePos ||
+ (size_t)(unsigned long)(curFilePos -
+ stream->oriFilePos) <
+ stream->fileRealRead) {
+ /* Try to remedy the problem */
+ long adjustNum =
+ (long)(stream->fileRealRead -
+ (size_t)(unsigned long)(curFilePos -
+ stream->oriFilePos));
+ (void)fseek(stream->pf, adjustNum, SEEK_CUR);
+ }
+ }
+#else
+ /* Seek from oriFilePos. Regardless of the integer sign problem, call scanf will not read very large data */
+ if (fseek(stream->pf, (long)stream->fileRealRead, SEEK_CUR) !=
+ 0) {
+ /* Seek failed, ignore it */
+ stream->oriFilePos = 0;
+ return;
+ }
+#endif
+ }
+ return;
+}
+
+/*
+ * Adjust the pointer position of the file stream and free memory
+ */
+SECUREC_INLINE void SecAdjustStream(SecFileStream *stream)
+{
+ if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0 &&
+ stream->base != NULL) {
+ SecSeekStream(stream);
+ SECUREC_FREE(stream->base);
+ stream->base = NULL;
+ }
+ return;
+}
+#endif
+
+SECUREC_INLINE void SecSkipSpaceFormat(const SecUnsignedChar **format)
+{
+ const SecUnsignedChar *fmt = *format;
+ while (SecIsSpace((SecInt)(int)(*fmt)) != 0) {
+ ++fmt;
+ }
+ *format = fmt;
+}
+
+#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)
+/*
+ * Handling multi-character characters
+ */
+SECUREC_INLINE int SecDecodeLeadByte(SecScanSpec *spec,
+ const SecUnsignedChar **format,
+ SecFileStream *stream)
+{
+#if SECUREC_HAVE_MBTOWC
+ const SecUnsignedChar *fmt = *format;
+ int ch1 = (int)spec->ch;
+ int ch2 = SecGetChar(stream, &(spec->charCount));
+ spec->ch = (SecInt)ch2;
+ if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch2) {
+ /* in console mode, ungetc twice may cause problem */
+ SecUnGetChar(ch2, stream, &(spec->charCount));
+ SecUnGetChar(ch1, stream, &(spec->charCount));
+ return -1;
+ }
+ ++fmt;
+ if ((unsigned int)MB_CUR_MAX >= SECUREC_UTF8_BOM_HEADER_SIZE &&
+ (((unsigned char)ch1 & SECUREC_UTF8_LEAD_1ST) ==
+ SECUREC_UTF8_LEAD_1ST) &&
+ (((unsigned char)ch2 & SECUREC_UTF8_LEAD_2ND) ==
+ SECUREC_UTF8_LEAD_2ND)) {
+ /* This char is very likely to be a UTF-8 char */
+ wchar_t tempWChar;
+ char temp[SECUREC_MULTI_BYTE_MAX_LEN];
+ int ch3 = (int)SecGetChar(stream, &(spec->charCount));
+ spec->ch = (SecInt)ch3;
+ if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch3) {
+ SecUnGetChar(ch3, stream, &(spec->charCount));
+ return -1;
+ }
+ temp[0] = (char)ch1;
+ temp[1] = (char)ch2; /* 1 index of second character */
+ temp[2] = (char)ch3; /* 2 index of third character */
+ temp[3] = '\0'; /* 3 of string terminator position */
+ if (mbtowc(&tempWChar, temp, sizeof(temp)) > 0) {
+ /* Succeed */
+ ++fmt;
+ --spec->charCount;
+ } else {
+ SecUnGetChar(ch3, stream, &(spec->charCount));
+ }
+ }
+ --spec->charCount; /* Only count as one character read */
+ *format = fmt;
+ return 0;
+#else
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ (void)format; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+ return -1;
+#endif
+}
+
+SECUREC_INLINE int SecFilterWcharInFormat(SecScanSpec *spec,
+ const SecUnsignedChar **format,
+ SecFileStream *stream)
+{
+ if (SecIsLeadByte(spec->ch) != 0) {
+ if (SecDecodeLeadByte(spec, format, stream) != 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+#endif
+
+/*
+ * Resolving sequence of characters from %[ format, format wile point to ']'
+ */
+SECUREC_INLINE int SecSetupBracketTable(const SecUnsignedChar **format,
+ SecBracketTable *bracketTable)
+{
+ const SecUnsignedChar *fmt = *format;
+ SecUnsignedChar prevChar = 0;
+#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
+ if (*fmt == SECUREC_CHAR('{')) {
+ return -1;
+ }
+#endif
+ /* For building "table" data */
+ ++fmt; /* Skip [ */
+ bracketTable->mask = 0; /* Set all bits to 0 */
+ if (*fmt == SECUREC_CHAR('^')) {
+ ++fmt;
+ bracketTable->mask =
+ (unsigned char)0xffU; /* Use 0xffU to set all bits to 1 */
+ }
+ if (*fmt == SECUREC_CHAR(']')) {
+ prevChar = SECUREC_CHAR(']');
+ ++fmt;
+ SecBracketSetBit(bracketTable->table, SECUREC_CHAR(']'));
+ }
+ while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) {
+ SecUnsignedChar expCh = *fmt;
+ ++fmt;
+ if (expCh != SECUREC_CHAR('-') || prevChar == 0 ||
+ *fmt == SECUREC_CHAR(']')) {
+ /* Normal character */
+ prevChar = expCh;
+ SecBracketSetBit(bracketTable->table, expCh);
+ } else {
+ /* For %[a-z] */
+ expCh = *fmt; /* Get end of range */
+ ++fmt;
+ if (prevChar <= expCh) { /* %[a-z] %[a-a] */
+ SecBracketSetBitRange(bracketTable->table,
+ prevChar, expCh);
+ } else {
+ /* For %[z-a] */
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ /* Swap start and end characters */
+ SecBracketSetBitRange(bracketTable->table,
+ expCh, prevChar);
+#else
+ SecBracketSetBit(bracketTable->table,
+ SECUREC_CHAR('-'));
+ SecBracketSetBit(bracketTable->table, expCh);
+#endif
+ }
+ prevChar = 0;
+ }
+ }
+ *format = fmt;
+ return 0;
+}
+
+#ifdef SECUREC_FOR_WCHAR
+SECUREC_INLINE int SecInputForWchar(SecScanSpec *spec)
+{
+ void *endPtr = spec->argPtr;
+ if (spec->isWCharOrLong > 0) {
+ *(wchar_t UNALIGNED *)endPtr = (wchar_t)spec->ch;
+ endPtr = (wchar_t *)endPtr + 1;
+ --spec->arrayWidth;
+ } else {
+#if SECUREC_HAVE_WCTOMB
+ int temp;
+ char tmpBuf[SECUREC_MB_LEN + 1];
+ SECUREC_MASK_MSVC_CRT_WARNING temp =
+ wctomb(tmpBuf, (wchar_t)spec->ch);
+ SECUREC_END_MASK_MSVC_CRT_WARNING
+ if (temp <= 0 || (size_t)(unsigned int)temp > sizeof(tmpBuf)) {
+ /* If wctomb error, then ignore character */
+ return 0;
+ }
+ if (((size_t)(unsigned int)temp) > spec->arrayWidth) {
+ return -1;
+ }
+ if (memcpy_s(endPtr, spec->arrayWidth, tmpBuf,
+ (size_t)(unsigned int)temp) != EOK) {
+ return -1;
+ }
+ endPtr = (char *)endPtr + temp;
+ spec->arrayWidth -= (size_t)(unsigned int)temp;
+#else
+ return -1;
+#endif
+ }
+ spec->argPtr = endPtr;
+ return 0;
+}
+#endif
+
+#ifndef SECUREC_FOR_WCHAR
+#if SECUREC_HAVE_WCHART
+SECUREC_INLINE wchar_t SecConvertInputCharToWchar(SecScanSpec *spec,
+ SecFileStream *stream)
+{
+ wchar_t tempWChar = L'?'; /* Set default char is ? */
+#if SECUREC_HAVE_MBTOWC
+ char temp[SECUREC_MULTI_BYTE_MAX_LEN + 1];
+ temp[0] = (char)spec->ch;
+ temp[1] = '\0';
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ if (SecIsLeadByte(spec->ch) != 0) {
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ temp[1] = (char)spec->ch;
+ temp[2] = '\0'; /* 2 of string terminator position */
+ }
+ if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) {
+ /* No string termination error for tool */
+ tempWChar = L'?';
+ }
+#else
+ if (SecIsLeadByte(spec->ch) != 0) {
+ int convRes = 0;
+ int di = 1;
+ /* On Linux like system, the string is encoded in UTF-8 */
+ while (convRes <= 0 && di < (int)MB_CUR_MAX &&
+ di < SECUREC_MULTI_BYTE_MAX_LEN) {
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ temp[di] = (char)spec->ch;
+ ++di;
+ temp[di] = '\0';
+ convRes = mbtowc(&tempWChar, temp, sizeof(temp));
+ }
+ if (convRes <= 0) {
+ tempWChar = L'?';
+ }
+ } else {
+ if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) {
+ tempWChar = L'?';
+ }
+ }
+#endif
+#else
+ (void)spec; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+ (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+#endif /* SECUREC_HAVE_MBTOWC */
+
+ return tempWChar;
+}
+#endif /* SECUREC_HAVE_WCHART */
+
+SECUREC_INLINE int SecInputForChar(SecScanSpec *spec, SecFileStream *stream)
+{
+ void *endPtr = spec->argPtr;
+ if (spec->isWCharOrLong > 0) {
+#if SECUREC_HAVE_WCHART
+ *(wchar_t UNALIGNED *)endPtr =
+ SecConvertInputCharToWchar(spec, stream);
+ endPtr = (wchar_t *)endPtr + 1;
+ --spec->arrayWidth;
+#else
+ (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+ return -1;
+#endif
+ } else {
+ *(char *)endPtr = (char)spec->ch;
+ endPtr = (char *)endPtr + 1;
+ --spec->arrayWidth;
+ }
+ spec->argPtr = endPtr;
+ return 0;
+}
+#endif
+
+/*
+ * Scan digital part of %d %i %o %u %x %p.
+ * Return 0 OK
+ */
+SECUREC_INLINE int SecInputNumberDigital(SecFileStream *stream,
+ SecScanSpec *spec)
+{
+ static void (*const secFinishNumber[SECUREC_DECODE_NUMBER_FUNC_NUM])(
+ SecScanSpec * spec) = { SecFinishNumber, SecFinishNumber64 };
+ while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ /* Decode ch to number */
+ if (SecDecodeNumber(spec) != 0) {
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ break;
+ }
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Must be behind un get char, otherwise the logic is incorrect */
+ spec->numberState = SECUREC_NUMBER_STATE_STARTED;
+ }
+ /* Handling integer negative numbers and beyond max */
+ (*secFinishNumber[spec->numberArgType])(spec);
+ if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) {
+ return 0;
+ }
+ return -1;
+}
+
+/*
+ * Scan %d %i %o %u %x %p.
+ * Return 0 OK
+ */
+SECUREC_INLINE int SecInputNumber(SecFileStream *stream, SecScanSpec *spec)
+{
+ /* Character already read */
+ if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) {
+ if (spec->ch == SECUREC_CHAR('-')) {
+ spec->negative = 1;
+#if SECUREC_IN_KERNEL
+ /* In kernel Refuse to enter negative number */
+ if (SECUREC_CONVERT_IS_UNSIGNED(spec->oriConvChr)) {
+ return -1;
+ }
+#endif
+ }
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Do not need to check width here, must be greater than 0 */
+ spec->ch =
+ SecGetChar(stream, &(spec->charCount)); /* Eat + or - */
+ spec->ch = SecGetChar(
+ stream,
+ &(spec->charCount)); /* Get next character, used for the '0' judgments */
+ SecUnGetChar(
+ spec->ch, stream,
+ &(spec->charCount)); /* Not sure if it was actually read, so push back */
+ }
+
+ if (spec->oriConvChr == 'i') {
+ spec->convChr =
+ 'd'; /* The i could be d, o, or x, use d as default */
+ }
+
+ if (spec->ch == SECUREC_CHAR('0') &&
+ (spec->oriConvChr == 'x' || spec->oriConvChr == 'i') &&
+ SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ /* Input string begin with 0, may be 0x123 0X123 0123 0x 01 0yy 09 0 0ab 00 */
+ SECUREC_FILED_WIDTH_DEC(spec);
+ spec->ch =
+ SecGetChar(stream, &(spec->charCount)); /* ch is '0' */
+
+ /* Read only '0' due to width limitation */
+ if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ /* The number or number64 in spec has been set 0 */
+ return 0;
+ }
+
+ spec->ch = SecGetChar(
+ stream,
+ &(spec->charCount)); /* Get next char to check x or X, do not dec width */
+ if ((SecChar)spec->ch == SECUREC_CHAR('x') ||
+ (SecChar)spec->ch == SECUREC_CHAR('X')) {
+ spec->convChr = 'x';
+ SECUREC_FILED_WIDTH_DEC(
+ spec); /* Make incorrect width for x or X */
+ } else {
+ if (spec->oriConvChr == 'i') {
+ spec->convChr = 'o';
+ }
+ /* For "0y" "08" "01" "0a" ... ,push the 'y' '8' '1' 'a' back */
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ /* Since 0 has been read, it indicates that a valid character has been read */
+ spec->numberState = SECUREC_NUMBER_STATE_STARTED;
+ }
+ }
+ return SecInputNumberDigital(stream, spec);
+}
+
+/*
+ * Scan %c %s %[
+ * Return 0 OK
+ */
+SECUREC_INLINE int SecInputString(SecFileStream *stream, SecScanSpec *spec,
+ const SecBracketTable *bracketTable,
+ int *doneCount)
+{
+ void *startPtr = spec->argPtr;
+ int suppressed = 0;
+ int errNoMem = 0;
+
+ while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
+ SECUREC_FILED_WIDTH_DEC(spec);
+ spec->ch = SecGetChar(stream, &(spec->charCount));
+ /*
+ * The char condition or string condition and bracket condition.
+ * Only supports wide characters with a maximum length of two bytes
+ */
+ if (spec->ch != SECUREC_EOF &&
+ (SecCanInputCharacter(spec->convChr) != 0 ||
+ SecCanInputString(spec->convChr, spec->ch) != 0 ||
+ SecCanInputForBracket(spec->convChr, spec->ch,
+ bracketTable) != 0)) {
+ if (spec->suppress != 0) {
+ /* Used to identify processed data for %*, use argPtr to identify will cause 613, so use suppressed */
+ suppressed = 1;
+ continue;
+ }
+ /* Now suppress is not set */
+ if (spec->arrayWidth == 0) {
+ errNoMem =
+ 1; /* We have exhausted the user's buffer */
+ break;
+ }
+#ifdef SECUREC_FOR_WCHAR
+ errNoMem = SecInputForWchar(spec);
+#else
+ errNoMem = SecInputForChar(spec, stream);
+#endif
+ if (errNoMem != 0) {
+ break;
+ }
+ } else {
+ SecUnGetChar(spec->ch, stream, &(spec->charCount));
+ break;
+ }
+ }
+
+ if (errNoMem != 0) {
+ /* In case of error, blank out the input buffer */
+ SecAddEndingZero(startPtr, spec);
+ return -1;
+ }
+ if ((spec->suppress != 0 && suppressed == 0) ||
+ (spec->suppress == 0 && startPtr == spec->argPtr)) {
+ /* No input was scanned */
+ return -1;
+ }
+ if (spec->convChr != 'c') {
+ /* Add null-terminate for strings */
+ SecAddEndingZero(spec->argPtr, spec);
+ }
+ if (spec->suppress == 0) {
+ *doneCount = *doneCount + 1;
+ }
+ return 0;
+}
+
+#ifdef SECUREC_FOR_WCHAR
+/*
+ * Alloce buffer for wchar version of %[.
+ * Return 0 OK
+ */
+SECUREC_INLINE int SecAllocBracketTable(SecBracketTable *bracketTable)
+{
+ if (bracketTable->table == NULL) {
+ /* Table should be freed after use */
+ bracketTable->table = (unsigned char *)SECUREC_MALLOC(
+ SECUREC_BRACKET_TABLE_SIZE);
+ if (bracketTable->table == NULL) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Free buffer for wchar version of %[
+ */
+SECUREC_INLINE void SecFreeBracketTable(SecBracketTable *bracketTable)
+{
+ if (bracketTable->table != NULL) {
+ SECUREC_FREE(bracketTable->table);
+ bracketTable->table = NULL;
+ }
+}
+#endif
+
+#ifdef SECUREC_FOR_WCHAR
+/*
+ * Formatting input core functions for wchar version.Called by a function such as vswscanf_s
+ */
+int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList)
+#else
+/*
+ * Formatting input core functions for char version.Called by a function such as vsscanf_s
+ */
+int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList)
+#endif
+{
+ const SecUnsignedChar *format = (const SecUnsignedChar *)cFormat;
+ SecBracketTable bracketTable = SECUREC_INIT_BRACKET_TABLE;
+ SecScanSpec spec;
+ int doneCount = 0;
+ int formatError = 0;
+ int paraIsNull = 0;
+ int match = 0; /* When % is found , inc this value */
+ int errRet = 0;
+#if SECUREC_ENABLE_SCANF_FLOAT
+ SecFloatSpec floatSpec;
+ SecInitFloatSpec(&floatSpec);
+#endif
+ spec.ch = 0; /* Need to initialize to 0 */
+ spec.charCount = 0; /* Need to initialize to 0 */
+
+ /* Format must not NULL, use err < 1 to claer 845 */
+ while (errRet < 1 && *format != SECUREC_CHAR('\0')) {
+ /* Skip space in format and space in input */
+ if (SecIsSpace((SecInt)(int)(*format)) != 0) {
+ /* Read first no space char */
+ spec.ch = SecSkipSpaceChar(stream, &(spec.charCount));
+ /* Read the EOF cannot be returned directly here, because the case of " %n" needs to be handled */
+ /* Put fist no space char backup. put EOF back is also OK, and to modify the character count */
+ SecUnGetChar(spec.ch, stream, &(spec.charCount));
+ SecSkipSpaceFormat(&format);
+ continue;
+ }
+
+ if (*format != SECUREC_CHAR('%')) {
+ spec.ch = SecGetChar(stream, &(spec.charCount));
+ if ((int)(*format) != (int)(spec.ch)) {
+ SecUnGetChar(spec.ch, stream,
+ &(spec.charCount));
+ break;
+ }
+ ++format;
+#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)
+ if (SecFilterWcharInFormat(&spec, &format, stream) !=
+ 0) {
+ break;
+ }
+#endif
+ continue;
+ }
+
+ /* Now *format is % */
+ /* Set default value for each % */
+ SecSetDefaultScanSpec(&spec);
+ if (SecDecodeScanFlag(&format, &spec) != 0) {
+ formatError = 1;
+ ++errRet;
+ continue;
+ }
+ if (!SECUREC_FILED_WIDTH_ENOUGH(&spec)) {
+ /* 0 width in format */
+ ++errRet;
+ continue;
+ }
+
+ /* Update wchar flag for %S %C */
+ SecUpdateWcharFlagByType(*format, &spec);
+
+ spec.convChr = SECUREC_TO_LOWERCASE(*format);
+ spec.oriConvChr =
+ spec.convChr; /* convChr may be modified to handle integer logic */
+ if (spec.convChr != 'n') {
+ if (spec.convChr != 'c' &&
+ spec.convChr != SECUREC_BRACE) {
+ spec.ch = SecSkipSpaceChar(stream,
+ &(spec.charCount));
+ } else {
+ spec.ch = SecGetChar(stream, &(spec.charCount));
+ }
+ if (spec.ch == SECUREC_EOF) {
+ ++errRet;
+ continue;
+ }
+ }
+
+ /* Now no 0 width in format and get one char from input */
+ switch (spec.oriConvChr) {
+ case 'c': /* Also 'C' */
+ if (spec.widthSet == 0) {
+ spec.widthSet = 1;
+ spec.width = 1;
+ }
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 's': /* Also 'S': */
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_BRACE:
+ /* Unset last char to stream */
+ SecUnGetChar(spec.ch, stream, &(spec.charCount));
+ /* Check dest buffer and size */
+ if (spec.suppress == 0) {
+ spec.argPtr = (void *)va_arg(argList, void *);
+ if (spec.argPtr == NULL) {
+ paraIsNull = 1;
+ ++errRet;
+ continue;
+ }
+ /* Get the next argument, size of the array in characters */
+ spec.arrayWidth =
+ SECUREC_GET_ARRAYWIDTH(argList);
+ if (SECUREC_ARRAY_WIDTH_IS_WRONG(spec)) {
+ /* Do not clear buffer just go error */
+ ++errRet;
+ continue;
+ }
+ /* One element is needed for '\0' for %s and %[ */
+ if (spec.convChr != 'c') {
+ --spec.arrayWidth;
+ }
+ } else {
+ /* Set argPtr to NULL is necessary, in supress mode we don't use argPtr to store data */
+ spec.argPtr = NULL;
+ }
+
+ if (spec.convChr == SECUREC_BRACE) {
+ /* Malloc when first %[ is meet for wchar version */
+#ifdef SECUREC_FOR_WCHAR
+ if (SecAllocBracketTable(&bracketTable) != 0) {
+ ++errRet;
+ continue;
+ }
+#endif
+ (void)SECUREC_MEMSET_FUNC_OPT(
+ bracketTable.table, 0,
+ (size_t)SECUREC_BRACKET_TABLE_SIZE);
+ if (SecSetupBracketTable(&format,
+ &bracketTable) != 0) {
+ ++errRet;
+ continue;
+ }
+
+ if (*format == SECUREC_CHAR('\0')) {
+ /* Default add string terminator */
+ SecAddEndingZero(spec.argPtr, &spec);
+ ++errRet;
+ /* Truncated format */
+ continue;
+ }
+ }
+
+ /* Set completed. Now read string or character */
+ if (SecInputString(stream, &spec, &bracketTable,
+ &doneCount) != 0) {
+ ++errRet;
+ continue;
+ }
+ break;
+ case 'p':
+ /* Make %hp same as %p */
+ spec.numberWidth = SECUREC_NUM_WIDTH_INT;
+#ifdef SECUREC_ON_64BITS
+ spec.numberArgType = 1;
+#endif
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'o':
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'u':
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'd':
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'i':
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'x':
+ /* Unset last char to stream */
+ SecUnGetChar(spec.ch, stream, &(spec.charCount));
+ if (SecInputNumber(stream, &spec) != 0) {
+ ++errRet;
+ continue;
+ }
+ if (spec.suppress == 0) {
+ spec.argPtr = (void *)va_arg(argList, void *);
+ if (spec.argPtr == NULL) {
+ paraIsNull = 1;
+ ++errRet;
+ continue;
+ }
+ SecAssignNumber(&spec);
+ ++doneCount;
+ }
+ break;
+ case 'n': /* Char count */
+ if (spec.suppress == 0) {
+ spec.argPtr = (void *)va_arg(argList, void *);
+ if (spec.argPtr == NULL) {
+ paraIsNull = 1;
+ ++errRet;
+ continue;
+ }
+ spec.number =
+ (unsigned long)(unsigned int)(spec.charCount);
+ spec.numberArgType = 0;
+ SecAssignNumber(&spec);
+ }
+ break;
+ case 'e':
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'f':
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case 'g': /* Scan a float */
+ /* Unset last char to stream */
+ SecUnGetChar(spec.ch, stream, &(spec.charCount));
+#if SECUREC_ENABLE_SCANF_FLOAT
+ if (SecInputFloat(stream, &spec, &floatSpec) != 0) {
+ ++errRet;
+ continue;
+ }
+ if (spec.suppress == 0) {
+ spec.argPtr = (void *)va_arg(argList, void *);
+ if (spec.argPtr == NULL) {
+ ++errRet;
+ paraIsNull = 1;
+ continue;
+ }
+ if (SecAssignFloat(&floatSpec, &spec) != 0) {
+ ++errRet;
+ continue;
+ }
+ ++doneCount;
+ }
+ break;
+#else /* SECUREC_ENABLE_SCANF_FLOAT */
+ ++errRet;
+ continue;
+#endif
+ default:
+ if ((int)(*format) != (int)spec.ch) {
+ SecUnGetChar(spec.ch, stream,
+ &(spec.charCount));
+ formatError = 1;
+ ++errRet;
+ continue;
+ } else {
+ --match; /* Compensate for the self-increment of the following code */
+ }
+ break;
+ }
+ ++match;
+ ++format;
+ }
+
+#ifdef SECUREC_FOR_WCHAR
+ SecFreeBracketTable(&bracketTable);
+#endif
+
+#if SECUREC_ENABLE_SCANF_FLOAT
+ SecFreeFloatSpec(&floatSpec, &doneCount);
+#endif
+
+#if SECUREC_ENABLE_SCANF_FILE
+ SecAdjustStream(stream);
+#endif
+
+ if (spec.ch == SECUREC_EOF) {
+ return ((doneCount != 0 || match != 0) ? doneCount :
+ SECUREC_SCANF_EINVAL);
+ }
+ if (formatError != 0 || paraIsNull != 0) {
+ /* Invalid Input Format or parameter, but not meet EOF */
+ return SECUREC_SCANF_ERROR_PARA;
+ }
+ return doneCount;
+}
+
+#if SECUREC_ENABLE_SCANF_FILE
+/*
+ * Get char from stream use std function
+ */
+SECUREC_INLINE SecInt SecGetCharFromStream(const SecFileStream *stream)
+{
+ SecInt ch;
+ ch = SECUREC_GETC(stream->pf);
+ return ch;
+}
+
+/*
+ * Try to read the BOM header, when meet a BOM head, discard it, then data is Aligned to base
+ */
+SECUREC_INLINE void SecReadAndSkipBomHeader(SecFileStream *stream)
+{
+ /* Use size_t type conversion to clean e747 */
+ stream->count = fread(stream->base, (size_t)1,
+ (size_t)SECUREC_BOM_HEADER_SIZE, stream->pf);
+ if (stream->count > SECUREC_BOM_HEADER_SIZE) {
+ stream->count = 0;
+ }
+ if (SECUREC_BEGIN_WITH_BOM(stream->base, stream->count)) {
+ /* It's BOM header, discard it */
+ stream->count = 0;
+ }
+}
+
+/*
+ * Get char from file stream or buffer
+ */
+SECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream)
+{
+ SecInt ch;
+ if (stream->count < sizeof(SecChar)) {
+ /* Load file to buffer */
+ size_t len;
+ if (stream->base != NULL) {
+ /* Put the last unread data in the buffer head */
+ for (len = 0; len < stream->count; ++len) {
+ stream->base[len] = stream->cur[len];
+ }
+ } else {
+ stream->oriFilePos = ftell(
+ stream->pf); /* Save original file read position */
+ if (stream->oriFilePos == -1) {
+ /* It may be a pipe stream */
+ stream->flag = SECUREC_PIPE_STREAM_FLAG;
+ return SecGetCharFromStream(stream);
+ }
+ /* Reserve the length of BOM head */
+ stream->base = (char *)SECUREC_MALLOC(
+ SECUREC_BUFFERED_BLOK_SIZE +
+ SECUREC_BOM_HEADER_SIZE +
+ sizeof(SecChar)); /* To store '\0' and aligned to wide char */
+ if (stream->base == NULL) {
+ return SECUREC_EOF;
+ }
+ /* First read file */
+ if (stream->oriFilePos == 0) {
+ /* Make sure the data is aligned to base */
+ SecReadAndSkipBomHeader(stream);
+ }
+ }
+
+ /* Skip existing data and read data */
+ len = fread(stream->base + stream->count, (size_t)1,
+ (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf);
+ if (len > SECUREC_BUFFERED_BLOK_SIZE) { /* It won't happen, */
+ len = 0;
+ }
+ stream->count += len;
+ stream->cur = stream->base;
+ stream->flag |= SECUREC_LOAD_FILE_TO_MEM_FLAG;
+ stream->base[stream->count] =
+ '\0'; /* For tool Warning string null */
+ }
+
+ SECUREC_GET_CHAR(stream, &ch);
+ if (ch != SECUREC_EOF) {
+ stream->fileRealRead += sizeof(SecChar);
+ }
+ return ch;
+}
+#endif
+
+/*
+ * Get char for wchar version
+ */
+SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter)
+{
+ *counter = *counter + 1; /* Always plus 1 */
+ /* The main scenario is scanf str */
+ if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {
+ SecInt ch;
+ SECUREC_GET_CHAR(stream, &ch);
+ return ch;
+ }
+#if SECUREC_ENABLE_SCANF_FILE
+ if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) {
+ return SecGetCharFromFile(stream);
+ }
+ if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) {
+ return SecGetCharFromStream(stream);
+ }
+#endif
+ return SECUREC_EOF;
+}
+
+/*
+ * Unget Public realizatio char for wchar and char version
+ */
+SECUREC_INLINE void SecUnGetCharImpl(SecInt ch, SecFileStream *stream)
+{
+ if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {
+ SECUREC_UN_GET_CHAR(stream);
+ return;
+ }
+#if SECUREC_ENABLE_SCANF_FILE
+ if ((stream->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) != 0) {
+ SECUREC_UN_GET_CHAR(stream);
+ if (stream->fileRealRead > 0) {
+ stream->fileRealRead -= sizeof(SecChar);
+ }
+ return;
+ }
+ if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) {
+ (void)SECUREC_UN_GETC(ch, stream->pf);
+ return;
+ }
+#else
+ (void)ch; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+#endif
+}
+
+/*
+ * Unget char for char version
+ */
+SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter)
+{
+ *counter = *counter - 1; /* Always mius 1 */
+ if (ch != SECUREC_EOF) {
+ SecUnGetCharImpl(ch, stream);
+ }
+}
+
+/*
+ * Skip space char by isspace
+ */
+SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter)
+{
+ SecInt ch;
+ do {
+ ch = SecGetChar(stream, counter);
+ if (ch == SECUREC_EOF) {
+ break;
+ }
+ } while (SecIsSpace(ch) != 0);
+ return ch;
+}
+#endif /* INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 */
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memcpy_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memcpy_s.c
new file mode 100644
index 000000000..efdd4fb54
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memcpy_s.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: memcpy_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Portability
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
+ * And sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+#if SECUREC_WITH_PERFORMANCE_ADDONS
+#ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE
+#define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL
+#endif
+
+#define SECUREC_SMALL_MEM_COPY(dest, src, count) \
+ do { \
+ if (SECUREC_ADDR_ALIGNED_8(dest) && \
+ SECUREC_ADDR_ALIGNED_8(src)) { \
+ /* Use struct assignment */ \
+ switch (count) { \
+ case 1: \
+ *(unsigned char *)(dest) = \
+ *(const unsigned char *)(src); \
+ break; \
+ case 2: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 2); \
+ break; \
+ case 3: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 3); \
+ break; \
+ case 4: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 4); \
+ break; \
+ case 5: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 5); \
+ break; \
+ case 6: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 6); \
+ break; \
+ case 7: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 7); \
+ break; \
+ case 8: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 8); \
+ break; \
+ case 9: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 9); \
+ break; \
+ case 10: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 10); \
+ break; \
+ case 11: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 11); \
+ break; \
+ case 12: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 12); \
+ break; \
+ case 13: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 13); \
+ break; \
+ case 14: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 14); \
+ break; \
+ case 15: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 15); \
+ break; \
+ case 16: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 16); \
+ break; \
+ case 17: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 17); \
+ break; \
+ case 18: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 18); \
+ break; \
+ case 19: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 19); \
+ break; \
+ case 20: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 20); \
+ break; \
+ case 21: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 21); \
+ break; \
+ case 22: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 22); \
+ break; \
+ case 23: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 23); \
+ break; \
+ case 24: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 24); \
+ break; \
+ case 25: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 25); \
+ break; \
+ case 26: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 26); \
+ break; \
+ case 27: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 27); \
+ break; \
+ case 28: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 28); \
+ break; \
+ case 29: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 29); \
+ break; \
+ case 30: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 30); \
+ break; \
+ case 31: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 31); \
+ break; \
+ case 32: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 32); \
+ break; \
+ case 33: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 33); \
+ break; \
+ case 34: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 34); \
+ break; \
+ case 35: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 35); \
+ break; \
+ case 36: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 36); \
+ break; \
+ case 37: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 37); \
+ break; \
+ case 38: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 38); \
+ break; \
+ case 39: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 39); \
+ break; \
+ case 40: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 40); \
+ break; \
+ case 41: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 41); \
+ break; \
+ case 42: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 42); \
+ break; \
+ case 43: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 43); \
+ break; \
+ case 44: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 44); \
+ break; \
+ case 45: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 45); \
+ break; \
+ case 46: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 46); \
+ break; \
+ case 47: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 47); \
+ break; \
+ case 48: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 48); \
+ break; \
+ case 49: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 49); \
+ break; \
+ case 50: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 50); \
+ break; \
+ case 51: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 51); \
+ break; \
+ case 52: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 52); \
+ break; \
+ case 53: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 53); \
+ break; \
+ case 54: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 54); \
+ break; \
+ case 55: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 55); \
+ break; \
+ case 56: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 56); \
+ break; \
+ case 57: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 57); \
+ break; \
+ case 58: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 58); \
+ break; \
+ case 59: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 59); \
+ break; \
+ case 60: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 60); \
+ break; \
+ case 61: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 61); \
+ break; \
+ case 62: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 62); \
+ break; \
+ case 63: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 63); \
+ break; \
+ case 64: \
+ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), \
+ 64); \
+ break; \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } /* END switch */ \
+ } else { \
+ unsigned char *tmpDest_ = (unsigned char *)(dest); \
+ const unsigned char *tmpSrc_ = \
+ (const unsigned char *)(src); \
+ switch (count) { \
+ case 64: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 63: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 62: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 61: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 60: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 59: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 58: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 57: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 56: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 55: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 54: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 53: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 52: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 51: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 50: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 49: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 48: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 47: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 46: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 45: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 44: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 43: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 42: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 41: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 40: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 39: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 38: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 37: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 36: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 35: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 34: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 33: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 32: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 31: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 30: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 29: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 28: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 27: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 26: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 25: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 24: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 23: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 22: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 21: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 20: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 19: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 18: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 17: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 16: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 15: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 14: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 13: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 12: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 11: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 10: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 9: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 8: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 7: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 6: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 5: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 4: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 3: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 2: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 1: \
+ *(tmpDest_++) = *(tmpSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+/*
+ * Performance optimization
+ */
+#define SECUREC_MEMCPY_OPT(dest, src, count) \
+ do { \
+ if ((count) > SECUREC_MEMCOPY_THRESHOLD_SIZE) { \
+ SECUREC_MEMCPY_WARP_OPT((dest), (src), (count)); \
+ } else { \
+ SECUREC_SMALL_MEM_COPY((dest), (src), (count)); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+#endif
+
+/*
+ * Handling errors
+ */
+SECUREC_INLINE errno_t SecMemcpyError(void *dest, size_t destMax,
+ const void *src, size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("memcpy_s");
+ return ERANGE;
+ }
+ if (dest == NULL || src == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("memcpy_s");
+ if (dest != NULL) {
+ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ if (count > destMax) {
+ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);
+ SECUREC_ERROR_INVALID_RANGE("memcpy_s");
+ return ERANGE_AND_RESET;
+ }
+ if (SECUREC_MEMORY_IS_OVERLAP(dest, src, count)) {
+ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);
+ SECUREC_ERROR_BUFFER_OVERLAP("memcpy_s");
+ return EOVERLAP_AND_RESET;
+ }
+ /* Count is 0 or dest equal src also ret EOK */
+ return EOK;
+}
+
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+/*
+ * The fread API in windows will call memcpy_s and pass 0xffffffff to destMax.
+ * To avoid the failure of fread, we don't check desMax limit.
+ */
+#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) \
+ (SECUREC_LIKELY((count) <= (destMax) && (dest) != NULL && \
+ (src) != NULL && (count) > 0 && \
+ SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
+#else
+#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) \
+ (SECUREC_LIKELY((count) <= (destMax) && (dest) != NULL && \
+ (src) != NULL && (destMax) <= SECUREC_MEM_MAX_LEN && \
+ (count) > 0 && \
+ SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))
+#endif
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest
+ *
+ * <INPUT PARAMETERS>
+ * dest Destination buffer.
+ * destMax Size of the destination buffer.
+ * src Buffer to copy from.
+ * count Number of characters to copy
+ *
+ * <OUTPUT PARAMETERS>
+ * dest buffer is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
+ * EINVAL_AND_RESET dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
+ * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0
+ * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
+ * and dest != NULL and src != NULL
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
+ * count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
+ * and src != NULL and dest != src
+ *
+ * if an error occurred, dest will be filled with 0.
+ * If the source and destination overlap, the behavior of memcpy_s is undefined.
+ * Use memmove_s to handle overlapping regions.
+ */
+errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count)
+{
+ if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
+ SECUREC_MEMCPY_WARP_OPT(dest, src, count);
+ return EOK;
+ }
+ /* Meet some runtime violation, return error code */
+ return SecMemcpyError(dest, destMax, src, count);
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(memcpy_s);
+#endif
+
+#if SECUREC_WITH_PERFORMANCE_ADDONS
+/*
+ * Performance optimization
+ */
+errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src,
+ size_t count)
+{
+ if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {
+ SECUREC_MEMCPY_OPT(dest, src, count);
+ return EOK;
+ }
+ /* Meet some runtime violation, return error code */
+ return SecMemcpyError(dest, destMax, src, count);
+}
+
+/* Trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" */
+errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count)
+{
+ if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL &&
+ count > 0 &&
+ SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) {
+ SECUREC_MEMCPY_OPT(dest, src, count);
+ return EOK;
+ }
+ /* Meet some runtime violation, return error code */
+ return SecMemcpyError(dest, destMax, src, count);
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memmove_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memmove_s.c
new file mode 100644
index 000000000..a29f1a2aa
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memmove_s.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: memmove_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Portability
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
+ * And sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+#ifdef SECUREC_NOT_CALL_LIBC_CORE_API
+/*
+ * Implementing memory data movement
+ */
+SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count)
+{
+ unsigned char *pDest = (unsigned char *)dst;
+ const unsigned char *pSrc = (const unsigned char *)src;
+ size_t maxCount = count;
+
+ if (dst <= src || pDest >= (pSrc + maxCount)) {
+ /*
+ * Non-Overlapping Buffers
+ * Copy from lower addresses to higher addresses
+ */
+ while (maxCount > 0) {
+ --maxCount;
+ *pDest = *pSrc;
+ ++pDest;
+ ++pSrc;
+ }
+ } else {
+ /*
+ * Overlapping Buffers
+ * Copy from higher addresses to lower addresses
+ */
+ pDest = pDest + maxCount - 1;
+ pSrc = pSrc + maxCount - 1;
+ while (maxCount > 0) {
+ --maxCount;
+ *pDest = *pSrc;
+ --pDest;
+ --pSrc;
+ }
+ }
+}
+#endif
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The memmove_s function copies count bytes of characters from src to dest.
+ * This function can be assigned correctly when memory overlaps.
+ * <INPUT PARAMETERS>
+ * dest Destination object.
+ * destMax Size of the destination buffer.
+ * src Source object.
+ * count Number of characters to copy.
+ *
+ * <OUTPUT PARAMETERS>
+ * dest buffer is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
+ * EINVAL_AND_RESET dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
+ * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0
+ * ERANGE_AND_RESET count > destMax and dest != NULL and src != NULL and destMax != 0
+ * and destMax <= SECUREC_MEM_MAX_LEN
+ *
+ * If an error occurred, dest will be filled with 0 when dest and destMax valid.
+ * If some regions of the source area and the destination overlap, memmove_s
+ * ensures that the original source bytes in the overlapping region are copied
+ * before being overwritten.
+ */
+errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("memmove_s");
+ return ERANGE;
+ }
+ if (dest == NULL || src == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("memmove_s");
+ if (dest != NULL) {
+ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ if (count > destMax) {
+ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);
+ SECUREC_ERROR_INVALID_RANGE("memmove_s");
+ return ERANGE_AND_RESET;
+ }
+ if (dest == src) {
+ return EOK;
+ }
+
+ if (count > 0) {
+#ifdef SECUREC_NOT_CALL_LIBC_CORE_API
+ SecUtilMemmove(dest, src, count);
+#else
+ /* Use underlying memmove for performance consideration */
+ (void)memmove(dest, src, count);
+#endif
+ }
+ return EOK;
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(memmove_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memset_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memset_s.c
new file mode 100644
index 000000000..4e4a60c28
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/memset_s.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: memset_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Portability
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
+ * And sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+#define SECUREC_MEMSET_PARAM_OK(dest, destMax, count) \
+ (SECUREC_LIKELY((destMax) <= SECUREC_MEM_MAX_LEN && (dest) != NULL && \
+ (count) <= (destMax)))
+
+#if SECUREC_WITH_PERFORMANCE_ADDONS
+
+/* Use union to clear strict-aliasing warning */
+typedef union {
+ SecStrBuf32 buf32;
+ SecStrBuf31 buf31;
+ SecStrBuf30 buf30;
+ SecStrBuf29 buf29;
+ SecStrBuf28 buf28;
+ SecStrBuf27 buf27;
+ SecStrBuf26 buf26;
+ SecStrBuf25 buf25;
+ SecStrBuf24 buf24;
+ SecStrBuf23 buf23;
+ SecStrBuf22 buf22;
+ SecStrBuf21 buf21;
+ SecStrBuf20 buf20;
+ SecStrBuf19 buf19;
+ SecStrBuf18 buf18;
+ SecStrBuf17 buf17;
+ SecStrBuf16 buf16;
+ SecStrBuf15 buf15;
+ SecStrBuf14 buf14;
+ SecStrBuf13 buf13;
+ SecStrBuf12 buf12;
+ SecStrBuf11 buf11;
+ SecStrBuf10 buf10;
+ SecStrBuf9 buf9;
+ SecStrBuf8 buf8;
+ SecStrBuf7 buf7;
+ SecStrBuf6 buf6;
+ SecStrBuf5 buf5;
+ SecStrBuf4 buf4;
+ SecStrBuf3 buf3;
+ SecStrBuf2 buf2;
+} SecStrBuf32Union;
+/* C standard initializes the first member of the consortium. */
+static const SecStrBuf32 g_allZero = {
+ { 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
+ 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U }
+};
+static const SecStrBuf32 g_allFF = {
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+};
+
+/* Clear conversion warning strict aliasing" */
+SECUREC_INLINE const SecStrBuf32Union *
+SecStrictAliasingCast(const SecStrBuf32 *buf)
+{
+ return (const SecStrBuf32Union *)buf;
+}
+
+#ifndef SECUREC_MEMSET_THRESHOLD_SIZE
+#define SECUREC_MEMSET_THRESHOLD_SIZE 32UL
+#endif
+
+#define SECUREC_UNALIGNED_SET(dest, c, count) \
+ do { \
+ unsigned char *pDest_ = (unsigned char *)(dest); \
+ switch (count) { \
+ case 32: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 31: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 30: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 29: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 28: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 27: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 26: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 25: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 24: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 23: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 22: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 21: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 20: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 19: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 18: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 17: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 16: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 15: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 14: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 13: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 12: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 11: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 10: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 9: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 8: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 7: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 6: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 5: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 4: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 3: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 2: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 1: \
+ *(pDest_++) = (unsigned char)(c); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+#define SECUREC_SET_VALUE_BY_STRUCT(dest, dataName, n) \
+ do { \
+ *(SecStrBuf##n *)(dest) = *(const SecStrBuf##n *)(&( \
+ (SecStrictAliasingCast(&(dataName)))->buf##n)); \
+ } \
+ SECUREC_WHILE_ZERO
+
+#define SECUREC_ALIGNED_SET_OPT_ZERO_FF(dest, c, count) \
+ do { \
+ switch (c) { \
+ case 0: \
+ switch (count) { \
+ case 1: \
+ *(unsigned char *)(dest) = (unsigned char)0; \
+ break; \
+ case 2: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 2); \
+ break; \
+ case 3: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 3); \
+ break; \
+ case 4: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 4); \
+ break; \
+ case 5: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 5); \
+ break; \
+ case 6: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 6); \
+ break; \
+ case 7: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 7); \
+ break; \
+ case 8: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 8); \
+ break; \
+ case 9: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 9); \
+ break; \
+ case 10: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 10); \
+ break; \
+ case 11: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 11); \
+ break; \
+ case 12: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 12); \
+ break; \
+ case 13: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 13); \
+ break; \
+ case 14: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 14); \
+ break; \
+ case 15: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 15); \
+ break; \
+ case 16: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 16); \
+ break; \
+ case 17: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 17); \
+ break; \
+ case 18: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 18); \
+ break; \
+ case 19: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 19); \
+ break; \
+ case 20: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 20); \
+ break; \
+ case 21: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 21); \
+ break; \
+ case 22: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 22); \
+ break; \
+ case 23: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 23); \
+ break; \
+ case 24: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 24); \
+ break; \
+ case 25: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 25); \
+ break; \
+ case 26: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 26); \
+ break; \
+ case 27: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 27); \
+ break; \
+ case 28: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 28); \
+ break; \
+ case 29: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 29); \
+ break; \
+ case 30: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 30); \
+ break; \
+ case 31: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 31); \
+ break; \
+ case 32: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, \
+ 32); \
+ break; \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } \
+ break; \
+ case 0xFF: \
+ switch (count) { \
+ case 1: \
+ *(unsigned char *)(dest) = \
+ (unsigned char)0xffU; \
+ break; \
+ case 2: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 2); \
+ break; \
+ case 3: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 3); \
+ break; \
+ case 4: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 4); \
+ break; \
+ case 5: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 5); \
+ break; \
+ case 6: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 6); \
+ break; \
+ case 7: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 7); \
+ break; \
+ case 8: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 8); \
+ break; \
+ case 9: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 9); \
+ break; \
+ case 10: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 10); \
+ break; \
+ case 11: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 11); \
+ break; \
+ case 12: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 12); \
+ break; \
+ case 13: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 13); \
+ break; \
+ case 14: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 14); \
+ break; \
+ case 15: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 15); \
+ break; \
+ case 16: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 16); \
+ break; \
+ case 17: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 17); \
+ break; \
+ case 18: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 18); \
+ break; \
+ case 19: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 19); \
+ break; \
+ case 20: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 20); \
+ break; \
+ case 21: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 21); \
+ break; \
+ case 22: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 22); \
+ break; \
+ case 23: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 23); \
+ break; \
+ case 24: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 24); \
+ break; \
+ case 25: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 25); \
+ break; \
+ case 26: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 26); \
+ break; \
+ case 27: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 27); \
+ break; \
+ case 28: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 28); \
+ break; \
+ case 29: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 29); \
+ break; \
+ case 30: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 30); \
+ break; \
+ case 31: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 31); \
+ break; \
+ case 32: \
+ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, \
+ 32); \
+ break; \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } \
+ break; \
+ default: \
+ SECUREC_UNALIGNED_SET((dest), (c), (count)); \
+ break; \
+ } /* END switch */ \
+ } \
+ SECUREC_WHILE_ZERO
+
+#define SECUREC_SMALL_MEM_SET(dest, c, count) \
+ do { \
+ if (SECUREC_ADDR_ALIGNED_8((dest))) { \
+ SECUREC_ALIGNED_SET_OPT_ZERO_FF((dest), (c), (count)); \
+ } else { \
+ SECUREC_UNALIGNED_SET((dest), (c), (count)); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+/*
+ * Performance optimization
+ */
+#define SECUREC_MEMSET_OPT(dest, c, count) \
+ do { \
+ if ((count) > SECUREC_MEMSET_THRESHOLD_SIZE) { \
+ SECUREC_MEMSET_PREVENT_DSE((dest), (c), (count)); \
+ } else { \
+ SECUREC_SMALL_MEM_SET((dest), (c), (count)); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+#endif
+
+/*
+ * Handling errors
+ */
+SECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c)
+{
+ /* Check destMax is 0 compatible with _sp macro */
+ if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("memset_s");
+ return ERANGE;
+ }
+ if (dest == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("memset_s");
+ return EINVAL;
+ }
+ SECUREC_MEMSET_PREVENT_DSE(dest, c,
+ destMax); /* Set entire buffer to value c */
+ SECUREC_ERROR_INVALID_RANGE("memset_s");
+ return ERANGE_AND_RESET;
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The memset_s function copies the value of c (converted to an unsigned char)
+ * into each of the first count characters of the object pointed to by dest.
+ *
+ * <INPUT PARAMETERS>
+ * dest Pointer to destination.
+ * destMax The size of the buffer.
+ * c Character to set.
+ * count Number of characters.
+ *
+ * <OUTPUT PARAMETERS>
+ * dest buffer is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL dest == NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN
+ * ERANGE destMax > SECUREC_MEM_MAX_LEN or (destMax is 0 and count > destMax)
+ * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL
+ *
+ * if return ERANGE_AND_RESET then fill dest to c ,fill length is destMax
+ */
+errno_t memset_s(void *dest, size_t destMax, int c, size_t count)
+{
+ if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) {
+ SECUREC_MEMSET_PREVENT_DSE(dest, c, count);
+ return EOK;
+ }
+ /* Meet some runtime violation, return error code */
+ return SecMemsetError(dest, destMax, c);
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(memset_s);
+#endif
+
+#if SECUREC_WITH_PERFORMANCE_ADDONS
+/*
+ * Performance optimization
+ */
+errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count)
+{
+ if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) {
+ SECUREC_MEMSET_OPT(dest, c, count);
+ return EOK;
+ }
+ /* Meet some runtime violation, return error code */
+ return SecMemsetError(dest, destMax, c);
+}
+
+/*
+ * Performance optimization, trim judgement on "destMax <= SECUREC_MEM_MAX_LEN"
+ */
+errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count)
+{
+ if (SECUREC_LIKELY(count <= destMax && dest != NULL)) {
+ SECUREC_MEMSET_OPT(dest, c, count);
+ return EOK;
+ }
+ /* Meet some runtime violation, return error code */
+ return SecMemsetError(dest, destMax, c);
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/output.inl b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/output.inl
new file mode 100644
index 000000000..440711b1d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/output.inl
@@ -0,0 +1,1951 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Used by secureprintoutput_a.c and secureprintoutput_w.c to include.
+ * This file provides a template function for ANSI and UNICODE compiling
+ * by different type definition. The functions of SecOutputS or
+ * SecOutputSW provides internal implementation for printf family API, such as sprintf, swprintf_s.
+ * Create: 2014-02-25
+ * Notes: see www.cplusplus.com/reference/cstdio/printf/
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Portability
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
+ * And sufficient input validation is performed before calling
+ */
+#ifndef OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5
+#define OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5
+
+#ifndef SECUREC_ENABLE_SPRINTF_LONG_DOUBLE
+/* Some compilers do not support long double */
+#define SECUREC_ENABLE_SPRINTF_LONG_DOUBLE 1
+#endif
+
+#define SECUREC_NULL_STRING_SIZE 8
+#define SECUREC_STATE_TABLE_SIZE 337
+
+#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)
+#define SECUREC_DIV_QUOTIENT_OCTAL(val64) ((val64) >> 3ULL)
+#define SECUREC_DIV_RESIDUE_OCTAL(val64) ((val64)&7ULL)
+
+#define SECUREC_DIV_QUOTIENT_HEX(val64) ((val64) >> 4ULL)
+#define SECUREC_DIV_RESIDUE_HEX(val64) ((val64)&0xfULL)
+#endif
+
+#define SECUREC_RADIX_OCTAL 8U
+#define SECUREC_RADIX_DECIMAL 10U
+#define SECUREC_RADIX_HEX 16U
+#define SECUREC_PREFIX_LEN 2
+/* Size include '+' and '\0' */
+#define SECUREC_FLOAT_BUF_EXT 2
+
+/* Sign extend or Zero-extend */
+#define SECUREC_GET_LONG_FROM_ARG(attr) \
+ ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \
+ (SecInt64)(long)va_arg(argList, long) : \
+ (SecInt64)(unsigned long)va_arg(argList, long))
+
+/* Sign extend or Zero-extend */
+#define SECUREC_GET_CHAR_FROM_ARG(attr) \
+ ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \
+ SecUpdateNegativeChar(&(attr), \
+ ((char)va_arg(argList, int))) : \
+ (SecInt64)(unsigned char)va_arg(argList, int))
+
+/* Sign extend or Zero-extend */
+#define SECUREC_GET_SHORT_FROM_ARG(attr) \
+ ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \
+ (SecInt64)(short)va_arg(argList, int) : \
+ (SecInt64)(unsigned short)va_arg(argList, int))
+
+/* Sign extend or Zero-extend */
+#define SECUREC_GET_INT_FROM_ARG(attr) \
+ ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \
+ (SecInt64)(int)va_arg(argList, int) : \
+ (SecInt64)(unsigned int)va_arg(argList, int))
+
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+/* Sign extend or Zero-extend. No suitable macros were found to handle the branch */
+#define SECUREC_GET_SIZE_FROM_ARG(attr) \
+ ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \
+ ((SecIsSameSize(sizeof(size_t), sizeof(long)) != 0) ? \
+ (SecInt64)(long)va_arg(argList, long) : \
+ ((SecIsSameSize(sizeof(size_t), \
+ sizeof(long long)) != 0) ? \
+ (SecInt64)(long long)va_arg(argList, \
+ long long) : \
+ (SecInt64)(int)va_arg(argList, int))) : \
+ (SecInt64)(size_t)va_arg(argList, size_t))
+#endif
+
+/* Format output buffer pointer and available size */
+typedef struct {
+ int count;
+ SecChar *cur;
+} SecPrintfStream;
+
+typedef union {
+ /* Integer formatting refers to the end of the buffer, plus 1 to prevent tool alarms */
+ char str[SECUREC_BUFFER_SIZE + 1];
+#if SECUREC_HAVE_WCHART
+ wchar_t wStr[SECUREC_WCHAR_BUFFER_SIZE]; /* Just for %lc */
+#endif
+} SecBuffer;
+
+typedef union {
+ char *str; /* Not a null terminated string */
+#if SECUREC_HAVE_WCHART
+ wchar_t *wStr;
+#endif
+} SecFormatBuf;
+
+typedef struct {
+ const char *digits; /* Point to the hexadecimal subset */
+ SecFormatBuf text; /* Point to formatted string */
+ int textLen; /* Length of the text */
+ int textIsWide; /* Flag for text is wide chars ; 0 is not wide char */
+ unsigned int radix; /* Use for output number , default set to 10 */
+ unsigned int flags;
+ int fldWidth;
+ int precision;
+ int dynWidth; /* %* 1 width from variable parameter ;0 not */
+ int dynPrecision; /* %.* 1 precision from variable parameter ;0 not */
+ int padding; /* Padding len */
+ int prefixLen; /* Length of prefix, 0 or 1 or 2 */
+ SecChar prefix[SECUREC_PREFIX_LEN]; /* Prefix is 0 or 0x */
+ SecBuffer buffer;
+} SecFormatAttr;
+
+#if SECUREC_ENABLE_SPRINTF_FLOAT
+#ifdef SECUREC_STACK_SIZE_LESS_THAN_1K
+#define SECUREC_FMT_STR_LEN 8
+#else
+#define SECUREC_FMT_STR_LEN 16
+#endif
+typedef struct {
+ char buffer[SECUREC_FMT_STR_LEN];
+ char *fmtStr; /* Initialization must point to buffer */
+ char *allocatedFmtStr; /* Initialization must be NULL to store allocated point */
+ char *floatBuffer; /* Use heap memory if the SecFormatAttr.buffer is not enough */
+ int bufferSize; /* The size of floatBuffer */
+} SecFloatAdapt;
+#endif
+
+/* Use 20 to Align the data */
+#define SECUREC_DIGITS_BUF_SIZE 20
+/* The serial number of 'x' or 'X' is 16 */
+#define SECUREC_NUMBER_OF_X 16
+/* Some systems can not use pointers to point to string literals, but can use string arrays. */
+/* For example, when handling code under uboot, there is a problem with the pointer */
+static const char g_itoaUpperDigits[SECUREC_DIGITS_BUF_SIZE] =
+ "0123456789ABCDEFX";
+static const char g_itoaLowerDigits[SECUREC_DIGITS_BUF_SIZE] =
+ "0123456789abcdefx";
+
+#if SECUREC_ENABLE_SPRINTF_FLOAT
+/* Call system sprintf to format float value */
+SECUREC_INLINE int SecFormatFloat(char *strDest, const char *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ SECUREC_MASK_VSPRINTF_WARNING
+ ret = vsprintf(strDest, format, argList);
+ SECUREC_END_MASK_VSPRINTF_WARNING
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
+
+#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && \
+ SECUREC_ENABLE_SPRINTF_LONG_DOUBLE
+/* Out put long double value to dest */
+SECUREC_INLINE void SecFormatLongDouble(SecFormatAttr *attr,
+ const SecFloatAdapt *floatAdapt,
+ long double ldValue)
+{
+ int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ?
+ (-attr->fldWidth) :
+ attr->fldWidth);
+ if (attr->dynWidth != 0 && attr->dynPrecision != 0) {
+ attr->textLen = SecFormatFloat(attr->text.str,
+ floatAdapt->fmtStr, fldWidth,
+ attr->precision, ldValue);
+ } else if (attr->dynWidth != 0) {
+ attr->textLen = SecFormatFloat(
+ attr->text.str, floatAdapt->fmtStr, fldWidth, ldValue);
+ } else if (attr->dynPrecision != 0) {
+ attr->textLen = SecFormatFloat(attr->text.str,
+ floatAdapt->fmtStr,
+ attr->precision, ldValue);
+ } else {
+ attr->textLen = SecFormatFloat(attr->text.str,
+ floatAdapt->fmtStr, ldValue);
+ }
+ if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) {
+ attr->textLen = 0;
+ }
+}
+#endif
+
+/* Out put double value to dest */
+SECUREC_INLINE void SecFormatDouble(SecFormatAttr *attr,
+ const SecFloatAdapt *floatAdapt,
+ double dValue)
+{
+ int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ?
+ (-attr->fldWidth) :
+ attr->fldWidth);
+ if (attr->dynWidth != 0 && attr->dynPrecision != 0) {
+ attr->textLen = SecFormatFloat(attr->text.str,
+ floatAdapt->fmtStr, fldWidth,
+ attr->precision, dValue);
+ } else if (attr->dynWidth != 0) {
+ attr->textLen = SecFormatFloat(
+ attr->text.str, floatAdapt->fmtStr, fldWidth, dValue);
+ } else if (attr->dynPrecision != 0) {
+ attr->textLen = SecFormatFloat(attr->text.str,
+ floatAdapt->fmtStr,
+ attr->precision, dValue);
+ } else {
+ attr->textLen = SecFormatFloat(attr->text.str,
+ floatAdapt->fmtStr, dValue);
+ }
+ if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) {
+ attr->textLen = 0;
+ }
+}
+#endif
+
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+/* To clear e506 warning */
+SECUREC_INLINE int SecIsSameSize(size_t sizeA, size_t sizeB)
+{
+ return (int)(sizeA == sizeB);
+}
+#endif
+
+#ifndef SECUREC_ON_64BITS
+/*
+ * Compiler Optimized Division 8.
+ * The text.str point to buffer end, must be Large enough
+ */
+SECUREC_INLINE void SecNumber32ToOctalString(SecUnsignedInt32 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt32 val32 = number;
+ do {
+ --attr->text.str;
+ /* Just use lowerDigits for 0 - 9 */
+ *(attr->text.str) =
+ g_itoaLowerDigits[val32 % SECUREC_RADIX_OCTAL];
+ val32 /= SECUREC_RADIX_OCTAL;
+ } while (val32 != 0);
+}
+
+#ifdef _AIX
+/*
+ * Compiler Optimized Division 10.
+ * The text.str point to buffer end, must be Large enough
+ */
+SECUREC_INLINE void SecNumber32ToDecString(SecUnsignedInt32 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt32 val32 = number;
+ do {
+ --attr->text.str;
+ /* Just use lowerDigits for 0 - 9 */
+ *(attr->text.str) =
+ g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL];
+ val32 /= SECUREC_RADIX_DECIMAL;
+ } while (val32 != 0);
+}
+#endif
+/*
+ * Compiler Optimized Division 16.
+ * The text.str point to buffer end, must be Large enough
+ */
+SECUREC_INLINE void SecNumber32ToHexString(SecUnsignedInt32 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt32 val32 = number;
+ do {
+ --attr->text.str;
+ *(attr->text.str) = attr->digits[val32 % SECUREC_RADIX_HEX];
+ val32 /= SECUREC_RADIX_HEX;
+ } while (val32 != 0);
+}
+
+#ifndef _AIX
+/* Use fast div 10 */
+SECUREC_INLINE void SecNumber32ToDecStringFast(SecUnsignedInt32 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt32 val32 = number;
+ do {
+ SecUnsignedInt32 quotient;
+ SecUnsignedInt32 remain;
+ --attr->text.str;
+ *(attr->text.str) =
+ g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL];
+ quotient =
+ (val32 >> 1U) + (val32 >> 2U); /* Fast div magic 2 */
+ quotient = quotient + (quotient >> 4U); /* Fast div magic 4 */
+ quotient = quotient + (quotient >> 8U); /* Fast div magic 8 */
+ quotient =
+ quotient + (quotient >> 16U); /* Fast div magic 16 */
+ quotient = quotient >> 3U; /* Fast div magic 3 */
+ remain = val32 - SECUREC_MUL_TEN(quotient);
+ val32 = (remain > 9U) ? (quotient + 1U) :
+ quotient; /* Fast div magic 9 */
+ } while (val32 != 0);
+}
+#endif
+
+SECUREC_INLINE void SecNumber32ToString(SecUnsignedInt32 number,
+ SecFormatAttr *attr)
+{
+ switch (attr->radix) {
+ case SECUREC_RADIX_HEX:
+ SecNumber32ToHexString(number, attr);
+ break;
+ case SECUREC_RADIX_OCTAL:
+ SecNumber32ToOctalString(number, attr);
+ break;
+ case SECUREC_RADIX_DECIMAL:
+#ifdef _AIX
+ /* The compiler will optimize div 10 */
+ SecNumber32ToDecString(number, attr);
+#else
+ SecNumber32ToDecStringFast(number, attr);
+#endif
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+}
+#endif
+
+#if defined(SECUREC_USE_SPECIAL_DIV64) || \
+ (defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS))
+/*
+ * This function just to clear warning, on sume vxworks compiler shift 32 bit make warnings
+ */
+SECUREC_INLINE SecUnsignedInt64 SecU64Shr32(SecUnsignedInt64 number)
+{
+ return (((number) >> 16U) >>
+ 16U); /* Two shifts of 16 bits to realize shifts of 32 bits */
+}
+/*
+ * Fast divide by 10 algorithm.
+ * Calculation divisor multiply 0xcccccccccccccccdULL, resultHi64 >> 3 as quotient
+ */
+SECUREC_INLINE void SecU64Div10(SecUnsignedInt64 divisor,
+ SecUnsignedInt64 *quotient,
+ SecUnsignedInt32 *residue)
+{
+ SecUnsignedInt64 mask =
+ 0xffffffffULL; /* Use 0xffffffffULL as 32 bit mask */
+ SecUnsignedInt64 magicHi =
+ 0xccccccccULL; /* Fast divide 10 magic numbers high 32bit 0xccccccccULL */
+ SecUnsignedInt64 magicLow =
+ 0xcccccccdULL; /* Fast divide 10 magic numbers low 32bit 0xcccccccdULL */
+ SecUnsignedInt64 divisorHi =
+ (SecUnsignedInt64)(SecU64Shr32(divisor)); /* High 32 bit use */
+ SecUnsignedInt64 divisorLow =
+ (SecUnsignedInt64)(divisor & mask); /* Low 32 bit mask */
+ SecUnsignedInt64 factorHi = divisorHi * magicHi;
+ SecUnsignedInt64 factorLow1 = divisorHi * magicLow;
+ SecUnsignedInt64 factorLow2 = divisorLow * magicHi;
+ SecUnsignedInt64 factorLow3 = divisorLow * magicLow;
+ SecUnsignedInt64 carry = (factorLow1 & mask) + (factorLow2 & mask) +
+ SecU64Shr32(factorLow3);
+ SecUnsignedInt64 resultHi64 = factorHi + SecU64Shr32(factorLow1) +
+ SecU64Shr32(factorLow2) +
+ SecU64Shr32(carry);
+
+ *quotient = resultHi64 >> 3U; /* Fast divide 10 magic numbers 3 */
+ *residue = (SecUnsignedInt32)(divisor -
+ ((*quotient) * 10)); /* Quotient mul 10 */
+ return;
+}
+#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)
+/*
+ * Divide function for VXWORKS
+ */
+SECUREC_INLINE int SecU64Div32(SecUnsignedInt64 divisor, SecUnsignedInt32 radix,
+ SecUnsignedInt64 *quotient,
+ SecUnsignedInt32 *residue)
+{
+ switch (radix) {
+ case SECUREC_RADIX_DECIMAL:
+ SecU64Div10(divisor, quotient, residue);
+ break;
+ case SECUREC_RADIX_HEX:
+ *quotient = SECUREC_DIV_QUOTIENT_HEX(divisor);
+ *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_HEX(divisor);
+ break;
+ case SECUREC_RADIX_OCTAL:
+ *quotient = SECUREC_DIV_QUOTIENT_OCTAL(divisor);
+ *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_OCTAL(divisor);
+ break;
+ default:
+ return -1; /* This does not happen in the current file */
+ }
+ return 0;
+}
+SECUREC_INLINE void SecNumber64ToStringSpecial(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt64 val64 = number;
+ do {
+ SecUnsignedInt32 digit = 0; /* Ascii value of digit */
+ SecUnsignedInt64 quotient = 0;
+ if (SecU64Div32(val64, (SecUnsignedInt32)attr->radix, "ient,
+ &digit) != 0) {
+ /* Just break, when enter this function, no error is returned */
+ break;
+ }
+ --attr->text.str;
+ *(attr->text.str) = attr->digits[digit];
+ val64 = quotient;
+ } while (val64 != 0);
+}
+#endif
+#endif
+
+#if defined(SECUREC_ON_64BITS) || !defined(SECUREC_VXWORKS_VERSION_5_4)
+#if defined(SECUREC_USE_SPECIAL_DIV64)
+/* The compiler does not provide 64 bit division problems */
+SECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt64 val64 = number;
+ do {
+ SecUnsignedInt64 quotient = 0;
+ SecUnsignedInt32 digit = 0;
+ SecU64Div10(val64, "ient, &digit);
+ --attr->text.str;
+ /* Just use lowerDigits for 0 - 9 */
+ *(attr->text.str) = g_itoaLowerDigits[digit];
+ val64 = quotient;
+ } while (val64 != 0);
+}
+#else
+/*
+ * Compiler Optimized Division 10.
+ * The text.str point to buffer end, must be Large enough
+ */
+SECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt64 val64 = number;
+ do {
+ --attr->text.str;
+ /* Just use lowerDigits for 0 - 9 */
+ *(attr->text.str) =
+ g_itoaLowerDigits[val64 % SECUREC_RADIX_DECIMAL];
+ val64 /= SECUREC_RADIX_DECIMAL;
+ } while (val64 != 0);
+}
+#endif
+
+/*
+ * Compiler Optimized Division 8.
+ * The text.str point to buffer end, must be Large enough
+ */
+SECUREC_INLINE void SecNumber64ToOctalString(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt64 val64 = number;
+ do {
+ --attr->text.str;
+ /* Just use lowerDigits for 0 - 9 */
+ *(attr->text.str) =
+ g_itoaLowerDigits[val64 % SECUREC_RADIX_OCTAL];
+ val64 /= SECUREC_RADIX_OCTAL;
+ } while (val64 != 0);
+}
+/*
+ * Compiler Optimized Division 16.
+ * The text.str point to buffer end, must be Large enough
+ */
+SECUREC_INLINE void SecNumber64ToHexString(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+ SecUnsignedInt64 val64 = number;
+ do {
+ --attr->text.str;
+ *(attr->text.str) = attr->digits[val64 % SECUREC_RADIX_HEX];
+ val64 /= SECUREC_RADIX_HEX;
+ } while (val64 != 0);
+}
+
+SECUREC_INLINE void SecNumber64ToString(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+ switch (attr->radix) {
+ /* The compiler will optimize div 10 */
+ case SECUREC_RADIX_DECIMAL:
+ SecNumber64ToDecString(number, attr);
+ break;
+ case SECUREC_RADIX_OCTAL:
+ SecNumber64ToOctalString(number, attr);
+ break;
+ case SECUREC_RADIX_HEX:
+ SecNumber64ToHexString(number, attr);
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+}
+#endif
+
+/*
+ * Converting integers to string
+ */
+SECUREC_INLINE void SecNumberToString(SecUnsignedInt64 number,
+ SecFormatAttr *attr)
+{
+#ifdef SECUREC_ON_64BITS
+ SecNumber64ToString(number, attr);
+#else /* For 32 bits system */
+ if (number <=
+ 0xffffffffUL) { /* Use 0xffffffffUL to check if the value is in the 32-bit range */
+ /* In most case, the value to be converted is small value */
+ SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number;
+ SecNumber32ToString(n32Tmp, attr);
+ } else {
+ /* The value to be converted is greater than 4G */
+#if defined(SECUREC_VXWORKS_VERSION_5_4)
+ SecNumber64ToStringSpecial(number, attr);
+#else
+ SecNumber64ToString(number, attr);
+#endif
+ }
+#endif
+}
+
+SECUREC_INLINE int SecIsNumberNeedTo32Bit(const SecFormatAttr *attr)
+{
+ return (int)(((attr->flags & SECUREC_FLAG_I64) == 0) &&
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+ ((attr->flags & SECUREC_FLAG_INTMAX) == 0) &&
+#endif
+#ifdef SECUREC_ON_64BITS
+ ((attr->flags & SECUREC_FLAG_PTRDIFF) == 0) &&
+ ((attr->flags & SECUREC_FLAG_SIZE) == 0) &&
+#if !defined( \
+ SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */
+ ((attr->flags & SECUREC_FLAG_LONG) == 0) &&
+#endif
+#endif
+ ((attr->flags & SECUREC_FLAG_LONGLONG) == 0));
+}
+
+SECUREC_INLINE void SecNumberToBuffer(SecFormatAttr *attr, SecInt64 num64)
+{
+ SecUnsignedInt64 number;
+ /* Check for negative; copy into number */
+ if ((attr->flags & SECUREC_FLAG_SIGNED) != 0 && num64 < 0) {
+ number =
+ (SecUnsignedInt64)(0 -
+ (SecUnsignedInt64)
+ num64); /* Wrap with unsigned int64 numbers */
+ attr->flags |= SECUREC_FLAG_NEGATIVE;
+ } else {
+ number = (SecUnsignedInt64)num64;
+ }
+ if (SecIsNumberNeedTo32Bit(attr) != 0) {
+ number =
+ (number &
+ (SecUnsignedInt64)0xffffffffUL); /* Use 0xffffffff as 32 bit mask */
+ }
+
+ /* The text.str must be point to buffer.str, this pointer is used outside the function */
+ attr->text.str = &attr->buffer.str[SECUREC_BUFFER_SIZE];
+
+ if (number == 0) {
+ /* Turn off hex prefix default, and textLen is zero */
+ attr->prefixLen = 0;
+ attr->textLen = 0;
+ return;
+ }
+
+ /* Convert integer to string. It must be invoked when number > 0, otherwise the following logic is incorrect */
+ SecNumberToString(number, attr);
+ /* Compute length of number, text.str must be in buffer.str */
+ attr->textLen =
+ (int)(size_t)((char *)&attr->buffer.str[SECUREC_BUFFER_SIZE] -
+ attr->text.str);
+}
+
+/*
+ * Write one character to dest buffer
+ */
+SECUREC_INLINE void SecWriteChar(SecPrintfStream *stream, SecChar ch,
+ int *charsOut)
+{
+ /* Count must be reduced first, In order to identify insufficient length */
+ --stream->count;
+ if (stream->count >= 0) {
+ *(stream->cur) = ch;
+ ++stream->cur;
+ *charsOut = *charsOut + 1;
+ return;
+ }
+ /* No enough length */
+ *charsOut = -1;
+}
+
+/*
+* Write multiple identical characters.
+*/
+SECUREC_INLINE void SecWriteMultiChar(SecPrintfStream *stream, SecChar ch,
+ int num, int *charsOut)
+{
+ int count;
+ for (count = num; count > 0; --count) {
+ --stream->count; /* count may be negative,indicating insufficient space */
+ if (stream->count < 0) {
+ *charsOut = -1;
+ return;
+ }
+ *(stream->cur) = ch;
+ ++stream->cur;
+ }
+ *charsOut = *charsOut + num;
+}
+
+/*
+* Write string function, where this function is called, make sure that len is greater than 0
+*/
+SECUREC_INLINE void SecWriteString(SecPrintfStream *stream, const SecChar *str,
+ int len, int *charsOut)
+{
+ const SecChar *tmp = str;
+ int count;
+ for (count = len; count > 0; --count) {
+ --stream->count; /* count may be negative,indicating insufficient space */
+ if (stream->count < 0) {
+ *charsOut = -1;
+ return;
+ }
+ *(stream->cur) = *tmp;
+ ++stream->cur;
+ ++tmp;
+ }
+ *charsOut = *charsOut + len;
+}
+
+/* Use loop copy char or wchar_t string */
+SECUREC_INLINE void SecWriteStringByLoop(SecPrintfStream *stream,
+ const SecChar *str, int len)
+{
+ int i;
+ const SecChar *tmp = str;
+ for (i = 0; i < len; ++i) {
+ *stream->cur = *tmp;
+ ++stream->cur;
+ ++tmp;
+ }
+ stream->count -= len;
+}
+
+SECUREC_INLINE void SecWriteStringOpt(SecPrintfStream *stream,
+ const SecChar *str, int len)
+{
+ if (len <
+ 12) { /* Performance optimization for mobile number length 12 */
+ SecWriteStringByLoop(stream, str, len);
+ } else {
+ size_t count = (size_t)(unsigned int)len * sizeof(SecChar);
+ SECUREC_MEMCPY_WARP_OPT(stream->cur, str, count);
+ stream->cur += len;
+ stream->count -= len;
+ }
+}
+
+/*
+ * Return if buffer length is enough
+ * The count variable can be reduced to 0, and the external function complements the \0 terminator.
+ */
+SECUREC_INLINE int SecIsStreamBufEnough(const SecPrintfStream *stream,
+ int needLen)
+{
+ return (int)(stream->count >= needLen);
+}
+
+/* Write text string */
+SECUREC_INLINE void SecWriteTextOpt(SecPrintfStream *stream, const SecChar *str,
+ int len, int *charsOut)
+{
+ if (SecIsStreamBufEnough(stream, len) != 0) {
+ SecWriteStringOpt(stream, str, len);
+ *charsOut += len;
+ } else {
+ SecWriteString(stream, str, len, charsOut);
+ }
+}
+
+/* Write left padding */
+SECUREC_INLINE void SecWriteLeftPadding(SecPrintfStream *stream,
+ const SecFormatAttr *attr,
+ int *charsOut)
+{
+ if ((attr->flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) == 0 &&
+ attr->padding > 0) {
+ /* Pad on left with blanks */
+ SecWriteMultiChar(stream, SECUREC_CHAR(' '), attr->padding,
+ charsOut);
+ }
+}
+
+/* Write prefix */
+SECUREC_INLINE void SecWritePrefix(SecPrintfStream *stream,
+ const SecFormatAttr *attr, int *charsOut)
+{
+ if (attr->prefixLen > 0) {
+ SecWriteString(stream, attr->prefix, attr->prefixLen, charsOut);
+ }
+}
+
+/* Write leading zeros */
+SECUREC_INLINE void SecWriteLeadingZero(SecPrintfStream *stream,
+ const SecFormatAttr *attr,
+ int *charsOut)
+{
+ if ((attr->flags & SECUREC_FLAG_LEADZERO) != 0 &&
+ (attr->flags & SECUREC_FLAG_LEFT) == 0 && attr->padding > 0) {
+ SecWriteMultiChar(stream, SECUREC_CHAR('0'), attr->padding,
+ charsOut);
+ }
+}
+
+/* Write right padding */
+SECUREC_INLINE void SecWriteRightPadding(SecPrintfStream *stream,
+ const SecFormatAttr *attr,
+ int *charsOut)
+{
+ if (*charsOut >= 0 && (attr->flags & SECUREC_FLAG_LEFT) != 0 &&
+ attr->padding > 0) {
+ /* Pad on right with blanks */
+ SecWriteMultiChar(stream, SECUREC_CHAR(' '), attr->padding,
+ charsOut);
+ }
+}
+
+#ifdef SECUREC_FOR_WCHAR
+#define SECUREC_TEXT_CHAR_PTR(text) ((text).wStr)
+#define SECUREC_NEED_CONVERT_TEXT(attr) ((attr)->textIsWide == 0)
+#if SECUREC_HAVE_MBTOWC
+#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) \
+ SecWriteTextAfterMbtowc((stream), (attr), (charsOut))
+#else
+#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) \
+ (*(charsOut) = -1)
+#endif
+#else
+#define SECUREC_TEXT_CHAR_PTR(text) ((text).str)
+#define SECUREC_NEED_CONVERT_TEXT(attr) ((attr)->textIsWide != 0)
+#if SECUREC_HAVE_WCTOMB
+#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) \
+ SecWriteTextAfterWctomb((stream), (attr), (charsOut))
+#else
+#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) \
+ (*(charsOut) = -1)
+#endif
+#endif
+
+#ifdef SECUREC_FOR_WCHAR
+#if SECUREC_HAVE_MBTOWC
+SECUREC_INLINE void SecWriteTextAfterMbtowc(SecPrintfStream *stream,
+ const SecFormatAttr *attr,
+ int *charsOut)
+{
+ const char *p = attr->text.str;
+ int count = attr->textLen;
+ while (count > 0) {
+ wchar_t wChar = L'\0';
+ int retVal = mbtowc(&wChar, p, (size_t)MB_CUR_MAX);
+ if (retVal <= 0) {
+ *charsOut = -1;
+ break;
+ }
+ SecWriteChar(stream, wChar, charsOut);
+ if (*charsOut == -1) {
+ break;
+ }
+ p += retVal;
+ count -= retVal;
+ }
+}
+#endif
+#else /* Not SECUREC_FOR_WCHAR */
+#if SECUREC_HAVE_WCTOMB
+SECUREC_INLINE void SecWriteTextAfterWctomb(SecPrintfStream *stream,
+ const SecFormatAttr *attr,
+ int *charsOut)
+{
+ const wchar_t *p = attr->text.wStr;
+ int count = attr->textLen;
+ while (count > 0) {
+ char tmpBuf[SECUREC_MB_LEN + 1];
+ SECUREC_MASK_MSVC_CRT_WARNING
+ int retVal = wctomb(tmpBuf, *p);
+ SECUREC_END_MASK_MSVC_CRT_WARNING
+ if (retVal <= 0) {
+ *charsOut = -1;
+ break;
+ }
+ SecWriteString(stream, tmpBuf, retVal, charsOut);
+ if (*charsOut == -1) {
+ break;
+ }
+ --count;
+ ++p;
+ }
+}
+#endif
+#endif
+
+#if SECUREC_ENABLE_SPRINTF_FLOAT
+/*
+ * Write text of float
+ * Using independent functions to optimize the expansion of inline functions by the compiler
+ */
+SECUREC_INLINE void SecWriteFloatText(SecPrintfStream *stream,
+ const SecFormatAttr *attr, int *charsOut)
+{
+#ifdef SECUREC_FOR_WCHAR
+#if SECUREC_HAVE_MBTOWC
+ SecWriteTextAfterMbtowc(stream, attr, charsOut);
+#else
+ *charsOut = -1;
+ (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+ (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+#endif
+#else /* Not SECUREC_FOR_WCHAR */
+ SecWriteString(stream, attr->text.str, attr->textLen, charsOut);
+#endif
+}
+#endif
+
+/* Write text of integer or string ... */
+SECUREC_INLINE void SecWriteText(SecPrintfStream *stream,
+ const SecFormatAttr *attr, int *charsOut)
+{
+ if (SECUREC_NEED_CONVERT_TEXT(attr)) {
+ SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut);
+ } else {
+ SecWriteTextOpt(stream, SECUREC_TEXT_CHAR_PTR(attr->text),
+ attr->textLen, charsOut);
+ }
+}
+
+#define SECUREC_FMT_STATE_OFFSET 256
+
+SECUREC_INLINE SecFmtState SecDecodeState(SecChar ch, SecFmtState lastState)
+{
+ static const unsigned char stateTable[SECUREC_STATE_TABLE_SIZE] = {
+ /*
+ * Type
+ * 0: nospecial meaning;
+ * 1: '%'
+ * 2: '.'
+ * 3: '*'
+ * 4: '0'
+ * 5: '1' ... '9'
+ * 6: ' ', '+', '-', '#'
+ * 7: 'h', 'l', 'L', 'w' , 'N', 'z', 'q', 't', 'j'
+ * 8: 'd', 'o', 'u', 'i', 'x', 'X', 'e', 'f', 'g', 'E', 'F', 'G', 's', 'c', '[', 'p'
+ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00, 0x04, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08,
+ 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00,
+ 0x00, 0x08, 0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07,
+ 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Fill zero for normal char 128 byte for 0x80 - 0xff */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*
+ * State
+ * 0: normal
+ * 1: percent
+ * 2: flag
+ * 3: width
+ * 4: dot
+ * 5: precis
+ * 6: size
+ * 7: type
+ * 8: invalid
+ */
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01,
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x01, 0x00, 0x00, 0x04,
+ 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x08, 0x05, 0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03,
+ 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x05,
+ 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00
+ };
+
+#ifdef SECUREC_FOR_WCHAR
+ /* Convert to unsigned char to clear gcc 4.3.4 warning */
+ unsigned char fmtType =
+ (unsigned char)((((unsigned int)(int)(ch)) <=
+ (unsigned int)(int)(L'~')) ?
+ (stateTable[(unsigned char)(ch)]) :
+ 0);
+ return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID +
+ 1) +
+ (unsigned char)(lastState) +
+ SECUREC_FMT_STATE_OFFSET]);
+#else
+ unsigned char fmtType = stateTable[(unsigned char)(ch)];
+ return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID +
+ 1) +
+ (unsigned char)(lastState) +
+ SECUREC_FMT_STATE_OFFSET]);
+#endif
+}
+
+SECUREC_INLINE void SecDecodeFlags(SecChar ch, SecFormatAttr *attr)
+{
+ switch (ch) {
+ case SECUREC_CHAR(' '):
+ attr->flags |= SECUREC_FLAG_SIGN_SPACE;
+ break;
+ case SECUREC_CHAR('+'):
+ attr->flags |= SECUREC_FLAG_SIGN;
+ break;
+ case SECUREC_CHAR('-'):
+ attr->flags |= SECUREC_FLAG_LEFT;
+ break;
+ case SECUREC_CHAR('0'):
+ attr->flags |=
+ SECUREC_FLAG_LEADZERO; /* Add zero th the front */
+ break;
+ case SECUREC_CHAR('#'):
+ attr->flags |= SECUREC_FLAG_ALTERNATE; /* Output %x with 0x */
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ return;
+}
+
+/*
+ * Decoded size identifier in format string to Reduce the number of lines of function code
+ */
+SECUREC_INLINE int SecDecodeSizeI(SecFormatAttr *attr, const SecChar **format)
+{
+#ifdef SECUREC_ON_64BITS
+ attr->flags |= SECUREC_FLAG_I64; /* %I to INT64 */
+#endif
+ if ((**format == SECUREC_CHAR('6')) &&
+ (*((*format) + 1) == SECUREC_CHAR('4'))) {
+ (*format) += 2; /* Add 2 to skip I64 */
+ attr->flags |= SECUREC_FLAG_I64; /* %I64 to INT64 */
+ } else if ((**format == SECUREC_CHAR('3')) &&
+ (*((*format) + 1) == SECUREC_CHAR('2'))) {
+ (*format) += 2; /* Add 2 to skip I32 */
+ attr->flags &= ~SECUREC_FLAG_I64; /* %I64 to INT32 */
+ } else if ((**format == SECUREC_CHAR('d')) ||
+ (**format == SECUREC_CHAR('i')) ||
+ (**format == SECUREC_CHAR('o')) ||
+ (**format == SECUREC_CHAR('u')) ||
+ (**format == SECUREC_CHAR('x')) ||
+ (**format == SECUREC_CHAR('X'))) {
+ /* Do nothing */
+ } else {
+ /* Compatibility code for "%I" just print I */
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Decoded size identifier in format string, and skip format to next charater
+ */
+SECUREC_INLINE int SecDecodeSize(SecChar ch, SecFormatAttr *attr,
+ const SecChar **format)
+{
+ switch (ch) {
+ case SECUREC_CHAR('l'):
+ if (**format == SECUREC_CHAR('l')) {
+ *format = *format + 1;
+ attr->flags |=
+ SECUREC_FLAG_LONGLONG; /* For long long */
+ } else {
+ attr->flags |=
+ SECUREC_FLAG_LONG; /* For long int or wchar_t */
+ }
+ break;
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+ case SECUREC_CHAR('z'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('Z'):
+ attr->flags |= SECUREC_FLAG_SIZE;
+ break;
+ case SECUREC_CHAR('j'):
+ attr->flags |= SECUREC_FLAG_INTMAX;
+ break;
+#endif
+ case SECUREC_CHAR('t'):
+ attr->flags |= SECUREC_FLAG_PTRDIFF;
+ break;
+ case SECUREC_CHAR('q'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('L'):
+ attr->flags |=
+ (SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE);
+ break;
+ case SECUREC_CHAR('I'):
+ if (SecDecodeSizeI(attr, format) != 0) {
+ /* Compatibility code for "%I" just print I */
+ return -1;
+ }
+ break;
+ case SECUREC_CHAR('h'):
+ if (**format == SECUREC_CHAR('h')) {
+ *format = *format + 1;
+ attr->flags |= SECUREC_FLAG_CHAR; /* For char */
+ } else {
+ attr->flags |= SECUREC_FLAG_SHORT; /* For short int */
+ }
+ break;
+ case SECUREC_CHAR('w'):
+ attr->flags |= SECUREC_FLAG_WIDECHAR; /* For wide char */
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Decoded char type identifier
+ */
+SECUREC_INLINE void SecDecodeTypeC(SecFormatAttr *attr, unsigned int c)
+{
+ attr->textLen = 1; /* Only 1 wide character */
+
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && \
+ !(defined(SECUREC_ON_SOLARIS))
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+#endif
+
+#ifdef SECUREC_FOR_WCHAR
+ if ((attr->flags & SECUREC_FLAG_SHORT) != 0) {
+ /* Get multibyte character from argument */
+ attr->buffer.str[0] = (char)c;
+ attr->text.str = attr->buffer.str;
+ attr->textIsWide = 0;
+ } else {
+ attr->buffer.wStr[0] = (wchar_t)c;
+ attr->text.wStr = attr->buffer.wStr;
+ attr->textIsWide = 1;
+ }
+#else /* Not SECUREC_FOR_WCHAR */
+ if ((attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) != 0) {
+#if SECUREC_HAVE_WCHART
+ attr->buffer.wStr[0] = (wchar_t)c;
+ attr->text.wStr = attr->buffer.wStr;
+ attr->textIsWide = 1;
+#else
+ attr->textLen = 0; /* Ignore unsupported characters */
+ attr->fldWidth = 0; /* No paddings */
+#endif
+ } else {
+ /* Get multibyte character from argument */
+ attr->buffer.str[0] = (char)c;
+ attr->text.str = attr->buffer.str;
+ attr->textIsWide = 0;
+ }
+#endif
+}
+
+#ifdef SECUREC_FOR_WCHAR
+#define SECUREC_IS_NARROW_STRING(attr) \
+ (((attr)->flags & SECUREC_FLAG_SHORT) != 0)
+#else
+#define SECUREC_IS_NARROW_STRING(attr) \
+ (((attr)->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) == 0)
+#endif
+
+SECUREC_INLINE void SecDecodeTypeSchar(SecFormatAttr *attr)
+{
+ size_t textLen;
+ if (attr->text.str == NULL) {
+ /*
+ * Literal string to print null ptr, define it as array rather than const text area
+ * To avoid gcc warning with pointing const text with variable
+ */
+ static char strNullString[SECUREC_NULL_STRING_SIZE] = "(null)";
+ attr->text.str = strNullString;
+ }
+ if (attr->precision == -1) {
+ /* Precision NOT assigned */
+ /* The strlen performance is high when the string length is greater than 32 */
+ textLen = strlen(attr->text.str);
+ if (textLen > SECUREC_STRING_MAX_LEN) {
+ textLen = 0;
+ }
+ } else {
+ /* Precision assigned */
+ SECUREC_CALC_STR_LEN(attr->text.str,
+ (size_t)(unsigned int)attr->precision,
+ &textLen);
+ }
+ attr->textLen = (int)textLen;
+}
+
+SECUREC_INLINE void SecDecodeTypeSwchar(SecFormatAttr *attr)
+{
+#if SECUREC_HAVE_WCHART
+ size_t textLen;
+ attr->textIsWide = 1;
+ if (attr->text.wStr == NULL) {
+ /*
+ * Literal string to print null ptr, define it as array rather than const text area
+ * To avoid gcc warning with pointing const text with variable
+ */
+ static wchar_t wStrNullString[SECUREC_NULL_STRING_SIZE] = {
+ L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0'
+ };
+ attr->text.wStr = wStrNullString;
+ }
+ /* The textLen in wchar_t,when precision is -1, it is unlimited */
+ SECUREC_CALC_WSTR_LEN(attr->text.wStr,
+ (size_t)(unsigned int)attr->precision, &textLen);
+ if (textLen > SECUREC_WCHAR_STRING_MAX_LEN) {
+ textLen = 0;
+ }
+ attr->textLen = (int)textLen;
+#else
+ attr->textLen = 0;
+#endif
+}
+
+/*
+ * Decoded string identifier
+ */
+SECUREC_INLINE void SecDecodeTypeS(SecFormatAttr *attr, char *argPtr)
+{
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT))
+#if (!defined(SECUREC_ON_UNIX))
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+#endif
+#if (defined(SECUREC_FOR_WCHAR))
+ if ((attr->flags & SECUREC_FLAG_LONG) == 0) {
+ attr->flags |= SECUREC_FLAG_SHORT;
+ }
+#endif
+#endif
+ attr->text.str = argPtr;
+ if (SECUREC_IS_NARROW_STRING(attr)) {
+ /* The textLen now contains length in multibyte chars */
+ SecDecodeTypeSchar(attr);
+ } else {
+ /* The textLen now contains length in wide chars */
+ SecDecodeTypeSwchar(attr);
+ }
+}
+
+/*
+ * Check precision in format
+ */
+SECUREC_INLINE int SecDecodePrecision(SecChar ch, SecFormatAttr *attr)
+{
+ if (attr->dynPrecision == 0) {
+ /* Add digit to current precision */
+ if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->precision)) {
+ return -1;
+ }
+ attr->precision =
+ (int)SECUREC_MUL_TEN((unsigned int)attr->precision) +
+ (unsigned char)(ch - SECUREC_CHAR('0'));
+ } else {
+ if (attr->precision < 0) {
+ attr->precision = -1;
+ }
+ if (attr->precision > SECUREC_MAX_WIDTH_LEN) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Check width in format
+ */
+SECUREC_INLINE int SecDecodeWidth(SecChar ch, SecFormatAttr *attr,
+ SecFmtState lastState)
+{
+ if (attr->dynWidth == 0) {
+ if (lastState != STAT_WIDTH) {
+ attr->fldWidth = 0;
+ }
+ if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->fldWidth)) {
+ return -1;
+ }
+ attr->fldWidth =
+ (int)SECUREC_MUL_TEN((unsigned int)attr->fldWidth) +
+ (unsigned char)(ch - SECUREC_CHAR('0'));
+ } else {
+ if (attr->fldWidth < 0) {
+ attr->flags |= SECUREC_FLAG_LEFT;
+ attr->fldWidth = (-attr->fldWidth);
+ }
+ if (attr->fldWidth > SECUREC_MAX_WIDTH_LEN) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * The sprintf_s function processes the wide character as a parameter for %C
+ * The swprintf_s function processes the multiple character as a parameter for %C
+ */
+SECUREC_INLINE void SecUpdateWcharFlags(SecFormatAttr *attr)
+{
+ if ((attr->flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG |
+ SECUREC_FLAG_WIDECHAR)) == 0) {
+#ifdef SECUREC_FOR_WCHAR
+ attr->flags |= SECUREC_FLAG_SHORT;
+#else
+ attr->flags |= SECUREC_FLAG_WIDECHAR;
+#endif
+ }
+}
+/*
+ * When encountering %S, current just same as %C
+ */
+SECUREC_INLINE void SecUpdateWstringFlags(SecFormatAttr *attr)
+{
+ SecUpdateWcharFlags(attr);
+}
+
+#if SECUREC_IN_KERNEL
+SECUREC_INLINE void SecUpdatePointFlagsForKernel(SecFormatAttr *attr)
+{
+ /* Width is not set */
+ if (attr->fldWidth <= 0) {
+ attr->flags |= SECUREC_FLAG_LEADZERO;
+ attr->fldWidth =
+ 2 *
+ sizeof(void *); /* 2 x byte number is the length of hex */
+ }
+ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {
+ /* Alternate form means '0x' prefix */
+ attr->prefix[0] = SECUREC_CHAR('0');
+ attr->prefix[1] = SECUREC_CHAR('x');
+ attr->prefixLen = SECUREC_PREFIX_LEN;
+ }
+ attr->flags |= SECUREC_FLAG_LONG; /* Converting a long */
+}
+#endif
+
+SECUREC_INLINE void SecUpdatePointFlags(SecFormatAttr *attr)
+{
+ attr->flags |= SECUREC_FLAG_POINTER;
+#if SECUREC_IN_KERNEL
+ SecUpdatePointFlagsForKernel(attr);
+#else
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || \
+ defined(SECUREC_VXWORKS_PLATFORM)) && \
+ (!defined(SECUREC_ON_UNIX))
+#if defined(SECUREC_VXWORKS_PLATFORM)
+ attr->precision = 1;
+#else
+ attr->precision = 0;
+#endif
+ attr->flags |=
+ SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */
+ attr->digits = g_itoaLowerDigits;
+#else /* On unix or win */
+#if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
+ attr->precision = 1;
+#else
+ attr->precision =
+ 2 * sizeof(void *); /* 2 x byte number is the length of hex */
+#endif
+#if defined(SECUREC_ON_UNIX)
+ attr->digits = g_itoaLowerDigits;
+#else
+ attr->digits = g_itoaUpperDigits;
+#endif
+#endif
+
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+#endif
+
+#ifdef SECUREC_ON_64BITS
+ attr->flags |= SECUREC_FLAG_I64; /* Converting an int64 */
+#else
+ attr->flags |= SECUREC_FLAG_LONG; /* Converting a long */
+#endif
+ /* Set up for %#p on different system */
+ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {
+ /* Alternate form means '0x' prefix */
+ attr->prefix[0] = SECUREC_CHAR('0');
+#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || \
+ defined(SECUREC_VXWORKS_PLATFORM))
+ attr->prefix[1] = SECUREC_CHAR('x');
+#else
+ attr->prefix[1] = (SecChar)(attr->digits[SECUREC_NUMBER_OF_X]);
+#endif
+#if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
+ attr->prefixLen = 0;
+#else
+ attr->prefixLen = SECUREC_PREFIX_LEN;
+#endif
+ }
+#endif
+}
+
+SECUREC_INLINE void SecUpdateXpxFlags(SecFormatAttr *attr, SecChar ch)
+{
+ /* Use unsigned lower hex output for 'x' */
+ attr->digits = g_itoaLowerDigits;
+ attr->radix = SECUREC_RADIX_HEX;
+ switch (ch) {
+ case SECUREC_CHAR('p'):
+ /* Print a pointer */
+ SecUpdatePointFlags(attr);
+ break;
+ case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */
+ /* Unsigned upper hex output */
+ attr->digits = g_itoaUpperDigits;
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ default:
+ /* For %#x or %#X */
+ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {
+ /* Alternate form means '0x' prefix */
+ attr->prefix[0] = SECUREC_CHAR('0');
+ attr->prefix[1] =
+ (SecChar)(attr->digits[SECUREC_NUMBER_OF_X]);
+ attr->prefixLen = SECUREC_PREFIX_LEN;
+ }
+ break;
+ }
+}
+
+SECUREC_INLINE void SecUpdateOudiFlags(SecFormatAttr *attr, SecChar ch)
+{
+ /* Do not set digits here */
+ switch (ch) {
+ case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */
+ /* For signed decimal output */
+ attr->flags |= SECUREC_FLAG_SIGNED;
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('u'):
+ attr->radix = SECUREC_RADIX_DECIMAL;
+ attr->digits = g_itoaLowerDigits;
+ break;
+ case SECUREC_CHAR('o'):
+ /* For unsigned octal output */
+ attr->radix = SECUREC_RADIX_OCTAL;
+ attr->digits = g_itoaLowerDigits;
+ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {
+ /* Alternate form means force a leading 0 */
+ attr->flags |= SECUREC_FLAG_FORCE_OCTAL;
+ }
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+}
+
+#if SECUREC_ENABLE_SPRINTF_FLOAT
+SECUREC_INLINE void SecFreeFloatBuffer(SecFloatAdapt *floatAdapt)
+{
+ if (floatAdapt->floatBuffer != NULL) {
+ SECUREC_FREE(floatAdapt->floatBuffer);
+ }
+ if (floatAdapt->allocatedFmtStr != NULL) {
+ SECUREC_FREE(floatAdapt->allocatedFmtStr);
+ }
+ floatAdapt->floatBuffer = NULL;
+ floatAdapt->allocatedFmtStr = NULL;
+ floatAdapt->fmtStr = NULL;
+ floatAdapt->bufferSize = 0;
+}
+
+SECUREC_INLINE void SecSeekToFrontPercent(const SecChar **format)
+{
+ const SecChar *fmt = *format;
+ while (*fmt != SECUREC_CHAR('%')) { /* Must meet '%' */
+ --fmt;
+ }
+ *format = fmt;
+}
+
+/* Init float format, return 0 is OK */
+SECUREC_INLINE int SecInitFloatFmt(SecFloatAdapt *floatFmt,
+ const SecChar *format)
+{
+ const SecChar *fmt =
+ format - 2; /* Sub 2 to the position before 'f' or 'g' */
+ int fmtStrLen;
+ int i;
+
+ SecSeekToFrontPercent(&fmt);
+ /* Now fmt point to '%' */
+ fmtStrLen =
+ (int)(size_t)(format - fmt) + 1; /* With ending terminator */
+ if (fmtStrLen > (int)sizeof(floatFmt->buffer)) {
+ /* When buffer is NOT enough, alloc a new buffer */
+ floatFmt->allocatedFmtStr = (char *)SECUREC_MALLOC(
+ (size_t)((unsigned int)fmtStrLen));
+ if (floatFmt->allocatedFmtStr == NULL) {
+ return -1;
+ }
+ floatFmt->fmtStr = floatFmt->allocatedFmtStr;
+ } else {
+ floatFmt->fmtStr = floatFmt->buffer;
+ floatFmt->allocatedFmtStr =
+ NULL; /* Must set to NULL, later code free memory based on this identity */
+ }
+
+ for (i = 0; i < fmtStrLen - 1; ++i) {
+ /* Convert wchar to char */
+ floatFmt->fmtStr[i] =
+ (char)(fmt[i]); /* Copy the format string */
+ }
+ floatFmt->fmtStr[fmtStrLen - 1] = '\0';
+
+ return 0;
+}
+
+/* Init float buffer and format, return 0 is OK */
+SECUREC_INLINE int SecInitFloatBuffer(SecFloatAdapt *floatAdapt,
+ const SecChar *format,
+ SecFormatAttr *attr)
+{
+ floatAdapt->allocatedFmtStr = NULL;
+ floatAdapt->fmtStr = NULL;
+ floatAdapt->floatBuffer = NULL;
+ /* Compute the precision value */
+ if (attr->precision < 0) {
+ attr->precision = SECUREC_FLOAT_DEFAULT_PRECISION;
+ }
+ /*
+ * Calc buffer size to store double value
+ * The maximum length of SECUREC_MAX_WIDTH_LEN is enough
+ */
+ if ((attr->flags & SECUREC_FLAG_LONG_DOUBLE) != 0) {
+ if (attr->precision >
+ (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE_LB)) {
+ return -1;
+ }
+ /* Long double needs to meet the basic print length */
+ floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE_LB +
+ attr->precision +
+ SECUREC_FLOAT_BUF_EXT;
+ } else {
+ if (attr->precision >
+ (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE)) {
+ return -1;
+ }
+ /* Double needs to meet the basic print length */
+ floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE +
+ attr->precision +
+ SECUREC_FLOAT_BUF_EXT;
+ }
+ if (attr->fldWidth > floatAdapt->bufferSize) {
+ floatAdapt->bufferSize = attr->fldWidth + SECUREC_FLOAT_BUF_EXT;
+ }
+
+ if (floatAdapt->bufferSize > SECUREC_BUFFER_SIZE) {
+ /* The current value of SECUREC_BUFFER_SIZE could not store the formatted float string */
+ floatAdapt->floatBuffer = (char *)SECUREC_MALLOC(
+ ((size_t)(unsigned int)floatAdapt->bufferSize));
+ if (floatAdapt->floatBuffer == NULL) {
+ return -1;
+ }
+ attr->text.str = floatAdapt->floatBuffer;
+ } else {
+ attr->text.str =
+ attr->buffer
+ .str; /* Output buffer for float string with default size */
+ }
+
+ if (SecInitFloatFmt(floatAdapt, format) != 0) {
+ if (floatAdapt->floatBuffer != NULL) {
+ SECUREC_FREE(floatAdapt->floatBuffer);
+ floatAdapt->floatBuffer = NULL;
+ }
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+SECUREC_INLINE SecInt64 SecUpdateNegativeChar(SecFormatAttr *attr, char ch)
+{
+ SecInt64 num64 = ch; /* Sign extend */
+ if (num64 >= 128) { /* 128 on some platform, char is always unsigned */
+ unsigned char tmp = (unsigned char)(~((unsigned char)ch));
+ num64 = tmp + 1;
+ attr->flags |= SECUREC_FLAG_NEGATIVE;
+ }
+ return num64;
+}
+
+/*
+ * If the precision is not satisfied, zero is added before the string
+ */
+SECUREC_INLINE void SecNumberSatisfyPrecision(SecFormatAttr *attr)
+{
+ int precision;
+ if (attr->precision < 0) {
+ precision = 1; /* Default precision 1 */
+ } else {
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+#else
+ if ((attr->flags & SECUREC_FLAG_POINTER) == 0) {
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+ }
+#endif
+ if (attr->precision > SECUREC_MAX_PRECISION) {
+ attr->precision = SECUREC_MAX_PRECISION;
+ }
+ precision = attr->precision;
+ }
+ while (attr->textLen < precision) {
+ --attr->text.str;
+ *(attr->text.str) = '0';
+ ++attr->textLen;
+ }
+}
+
+/*
+ * Add leading zero for %#o
+ */
+SECUREC_INLINE void SecNumberForceOctal(SecFormatAttr *attr)
+{
+ /* Force a leading zero if FORCEOCTAL flag set */
+ if ((attr->flags & SECUREC_FLAG_FORCE_OCTAL) != 0 &&
+ (attr->textLen == 0 || attr->text.str[0] != '0')) {
+ --attr->text.str;
+ *(attr->text.str) = '0';
+ ++attr->textLen;
+ }
+}
+
+SECUREC_INLINE void SecUpdateSignedNumberPrefix(SecFormatAttr *attr)
+{
+ if ((attr->flags & SECUREC_FLAG_SIGNED) == 0) {
+ return;
+ }
+ if ((attr->flags & SECUREC_FLAG_NEGATIVE) != 0) {
+ /* Prefix is '-' */
+ attr->prefix[0] = SECUREC_CHAR('-');
+ attr->prefixLen = 1;
+ return;
+ }
+ if ((attr->flags & SECUREC_FLAG_SIGN) != 0) {
+ /* Prefix is '+' */
+ attr->prefix[0] = SECUREC_CHAR('+');
+ attr->prefixLen = 1;
+ return;
+ }
+ if ((attr->flags & SECUREC_FLAG_SIGN_SPACE) != 0) {
+ /* Prefix is ' ' */
+ attr->prefix[0] = SECUREC_CHAR(' ');
+ attr->prefixLen = 1;
+ return;
+ }
+ return;
+}
+
+SECUREC_INLINE void SecNumberCompatZero(SecFormatAttr *attr)
+{
+#if SECUREC_IN_KERNEL
+ if ((attr->flags & SECUREC_FLAG_POINTER) != 0) {
+ static char strNullPointer[SECUREC_NULL_STRING_SIZE] = "(null)";
+ attr->text.str = strNullPointer;
+ attr->textLen = 6; /* Length of (null) is 6 */
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+ attr->prefixLen = 0;
+ if (attr->precision >= 0 && attr->precision < attr->textLen) {
+ attr->textLen = attr->precision;
+ }
+ }
+ if ((attr->flags & SECUREC_FLAG_POINTER) == 0 &&
+ attr->radix == SECUREC_RADIX_HEX &&
+ (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {
+ /* Add 0x prefix for %x or %X, the prefix string has been set before */
+ attr->prefixLen = SECUREC_PREFIX_LEN;
+ }
+#elif defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX))
+ if ((attr->flags & SECUREC_FLAG_POINTER) != 0) {
+ static char strNullPointer[SECUREC_NULL_STRING_SIZE] = "(nil)";
+ attr->text.str = strNullPointer;
+ attr->textLen = 5; /* Length of (nil) is 5 */
+ attr->flags &= ~SECUREC_FLAG_LEADZERO;
+ }
+#elif defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux)
+ if ((attr->flags & SECUREC_FLAG_POINTER) != 0 &&
+ (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {
+ /* Add 0x prefix for %p, the prefix string has been set before */
+ attr->prefixLen = SECUREC_PREFIX_LEN;
+ }
+#endif
+ (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+}
+
+/*
+ * Formatting output core function
+ */
+SECUREC_INLINE int SecOutput(SecPrintfStream *stream, const SecChar *cFormat,
+ va_list argList)
+{
+ const SecChar *format = cFormat;
+ int charsOut; /* Characters written */
+ int noOutput = 0; /* Must be initialized or compiler alerts */
+ SecFmtState state;
+ SecFormatAttr formatAttr;
+
+ formatAttr.flags = 0;
+ formatAttr.textIsWide = 0; /* Flag for buffer contains wide chars */
+ formatAttr.fldWidth = 0;
+ formatAttr.precision = 0;
+ formatAttr.dynWidth = 0;
+ formatAttr.dynPrecision = 0;
+ formatAttr.digits = g_itoaUpperDigits;
+ formatAttr.radix = SECUREC_RADIX_DECIMAL;
+ formatAttr.padding = 0;
+ formatAttr.textLen = 0;
+ formatAttr.text.str = NULL;
+ formatAttr.prefixLen = 0;
+ formatAttr.prefix[0] = SECUREC_CHAR('\0');
+ formatAttr.prefix[1] = SECUREC_CHAR('\0');
+ charsOut = 0;
+ state = STAT_NORMAL; /* Starting state */
+
+ /* Loop each format character */
+ while (*format != SECUREC_CHAR('\0') && charsOut >= 0) {
+ SecFmtState lastState = state;
+ SecChar ch = *format; /* Currently read character */
+ ++format;
+ state = SecDecodeState(ch, lastState);
+ switch (state) {
+ case STAT_NORMAL:
+ SecWriteChar(stream, ch, &charsOut);
+ continue;
+ case STAT_PERCENT:
+ /* Set default values */
+ noOutput = 0;
+ formatAttr.prefixLen = 0;
+ formatAttr.textLen = 0;
+ formatAttr.flags = 0;
+ formatAttr.fldWidth = 0;
+ formatAttr.precision = -1;
+ formatAttr.textIsWide = 0;
+ formatAttr.dynWidth = 0;
+ formatAttr.dynPrecision = 0;
+ break;
+ case STAT_FLAG:
+ /* Set flag based on which flag character */
+ SecDecodeFlags(ch, &formatAttr);
+ break;
+ case STAT_WIDTH:
+ /* Update width value */
+ if (ch == SECUREC_CHAR('*')) {
+ /* get width from arg list */
+ formatAttr.fldWidth = (int)va_arg(argList, int);
+ formatAttr.dynWidth = 1;
+ }
+ if (SecDecodeWidth(ch, &formatAttr, lastState) != 0) {
+ return -1;
+ }
+ break;
+ case STAT_DOT:
+ formatAttr.precision = 0;
+ break;
+ case STAT_PRECIS:
+ /* Update precision value */
+ if (ch == SECUREC_CHAR('*')) {
+ /* Get precision from arg list */
+ formatAttr.precision =
+ (int)va_arg(argList, int);
+ formatAttr.dynPrecision = 1;
+ }
+ if (SecDecodePrecision(ch, &formatAttr) != 0) {
+ return -1;
+ }
+ break;
+ case STAT_SIZE:
+ /* Read a size specifier, set the formatAttr.flags based on it, and skip format to next character */
+ if (SecDecodeSize(ch, &formatAttr, &format) != 0) {
+ /* Compatibility code for "%I" just print I */
+ SecWriteChar(stream, ch, &charsOut);
+ state = STAT_NORMAL;
+ continue;
+ }
+ break;
+ case STAT_TYPE:
+ switch (ch) {
+ case SECUREC_CHAR('C'): /* Wide char */
+ SecUpdateWcharFlags(&formatAttr);
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+
+ case SECUREC_CHAR('c'): {
+ unsigned int cValue =
+ (unsigned int)va_arg(argList, int);
+ SecDecodeTypeC(&formatAttr, cValue);
+ break;
+ }
+ case SECUREC_CHAR('S'): /* Wide char string */
+ SecUpdateWstringFlags(&formatAttr);
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+
+ case SECUREC_CHAR('s'): {
+ char *argPtr = (char *)va_arg(argList, char *);
+ SecDecodeTypeS(&formatAttr, argPtr);
+ break;
+ }
+ case SECUREC_CHAR('G'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('g'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('E'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('F'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('e'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('f'): {
+#if SECUREC_ENABLE_SPRINTF_FLOAT
+ /* Add following code to call system sprintf API for float number */
+ SecFloatAdapt floatAdapt;
+ noOutput =
+ 1; /* It's no more data needs to be written */
+
+ /* Now format is pointer to the next character of 'f' */
+ if (SecInitFloatBuffer(&floatAdapt, format,
+ &formatAttr) != 0) {
+ break;
+ }
+
+ if ((formatAttr.flags &
+ SECUREC_FLAG_LONG_DOUBLE) != 0) {
+#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && \
+ SECUREC_ENABLE_SPRINTF_LONG_DOUBLE
+ long double tmp = (long double)va_arg(
+ argList, long double);
+ SecFormatLongDouble(&formatAttr,
+ &floatAdapt, tmp);
+#else
+ double tmp =
+ (double)va_arg(argList, double);
+ SecFormatDouble(&formatAttr,
+ &floatAdapt, tmp);
+#endif
+ } else {
+ double tmp =
+ (double)va_arg(argList, double);
+ SecFormatDouble(&formatAttr,
+ &floatAdapt, tmp);
+ }
+
+ /* Only need write formatted float string */
+ SecWriteFloatText(stream, &formatAttr,
+ &charsOut);
+ SecFreeFloatBuffer(&floatAdapt);
+ break;
+#else
+ return -1;
+#endif
+ }
+ case SECUREC_CHAR('X'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('p'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR(
+ 'x'): /* fall-through */ /* FALLTHRU */
+ SecUpdateXpxFlags(&formatAttr, ch);
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('i'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('d'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('u'):
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ case SECUREC_CHAR('o'): {
+ SecInt64 num64;
+ SecUpdateOudiFlags(&formatAttr, ch);
+ /* Read argument into variable num64. Be careful, depend on the order of judgment */
+ if ((formatAttr.flags & SECUREC_FLAG_I64) !=
+ 0 ||
+ (formatAttr.flags &
+ SECUREC_FLAG_LONGLONG) != 0) {
+ num64 = (SecInt64)va_arg(
+ argList,
+ SecInt64); /* Maximum Bit Width sign bit unchanged */
+ } else if ((formatAttr.flags &
+ SECUREC_FLAG_LONG) != 0) {
+ num64 = SECUREC_GET_LONG_FROM_ARG(
+ formatAttr);
+ } else if ((formatAttr.flags &
+ SECUREC_FLAG_CHAR) != 0) {
+ num64 = SECUREC_GET_CHAR_FROM_ARG(
+ formatAttr);
+ } else if ((formatAttr.flags &
+ SECUREC_FLAG_SHORT) != 0) {
+ num64 = SECUREC_GET_SHORT_FROM_ARG(
+ formatAttr);
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+ } else if ((formatAttr.flags &
+ SECUREC_FLAG_PTRDIFF) != 0) {
+ num64 = (ptrdiff_t)va_arg(
+ argList,
+ ptrdiff_t); /* Sign extend */
+ } else if ((formatAttr.flags &
+ SECUREC_FLAG_SIZE) != 0) {
+ num64 = SECUREC_GET_SIZE_FROM_ARG(
+ formatAttr);
+ } else if ((formatAttr.flags &
+ SECUREC_FLAG_INTMAX) != 0) {
+ num64 = (SecInt64)va_arg(argList,
+ SecInt64);
+#endif
+ } else {
+ num64 = SECUREC_GET_INT_FROM_ARG(
+ formatAttr);
+ }
+
+ /* The order of the following calls must be correct */
+ SecNumberToBuffer(&formatAttr, num64);
+ SecNumberSatisfyPrecision(&formatAttr);
+ SecNumberForceOctal(&formatAttr);
+ SecUpdateSignedNumberPrefix(&formatAttr);
+ if (num64 == 0) {
+ SecNumberCompatZero(&formatAttr);
+ }
+ break;
+ }
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ if (noOutput == 0) {
+ /* Calculate amount of padding */
+ formatAttr.padding = (formatAttr.fldWidth -
+ formatAttr.textLen) -
+ formatAttr.prefixLen;
+
+ /* Put out the padding, prefix, and text, in the correct order */
+ SecWriteLeftPadding(stream, &formatAttr,
+ &charsOut);
+ SecWritePrefix(stream, &formatAttr, &charsOut);
+ SecWriteLeadingZero(stream, &formatAttr,
+ &charsOut);
+ SecWriteText(stream, &formatAttr, &charsOut);
+ SecWriteRightPadding(stream, &formatAttr,
+ &charsOut);
+ }
+ break;
+ case STAT_INVALID:
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */
+ default:
+ return -1; /* Input format is wrong(STAT_INVALID), directly return */
+ }
+ }
+
+ if (state != STAT_NORMAL && state != STAT_TYPE) {
+ return -1;
+ }
+
+ return charsOut; /* The number of characters written */
+}
+
+/*
+ * Output one zero character zero into the SecPrintfStream structure
+ * If there is not enough space, make sure f->count is less than 0
+ */
+SECUREC_INLINE int SecPutZeroChar(SecPrintfStream *stream)
+{
+ --stream->count;
+ if (stream->count >= 0) {
+ *(stream->cur) = SECUREC_CHAR('\0');
+ ++stream->cur;
+ return 0;
+ }
+ return -1;
+}
+
+/*
+ * Multi character formatted output implementation
+ */
+#ifdef SECUREC_FOR_WCHAR
+int SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format,
+ va_list argList)
+#else
+int SecVsnprintfImpl(char *string, size_t count, const char *format,
+ va_list argList)
+#endif
+{
+ SecPrintfStream stream;
+ int retVal;
+
+ stream.count = (int)
+ count; /* The count include \0 character, must be greater than zero */
+ stream.cur = string;
+
+ retVal = SecOutput(&stream, format, argList);
+ if (retVal >= 0) {
+ if (SecPutZeroChar(&stream) == 0) {
+ return retVal;
+ }
+ }
+ if (stream.count < 0) {
+ /* The buffer was too small, then truncate */
+ string[count - 1] = SECUREC_CHAR('\0');
+ return SECUREC_PRINTF_TRUNCATE;
+ }
+ string[0] = SECUREC_CHAR('\0'); /* Empty the dest string */
+ return -1;
+}
+#endif /* OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 */
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/scanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/scanf_s.c
new file mode 100644
index 000000000..b76d58817
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/scanf_s.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: scanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s
+ * The scanf_s function reads data from the standard input stream stdin and
+ * writes the data into the location that's given by argument. Each argument
+ * must be a pointer to a variable of a type that corresponds to a type specifier
+ * in format. If copying occurs between strings that overlap, the behavior is
+ * undefined.
+ *
+ * <INPUT PARAMETERS>
+ * format Format control string.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * ... The converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Returns the number of fields successfully converted and assigned;
+ * the return value does not include fields that were read but not assigned.
+ * A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int scanf_s(const char *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vscanf_s(format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secinput.h b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secinput.h
new file mode 100644
index 000000000..2a1cfeac1
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secinput.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Define macro, data struct, and declare function prototype,
+ * which is used by input.inl, secureinput_a.c and secureinput_w.c.
+ * Create: 2014-02-25
+ */
+
+#ifndef SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C
+#define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C
+#include "securecutil.h"
+
+#define SECUREC_SCANF_EINVAL (-1)
+#define SECUREC_SCANF_ERROR_PARA (-2)
+
+/* For internal stream flag */
+#define SECUREC_MEM_STR_FLAG 0x01U
+#define SECUREC_FILE_STREAM_FLAG 0x02U
+#define SECUREC_PIPE_STREAM_FLAG 0x04U
+#define SECUREC_LOAD_FILE_TO_MEM_FLAG 0x08U
+
+#define SECUREC_UCS_BOM_HEADER_SIZE 2U
+#define SECUREC_UCS_BOM_HEADER_BE_1ST 0xfeU
+#define SECUREC_UCS_BOM_HEADER_BE_2ST 0xffU
+#define SECUREC_UCS_BOM_HEADER_LE_1ST 0xffU
+#define SECUREC_UCS_BOM_HEADER_LE_2ST 0xfeU
+#define SECUREC_UTF8_BOM_HEADER_SIZE 3U
+#define SECUREC_UTF8_BOM_HEADER_1ST 0xefU
+#define SECUREC_UTF8_BOM_HEADER_2ND 0xbbU
+#define SECUREC_UTF8_BOM_HEADER_3RD 0xbfU
+#define SECUREC_UTF8_LEAD_1ST 0xe0U
+#define SECUREC_UTF8_LEAD_2ND 0x80U
+
+#define SECUREC_BEGIN_WITH_UCS_BOM(s, len) \
+ ((len) == SECUREC_UCS_BOM_HEADER_SIZE && \
+ (((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_LE_1ST && \
+ (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_LE_2ST) || \
+ ((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_BE_1ST && \
+ (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_BE_2ST)))
+
+#define SECUREC_BEGIN_WITH_UTF8_BOM(s, len) \
+ ((len) == SECUREC_UTF8_BOM_HEADER_SIZE && \
+ (unsigned char)((s)[0]) == SECUREC_UTF8_BOM_HEADER_1ST && \
+ (unsigned char)((s)[1]) == SECUREC_UTF8_BOM_HEADER_2ND && \
+ (unsigned char)((s)[2]) == SECUREC_UTF8_BOM_HEADER_3RD)
+
+#ifdef SECUREC_FOR_WCHAR
+#define SECUREC_BOM_HEADER_SIZE SECUREC_UCS_BOM_HEADER_SIZE
+#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UCS_BOM((s), (len))
+#else
+#define SECUREC_BOM_HEADER_SIZE SECUREC_UTF8_BOM_HEADER_SIZE
+#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UTF8_BOM((s), (len))
+#endif
+
+typedef struct {
+ unsigned int flag; /* Mark the properties of input stream */
+ char *base; /* The pointer to the header of buffered string */
+ const char *cur; /* The pointer to next read position */
+ size_t count; /* The size of buffered string in bytes */
+#if SECUREC_ENABLE_SCANF_FILE
+ FILE *pf; /* The file pointer */
+ size_t fileRealRead;
+ long oriFilePos; /* The original position of file offset when fscanf is called */
+#endif
+} SecFileStream;
+
+#if SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) \
+ do { \
+ (stream)->pf = (fp); \
+ (stream)->fileRealRead = 0; \
+ (stream)->oriFilePos = 0; \
+ } \
+ SECUREC_WHILE_ZERO
+#else
+/* Disable file */
+#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp)
+#endif
+
+/* This initialization for eliminating redundant initialization. */
+#define SECUREC_FILE_STREAM_FROM_STRING(stream, buf, cnt) \
+ do { \
+ (stream)->flag = SECUREC_MEM_STR_FLAG; \
+ (stream)->base = NULL; \
+ (stream)->cur = (buf); \
+ (stream)->count = (cnt); \
+ SECUREC_FILE_STREAM_INIT_FILE((stream), NULL); \
+ } \
+ SECUREC_WHILE_ZERO
+
+/* This initialization for eliminating redundant initialization. */
+#define SECUREC_FILE_STREAM_FROM_FILE(stream, fp) \
+ do { \
+ (stream)->flag = SECUREC_FILE_STREAM_FLAG; \
+ (stream)->base = NULL; \
+ (stream)->cur = NULL; \
+ (stream)->count = 0; \
+ SECUREC_FILE_STREAM_INIT_FILE((stream), (fp)); \
+ } \
+ SECUREC_WHILE_ZERO
+
+/* This initialization for eliminating redundant initialization. */
+#define SECUREC_FILE_STREAM_FROM_STDIN(stream) \
+ do { \
+ (stream)->flag = SECUREC_PIPE_STREAM_FLAG; \
+ (stream)->base = NULL; \
+ (stream)->cur = NULL; \
+ (stream)->count = 0; \
+ SECUREC_FILE_STREAM_INIT_FILE((stream), SECUREC_STREAM_STDIN); \
+ } \
+ SECUREC_WHILE_ZERO
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList);
+void SecClearDestBuf(const char *buffer, const char *format, va_list argList);
+#ifdef SECUREC_FOR_WCHAR
+int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList);
+void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format,
+ va_list argList);
+#endif
+
+/* 20150105 For software and hardware decoupling,such as UMG */
+#ifdef SECUREC_SYSAPI4VXWORKS
+#ifdef feof
+#undef feof
+#endif
+extern int feof(FILE *stream);
+#endif
+
+#if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT)
+#ifndef isspace
+#define isspace(c) \
+ (((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n'))
+#endif
+#ifndef iswspace
+#define iswspace(c) \
+ (((c) == L' ') || ((c) == L'\t') || ((c) == L'\r') || ((c) == L'\n'))
+#endif
+#ifndef isascii
+#define isascii(c) (((unsigned char)(c)) <= 0x7f)
+#endif
+#ifndef isupper
+#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
+#endif
+#ifndef islower
+#define islower(c) ((c) >= 'a' && (c) <= 'z')
+#endif
+#ifndef isalpha
+#define isalpha(c) (isupper(c) || (islower(c)))
+#endif
+#ifndef isdigit
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+#endif
+#ifndef isxupper
+#define isxupper(c) ((c) >= 'A' && (c) <= 'F')
+#endif
+#ifndef isxlower
+#define isxlower(c) ((c) >= 'a' && (c) <= 'f')
+#endif
+#ifndef isxdigit
+#define isxdigit(c) (isdigit(c) || isxupper(c) || isxlower(c))
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+/* Reserved file operation macro interface, s is FILE *, i is fileno zero. */
+#ifndef SECUREC_LOCK_FILE
+#define SECUREC_LOCK_FILE(s)
+#endif
+
+#ifndef SECUREC_UNLOCK_FILE
+#define SECUREC_UNLOCK_FILE(s)
+#endif
+
+#ifndef SECUREC_LOCK_STDIN
+#define SECUREC_LOCK_STDIN(i, s)
+#endif
+
+#ifndef SECUREC_UNLOCK_STDIN
+#define SECUREC_UNLOCK_STDIN(i, s)
+#endif
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.c
new file mode 100644
index 000000000..480850f4f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Provides internal functions used by this library, such as memory
+ * copy and memory move. Besides, include some helper function for
+ * printf family API, such as SecVsnprintfImpl
+ * Create: 2014-02-25
+ */
+
+/* Avoid duplicate header files,not include securecutil.h */
+#include "securecutil.h"
+
+#if defined(ANDROID) && !defined(SECUREC_CLOSE_ANDROID_HANDLE) && \
+ (SECUREC_HAVE_WCTOMB || SECUREC_HAVE_MBTOWC)
+#include <wchar.h>
+#if SECUREC_HAVE_WCTOMB
+/*
+ * Convert wide characters to narrow multi-bytes
+ */
+int wctomb(char *s, wchar_t wc)
+{
+ return (int)wcrtomb(s, wc, NULL);
+}
+#endif
+
+#if SECUREC_HAVE_MBTOWC
+/*
+ * Converting narrow multi-byte characters to wide characters
+ * mbrtowc returns -1 or -2 upon failure, unlike mbtowc, which only returns -1
+ * When the return value is less than zero, we treat it as a failure
+ */
+int mbtowc(wchar_t *pwc, const char *s, size_t n)
+{
+ return (int)mbrtowc(pwc, s, n, NULL);
+}
+#endif
+#endif
+
+/* The V100R001C01 version num is 0x5 (High 8 bits) */
+#define SECUREC_C_VERSION 0x500U
+#define SECUREC_SPC_VERSION 0xbU
+#define SECUREC_VERSION_STR "Huawei Secure C V100R001C01SPC017B001"
+
+/*
+ * Get version string and version number.
+ * The rules for version number are as follows:
+ * 1) SPC verNumber<->verStr like:
+ * 0x201<->C01
+ * 0x202<->C01SPC001 Redefine numbers after this version
+ * 0x502<->C01SPC002
+ * 0x503<->C01SPC003
+ * ...
+ * 0X50a<->SPC010
+ * 0X50b<->SPC011
+ * ...
+ * 0x700<->C02
+ * 0x701<->C01SPC001
+ * 0x702<->C02SPC002
+ * ...
+ * 2) CP verNumber<->verStr like:
+ * 0X601<->CP0001
+ * 0X602<->CP0002
+ * ...
+ */
+const char *GetHwSecureCVersion(unsigned short *verNumber)
+{
+ if (verNumber != NULL) {
+ *verNumber = (unsigned short)(SECUREC_C_VERSION |
+ SECUREC_SPC_VERSION);
+ }
+ return SECUREC_VERSION_STR;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(GetHwSecureCVersion);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.h b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.h
new file mode 100644
index 000000000..26c151d46
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/securecutil.h
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Define macro, data struct, and declare internal used function prototype,
+ * which is used by secure functions.
+ * Create: 2014-02-25
+ */
+
+#ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F
+#define SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F
+#include "securec.h"
+
+#if (defined(_MSC_VER)) && (_MSC_VER >= 1400)
+/* Shield compilation alerts using discarded functions and Constant expression to maximize code compatibility */
+#define SECUREC_MASK_MSVC_CRT_WARNING \
+ __pragma(warning(push)) __pragma(warning(disable : 4996 4127))
+#define SECUREC_END_MASK_MSVC_CRT_WARNING __pragma(warning(pop))
+#else
+#define SECUREC_MASK_MSVC_CRT_WARNING
+#define SECUREC_END_MASK_MSVC_CRT_WARNING
+#endif
+#define SECUREC_WHILE_ZERO \
+ SECUREC_MASK_MSVC_CRT_WARNING while (0) \
+ SECUREC_END_MASK_MSVC_CRT_WARNING
+
+/* Automatically identify the platform that supports strnlen function, and use this function to improve performance */
+#ifndef SECUREC_HAVE_STRNLEN
+#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || \
+ (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
+#if SECUREC_IN_KERNEL
+#define SECUREC_HAVE_STRNLEN 0
+#else
+#if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && \
+ __GLIBC_MINOR__ >= 10
+#define SECUREC_HAVE_STRNLEN 1
+#else
+#define SECUREC_HAVE_STRNLEN 0
+#endif
+#endif
+#else
+#define SECUREC_HAVE_STRNLEN 0
+#endif
+#endif
+
+#if SECUREC_IN_KERNEL
+/* In kernel disable functions */
+#ifndef SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_SCANF_FILE 0
+#endif
+#ifndef SECUREC_ENABLE_SCANF_FLOAT
+#define SECUREC_ENABLE_SCANF_FLOAT 0
+#endif
+#ifndef SECUREC_ENABLE_SPRINTF_FLOAT
+#define SECUREC_ENABLE_SPRINTF_FLOAT 0
+#endif
+#ifndef SECUREC_HAVE_MBTOWC
+#define SECUREC_HAVE_MBTOWC 0
+#endif
+#ifndef SECUREC_HAVE_WCTOMB
+#define SECUREC_HAVE_WCTOMB 0
+#endif
+#ifndef SECUREC_HAVE_WCHART
+#define SECUREC_HAVE_WCHART 0
+#endif
+#else /* Not in kernel */
+/* Systems that do not support file, can define this macro to 0. */
+#ifndef SECUREC_ENABLE_SCANF_FILE
+#define SECUREC_ENABLE_SCANF_FILE 1
+#endif
+#ifndef SECUREC_ENABLE_SCANF_FLOAT
+#define SECUREC_ENABLE_SCANF_FLOAT 1
+#endif
+/* Systems that do not support float, can define this macro to 0. */
+#ifndef SECUREC_ENABLE_SPRINTF_FLOAT
+#define SECUREC_ENABLE_SPRINTF_FLOAT 1
+#endif
+#ifndef SECUREC_HAVE_MBTOWC
+#define SECUREC_HAVE_MBTOWC 1
+#endif
+#ifndef SECUREC_HAVE_WCTOMB
+#define SECUREC_HAVE_WCTOMB 1
+#endif
+#ifndef SECUREC_HAVE_WCHART
+#define SECUREC_HAVE_WCHART 1
+#endif
+#endif
+
+#ifndef SECUREC_ENABLE_INLINE
+#define SECUREC_ENABLE_INLINE 0
+#endif
+
+#ifndef SECUREC_INLINE
+#if SECUREC_ENABLE_INLINE
+#define SECUREC_INLINE static inline
+#else
+#define SECUREC_INLINE static
+#endif
+#endif
+
+#ifndef SECUREC_WARP_OUTPUT
+#if SECUREC_IN_KERNEL
+#define SECUREC_WARP_OUTPUT 1
+#else
+#define SECUREC_WARP_OUTPUT 0
+#endif
+#endif
+
+#ifndef SECUREC_STREAM_STDIN
+#define SECUREC_STREAM_STDIN stdin
+#endif
+
+#define SECUREC_MUL_SIXTEEN(x) ((x) << 4U)
+#define SECUREC_MUL_EIGHT(x) ((x) << 3U)
+#define SECUREC_MUL_TEN(x) ((((x) << 2U) + (x)) << 1U)
+/* Limited format input and output width, use signed integer */
+#define SECUREC_MAX_WIDTH_LEN_DIV_TEN 21474836
+#define SECUREC_MAX_WIDTH_LEN (SECUREC_MAX_WIDTH_LEN_DIV_TEN * 10)
+/* Is the x multiplied by 10 greater than */
+#define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x) \
+ (((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN))
+
+#define SECUREC_FLOAT_BUFSIZE (309 + 40) /* Max length of double value */
+#define SECUREC_FLOAT_BUFSIZE_LB \
+ (4932 + 40) /* Max length of long double value */
+#define SECUREC_FLOAT_DEFAULT_PRECISION 6
+
+/* This macro does not handle pointer equality or integer overflow */
+#define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \
+ (((src) < (dest) && \
+ ((const char *)(src) + (count)) <= (char *)(dest)) || \
+ ((dest) < (src) && \
+ ((char *)(dest) + (count)) <= (const char *)(src)))
+
+#define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \
+ (((src) < (dest) && \
+ ((const char *)(src) + (count)) > (char *)(dest)) || \
+ ((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src)))
+
+/*
+ * Check whether the strings overlap, len is the length of the string not include terminator
+ * Length is related to data type char or wchar , do not force conversion of types
+ */
+#define SECUREC_STRING_NO_OVERLAP(dest, src, len) \
+ (((src) < (dest) && ((src) + (len)) < (dest)) || \
+ ((dest) < (src) && ((dest) + (len)) < (src)))
+
+/*
+ * Check whether the strings overlap for strcpy wcscpy function, dest len and src Len are not include terminator
+ * Length is related to data type char or wchar , do not force conversion of types
+ */
+#define SECUREC_STRING_IS_OVERLAP(dest, src, len) \
+ (((src) < (dest) && ((src) + (len)) >= (dest)) || \
+ ((dest) < (src) && ((dest) + (len)) >= (src)))
+
+/*
+ * Check whether the strings overlap for strcat wcscat function, dest len and src Len are not include terminator
+ * Length is related to data type char or wchar , do not force conversion of types
+ */
+#define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \
+ (((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \
+ ((src) < (dest) && ((src) + (srcLen)) >= (dest)))
+
+#if SECUREC_HAVE_STRNLEN
+#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) \
+ do { \
+ *(outLen) = strnlen((str), (maxLen)); \
+ } \
+ SECUREC_WHILE_ZERO
+#define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) \
+ do { \
+ if ((maxLen) > 8) { \
+ /* Optimization or len less then 8 */ \
+ if (*((str) + 0) == '\0') { \
+ *(outLen) = 0; \
+ } else if (*((str) + 1) == '\0') { \
+ *(outLen) = 1; \
+ } else if (*((str) + 2) == '\0') { \
+ *(outLen) = 2; \
+ } else if (*((str) + 3) == '\0') { \
+ *(outLen) = 3; \
+ } else if (*((str) + 4) == '\0') { \
+ *(outLen) = 4; \
+ } else if (*((str) + 5) == '\0') { \
+ *(outLen) = 5; \
+ } else if (*((str) + 6) == '\0') { \
+ *(outLen) = 6; \
+ } else if (*((str) + 7) == '\0') { \
+ *(outLen) = 7; \
+ } else if (*((str) + 8) == '\0') { \
+ /* Optimization with a length of 8 */ \
+ *(outLen) = 8; \
+ } else { \
+ /* The offset is 8 because the performance of 8 byte alignment is high */ \
+ *(outLen) = \
+ 8 + strnlen((str) + 8, (maxLen)-8); \
+ } \
+ } else { \
+ SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+#else
+#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) \
+ do { \
+ const char *strEnd_ = (const char *)(str); \
+ size_t availableSize_ = (size_t)(maxLen); \
+ while (availableSize_ > 0 && *strEnd_ != '\0') { \
+ --availableSize_; \
+ ++strEnd_; \
+ } \
+ *(outLen) = (size_t)(strEnd_ - (str)); \
+ } \
+ SECUREC_WHILE_ZERO
+#define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN
+#endif
+
+#define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) \
+ do { \
+ const wchar_t *strEnd_ = (const wchar_t *)(str); \
+ size_t len_ = 0; \
+ while (len_ < (maxLen) && *strEnd_ != L'\0') { \
+ ++len_; \
+ ++strEnd_; \
+ } \
+ *(outLen) = len_; \
+ } \
+ SECUREC_WHILE_ZERO
+
+/*
+ * Performance optimization, product may disable inline function.
+ * Using function pointer for MEMSET to prevent compiler optimization when cleaning up memory.
+ */
+#ifdef SECUREC_USE_ASM
+#define SECUREC_MEMSET_FUNC_OPT memset_opt
+#define SECUREC_MEMCPY_FUNC_OPT memcpy_opt
+#else
+#define SECUREC_MEMSET_FUNC_OPT memset
+#define SECUREC_MEMCPY_FUNC_OPT memcpy
+#endif
+
+#define SECUREC_MEMCPY_WARP_OPT(dest, src, count) \
+ (void)SECUREC_MEMCPY_FUNC_OPT((dest), (src), (count))
+
+#ifndef SECUREC_MEMSET_BARRIER
+#if defined(__GNUC__)
+/* Can be turned off for scenarios that do not use memory barrier */
+#define SECUREC_MEMSET_BARRIER 1
+#else
+#define SECUREC_MEMSET_BARRIER 0
+#endif
+#endif
+
+#ifndef SECUREC_MEMSET_INDIRECT_USE
+/* Can be turned off for scenarios that do not allow pointer calls */
+#define SECUREC_MEMSET_INDIRECT_USE 1
+#endif
+
+#if SECUREC_MEMSET_BARRIER
+#define SECUREC_MEMORY_BARRIER(dest) \
+ __asm__ __volatile__("" : : "r"(dest) : "memory")
+#else
+#define SECUREC_MEMORY_BARRIER(dest)
+#endif
+
+#if SECUREC_MEMSET_BARRIER
+#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) \
+ do { \
+ (void)SECUREC_MEMSET_FUNC_OPT(dest, value, count); \
+ SECUREC_MEMORY_BARRIER(dest); \
+ } \
+ SECUREC_WHILE_ZERO
+#elif SECUREC_MEMSET_INDIRECT_USE
+#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) \
+ do { \
+ void *(*const volatile fn_)(void *s_, int c_, size_t n_) = \
+ SECUREC_MEMSET_FUNC_OPT; \
+ (void)(*fn_)((dest), (value), (count)); \
+ } \
+ SECUREC_WHILE_ZERO
+#else
+#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) \
+ (void)SECUREC_MEMSET_FUNC_OPT((dest), (value), (count))
+#endif
+
+#ifdef SECUREC_FORMAT_OUTPUT_INPUT
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) || defined(__ARMCC_VERSION)
+typedef __int64 SecInt64;
+typedef unsigned __int64 SecUnsignedInt64;
+#if defined(__ARMCC_VERSION)
+typedef unsigned int SecUnsignedInt32;
+#else
+typedef unsigned __int32 SecUnsignedInt32;
+#endif
+#else
+typedef unsigned int SecUnsignedInt32;
+typedef long long SecInt64;
+typedef unsigned long long SecUnsignedInt64;
+#endif
+
+#ifdef SECUREC_FOR_WCHAR
+#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(__WINT_TYPE__)
+typedef wchar_t wint_t;
+#endif
+#ifndef WEOF
+#define WEOF ((wchar_t)(-1))
+#endif
+#define SECUREC_CHAR(x) L##x
+typedef wchar_t SecChar;
+typedef wchar_t SecUnsignedChar;
+typedef wint_t SecInt;
+typedef wint_t SecUnsignedInt;
+#else /* no SECUREC_FOR_WCHAR */
+#define SECUREC_CHAR(x) (x)
+typedef char SecChar;
+typedef unsigned char SecUnsignedChar;
+typedef int SecInt;
+typedef unsigned int SecUnsignedInt;
+#endif
+#endif
+
+/*
+ * Determine whether the address is 8-byte aligned
+ * Some systems do not have uintptr_t type, so use NULL to clear tool alarm 507
+ */
+#define SECUREC_ADDR_ALIGNED_8(addr) \
+ ((((size_t)(addr)) & 7U) == 0) /* Use 7 to check aligned 8 */
+
+/*
+ * If you define the memory allocation function, you need to define the function prototype.
+ * You can define this macro as a header file.
+ */
+#if defined(SECUREC_MALLOC_PROTOTYPE)
+SECUREC_MALLOC_PROTOTYPE
+#endif
+
+#ifndef SECUREC_MALLOC
+#define SECUREC_MALLOC(x) malloc((size_t)(x))
+#endif
+
+#ifndef SECUREC_FREE
+#define SECUREC_FREE(x) free((void *)(x))
+#endif
+
+/* Improve performance with struct assignment, buf1 is not defined to avoid tool false positive */
+#define SECUREC_COPY_VALUE_BY_STRUCT(dest, src, n) \
+ do { \
+ *(SecStrBuf##n *)(void *)(dest) = \
+ *(const SecStrBuf##n *)(const void *)(src); \
+ } \
+ SECUREC_WHILE_ZERO
+
+typedef struct {
+ unsigned char
+ buf[2]; /* Performance optimization code structure assignment length 2 bytes */
+} SecStrBuf2;
+typedef struct {
+ unsigned char
+ buf[3]; /* Performance optimization code structure assignment length 3 bytes */
+} SecStrBuf3;
+typedef struct {
+ unsigned char
+ buf[4]; /* Performance optimization code structure assignment length 4 bytes */
+} SecStrBuf4;
+typedef struct {
+ unsigned char
+ buf[5]; /* Performance optimization code structure assignment length 5 bytes */
+} SecStrBuf5;
+typedef struct {
+ unsigned char
+ buf[6]; /* Performance optimization code structure assignment length 6 bytes */
+} SecStrBuf6;
+typedef struct {
+ unsigned char
+ buf[7]; /* Performance optimization code structure assignment length 7 bytes */
+} SecStrBuf7;
+typedef struct {
+ unsigned char
+ buf[8]; /* Performance optimization code structure assignment length 8 bytes */
+} SecStrBuf8;
+typedef struct {
+ unsigned char
+ buf[9]; /* Performance optimization code structure assignment length 9 bytes */
+} SecStrBuf9;
+typedef struct {
+ unsigned char
+ buf[10]; /* Performance optimization code structure assignment length 10 bytes */
+} SecStrBuf10;
+typedef struct {
+ unsigned char
+ buf[11]; /* Performance optimization code structure assignment length 11 bytes */
+} SecStrBuf11;
+typedef struct {
+ unsigned char
+ buf[12]; /* Performance optimization code structure assignment length 12 bytes */
+} SecStrBuf12;
+typedef struct {
+ unsigned char
+ buf[13]; /* Performance optimization code structure assignment length 13 bytes */
+} SecStrBuf13;
+typedef struct {
+ unsigned char
+ buf[14]; /* Performance optimization code structure assignment length 14 bytes */
+} SecStrBuf14;
+typedef struct {
+ unsigned char
+ buf[15]; /* Performance optimization code structure assignment length 15 bytes */
+} SecStrBuf15;
+typedef struct {
+ unsigned char
+ buf[16]; /* Performance optimization code structure assignment length 16 bytes */
+} SecStrBuf16;
+typedef struct {
+ unsigned char
+ buf[17]; /* Performance optimization code structure assignment length 17 bytes */
+} SecStrBuf17;
+typedef struct {
+ unsigned char
+ buf[18]; /* Performance optimization code structure assignment length 18 bytes */
+} SecStrBuf18;
+typedef struct {
+ unsigned char
+ buf[19]; /* Performance optimization code structure assignment length 19 bytes */
+} SecStrBuf19;
+typedef struct {
+ unsigned char
+ buf[20]; /* Performance optimization code structure assignment length 20 bytes */
+} SecStrBuf20;
+typedef struct {
+ unsigned char
+ buf[21]; /* Performance optimization code structure assignment length 21 bytes */
+} SecStrBuf21;
+typedef struct {
+ unsigned char
+ buf[22]; /* Performance optimization code structure assignment length 22 bytes */
+} SecStrBuf22;
+typedef struct {
+ unsigned char
+ buf[23]; /* Performance optimization code structure assignment length 23 bytes */
+} SecStrBuf23;
+typedef struct {
+ unsigned char
+ buf[24]; /* Performance optimization code structure assignment length 24 bytes */
+} SecStrBuf24;
+typedef struct {
+ unsigned char
+ buf[25]; /* Performance optimization code structure assignment length 25 bytes */
+} SecStrBuf25;
+typedef struct {
+ unsigned char
+ buf[26]; /* Performance optimization code structure assignment length 26 bytes */
+} SecStrBuf26;
+typedef struct {
+ unsigned char
+ buf[27]; /* Performance optimization code structure assignment length 27 bytes */
+} SecStrBuf27;
+typedef struct {
+ unsigned char
+ buf[28]; /* Performance optimization code structure assignment length 28 bytes */
+} SecStrBuf28;
+typedef struct {
+ unsigned char
+ buf[29]; /* Performance optimization code structure assignment length 29 bytes */
+} SecStrBuf29;
+typedef struct {
+ unsigned char
+ buf[30]; /* Performance optimization code structure assignment length 30 bytes */
+} SecStrBuf30;
+typedef struct {
+ unsigned char
+ buf[31]; /* Performance optimization code structure assignment length 31 bytes */
+} SecStrBuf31;
+typedef struct {
+ unsigned char
+ buf[32]; /* Performance optimization code structure assignment length 32 bytes */
+} SecStrBuf32;
+typedef struct {
+ unsigned char
+ buf[33]; /* Performance optimization code structure assignment length 33 bytes */
+} SecStrBuf33;
+typedef struct {
+ unsigned char
+ buf[34]; /* Performance optimization code structure assignment length 34 bytes */
+} SecStrBuf34;
+typedef struct {
+ unsigned char
+ buf[35]; /* Performance optimization code structure assignment length 35 bytes */
+} SecStrBuf35;
+typedef struct {
+ unsigned char
+ buf[36]; /* Performance optimization code structure assignment length 36 bytes */
+} SecStrBuf36;
+typedef struct {
+ unsigned char
+ buf[37]; /* Performance optimization code structure assignment length 37 bytes */
+} SecStrBuf37;
+typedef struct {
+ unsigned char
+ buf[38]; /* Performance optimization code structure assignment length 38 bytes */
+} SecStrBuf38;
+typedef struct {
+ unsigned char
+ buf[39]; /* Performance optimization code structure assignment length 39 bytes */
+} SecStrBuf39;
+typedef struct {
+ unsigned char
+ buf[40]; /* Performance optimization code structure assignment length 40 bytes */
+} SecStrBuf40;
+typedef struct {
+ unsigned char
+ buf[41]; /* Performance optimization code structure assignment length 41 bytes */
+} SecStrBuf41;
+typedef struct {
+ unsigned char
+ buf[42]; /* Performance optimization code structure assignment length 42 bytes */
+} SecStrBuf42;
+typedef struct {
+ unsigned char
+ buf[43]; /* Performance optimization code structure assignment length 43 bytes */
+} SecStrBuf43;
+typedef struct {
+ unsigned char
+ buf[44]; /* Performance optimization code structure assignment length 44 bytes */
+} SecStrBuf44;
+typedef struct {
+ unsigned char
+ buf[45]; /* Performance optimization code structure assignment length 45 bytes */
+} SecStrBuf45;
+typedef struct {
+ unsigned char
+ buf[46]; /* Performance optimization code structure assignment length 46 bytes */
+} SecStrBuf46;
+typedef struct {
+ unsigned char
+ buf[47]; /* Performance optimization code structure assignment length 47 bytes */
+} SecStrBuf47;
+typedef struct {
+ unsigned char
+ buf[48]; /* Performance optimization code structure assignment length 48 bytes */
+} SecStrBuf48;
+typedef struct {
+ unsigned char
+ buf[49]; /* Performance optimization code structure assignment length 49 bytes */
+} SecStrBuf49;
+typedef struct {
+ unsigned char
+ buf[50]; /* Performance optimization code structure assignment length 50 bytes */
+} SecStrBuf50;
+typedef struct {
+ unsigned char
+ buf[51]; /* Performance optimization code structure assignment length 51 bytes */
+} SecStrBuf51;
+typedef struct {
+ unsigned char
+ buf[52]; /* Performance optimization code structure assignment length 52 bytes */
+} SecStrBuf52;
+typedef struct {
+ unsigned char
+ buf[53]; /* Performance optimization code structure assignment length 53 bytes */
+} SecStrBuf53;
+typedef struct {
+ unsigned char
+ buf[54]; /* Performance optimization code structure assignment length 54 bytes */
+} SecStrBuf54;
+typedef struct {
+ unsigned char
+ buf[55]; /* Performance optimization code structure assignment length 55 bytes */
+} SecStrBuf55;
+typedef struct {
+ unsigned char
+ buf[56]; /* Performance optimization code structure assignment length 56 bytes */
+} SecStrBuf56;
+typedef struct {
+ unsigned char
+ buf[57]; /* Performance optimization code structure assignment length 57 bytes */
+} SecStrBuf57;
+typedef struct {
+ unsigned char
+ buf[58]; /* Performance optimization code structure assignment length 58 bytes */
+} SecStrBuf58;
+typedef struct {
+ unsigned char
+ buf[59]; /* Performance optimization code structure assignment length 59 bytes */
+} SecStrBuf59;
+typedef struct {
+ unsigned char
+ buf[60]; /* Performance optimization code structure assignment length 60 bytes */
+} SecStrBuf60;
+typedef struct {
+ unsigned char
+ buf[61]; /* Performance optimization code structure assignment length 61 bytes */
+} SecStrBuf61;
+typedef struct {
+ unsigned char
+ buf[62]; /* Performance optimization code structure assignment length 62 bytes */
+} SecStrBuf62;
+typedef struct {
+ unsigned char
+ buf[63]; /* Performance optimization code structure assignment length 63 bytes */
+} SecStrBuf63;
+typedef struct {
+ unsigned char
+ buf[64]; /* Performance optimization code structure assignment length 64 bytes */
+} SecStrBuf64;
+
+/*
+ * User can change the error handler by modify the following definition,
+ * such as logging the detail error in file.
+ */
+#if defined(_DEBUG) || defined(DEBUG)
+#if defined(SECUREC_ERROR_HANDLER_BY_ASSERT)
+#define SECUREC_ERROR_INVALID_PARAMTER(msg) \
+ assert(msg "invalid argument" == NULL)
+#define SECUREC_ERROR_INVALID_RANGE(msg) \
+ assert(msg "invalid dest buffer size" == NULL)
+#define SECUREC_ERROR_BUFFER_OVERLAP(msg) assert(msg "buffer overlap" == NULL)
+#elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF)
+#if SECUREC_IN_KERNEL
+#define SECUREC_ERROR_INVALID_PARAMTER(msg) printk("%s invalid argument\n", msg)
+#define SECUREC_ERROR_INVALID_RANGE(msg) \
+ printk("%s invalid dest buffer size\n", msg)
+#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printk("%s buffer overlap\n", msg)
+#else
+#define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg)
+#define SECUREC_ERROR_INVALID_RANGE(msg) \
+ printf("%s invalid dest buffer size\n", msg)
+#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg)
+#endif
+#elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG)
+#define SECUREC_ERROR_INVALID_PARAMTER(msg) \
+ LogSecureCRuntimeError(msg " EINVAL\n")
+#define SECUREC_ERROR_INVALID_RANGE(msg) LogSecureCRuntimeError(msg " ERANGE\n")
+#define SECUREC_ERROR_BUFFER_OVERLAP(msg) \
+ LogSecureCRuntimeError(msg " EOVERLAP\n")
+#endif
+#endif
+
+/* Default handler is none */
+#ifndef SECUREC_ERROR_INVALID_PARAMTER
+#define SECUREC_ERROR_INVALID_PARAMTER(msg)
+#endif
+#ifndef SECUREC_ERROR_INVALID_RANGE
+#define SECUREC_ERROR_INVALID_RANGE(msg)
+#endif
+#ifndef SECUREC_ERROR_BUFFER_OVERLAP
+#define SECUREC_ERROR_BUFFER_OVERLAP(msg)
+#endif
+
+#if defined(__clang__)
+#ifndef fallthrough
+#define FALLTHROUGH __attribute__((fallthrough))
+#else
+#define FALLTHROUGH fallthrough
+#endif
+#else
+#define FALLTHROUGH
+#endif /* __clang__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Assembly language memory copy and memory set for X86 or MIPS ... */
+#ifdef SECUREC_USE_ASM
+void *memcpy_opt(void *dest, const void *src, size_t n);
+void *memset_opt(void *s, int c, size_t n);
+#endif
+
+#if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG)
+void LogSecureCRuntimeError(const char *errDetail);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_a.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_a.c
new file mode 100644
index 000000000..9e0d3a77b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_a.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: By defining data type for ANSI string and including "input.inl",
+ * this file generates real underlying function used by scanf family API.
+ * Create: 2014-02-25
+ */
+
+#define SECUREC_FORMAT_OUTPUT_INPUT 1
+#ifdef SECUREC_FOR_WCHAR
+#undef SECUREC_FOR_WCHAR
+#endif
+
+#include "secinput.h"
+
+#include "input.inl"
+
+SECUREC_INLINE int SecIsDigit(SecInt ch)
+{
+ /* SecInt to unsigned char clear 571, use bit mask to clear negative return of ch */
+ return isdigit((int)((unsigned int)(unsigned char)(ch)&0xffU));
+}
+SECUREC_INLINE int SecIsXdigit(SecInt ch)
+{
+ return isxdigit((int)((unsigned int)(unsigned char)(ch)&0xffU));
+}
+SECUREC_INLINE int SecIsSpace(SecInt ch)
+{
+ return isspace((int)((unsigned int)(unsigned char)(ch)&0xffU));
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_w.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_w.c
new file mode 100644
index 000000000..62bb62b0f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureinput_w.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: By defining data type for UNICODE string and including "input.inl",
+ * this file generates real underlying function used by scanf family API.
+ * Create: 2014-02-25
+ */
+
+/* If some platforms don't have wchar.h, don't include it */
+#if !(defined(SECUREC_VXWORKS_PLATFORM))
+/* If there is no macro below, it will cause vs2010 compiling alarm */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#ifndef __STDC_WANT_SECURE_LIB__
+/* The order of adjustment is to eliminate alarm of Duplicate Block */
+#define __STDC_WANT_SECURE_LIB__ 0
+#endif
+#ifndef _CRTIMP_ALTERNATIVE
+#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */
+#endif
+#endif
+#include <wchar.h>
+#endif
+
+/* Disable wchar func to clear vs warning */
+#define SECUREC_ENABLE_WCHAR_FUNC 0
+#define SECUREC_FORMAT_OUTPUT_INPUT 1
+
+#ifndef SECUREC_FOR_WCHAR
+#define SECUREC_FOR_WCHAR
+#endif
+
+#include "secinput.h"
+
+#include "input.inl"
+
+SECUREC_INLINE unsigned int SecWcharHighBits(SecInt ch)
+{
+ /* Convert int to unsigned int clear 571 */
+ return ((unsigned int)(int)ch & (~0xffU));
+}
+
+SECUREC_INLINE unsigned char SecWcharLowByte(SecInt ch)
+{
+ /* Convert int to unsigned int clear 571 */
+ return (unsigned char)((unsigned int)(int)ch & 0xffU);
+}
+
+SECUREC_INLINE int SecIsDigit(SecInt ch)
+{
+ if (SecWcharHighBits(ch) != 0) {
+ return 0; /* Same as isdigit */
+ }
+ return isdigit((int)SecWcharLowByte(ch));
+}
+
+SECUREC_INLINE int SecIsXdigit(SecInt ch)
+{
+ if (SecWcharHighBits(ch) != 0) {
+ return 0; /* Same as isxdigit */
+ }
+ return isxdigit((int)SecWcharLowByte(ch));
+}
+
+SECUREC_INLINE int SecIsSpace(SecInt ch)
+{
+ return iswspace((wint_t)(int)(ch));
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput.h b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput.h
new file mode 100644
index 000000000..a4b32f872
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: Define macro, enum, data struct, and declare internal used function
+ * prototype, which is used by output.inl, secureprintoutput_w.c and
+ * secureprintoutput_a.c.
+ * Create: 2014-02-25
+ */
+
+#ifndef SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C
+#define SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C
+#include "securecutil.h"
+
+/* Shield compilation alerts about using sprintf without format attribute to format float value. */
+#ifndef SECUREC_HANDLE_WFORMAT
+#define SECUREC_HANDLE_WFORMAT 1
+#endif
+
+#if defined(__clang__)
+#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && \
+ ((__GNUC__ >= 5) || \
+ (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)))
+#define SECUREC_MASK_WFORMAT_WARNING \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
+#define SECUREC_END_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic pop")
+#else
+#define SECUREC_MASK_WFORMAT_WARNING
+#define SECUREC_END_MASK_WFORMAT_WARNING
+#endif
+#else
+#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && \
+ ((__GNUC__ >= 5) || \
+ (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ > 7)))
+#define SECUREC_MASK_WFORMAT_WARNING \
+ _Pragma("GCC diagnostic push") _Pragma( \
+ "GCC diagnostic ignored \"-Wformat-nonliteral\"") \
+ _Pragma("GCC diagnostic ignored \"-Wmissing-format-attribute\"") \
+ _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
+#define SECUREC_END_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic pop")
+#else
+#define SECUREC_MASK_WFORMAT_WARNING
+#define SECUREC_END_MASK_WFORMAT_WARNING
+#endif
+#endif
+
+#define SECUREC_MASK_VSPRINTF_WARNING \
+ SECUREC_MASK_WFORMAT_WARNING \
+ SECUREC_MASK_MSVC_CRT_WARNING
+
+#define SECUREC_END_MASK_VSPRINTF_WARNING \
+ SECUREC_END_MASK_WFORMAT_WARNING \
+ SECUREC_END_MASK_MSVC_CRT_WARNING
+
+/*
+ * Flag definitions.
+ * Using macros instead of enumerations is because some of the enumerated types under the compiler are 16bit.
+ */
+#define SECUREC_FLAG_SIGN 0x00001U
+#define SECUREC_FLAG_SIGN_SPACE 0x00002U
+#define SECUREC_FLAG_LEFT 0x00004U
+#define SECUREC_FLAG_LEADZERO 0x00008U
+#define SECUREC_FLAG_LONG 0x00010U
+#define SECUREC_FLAG_SHORT 0x00020U
+#define SECUREC_FLAG_SIGNED 0x00040U
+#define SECUREC_FLAG_ALTERNATE 0x00080U
+#define SECUREC_FLAG_NEGATIVE 0x00100U
+#define SECUREC_FLAG_FORCE_OCTAL 0x00200U
+#define SECUREC_FLAG_LONG_DOUBLE 0x00400U
+#define SECUREC_FLAG_WIDECHAR 0x00800U
+#define SECUREC_FLAG_LONGLONG 0x01000U
+#define SECUREC_FLAG_CHAR 0x02000U
+#define SECUREC_FLAG_POINTER 0x04000U
+#define SECUREC_FLAG_I64 0x08000U
+#define SECUREC_FLAG_PTRDIFF 0x10000U
+#define SECUREC_FLAG_SIZE 0x20000U
+#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
+#define SECUREC_FLAG_INTMAX 0x40000U
+#endif
+
+/* State definitions. Identify the status of the current format */
+typedef enum {
+ STAT_NORMAL,
+ STAT_PERCENT,
+ STAT_FLAG,
+ STAT_WIDTH,
+ STAT_DOT,
+ STAT_PRECIS,
+ STAT_SIZE,
+ STAT_TYPE,
+ STAT_INVALID
+} SecFmtState;
+
+#ifndef SECUREC_BUFFER_SIZE
+#if SECUREC_IN_KERNEL
+#define SECUREC_BUFFER_SIZE 32
+#elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K)
+/*
+ * SECUREC BUFFER SIZE Can not be less than 23
+ * The length of the octal representation of 64-bit integers with zero lead
+ */
+#define SECUREC_BUFFER_SIZE 256
+#else
+#define SECUREC_BUFFER_SIZE 512
+#endif
+#endif
+#if SECUREC_BUFFER_SIZE < 23
+#error SECUREC_BUFFER_SIZE Can not be less than 23
+#endif
+/* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as possible */
+#define SECUREC_WCHAR_BUFFER_SIZE 4
+
+#define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE
+/* Max. # bytes in multibyte char,see MB_LEN_MAX */
+#define SECUREC_MB_LEN 16
+/* The return value of the internal function, which is returned when truncated */
+#define SECUREC_PRINTF_TRUNCATE (-2)
+
+#define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \
+ ((format) == NULL || (strDest) == NULL || (destMax) == 0 || \
+ (destMax) > (maxLimit))
+
+#define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) \
+ do { \
+ if ((strDest) != NULL && (destMax) > 0 && \
+ (destMax) <= (maxLimit)) { \
+ *(strDest) = '\0'; \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, \
+ maxLimit) \
+ (((format) == NULL || (strDest) == NULL || (destMax) == 0 || \
+ (destMax) > (maxLimit)) || \
+ ((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1)))
+
+#else
+#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, \
+ maxLimit) \
+ (((format) == NULL || (strDest) == NULL || (destMax) == 0 || \
+ (destMax) > (maxLimit)) || \
+ ((count) > (SECUREC_STRING_MAX_LEN - 1)))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef SECUREC_FOR_WCHAR
+int SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format,
+ va_list argList);
+#else
+int SecVsnprintfImpl(char *string, size_t count, const char *format,
+ va_list argList);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_a.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_a.c
new file mode 100644
index 000000000..c00e994f5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_a.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: By defining corresponding macro for ANSI string and including "output.inl",
+ * this file generates real underlying function used by printf family API.
+ * Create: 2014-02-25
+ */
+
+#define SECUREC_FORMAT_OUTPUT_INPUT 1
+
+#ifdef SECUREC_FOR_WCHAR
+#undef SECUREC_FOR_WCHAR
+#endif
+
+#include "secureprintoutput.h"
+#if SECUREC_WARP_OUTPUT
+#define SECUREC_FORMAT_FLAG_TABLE_SIZE 128
+SECUREC_INLINE const char *SecSkipKnownFlags(const char *format)
+{
+ static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = {
+ /*
+ * Known flag is "0123456789 +-#hlLwZzjqt*I$"
+ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ const char *fmt = format;
+ while (*fmt != '\0') {
+ char fmtChar = *fmt;
+ if ((unsigned char)fmtChar >
+ 0x7f) { /* 0x7f is upper limit of format char value */
+ break;
+ }
+ if (flagTable[(unsigned char)fmtChar] == 0) {
+ break;
+ }
+ ++fmt;
+ }
+ return fmt;
+}
+
+SECUREC_INLINE int SecFormatContainN(const char *format)
+{
+ const char *fmt = format;
+ while (*fmt != '\0') {
+ ++fmt;
+ /* Skip normal char */
+ if (*(fmt - 1) != '%') {
+ continue;
+ }
+ /* Meet %% */
+ if (*fmt == '%') {
+ ++fmt; /* Point to the character after the %. Correct handling %%xx */
+ continue;
+ }
+ /* Now parse %..., fmt point to the character after the % */
+ fmt = SecSkipKnownFlags(fmt);
+ if (*fmt == 'n') {
+ return 1;
+ }
+ }
+ return 0;
+}
+/*
+ * Multi character formatted output implementation, the count include \0 character, must be greater than zero
+ */
+int SecVsnprintfImpl(char *string, size_t count, const char *format,
+ va_list argList)
+{
+ int retVal;
+ if (SecFormatContainN(format) != 0) {
+ string[0] = '\0';
+ return -1;
+ }
+ SECUREC_MASK_VSPRINTF_WARNING
+ retVal = vsnprintf(string, count, format, argList);
+ SECUREC_END_MASK_VSPRINTF_WARNING
+ if (retVal >=
+ (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */
+ /* The buffer was too small; we return truncation */
+ string[count - 1] = '\0';
+ return SECUREC_PRINTF_TRUNCATE;
+ }
+ if (retVal < 0) {
+ string[0] = '\0'; /* Empty the dest strDest */
+ return -1;
+ }
+ return retVal;
+}
+#else
+#if SECUREC_IN_KERNEL
+#include <linux/ctype.h>
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+#include "output.inl"
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_w.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_w.c
new file mode 100644
index 000000000..75f45cdee
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/secureprintoutput_w.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: By defining corresponding macro for UNICODE string and including "output.inl",
+ * this file generates real underlying function used by printf family API.
+ * Create: 2014-02-25
+ */
+
+/* If some platforms don't have wchar.h, don't include it */
+#if !(defined(SECUREC_VXWORKS_PLATFORM))
+/* If there is no macro above, it will cause compiling alarm */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#ifndef _CRTIMP_ALTERNATIVE
+#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */
+#endif
+#ifndef __STDC_WANT_SECURE_LIB__
+#define __STDC_WANT_SECURE_LIB__ 0
+#endif
+#endif
+#include <wchar.h>
+#endif
+
+/* Disable wchar func to clear vs warning */
+#define SECUREC_ENABLE_WCHAR_FUNC 0
+#define SECUREC_FORMAT_OUTPUT_INPUT 1
+
+#ifndef SECUREC_FOR_WCHAR
+#define SECUREC_FOR_WCHAR
+#endif
+
+#include "secureprintoutput.h"
+
+#include "output.inl"
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/snprintf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/snprintf_s.c
new file mode 100644
index 000000000..7c2940083
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/snprintf_s.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: snprintf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+#if SECUREC_ENABLE_SNPRINTF
+/*
+ * <FUNCTION DESCRIPTION>
+ * The snprintf_s function is equivalent to the snprintf function
+ * except for the parameter destMax/count and the explicit runtime-constraints violation
+ * The snprintf_s function formats and stores count or fewer characters in
+ * strDest and appends a terminating null. Each argument (if any) is converted
+ * and output according to the corresponding format specification in format.
+ * The formatting is consistent with the printf family of functions; If copying
+ * occurs between strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax The size of the storage location for output. Size
+ * in bytes for snprintf_s or size in words for snwprintf_s.
+ * count Maximum number of character to store.
+ * format Format-control string.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of characters written, not including the terminating null
+ * return -1 if an error occurs.
+ * return -1 if count < destMax and the output string has been truncated
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ *
+ */
+int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format,
+ ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vsnprintf_s(strDest, destMax, count, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(snprintf_s);
+#endif
+#endif
+
+#if SECUREC_SNPRINTF_TRUNCATED
+/*
+ * <FUNCTION DESCRIPTION>
+ * The snprintf_truncated_s function is equivalent to the snprintf function
+ * except for the parameter destMax/count and the explicit runtime-constraints violation
+ * The snprintf_truncated_s function formats and stores count or fewer characters in
+ * strDest and appends a terminating null. Each argument (if any) is converted
+ * and output according to the corresponding format specification in format.
+ * The formatting is consistent with the printf family of functions; If copying
+ * occurs between strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax The size of the storage location for output. Size
+ * in bytes for snprintf_truncated_s or size in words for snwprintf_s.
+ * format Format-control string.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of characters written, not including the terminating null
+ * return -1 if an error occurs.
+ * return destMax-1 if output string has been truncated
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ *
+ */
+int snprintf_truncated_s(char *strDest, size_t destMax, const char *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vsnprintf_truncated_s(strDest, destMax, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(snprintf_truncated_s);
+#endif
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sprintf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sprintf_s.c
new file mode 100644
index 000000000..b372c63d8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sprintf_s.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: sprintf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The sprintf_s function is equivalent to the sprintf function
+ * except for the parameter destMax and the explicit runtime-constraints violation
+ * The sprintf_s function formats and stores a series of characters and values
+ * in strDest. Each argument (if any) is converted and output according to
+ * the corresponding format specification in format. The format consists of
+ * ordinary characters and has the same form and function as the format argument
+ * for printf. A null character is appended after the last character written.
+ * If copying occurs between strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for output.
+ * destMax Maximum number of characters to store.
+ * format Format-control string.
+ * ... Optional arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of bytes stored in strDest, not counting the terminating null character.
+ * return -1 if an error occurred.
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+int sprintf_s(char *strDest, size_t destMax, const char *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vsprintf_s(strDest, destMax, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(sprintf_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sscanf_s.c
new file mode 100644
index 000000000..775ac75b6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/sscanf_s.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: sscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The sscanf_s function is equivalent to fscanf_s,
+ * except that input is obtained from a string (specified by the argument buffer) rather than from a stream
+ * The sscanf function reads data from buffer into the location given by each
+ * argument. Every argument must be a pointer to a variable with a type that
+ * corresponds to a type specifier in format. The format argument controls the
+ * interpretation of the input fields and has the same form and function as
+ * the format argument for the scanf function.
+ * If copying takes place between strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * buffer Stored data.
+ * format Format control string, see Format Specifications.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * ... The converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned.
+ * A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int sscanf_s(const char *buffer, const char *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vsscanf_s(buffer, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(sscanf_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcat_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcat_s.c
new file mode 100644
index 000000000..3fb9fe1f8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcat_s.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: strcat_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+/*
+ * Befor this function, the basic parameter checking has been done
+ */
+SECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax,
+ const char *strSrc)
+{
+ size_t destLen;
+ size_t srcLen;
+ size_t maxSrcLen;
+ SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);
+ /* Only optimize strSrc, do not apply this function to strDest */
+ maxSrcLen = destMax - destLen;
+ SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen);
+
+ if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
+ strDest[0] = '\0';
+ if (strDest + destLen <= strSrc && destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_BUFFER_OVERLAP("strcat_s");
+ return EOVERLAP_AND_RESET;
+ }
+ if (srcLen + destLen >= destMax || strDest == strSrc) {
+ strDest[0] = '\0';
+ if (destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_INVALID_RANGE("strcat_s");
+ return ERANGE_AND_RESET;
+ }
+ SECUREC_MEMCPY_WARP_OPT(
+ strDest + destLen, strSrc,
+ srcLen + 1); /* Single character length include \0 */
+ return EOK;
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The strcat_s function appends a copy of the string pointed to by strSrc (including the terminating null character)
+ * to the end of the string pointed to by strDest.
+ * The initial character of strSrc overwrites the terminating null character of strDest.
+ * strcat_s will return EOVERLAP_AND_RESET if the source and destination strings overlap.
+ *
+ * Note that the second parameter is the total size of the buffer, not the
+ * remaining size.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Null-terminated destination string buffer.
+ * destMax Size of the destination string buffer.
+ * strSrc Null-terminated source string buffer.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
+ * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
+ * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)
+ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
+ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc)
+{
+ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("strcat_s");
+ return ERANGE;
+ }
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("strcat_s");
+ if (strDest != NULL) {
+ strDest[0] = '\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ return SecDoCat(strDest, destMax, strSrc);
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(strcat_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcpy_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcpy_s.c
new file mode 100644
index 000000000..d4433f6af
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strcpy_s.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: strcpy_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Performance-sensitive
+ * [reason] Always used in the performance critical path,
+ * and sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+#ifndef SECUREC_STRCPY_WITH_PERFORMANCE
+#define SECUREC_STRCPY_WITH_PERFORMANCE 1
+#endif
+
+#define SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc) \
+ ((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && \
+ (strDest) != NULL && (strSrc) != NULL && (strDest) != (strSrc))
+
+#if (!SECUREC_IN_KERNEL) && SECUREC_STRCPY_WITH_PERFORMANCE
+#ifndef SECUREC_STRCOPY_THRESHOLD_SIZE
+#define SECUREC_STRCOPY_THRESHOLD_SIZE 32UL
+#endif
+/* The purpose of converting to void is to clean up the alarm */
+#define SECUREC_SMALL_STR_COPY(strDest, strSrc, lenWithTerm) \
+ do { \
+ if (SECUREC_ADDR_ALIGNED_8(strDest) && \
+ SECUREC_ADDR_ALIGNED_8(strSrc)) { \
+ /* Use struct assignment */ \
+ switch (lenWithTerm) { \
+ case 1: \
+ *(strDest) = *(strSrc); \
+ break; \
+ case 2: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 2); \
+ break; \
+ case 3: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 3); \
+ break; \
+ case 4: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 4); \
+ break; \
+ case 5: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 5); \
+ break; \
+ case 6: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 6); \
+ break; \
+ case 7: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 7); \
+ break; \
+ case 8: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 8); \
+ break; \
+ case 9: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 9); \
+ break; \
+ case 10: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 10); \
+ break; \
+ case 11: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 11); \
+ break; \
+ case 12: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 12); \
+ break; \
+ case 13: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 13); \
+ break; \
+ case 14: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 14); \
+ break; \
+ case 15: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 15); \
+ break; \
+ case 16: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 16); \
+ break; \
+ case 17: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 17); \
+ break; \
+ case 18: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 18); \
+ break; \
+ case 19: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 19); \
+ break; \
+ case 20: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 20); \
+ break; \
+ case 21: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 21); \
+ break; \
+ case 22: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 22); \
+ break; \
+ case 23: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 23); \
+ break; \
+ case 24: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 24); \
+ break; \
+ case 25: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 25); \
+ break; \
+ case 26: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 26); \
+ break; \
+ case 27: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 27); \
+ break; \
+ case 28: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 28); \
+ break; \
+ case 29: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 29); \
+ break; \
+ case 30: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 30); \
+ break; \
+ case 31: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 31); \
+ break; \
+ case 32: \
+ SECUREC_COPY_VALUE_BY_STRUCT((strDest), \
+ (strSrc), 32); \
+ break; \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } /* END switch */ \
+ } else { \
+ char *tmpStrDest_ = (char *)(strDest); \
+ const char *tmpStrSrc_ = (const char *)(strSrc); \
+ switch (lenWithTerm) { \
+ case 32: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 31: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 30: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 29: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 28: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 27: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 26: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 25: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 24: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 23: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 22: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 21: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 20: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 19: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 18: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 17: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 16: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 15: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 14: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 13: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 12: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 11: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 10: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 9: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 8: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 7: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 6: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 5: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 4: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 3: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 2: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ case 1: \
+ *(tmpStrDest_++) = *(tmpStrSrc_++); \
+ FALLTHROUGH; /* fall-through */ /* FALLTHRU */ \
+ default: \
+ /* Do nothing */ \
+ break; \
+ } \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+#endif
+
+#if SECUREC_IN_KERNEL || (!SECUREC_STRCPY_WITH_PERFORMANCE)
+#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) \
+ SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm))
+#else
+/*
+ * Performance optimization. lenWithTerm include '\0'
+ */
+#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) \
+ do { \
+ if ((lenWithTerm) > SECUREC_STRCOPY_THRESHOLD_SIZE) { \
+ SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)); \
+ } else { \
+ SECUREC_SMALL_STR_COPY((dest), (src), (lenWithTerm)); \
+ } \
+ } \
+ SECUREC_WHILE_ZERO
+#endif
+
+/*
+ * Check Src Range
+ */
+SECUREC_INLINE errno_t CheckSrcRange(char *strDest, size_t destMax,
+ const char *strSrc)
+{
+ size_t tmpDestMax = destMax;
+ const char *tmpSrc = strSrc;
+ /* Use destMax as boundary checker and destMax must be greater than zero */
+ while (*tmpSrc != '\0' && tmpDestMax > 0) {
+ ++tmpSrc;
+ --tmpDestMax;
+ }
+ if (tmpDestMax == 0) {
+ strDest[0] = '\0';
+ SECUREC_ERROR_INVALID_RANGE("strcpy_s");
+ return ERANGE_AND_RESET;
+ }
+ return EOK;
+}
+
+/*
+ * Handling errors
+ */
+errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc)
+{
+ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("strcpy_s");
+ return ERANGE;
+ }
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("strcpy_s");
+ if (strDest != NULL) {
+ strDest[0] = '\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ return CheckSrcRange(strDest, destMax, strSrc);
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The strcpy_s function copies the string pointed to strSrc
+ * (including the terminating null character) into the array pointed to by strDest
+ * The destination string must be large enough to hold the source string,
+ * including the terminating null character. strcpy_s will return EOVERLAP_AND_RESET
+ * if the source and destination strings overlap.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Location of destination string buffer
+ * destMax Size of the destination string buffer.
+ * strSrc Null-terminated source string buffer.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
+ * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
+ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
+ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc)
+{
+ if (SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc)) {
+ size_t srcStrLen;
+ SECUREC_CALC_STR_LEN(strSrc, destMax, &srcStrLen);
+ ++srcStrLen; /* The length include '\0' */
+
+ if (srcStrLen <= destMax) {
+ /* Use mem overlap check include '\0' */
+ if (SECUREC_MEMORY_NO_OVERLAP(strDest, strSrc,
+ srcStrLen)) {
+ /* Performance optimization srcStrLen include '\0' */
+ SECUREC_STRCPY_OPT(strDest, strSrc, srcStrLen);
+ return EOK;
+ } else {
+ strDest[0] = '\0';
+ SECUREC_ERROR_BUFFER_OVERLAP("strcpy_s");
+ return EOVERLAP_AND_RESET;
+ }
+ }
+ }
+ return strcpy_error(strDest, destMax, strSrc);
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(strcpy_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncat_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncat_s.c
new file mode 100644
index 000000000..8a8986918
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncat_s.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: strncat_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+/*
+ * Befor this function, the basic parameter checking has been done
+ */
+SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax,
+ const char *strSrc, size_t count)
+{
+ size_t destLen;
+ size_t srcLen;
+ SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);
+ /*
+ * The strSrc is no longer optimized. The reason is that when count is small,
+ * the efficiency of strnlen is higher than that of self realization.
+ */
+ SECUREC_CALC_STR_LEN(strSrc, count, &srcLen);
+
+ if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
+ strDest[0] = '\0';
+ if (strDest + destLen <= strSrc && destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_BUFFER_OVERLAP("strncat_s");
+ return EOVERLAP_AND_RESET;
+ }
+ if (srcLen + destLen >= destMax || strDest == strSrc) {
+ strDest[0] = '\0';
+ if (destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_INVALID_RANGE("strncat_s");
+ return ERANGE_AND_RESET;
+ }
+ SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
+ srcLen); /* No terminator */
+ *(strDest + destLen + srcLen) = '\0';
+ return EOK;
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The strncat_s function appends not more than n successive characters
+ * (not including the terminating null character)
+ * from the array pointed to by strSrc to the end of the string pointed to by strDest
+ * The strncat_s function try to append the first D characters of strSrc to
+ * the end of strDest, where D is the lesser of count and the length of strSrc.
+ * If appending those D characters will fit within strDest (whose size is given
+ * as destMax) and still leave room for a null terminator, then those characters
+ * are appended, starting at the original terminating null of strDest, and a
+ * new terminating null is appended; otherwise, strDest[0] is set to the null
+ * character.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Null-terminated destination string.
+ * destMax Size of the destination buffer.
+ * strSrc Null-terminated source string.
+ * count Number of character to append, or truncate.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
+ * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid)or
+ * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)
+ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
+ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc,
+ size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("strncat_s");
+ return ERANGE;
+ }
+
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("strncat_s");
+ if (strDest != NULL) {
+ strDest[0] = '\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ if (count > SECUREC_STRING_MAX_LEN) {
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+ if (count == (size_t)(-1)) {
+ /* Windows internal functions may pass in -1 when calling this function */
+ return SecDoCatLimit(strDest, destMax, strSrc, destMax);
+ }
+#endif
+ strDest[0] = '\0';
+ SECUREC_ERROR_INVALID_RANGE("strncat_s");
+ return ERANGE_AND_RESET;
+ }
+ return SecDoCatLimit(strDest, destMax, strSrc, count);
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(strncat_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncpy_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncpy_s.c
new file mode 100644
index 000000000..dd6439bb7
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strncpy_s.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: strncpy_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Performance-sensitive
+ * [reason] Always used in the performance critical path,
+ * and sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
+#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \
+ (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && \
+ (strDest) != NULL && (strSrc) != NULL && \
+ ((count) <= SECUREC_STRING_MAX_LEN || (count) == ((size_t)(-1))) && \
+ (count) > 0))
+#else
+#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \
+ (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && \
+ (strDest) != NULL && (strSrc) != NULL && \
+ (count) <= SECUREC_STRING_MAX_LEN && (count) > 0))
+#endif
+
+/*
+ * Check Src Count Range
+ */
+SECUREC_INLINE errno_t CheckSrcCountRange(char *strDest, size_t destMax,
+ const char *strSrc, size_t count)
+{
+ size_t tmpDestMax = destMax;
+ size_t tmpCount = count;
+ const char *endPos = strSrc;
+
+ /* Use destMax and count as boundary checker and destMax must be greater than zero */
+ while (*(endPos) != '\0' && tmpDestMax > 0 && tmpCount > 0) {
+ ++endPos;
+ --tmpCount;
+ --tmpDestMax;
+ }
+ if (tmpDestMax == 0) {
+ strDest[0] = '\0';
+ SECUREC_ERROR_INVALID_RANGE("strncpy_s");
+ return ERANGE_AND_RESET;
+ }
+ return EOK;
+}
+
+/*
+ * Handling errors, when dest equal src return EOK
+ */
+errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc,
+ size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("strncpy_s");
+ return ERANGE;
+ }
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("strncpy_s");
+ if (strDest != NULL) {
+ strDest[0] = '\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ if (count > SECUREC_STRING_MAX_LEN) {
+ strDest[0] = '\0'; /* Clear dest string */
+ SECUREC_ERROR_INVALID_RANGE("strncpy_s");
+ return ERANGE_AND_RESET;
+ }
+ if (count == 0) {
+ strDest[0] = '\0';
+ return EOK;
+ }
+ return CheckSrcCountRange(strDest, destMax, strSrc, count);
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The strncpy_s function copies not more than n successive characters (not including the terminating null character)
+ * from the array pointed to by strSrc to the array pointed to by strDest.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Destination string.
+ * destMax The size of the destination string, in characters.
+ * strSrc Source string.
+ * count Number of characters to be copied.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
+ * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN
+ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN
+ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc,
+ size_t count)
+{
+ if (SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count)) {
+ size_t minCpLen; /* Use it to store the maxi length limit */
+ if (count < destMax) {
+ SECUREC_CALC_STR_LEN(
+ strSrc, count,
+ &minCpLen); /* No ending terminator */
+ } else {
+ size_t tmpCount = destMax;
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+ if (count == ((size_t)(-1))) {
+ tmpCount = destMax - 1;
+ }
+#endif
+ SECUREC_CALC_STR_LEN(
+ strSrc, tmpCount,
+ &minCpLen); /* No ending terminator */
+ if (minCpLen == destMax) {
+ strDest[0] = '\0';
+ SECUREC_ERROR_INVALID_RANGE("strncpy_s");
+ return ERANGE_AND_RESET;
+ }
+ }
+ if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, minCpLen) ||
+ strDest == strSrc) {
+ /* Not overlap */
+ SECUREC_MEMCPY_WARP_OPT(
+ strDest, strSrc,
+ minCpLen); /* Copy string without terminator */
+ strDest[minCpLen] = '\0';
+ return EOK;
+ } else {
+ strDest[0] = '\0';
+ SECUREC_ERROR_BUFFER_OVERLAP("strncpy_s");
+ return EOVERLAP_AND_RESET;
+ }
+ }
+ return strncpy_error(strDest, destMax, strSrc, count);
+}
+
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(strncpy_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strtok_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strtok_s.c
new file mode 100644
index 000000000..3530b0725
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/strtok_s.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: strtok_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+SECUREC_INLINE int SecIsInDelimit(char ch, const char *strDelimit)
+{
+ const char *ctl = strDelimit;
+ while (*ctl != '\0' && *ctl != ch) {
+ ++ctl;
+ }
+ return (int)(*ctl != '\0');
+}
+
+/*
+ * Find beginning of token (skip over leading delimiters).
+ * Note that there is no token if this loop sets string to point to the terminal null.
+ */
+SECUREC_INLINE char *SecFindBegin(char *strToken, const char *strDelimit)
+{
+ char *token = strToken;
+ while (*token != '\0') {
+ if (SecIsInDelimit(*token, strDelimit) != 0) {
+ ++token;
+ continue;
+ }
+ /* Don't find any delimiter in string header, break the loop */
+ break;
+ }
+ return token;
+}
+
+/*
+ * Find rest of token
+ */
+SECUREC_INLINE char *SecFindRest(char *strToken, const char *strDelimit)
+{
+ /* Find the rest of the token. If it is not the end of the string, put a null there */
+ char *token = strToken;
+ while (*token != '\0') {
+ if (SecIsInDelimit(*token, strDelimit) != 0) {
+ /* Find a delimiter, set string terminator */
+ *token = '\0';
+ ++token;
+ break;
+ }
+ ++token;
+ }
+ return token;
+}
+
+/*
+ * Find the final position pointer
+ */
+SECUREC_INLINE char *SecUpdateToken(char *strToken, const char *strDelimit,
+ char **context)
+{
+ /* Point to updated position. Record string position for next search in the context */
+ *context = SecFindRest(strToken, strDelimit);
+ /* Determine if a token has been found. */
+ if (*context == strToken) {
+ return NULL;
+ }
+ return strToken;
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The strtok_s function parses a string into a sequence of strToken,
+ * replace all characters in strToken string that match to strDelimit set with 0.
+ * On the first call to strtok_s the string to be parsed should be specified in strToken.
+ * In each subsequent call that should parse the same string, strToken should be NULL
+ * <INPUT PARAMETERS>
+ * strToken String containing token or tokens.
+ * strDelimit Set of delimiter characters.
+ * context Used to store position information between calls
+ * to strtok_s
+ * <OUTPUT PARAMETERS>
+ * context is updated
+ * <RETURN VALUE>
+ * On the first call returns the address of the first non \0 character, otherwise NULL is returned.
+ * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call,
+ * return NULL if the *context string length is equal 0, otherwise return *context.
+ */
+char *strtok_s(char *strToken, const char *strDelimit, char **context)
+{
+ char *orgToken = strToken;
+ /* Validate delimiter and string context */
+ if (context == NULL || strDelimit == NULL) {
+ return NULL;
+ }
+ /* Valid input string and string pointer from where to search */
+ if (orgToken == NULL && *context == NULL) {
+ return NULL;
+ }
+ /* If string is null, continue searching from previous string position stored in context */
+ if (orgToken == NULL) {
+ orgToken = *context;
+ }
+ orgToken = SecFindBegin(orgToken, strDelimit);
+ return SecUpdateToken(orgToken, strDelimit, context);
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(strtok_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swprintf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swprintf_s.c
new file mode 100644
index 000000000..c7e2bb67f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swprintf_s.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: swprintf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The swprintf_s function is the wide-character equivalent of the sprintf_s function
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax Maximum number of characters to store.
+ * format Format-control string.
+ * ... Optional arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of wide characters stored in strDest, not counting the terminating null wide character.
+ * return -1 if an error occurred.
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vswprintf_s(strDest, destMax, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swscanf_s.c
new file mode 100644
index 000000000..47456e045
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/swscanf_s.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: swscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The swscanf_s function is the wide-character equivalent of the sscanf_s function
+ * The swscanf_s function reads data from buffer into the location given by
+ * each argument. Every argument must be a pointer to a variable with a type
+ * that corresponds to a type specifier in format. The format argument controls
+ * the interpretation of the input fields and has the same form and function
+ * as the format argument for the scanf function. If copying takes place between
+ * strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * buffer Stored data.
+ * format Format control string, see Format Specifications.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * ... the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; The return value does not include fields that were read but not
+ * assigned.
+ * A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vswscanf_s(buffer, format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfscanf_s.c
new file mode 100644
index 000000000..9e8fb46b5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfscanf_s.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vfscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "secinput.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vfscanf_s function is equivalent to fscanf_s, with the variable argument list replaced by argList
+ * The vfscanf_s function reads data from the current position of stream into
+ * the locations given by argument (if any). Each argument must be a pointer
+ * to a variable of a type that corresponds to a type specifier in format.
+ * format controls the interpretation of the input fields and has the same
+ * form and function as the format argument for scanf.
+ *
+ * <INPUT PARAMETERS>
+ * stream Pointer to FILE structure.
+ * format Format control string, see Format Specifications.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * argList the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned. A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int vfscanf_s(FILE *stream, const char *format, va_list argList)
+{
+ int retVal; /* If initialization causes e838 */
+ SecFileStream fStr;
+
+ if (stream == NULL || format == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ if (stream == SECUREC_STREAM_STDIN) {
+ return vscanf_s(format, argList);
+ }
+
+ SECUREC_LOCK_FILE(stream);
+ SECUREC_FILE_STREAM_FROM_FILE(&fStr, stream);
+ retVal = SecInputS(&fStr, format, argList);
+ SECUREC_UNLOCK_FILE(stream);
+ if (retVal < 0) {
+ SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+
+ return retVal;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfwscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfwscanf_s.c
new file mode 100644
index 000000000..e5bfd0d9e
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vfwscanf_s.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vfwscanf_s function
+ * Create: 2014-02-25
+ */
+
+#ifndef SECUREC_FOR_WCHAR
+#define SECUREC_FOR_WCHAR
+#endif
+
+#include "secinput.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function
+ * The vfwscanf_s function reads data from the current position of stream into
+ * the locations given by argument (if any). Each argument must be a pointer
+ * to a variable of a type that corresponds to a type specifier in format.
+ * format controls the interpretation of the input fields and has the same form
+ * and function as the format argument for scanf.
+ *
+ * <INPUT PARAMETERS>
+ * stream Pointer to FILE structure.
+ * format Format control string, see Format Specifications.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * argList the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned. A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList)
+{
+ int retVal; /* If initialization causes e838 */
+ SecFileStream fStr;
+
+ if (stream == NULL || format == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ if (stream == SECUREC_STREAM_STDIN) {
+ return vwscanf_s(format, argList);
+ }
+
+ SECUREC_LOCK_FILE(stream);
+ SECUREC_FILE_STREAM_FROM_FILE(&fStr, stream);
+ retVal = SecInputSW(&fStr, format, argList);
+ SECUREC_UNLOCK_FILE(stream);
+ if (retVal < 0) {
+ SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ return retVal;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vscanf_s.c
new file mode 100644
index 000000000..45e8a52e6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vscanf_s.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "secinput.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList,
+ * The vscanf_s function reads data from the standard input stream stdin and
+ * writes the data into the location that's given by argument. Each argument
+ * must be a pointer to a variable of a type that corresponds to a type specifier
+ * in format. If copying occurs between strings that overlap, the behavior is
+ * undefined.
+ *
+ * <INPUT PARAMETERS>
+ * format Format control string.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * argList the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Returns the number of fields successfully converted and assigned;
+ * the return value does not include fields that were read but not assigned.
+ * A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int vscanf_s(const char *format, va_list argList)
+{
+ int retVal; /* If initialization causes e838 */
+ SecFileStream fStr;
+ SECUREC_FILE_STREAM_FROM_STDIN(&fStr);
+ /*
+ * The "va_list" has different definition on different platform, so we can't use argList == NULL
+ * To determine it's invalid. If you has fixed platform, you can check some fields to validate it,
+ * such as "argList == NULL" or argList.xxx != NULL or *(size_t *)&argList != 0.
+ */
+ if (format == NULL || fStr.pf == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("vscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+
+ SECUREC_LOCK_STDIN(0, fStr.pf);
+ retVal = SecInputS(&fStr, format, argList);
+ SECUREC_UNLOCK_STDIN(0, fStr.pf);
+ if (retVal < 0) {
+ SECUREC_ERROR_INVALID_PARAMTER("vscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ return retVal;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsnprintf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsnprintf_s.c
new file mode 100644
index 000000000..bb70dcbc9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsnprintf_s.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vsnprintf_s function
+ * Create: 2014-02-25
+ */
+
+#include "secureprintoutput.h"
+
+#if SECUREC_ENABLE_VSNPRINTF
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vsnprintf_s function is equivalent to the vsnprintf function
+ * except for the parameter destMax/count and the explicit runtime-constraints violation
+ * The vsnprintf_s function takes a pointer to an argument list, then formats
+ * and writes up to count characters of the given data to the memory pointed
+ * to by strDest and appends a terminating null.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax The size of the strDest for output.
+ * count Maximum number of character to write(not including
+ * the terminating NULL)
+ * format Format-control string.
+ * argList pointer to list of arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of characters written, not including the terminating null
+ * return -1 if an error occurs.
+ * return -1 if count < destMax and the output string has been truncated
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format,
+ va_list argList)
+{
+ int retVal;
+
+ if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count,
+ SECUREC_STRING_MAX_LEN)) {
+ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax,
+ SECUREC_STRING_MAX_LEN);
+ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s");
+ return -1;
+ }
+
+ if (destMax > count) {
+ retVal = SecVsnprintfImpl(strDest, count + 1, format, argList);
+ if (retVal ==
+ SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not destroyed 2014.2.18 */
+ /* The string has been truncated, return -1 */
+ return -1; /* To skip error handler, return strlen(strDest) or -1 */
+ }
+ } else {
+ retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+ if (retVal == SECUREC_PRINTF_TRUNCATE &&
+ count == (size_t)(-1)) {
+ return -1;
+ }
+#endif
+ }
+
+ if (retVal < 0) {
+ strDest[0] = '\0'; /* Empty the dest strDest */
+ if (retVal == SECUREC_PRINTF_TRUNCATE) {
+ /* Buffer too small */
+ SECUREC_ERROR_INVALID_RANGE("vsnprintf_s");
+ }
+ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s");
+ return -1;
+ }
+
+ return retVal;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(vsnprintf_s);
+#endif
+#endif
+
+#if SECUREC_SNPRINTF_TRUNCATED
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vsnprintf_truncated_s function is equivalent to the vsnprintf function
+ * except for the parameter destMax/count and the explicit runtime-constraints violation
+ * The vsnprintf_truncated_s function takes a pointer to an argument list, then formats
+ * and writes up to count characters of the given data to the memory pointed
+ * to by strDest and appends a terminating null.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax The size of the strDest for output.
+ * the terminating NULL)
+ * format Format-control string.
+ * argList pointer to list of arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of characters written, not including the terminating null
+ * return -1 if an error occurs.
+ * return destMax-1 if output string has been truncated
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format,
+ va_list argList)
+{
+ int retVal;
+
+ if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax,
+ SECUREC_STRING_MAX_LEN)) {
+ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax,
+ SECUREC_STRING_MAX_LEN);
+ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s");
+ return -1;
+ }
+
+ retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
+ if (retVal < 0) {
+ if (retVal == SECUREC_PRINTF_TRUNCATE) {
+ return (int)(destMax -
+ 1); /* To skip error handler, return strlen(strDest) */
+ }
+ strDest[0] = '\0'; /* Empty the dest strDest */
+ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s");
+ return -1;
+ }
+
+ return retVal;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(vsnprintf_truncated_s);
+#endif
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsprintf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsprintf_s.c
new file mode 100644
index 000000000..0d2611a17
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsprintf_s.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vsprintf_s function
+ * Create: 2014-02-25
+ */
+
+#include "secureprintoutput.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vsprintf_s function is equivalent to the vsprintf function
+ * except for the parameter destMax and the explicit runtime-constraints violation
+ * The vsprintf_s function takes a pointer to an argument list, and then formats
+ * and writes the given data to the memory pointed to by strDest.
+ * The function differ from the non-secure versions only in that the secure
+ * versions support positional parameters.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax Size of strDest
+ * format Format specification.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of characters written, not including the terminating null character,
+ * return -1 if an error occurs.
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+int vsprintf_s(char *strDest, size_t destMax, const char *format,
+ va_list argList)
+{
+ int retVal; /* If initialization causes e838 */
+
+ if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax,
+ SECUREC_STRING_MAX_LEN)) {
+ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax,
+ SECUREC_STRING_MAX_LEN);
+ SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s");
+ return -1;
+ }
+
+ retVal = SecVsnprintfImpl(strDest, destMax, format, argList);
+ if (retVal < 0) {
+ strDest[0] = '\0';
+ if (retVal == SECUREC_PRINTF_TRUNCATE) {
+ /* Buffer is too small */
+ SECUREC_ERROR_INVALID_RANGE("vsprintf_s");
+ }
+ SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s");
+ return -1;
+ }
+
+ return retVal;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(vsprintf_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsscanf_s.c
new file mode 100644
index 000000000..9d4626f11
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vsscanf_s.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vsscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "secinput.h"
+#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL && \
+ (!defined(SECUREC_SYSAPI4VXWORKS) && \
+ !defined(SECUREC_CTYPE_MACRO_ADAPT))
+#include <ctype.h>
+#endif
+
+/*
+ * <NAME>
+ * vsscanf_s
+ *
+ *
+ * <FUNCTION DESCRIPTION>
+ * The vsscanf_s function is equivalent to sscanf_s, with the variable argument list replaced by argList
+ * The vsscanf_s function reads data from buffer into the location given by
+ * each argument. Every argument must be a pointer to a variable with a type
+ * that corresponds to a type specifier in format. The format argument controls
+ * the interpretation of the input fields and has the same form and function
+ * as the format argument for the scanf function.
+ * If copying takes place between strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * buffer Stored data
+ * format Format control string, see Format Specifications.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * argList the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned. A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int vsscanf_s(const char *buffer, const char *format, va_list argList)
+{
+ size_t count; /* If initialization causes e838 */
+ int retVal;
+ SecFileStream fStr;
+
+ /* Validation section */
+ if (buffer == NULL || format == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ count = strlen(buffer);
+ if (count == 0 || count > SECUREC_STRING_MAX_LEN) {
+ SecClearDestBuf(buffer, format, argList);
+ SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL
+ /*
+ * On vxworks platform when buffer is white string, will set first %s argument to zero.Like following usage:
+ * " \v\f\t\r\n", "%s", str, strSize
+ * Do not check all character, just first and last character then consider it is white string
+ */
+ if (isspace((int)(unsigned char)buffer[0]) != 0 &&
+ isspace((int)(unsigned char)buffer[count - 1]) != 0) {
+ SecClearDestBuf(buffer, format, argList);
+ }
+#endif
+ SECUREC_FILE_STREAM_FROM_STRING(&fStr, buffer, count);
+ retVal = SecInputS(&fStr, format, argList);
+ if (retVal < 0) {
+ SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ return retVal;
+}
+#if SECUREC_EXPORT_KERNEL_SYMBOL
+EXPORT_SYMBOL(vsscanf_s);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswprintf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswprintf_s.c
new file mode 100644
index 000000000..70931ca97
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswprintf_s.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vswprintf_s function
+ * Create: 2014-02-25
+ */
+
+#ifndef SECUREC_FOR_WCHAR
+#define SECUREC_FOR_WCHAR
+#endif
+
+#include "secureprintoutput.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vswprintf_s function is the wide-character equivalent of the vsprintf_s function
+ *
+ * <INPUT PARAMETERS>
+ * strDest Storage location for the output.
+ * destMax Maximum number of characters to store
+ * format Format specification.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * return the number of wide characters stored in strDest, not counting the terminating null wide character.
+ * return -1 if an error occurred.
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format,
+ va_list argList)
+{
+ int retVal; /* If initialization causes e838 */
+ if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax,
+ SECUREC_WCHAR_STRING_MAX_LEN)) {
+ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax,
+ SECUREC_WCHAR_STRING_MAX_LEN);
+ SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s");
+ return -1;
+ }
+
+ retVal = SecVswprintfImpl(strDest, destMax, format, argList);
+ if (retVal < 0) {
+ strDest[0] = L'\0';
+ if (retVal == SECUREC_PRINTF_TRUNCATE) {
+ /* Buffer too small */
+ SECUREC_ERROR_INVALID_RANGE("vswprintf_s");
+ }
+ SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s");
+ return -1;
+ }
+
+ return retVal;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswscanf_s.c
new file mode 100644
index 000000000..c276a360a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vswscanf_s.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vswscanf_s function
+ * Create: 2014-02-25
+ */
+
+#ifndef SECUREC_FOR_WCHAR
+#define SECUREC_FOR_WCHAR
+#endif
+
+#include "secinput.h"
+
+SECUREC_INLINE size_t SecWcslen(const wchar_t *s)
+{
+ const wchar_t *end = s;
+ while (*end != L'\0') {
+ ++end;
+ }
+ return ((size_t)((end - s)));
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vswscanf_s function is the wide-character equivalent of the vsscanf_s function
+ * The vsscanf_s function reads data from buffer into the location given by
+ * each argument. Every argument must be a pointer to a variable with a type
+ * that corresponds to a type specifier in format.
+ * The format argument controls the interpretation of the input fields and
+ * has the same form and function as the format argument for the scanf function.
+ * If copying takes place between strings that overlap, the behavior is undefined.
+ *
+ * <INPUT PARAMETERS>
+ * buffer Stored data
+ * format Format control string, see Format Specifications.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * argList the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Each of these functions returns the number of fields successfully converted
+ * and assigned; the return value does not include fields that were read but
+ * not assigned. A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList)
+{
+ size_t count; /* If initialization causes e838 */
+ SecFileStream fStr;
+ int retVal;
+
+ /* Validation section */
+ if (buffer == NULL || format == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ count = SecWcslen(buffer);
+ if (count == 0 || count > SECUREC_WCHAR_STRING_MAX_LEN) {
+ SecClearDestBufW(buffer, format, argList);
+ SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ SECUREC_FILE_STREAM_FROM_STRING(&fStr, (const char *)buffer,
+ count * sizeof(wchar_t));
+ retVal = SecInputSW(&fStr, format, argList);
+ if (retVal < 0) {
+ SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+ return retVal;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vwscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vwscanf_s.c
new file mode 100644
index 000000000..5362fcaaf
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/vwscanf_s.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: vwscanf_s function
+ * Create: 2014-02-25
+ */
+
+#ifndef SECUREC_FOR_WCHAR
+#define SECUREC_FOR_WCHAR
+#endif
+
+#include "secinput.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The vwscanf_s function is the wide-character equivalent of the vscanf_s function
+ * The vwscanf_s function is the wide-character version of vscanf_s. The
+ * function reads data from the standard input stream stdin and writes the
+ * data into the location that's given by argument. Each argument must be a
+ * pointer to a variable of a type that corresponds to a type specifier in
+ * format. If copying occurs between strings that overlap, the behavior is
+ * undefined.
+ *
+ * <INPUT PARAMETERS>
+ * format Format control string.
+ * argList pointer to list of arguments
+ *
+ * <OUTPUT PARAMETERS>
+ * argList the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Returns the number of fields successfully converted and assigned;
+ * the return value does not include fields that were read but not assigned.
+ * A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int vwscanf_s(const wchar_t *format, va_list argList)
+{
+ int retVal; /* If initialization causes e838 */
+ SecFileStream fStr;
+ SECUREC_FILE_STREAM_FROM_STDIN(&fStr);
+ if (format == NULL || fStr.pf == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+
+ SECUREC_LOCK_STDIN(0, fStr.pf);
+ retVal = SecInputSW(&fStr, format, argList);
+ SECUREC_UNLOCK_STDIN(0, fStr.pf);
+ if (retVal < 0) {
+ SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s");
+ return SECUREC_SCANF_EINVAL;
+ }
+
+ return retVal;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscat_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscat_s.c
new file mode 100644
index 000000000..245c504d8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscat_s.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wcscat_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+/*
+ * Befor this function, the basic parameter checking has been done
+ */
+SECUREC_INLINE errno_t SecDoCatW(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc)
+{
+ size_t destLen;
+ size_t srcLen;
+ size_t maxCount; /* Store the maximum available count */
+
+ /* To calculate the length of a wide character, the parameter must be a wide character */
+ SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
+ maxCount = destMax - destLen;
+ SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen);
+
+ if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
+ strDest[0] = L'\0';
+ if (strDest + destLen <= strSrc && destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s");
+ return EOVERLAP_AND_RESET;
+ }
+ if (srcLen + destLen >= destMax || strDest == strSrc) {
+ strDest[0] = L'\0';
+ if (destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_INVALID_RANGE("wcscat_s");
+ return ERANGE_AND_RESET;
+ }
+ /* Copy single character length include \0 */
+ SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
+ (srcLen + 1) * sizeof(wchar_t));
+ return EOK;
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The wcscat_s function appends a copy of the wide string pointed to by strSrc
+* (including the terminating null wide character)
+ * to the end of the wide string pointed to by strDest.
+ * The arguments and return value of wcscat_s are wide-character strings.
+ *
+ * The wcscat_s function appends strSrc to strDest and terminates the resulting
+ * string with a null character. The initial character of strSrc overwrites the
+ * terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the
+ * source and destination strings overlap.
+ *
+ * Note that the second parameter is the total size of the buffer, not the
+ * remaining size.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Null-terminated destination string buffer.
+ * destMax Size of the destination string buffer.
+ * strSrc Null-terminated source string buffer.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
+ * (strDest != NULL and strSrc is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
+ * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
+ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
+{
+ if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("wcscat_s");
+ return ERANGE;
+ }
+
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcscat_s");
+ if (strDest != NULL) {
+ strDest[0] = L'\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+
+ return SecDoCatW(strDest, destMax, strSrc);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscpy_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscpy_s.c
new file mode 100644
index 000000000..458facfff
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcscpy_s.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wcscpy_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+SECUREC_INLINE errno_t SecDoCpyW(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc)
+{
+ size_t srcStrLen;
+ SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);
+
+ if (srcStrLen == destMax) {
+ strDest[0] = L'\0';
+ SECUREC_ERROR_INVALID_RANGE("wcscpy_s");
+ return ERANGE_AND_RESET;
+ }
+ if (strDest == strSrc) {
+ return EOK;
+ }
+
+ if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {
+ /* Performance optimization, srcStrLen is single character length include '\0' */
+ SECUREC_MEMCPY_WARP_OPT(strDest, strSrc,
+ (srcStrLen + 1) * sizeof(wchar_t));
+ return EOK;
+ } else {
+ strDest[0] = L'\0';
+ SECUREC_ERROR_BUFFER_OVERLAP("wcscpy_s");
+ return EOVERLAP_AND_RESET;
+ }
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The wcscpy_s function copies the wide string pointed to by strSrc
+ * (including the terminating null wide character) into the array pointed to by strDest
+
+ * <INPUT PARAMETERS>
+ * strDest Destination string buffer
+ * destMax Size of the destination string buffer.
+ * strSrc Null-terminated source string buffer.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
+ * ERANGE_AND_RESET destMax <= length of strSrc and strDest != strSrc
+ * and strDest != NULL and strSrc != NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and destMax != 0
+ * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * and strDest != NULL and strSrc !=NULL and strDest != strSrc
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)
+{
+ if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("wcscpy_s");
+ return ERANGE;
+ }
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcscpy_s");
+ if (strDest != NULL) {
+ strDest[0] = L'\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ return SecDoCpyW(strDest, destMax, strSrc);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncat_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncat_s.c
new file mode 100644
index 000000000..789e28859
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncat_s.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wcsncat_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+/*
+ * Befor this function, the basic parameter checking has been done
+ */
+SECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc, size_t count)
+{
+ /* To calculate the length of a wide character, the parameter must be a wide character */
+ size_t destLen;
+ size_t srcLen;
+ SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);
+ SECUREC_CALC_WSTR_LEN(strSrc, count, &srcLen);
+
+ if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {
+ strDest[0] = L'\0';
+ if (strDest + destLen <= strSrc && destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_BUFFER_OVERLAP("wcsncat_s");
+ return EOVERLAP_AND_RESET;
+ }
+ if (srcLen + destLen >= destMax || strDest == strSrc) {
+ strDest[0] = L'\0';
+ if (destLen == destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
+ return EINVAL_AND_RESET;
+ }
+ SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
+ return ERANGE_AND_RESET;
+ }
+ SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc,
+ srcLen * sizeof(wchar_t)); /* no terminator */
+ *(strDest + destLen + srcLen) = L'\0';
+ return EOK;
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The wcsncat_s function appends not more than n successive wide characters
+ * (not including the terminating null wide character)
+ * from the array pointed to by strSrc to the end of the wide string pointed to by strDest.
+ *
+ * The wcsncat_s function try to append the first D characters of strSrc to
+ * the end of strDest, where D is the lesser of count and the length of strSrc.
+ * If appending those D characters will fit within strDest (whose size is
+ * given as destMax) and still leave room for a null terminator, then those
+ * characters are appended, starting at the original terminating null of
+ * strDest, and a new terminating null is appended; otherwise, strDest[0] is
+ * set to the null character.
+ *
+ * <INPUT PARAMETERS>
+ * strDest Null-terminated destination string.
+ * destMax Size of the destination buffer.
+ * strSrc Null-terminated source string.
+ * count Number of character to append, or truncate.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or
+ * (strDest != NULL and strSrc is NULL and destMax != 0 and
+ * destMax <= SECUREC_WCHAR_STRING_MAX_LEN)
+ * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
+ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc,
+ size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
+ return ERANGE;
+ }
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s");
+ if (strDest != NULL) {
+ strDest[0] = L'\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+ if (count == ((size_t)(-1))) {
+ /* Windows internal functions may pass in -1 when calling this function */
+ return SecDoCatLimitW(strDest, destMax, strSrc,
+ destMax);
+ }
+#endif
+ strDest[0] = L'\0';
+ SECUREC_ERROR_INVALID_RANGE("wcsncat_s");
+ return ERANGE_AND_RESET;
+ }
+ return SecDoCatLimitW(strDest, destMax, strSrc, count);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncpy_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncpy_s.c
new file mode 100644
index 000000000..13a9a6c0b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcsncpy_s.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wcsncpy_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+SECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax,
+ const wchar_t *strSrc, size_t count)
+{
+ size_t srcStrLen;
+ if (count < destMax) {
+ SECUREC_CALC_WSTR_LEN(strSrc, count, &srcStrLen);
+ } else {
+ SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);
+ }
+ if (srcStrLen == destMax) {
+ strDest[0] = L'\0';
+ SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
+ return ERANGE_AND_RESET;
+ }
+ if (strDest == strSrc) {
+ return EOK;
+ }
+ if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {
+ /* Performance optimization srcStrLen not include '\0' */
+ SECUREC_MEMCPY_WARP_OPT(strDest, strSrc,
+ srcStrLen * sizeof(wchar_t));
+ *(strDest + srcStrLen) = L'\0';
+ return EOK;
+ } else {
+ strDest[0] = L'\0';
+ SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s");
+ return EOVERLAP_AND_RESET;
+ }
+}
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The wcsncpy_s function copies not more than n successive wide characters
+ * (not including the terminating null wide character)
+ * from the array pointed to by strSrc to the array pointed to by strDest
+ *
+ * <INPUT PARAMETERS>
+ * strDest Destination string.
+ * destMax The size of the destination string, in characters.
+ * strSrc Source string.
+ * count Number of characters to be copied.
+ *
+ * <OUTPUT PARAMETERS>
+ * strDest is updated
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN
+ * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0
+ * ERANGE_AND_RESET count > SECUREC_WCHAR_STRING_MAX_LEN or
+ * (destMax <= length of strSrc and destMax <= count and strDest != strSrc
+ * and strDest != NULL and strSrc != NULL and destMax != 0 and
+ * destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap)
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid
+ *
+ *
+ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid
+ */
+errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc,
+ size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {
+ SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
+ return ERANGE;
+ }
+ if (strDest == NULL || strSrc == NULL) {
+ SECUREC_ERROR_INVALID_PARAMTER("wcsncpy_s");
+ if (strDest != NULL) {
+ strDest[0] = L'\0';
+ return EINVAL_AND_RESET;
+ }
+ return EINVAL;
+ }
+ if (count > SECUREC_WCHAR_STRING_MAX_LEN) {
+#ifdef SECUREC_COMPATIBLE_WIN_FORMAT
+ if (count == (size_t)(-1)) {
+ return SecDoCpyLimitW(strDest, destMax, strSrc,
+ destMax - 1);
+ }
+#endif
+ strDest[0] = L'\0'; /* Clear dest string */
+ SECUREC_ERROR_INVALID_RANGE("wcsncpy_s");
+ return ERANGE_AND_RESET;
+ }
+
+ if (count == 0) {
+ strDest[0] = L'\0';
+ return EOK;
+ }
+
+ return SecDoCpyLimitW(strDest, destMax, strSrc, count);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcstok_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcstok_s.c
new file mode 100644
index 000000000..f494f8acd
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wcstok_s.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wcstok_s function
+ * Create: 2014-02-25
+ */
+
+#include "securecutil.h"
+
+SECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit)
+{
+ const wchar_t *ctl = strDelimit;
+ while (*ctl != L'\0' && *ctl != ch) {
+ ++ctl;
+ }
+ return (int)(*ctl != L'\0');
+}
+
+/*
+ * Find beginning of token (skip over leading delimiters).
+ * Note that there is no token if this loop sets string to point to the terminal null.
+ */
+SECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken,
+ const wchar_t *strDelimit)
+{
+ wchar_t *token = strToken;
+ while (*token != L'\0') {
+ if (SecIsInDelimitW(*token, strDelimit) != 0) {
+ ++token;
+ continue;
+ }
+ /* Don't find any delimiter in string header, break the loop */
+ break;
+ }
+ return token;
+}
+
+/*
+ * Find the end of the token. If it is not the end of the string, put a null there.
+ */
+SECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken,
+ const wchar_t *strDelimit)
+{
+ wchar_t *token = strToken;
+ while (*token != L'\0') {
+ if (SecIsInDelimitW(*token, strDelimit) != 0) {
+ /* Find a delimiter, set string terminator */
+ *token = L'\0';
+ ++token;
+ break;
+ }
+ ++token;
+ }
+ return token;
+}
+
+/*
+ * Update Token wide character function
+ */
+SECUREC_INLINE wchar_t *
+SecUpdateTokenW(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)
+{
+ /* Point to updated position. Record string position for next search in the context */
+ *context = SecFindRestW(strToken, strDelimit);
+ /* Determine if a token has been found */
+ if (*context == strToken) {
+ return NULL;
+ }
+ return strToken;
+}
+
+/*
+ * <NAME>
+ * wcstok_s
+ *
+ *
+ * <FUNCTION DESCRIPTION>
+ * The wcstok_s function is the wide-character equivalent of the strtok_s function
+ *
+ * <INPUT PARAMETERS>
+ * strToken String containing token or tokens.
+ * strDelimit Set of delimiter characters.
+ * context Used to store position information between calls to
+ * wcstok_s.
+ *
+ * <OUTPUT PARAMETERS>
+ * context is updated
+ * <RETURN VALUE>
+ * The wcstok_s function is the wide-character equivalent of the strtok_s function
+ */
+wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit,
+ wchar_t **context)
+{
+ wchar_t *orgToken = strToken;
+ /* Validation section */
+ if (context == NULL || strDelimit == NULL) {
+ return NULL;
+ }
+ if (orgToken == NULL && *context == NULL) {
+ return NULL;
+ }
+ /* If string==NULL, continue with previous string */
+ if (orgToken == NULL) {
+ orgToken = *context;
+ }
+ orgToken = SecFindBeginW(orgToken, strDelimit);
+ return SecUpdateTokenW(orgToken, strDelimit, context);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemcpy_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemcpy_s.c
new file mode 100644
index 000000000..25e2b9a2a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemcpy_s.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wmemcpy_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Portability
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
+ * And sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The wmemcpy_s function copies n successive wide characters
+ * from the object pointed to by src into the object pointed to by dest.t.
+ *
+ * <INPUT PARAMETERS>
+ * dest Destination buffer.
+ * destMax Size of the destination buffer.
+ * src Buffer to copy from.
+ * count Number of characters to copy.
+ *
+ * <OUTPUT PARAMETERS>
+ * dest buffer is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL dest is NULL and destMax != 0 and count <= destMax
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
+ * EINVAL_AND_RESET dest != NULL and src is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax
+ * ERANGE destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or
+ * (count > destMax and dest is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN)
+ * ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
+ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and
+ * count <= destMax destMax != 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
+ * and dest != NULL and src != NULL and dest != src
+ *
+ * if an error occurred, dest will be filled with 0 when dest and destMax valid .
+ * If the source and destination overlap, the behavior of wmemcpy_s is undefined.
+ * Use wmemmove_s to handle overlapping regions.
+ */
+errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src,
+ size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) {
+ SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s");
+ return ERANGE;
+ }
+ if (count > destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s");
+ if (dest != NULL) {
+ (void)SECUREC_MEMSET_FUNC_OPT(
+ dest, 0, destMax * sizeof(wchar_t));
+ return ERANGE_AND_RESET;
+ }
+ return ERANGE;
+ }
+ return memcpy_s(dest, destMax * sizeof(wchar_t), src,
+ count * sizeof(wchar_t));
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemmove_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemmove_s.c
new file mode 100644
index 000000000..7b3caf5c6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wmemmove_s.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wmemmove_s function
+ * Create: 2014-02-25
+ */
+/*
+ * [Standardize-exceptions] Use unsafe function: Portability
+ * [reason] Use unsafe function to implement security function to maintain platform compatibility.
+ * And sufficient input validation is performed before calling
+ */
+
+#include "securecutil.h"
+
+/*
+ * <FUNCTION DESCRIPTION>
+ * The wmemmove_s function copies n successive wide characters from the object pointed
+ * to by src into the object pointed to by dest.
+ *
+ * <INPUT PARAMETERS>
+ * dest Destination buffer.
+ * destMax Size of the destination buffer.
+ * src Source object.
+ * count Number of bytes or character to copy.
+ *
+ * <OUTPUT PARAMETERS>
+ * dest is updated.
+ *
+ * <RETURN VALUE>
+ * EOK Success
+ * EINVAL dest is NULL and destMax != 0 and count <= destMax
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
+ * EINVAL_AND_RESET dest != NULL and src is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax
+ * ERANGE destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or
+ * (count > destMax and dest is NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN)
+ * ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0
+ * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN
+ *
+ *
+ * If an error occurred, dest will be filled with 0 when dest and destMax valid.
+ * If some regions of the source area and the destination overlap, wmemmove_s
+ * ensures that the original source bytes in the overlapping region are copied
+ * before being overwritten
+ */
+errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src,
+ size_t count)
+{
+ if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) {
+ SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s");
+ return ERANGE;
+ }
+ if (count > destMax) {
+ SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s");
+ if (dest != NULL) {
+ (void)SECUREC_MEMSET_FUNC_OPT(
+ dest, 0, destMax * sizeof(wchar_t));
+ return ERANGE_AND_RESET;
+ }
+ return ERANGE;
+ }
+ return memmove_s(dest, destMax * sizeof(wchar_t), src,
+ count * sizeof(wchar_t));
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wscanf_s.c b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wscanf_s.c
new file mode 100644
index 000000000..93d76fee7
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/platform/huawei_secure_c/src/wscanf_s.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
+ * Licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * Description: wscanf_s function
+ * Create: 2014-02-25
+ */
+
+#include "securec.h"
+
+/*
+ * <NAME>
+ * <FUNCTION DESCRIPTION>
+ * The wscanf_s function is the wide-character equivalent of the scanf_s function
+ * The wscanf_s function reads data from the standard input stream stdin and
+ * writes the data into the location that's given by argument. Each argument
+ * must be a pointer to a variable of a type that corresponds to a type specifier
+ * in format. If copying occurs between strings that overlap, the behavior is
+ * undefined.
+ *
+ * <INPUT PARAMETERS>
+ * format Format control string.
+ * ... Optional arguments.
+ *
+ * <OUTPUT PARAMETERS>
+ * ... the converted value stored in user assigned address
+ *
+ * <RETURN VALUE>
+ * Returns the number of fields successfully converted and assigned;
+ * the return value does not include fields that were read but not assigned.
+ * A return value of 0 indicates that no fields were assigned.
+ * return -1 if an error occurs.
+ */
+int wscanf_s(const wchar_t *format, ...)
+{
+ int ret; /* If initialization causes e838 */
+ va_list argList;
+
+ va_start(argList, format);
+ ret = vwscanf_s(format, argList);
+ va_end(argList);
+ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hinic5_hmm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hinic5_hmm.h
new file mode 100644
index 000000000..b83769f4d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hinic5_hmm.h
@@ -0,0 +1,101 @@
+/* ***************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2022. All rights reserved.
+ ******************************************************************************/
+
+#ifndef HINIC_HMM_H__
+#define HINIC_HMM_H__
+
+/* has no mpt entry */
+#define HMM_MPT_EN_SW 1 /* has mpt, state INVALID */
+#define HMM_MPT_EN_HW 2 /* has mpt, state FREE or VALID */
+#define HMM_MPT_DISABLED 0 /* has no mpt entry */
+#define HMM_MPT_FIX_BUG_LKEY 0
+
+#include "hinic5_cqm.h"
+#include "hmm_common.h"
+
+/**
+ * @brief struct hmm_mr
+ * @details 定义了一个hmm_mr结构体,用于表示一个HMM内存资源
+ */
+struct hmm_mr {
+ struct hmm_umem
+ *umem; /**< 指向一个hmm_umem结构体的指针,表示一个HMM内存 */
+ struct hmm_rdma rdmamr; /**< 一个rdma_mr结构体,表示一个RDMA内存资源 */
+ void *hwdev; /**< 指向一个硬件设备的指针 */
+};
+
+/**
+ * @brief 获取HMM内存结构体
+ * @param hwdev 硬件设备
+ * @param addr 地址
+ * @param size 大小
+ * @param access 访问权限
+ * @param dmasync DMA同步
+ *
+ * @details 这一个函数声明,函数名为hmm_umem_get。这个函数的主要功能是获取一块内存区域,
+ * 在需要动态分配内存或者需要访问特定内存区域时,可以使用这个函数
+ *
+ * @return 返回hmm_umem结构体指针
+ */
+struct hmm_umem *hmm_umem_get(void *hwdev, unsigned long addr, size_t size,
+ int access, int dmasync);
+
+/**
+ * @brief 释放hmm_umem结构体所占用的内存
+ * @param hmem 要释放的hmm_umem结构体指针
+ *
+ * @return 无
+ */
+void hmm_umem_release(struct hmm_umem *hmem);
+
+/**
+ * @brief 初始化HMM资源
+ * @param hwdev 硬件设备指针
+ * @param service_type 服务类型
+ *
+ * @return 返回0表示成功,其他值表示失败
+ */
+int hmm_init_resource(void *hwdev, u32 service_type);
+
+/**
+ * @brief 清理HMM资源
+ * @param hwdev 硬件设备指针
+ * @param service_type 服务类型
+ *
+ * @return 无
+ */
+void hmm_cleanup_resource(void *hwdev, u32 service_type);
+
+/**
+ * @brief 注册用户内存区域
+ * @param hwdev 硬件设备信息
+ * @param start 内存区域起始地址
+ * @param pdn PDN号
+ * @param length 内存区域长度
+ * @param virt_addr 虚拟地址
+ * @param hmm_acess 内存访问权限
+ * @param service_type 服务类型
+ * @param channel 通道号
+ *
+ * @details 用于硬件设备驱动开发中,当需要CPU和硬件设备之间进行数据交换时,需要使用这个函数来注册用户内存区域
+ *
+ * @return 返回注册的内存区域信息
+ */
+struct hmm_mr *hmm_reg_user_mr(void *hwdev, u64 start, u32 pdn, u64 length,
+ u64 virt_addr, int hmm_acess, u32 service_type,
+ u16 channel);
+
+/**
+ * @brief 注销HMM模块的MR
+ * @param mr 要注销的HMM模块的MR指针
+ * @param service_type 服务类型
+ * @param channel 通道号
+ *
+ * @details 在某些情况下,可能需要取消注册一个已经注册的hmm_mr结构体。这可能是因为该结构体不再需要,或者需要更新为新的结构体
+ *
+ * @return 成功返回0,失败返回错误码
+ */
+int hmm_dereg_mr(struct hmm_mr *mr, u32 service_type, u16 channel);
+
+#endif /* HINIC_HMM_H__ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_buddy.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_buddy.h
new file mode 100644
index 000000000..ab8cb3319
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_buddy.h
@@ -0,0 +1,77 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ File Name : hmm_buddy.h
+ Version : Initial Draft
+ Description : define buddy related macro and structure
+***************************************************************************** */
+
+#ifndef HMM_BUDDY_H
+#define HMM_BUDDY_H
+
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+
+#if defined(__i386__)
+#include <asm/highmem.h>
+#endif
+
+#ifndef HMM_INVALID_INDEX
+#define HMM_INVALID_INDEX 0xFFFFFFFF /**< 表示无效的索引值 */
+#endif
+
+/**
+ * @brief struct hmm_buddy
+ * @details 定义了一个名为hmm_buddy的结构体,它是用于内存管理的一种数据结构
+ */
+struct hmm_buddy {
+ unsigned long **bits; /**< 指向多级bitmap的内存 */
+ unsigned int *num_free; /**< 指示各级bitmap中可用的索引个数 */
+ u32 max_order; /**< 指bitmap的级数 */
+ spinlock_t lock; /**< buddy的自旋锁 */
+};
+
+/**
+ * @brief 从hmm_buddy系统中分配一块内存
+ * @param buddy 指向hmm_buddy系统的指针
+ * @param order 要分配的内存块的阶序
+ *
+ * @details 这个函数从hmm_buddy系统中分配一块内存。参数order表示要分配的内存块的大小,
+ * 它是一个无符号32位整数,表示2的幂。函数返回分配成功的内存块的物理地址,如果分配失败,
+ * 则返回0。
+ *
+ * @return 分配成功返回内存块的物理地址,否则返回0
+ */
+u32 hmm_buddy_alloc(struct hmm_buddy *buddy, u32 order);
+/**
+ * @brief 释放hmm_buddy结构体所指定的内存块
+ * @param buddy 指向hmm_buddy结构体的指针
+ * @param first_index 内存块的首个索引
+ * @param order 内存块的顺序
+ *
+ * @details 在动态内存分配中,当我们不再需要某块内存时,我们需要将其释放,以便系统可以重新使用这部分内存。这个函数就是用来完成这个任务的
+ *
+ * @return 无
+ */
+void hmm_buddy_free(struct hmm_buddy *buddy, u32 first_index, u32 order);
+
+/**
+ * @brief 初始化HMM buddy系统
+ * @param buddy 要初始化的HMM buddy系统
+ * @param max_order 最大的分配顺序
+ *
+ * @details 此函数用于初始化HMM buddy系统,包括分配内存和初始化数据结构
+ *
+ * @return 成功初始化返回0,否则返回错误码
+ */
+int hmm_buddy_init(struct hmm_buddy *buddy, u32 max_order);
+/**
+ * @brief 清理hmm_buddy结构体
+ * @param buddy 要清理的hmm_buddy结构体指针
+ *
+ * @details 此函数用于清理hmm_buddy结构体,释放其占用的资源
+ *
+ * @return 无
+ */
+void hmm_buddy_cleanup(struct hmm_buddy *buddy);
+
+#endif // HMM_BUDDY_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_common.h
new file mode 100644
index 000000000..2fcbe4409
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_cfm_intf/hmm/hmm_common.h
@@ -0,0 +1,577 @@
+/* Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ File Name : hmm_common.h
+ Version : Initial Draft
+ Description : define rdma component related macro, structure and interface */
+
+#ifndef HMM_COMMON_H
+#define HMM_COMMON_H
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include "hmm_buddy.h"
+#include "hmm_context.h"
+#include "hinic5_cqm.h"
+#include "hinic5_lld.h"
+
+/* x86 */
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN \
+ 0x4321 /**< 表示大端字节序为0x4321,大端字节序是一种将高位字节放在前,低位字节放在后的存储方式 */
+#endif
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 0x1234 /**< 表示小端字节序为0x1234 */
+#endif
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN /**< 定义字节序为小端序 */
+#endif
+
+#define PCIE_LINK_DOWN 0xFFFFFFFF /**< 表示PCIE链路已经断开 */
+
+#define MPT_STATUS_INVALID 0xf /**< 表示无效的状态 */
+#define MPT_STATUS_FREE 0x3 /**< 表示MPT状态为空闲 */
+#define MPT_STATUS_VALID 0x1 /**< 表示状态有效的标志 */
+#define MPT_STATUS_MEM_INIT 0xa /**< 表示内存初始化的状态码 */
+
+#define MAX_RETRY \
+ 200 /**< 定义最大重试次数,用于控制程序在出现错误时的重试次数 */
+
+#define MPT_DMA_ATTR_IDX 0 /**< 定义一个宏,用于表示DMA属性的索引 */
+
+#define RDMA_MPT_SO_RO 0x1 /**< 设置RDMA的MPT的只读属性 */
+#define ROCE_DMA_MR_SIZE (~0ULL)
+#define FRMR_PAGE_SIZE 4096 /**< 表示页面大小为4096字节 */
+#define ROCE_FRMR_MAX_PAGES 512 /**< 表示ROCE帧错误的最大页数 */
+
+#define HMM_USER_DATA_LENGTH \
+ 6 /**< 表示HMM用户数据的长度(单位u32),需要与ROCE_RDMA_USER_DATE_LENGTH保持一致 */
+#define HMM_USER_DATA_MAX_BYTE (HMM_USER_DATA_LENGTH * (u32)sizeof(u32))
+
+/**
+ * @brief 定义一个宏,用于获取DMA地址的大小
+ * @param PA_SIZE 宏名,表示DMA地址的大小
+ *
+ * @return 返回DMA地址的大小,类型为u32
+ */
+#define PA_SIZE ((u32)sizeof(dma_addr_t))
+
+#define PAGE_SIZE_4K 4096 /**< page size is 4K */
+#define PAGE_SHIFT_4K 12 /**< page size is 1 left shift 12 */
+
+#define PAGE_SIZE_64K (64 * 1024) /**< page size is 64K */
+#define PAGE_SHIFT_64K 16 /**< page size is 1 left shift 16 */
+
+#define PAGE_SIZE_2M (2 * 1024 * 1024) /**< page size is 2M */
+#define PAGE_SHIFT_2M 21 /**< page size is 1 left shift 21 */
+
+#define MTT_PA_VALID 0x1
+
+#define HMM_MTT_NUM_PER_CACHELINE 32 /**< 256B Cache line has 32 records */
+
+#define HMM_US_PERF_DELAY 100 /**< 表示HMM模块的性能延迟时间 */
+#define rdma_delay() \
+ udelay(HMM_US_PERF_DELAY) /**< 使用udelay函数实现RDMA延迟,延迟的时间为HMM_US_PERF_DELAY */
+
+#define BLOCK_SIZE_DEVIDE_SECTOR 8 /**< Chip logic: 8 */
+
+#define CMDQ_ERR 1
+#define CMDQ_TIMEOUT 2
+
+#define RDMA_MPT_DISABLED 0 /* has no mpt entry */
+#define RDMA_MPT_EN_SW 1 /* has mpt, state INVALID */
+#define RDMA_MPT_EN_HW 2 /* has mpt, state FREE or VALID */
+
+#ifdef __EMU_X86__
+/**
+ * @brief enum
+ * @details 表示不同命令的超时时间
+ */
+enum {
+ CMD_TIME_OUT_A = 30000000, /**< 命令A的超时时间,单位为微秒 */
+ CMD_TIME_OUT_B = 40000000, /**< 命令B的超时时间,单位为微秒 */
+ CMD_TIME_OUT_C = 50000000 /**< 命令C的超时时间,单位为微秒 */
+};
+#else
+/**
+ * @brief enum
+ * @details 表示不同命令的超时时间
+ */
+enum {
+ CMD_TIME_OUT_A = 30000, /**< 命令A的超时时间,单位为毫秒 */
+ CMD_TIME_OUT_B = 40000, /**< 命令B的超时时间,单位为毫秒 */
+ CMD_TIME_OUT_C = 50000 /**< 命令C的超时时间,单位为毫秒 */
+};
+#endif
+
+/**
+ * @brief enum mpt_mr_mw
+ * @details 定义一个枚举类型,用于表示内存读写类型
+ */
+enum mpt_mr_mw {
+ MPT_MW = 0, /**< 表示写操作 */
+ MPT_MR = 1 /**< 表示读操作 */
+};
+
+/**
+ * @brief enum mtt_layer
+ * @details 定义一个枚举类型mtt_layer,用于表示不同的层级
+ */
+enum mtt_layer {
+ MTT_NO_LAYER = -1, /**< 表示没有层级,对应于dma mr不需要mtt */
+ MTT_ZERO_LAYER = 0, /**< 表示0层,对应于1页mr有0级mtt */
+ MTT_ONE_LAYER = 1, /**< 表示1层 */
+ MTT_TWO_LAYER = 2, /**< 表示2层 */
+ MTT_THREE_LAYER = 3 /**< 表示3层 */
+};
+
+/**
+ * @brief enum mtt_data_type_e
+ * @details 定义一个枚举类型,用于表示MTT数据的类型
+ */
+enum mtt_data_type_e {
+ MTT_DMTT_TYPE = 0, /**< 表示DMTT类型的数据 */
+ MTT_CMTT_TYPE /**< 表示CMTT类型的数据 */
+};
+
+/**
+ * @brief enum
+ * @details 定义枚举类型,用于表示内存分页的大小
+ */
+enum {
+ MTT_PAGE_SIZE_4K = 0, /**< 表示分页大小为4K */
+ MTT_PAGE_SIZE_64K = 1, /**< 表示分页大小为64K */
+ MTT_PAGE_SIZE_2M = 2 /**< 表示分页大小为2M */
+};
+
+enum rdma_mr_type {
+ RDMA_DMA_MR = 0,
+ RDMA_USER_MR = 1,
+ RDMA_FRMR = 2,
+ RDMA_FMR = 3,
+ RDMA_PHYS_MR = 4,
+ RDMA_RSVD_LKEY = 5,
+ RDMA_SIG_MR = 6,
+ RDMA_INDIRECT_MR = 8,
+ RDMA_ODP_IMPLICIT_MR = 9,
+ RDMA_ODP_EXPLICIT_MR = 10,
+};
+
+/**
+ * @brief struct ib_umem_odp
+ * @details 定义一个ib_umem_odp结构体,用于表示一个用户空间内存对象
+ */
+struct ib_umem_odp;
+
+/**
+ * @brief struct hmm_umem
+ * @details 定义了一个用于描述HugeTLB页面的结构体
+ */
+struct hmm_umem {
+ struct device *device;
+ struct pid *tgid; /**< 线程组ID */
+ size_t length; /**< 页面长度 */
+ unsigned long address; /**< 页面地址 */
+ int page_shift; /**< 页面偏移量 */
+ int writable; /**< 页面是否可写 */
+ int hugetlb; /**< 页面是否为HugeTLB页面 */
+ struct work_struct work; /**< 工作结构体 */
+ struct mm_struct *mm; /**< 内存管理结构体指针 */
+ unsigned long diff; /**< 地址差 */
+ struct ib_umem_odp *odp_data; /**< 用户内存对象数据指针 */
+ struct sg_table sg_head; /**< 范围表结构体 */
+ int nmap; /**< 映射数量 */
+ int npages; /**< 页面数量 */
+};
+
+/**
+ * @brief struct hmm_service_cap
+ * @details 定义了HMM服务能力的结构体
+ */
+struct hmm_service_cap {
+ u8 log_mtt; /**< 表示MTT PA必须是2的整数次幂,用对数表示。每个MTT表可以包含1、2、4、8、16个PA */
+ /* need to check whether related to max_mtt_seg */
+ u32 num_mtts; /**< 表示MTT表的数量(4M),实际上是MTT段的数量 */
+ /* max value needs to be confirmed */
+ /* MTT table number of Each MTT seg(3) */
+ u32 log_mtt_seg; /**< MTT表的数量(3) */
+ u32 mtt_entry_sz; /**< MTT表的大小为8B,包括1个PA(64位) */
+ u32 mpt_entry_sz; /**< MPT表的大小为64B */
+
+ u32 dmtt_cl_start;
+ u32 dmtt_cl_end;
+ u32 dmtt_cl_sz;
+
+ u32 mtt_page_size; /**< 4K, 8K, 16K, 32K */
+ u32 mtt_page_shift; /**< 12, 13, 14, 15 */
+};
+
+/**
+ * @brief struct mpt
+ * @details 定义一个结构体,用于封装cqm提供的mpt相关信息
+ */
+struct mpt {
+ u32 mpt_index; /**< 封装cqm提供的mpt_index */
+ void *vaddr; /**< 封装cqm提供的mpt_entry的虚拟地址 */
+ void *mpt_object; /**< 封装的cqm提供的指针 */
+};
+
+/**
+ * @brief struct mtt_seg
+ * @details 定义了一个mtt段的结构体,用于管理连续的mtt索引
+ */
+struct mtt_seg {
+ u32 offset; /**< 分配连续索引的首个索引 */
+ u32 order; /**< mtt索引个数为1<<order,每个索引对应一个mtt entry */
+ void *vaddr; /**< mtt_seg第一个MTT的起始虚拟地址 */
+ dma_addr_t paddr; /**< mtt_seg第一个MTT的起始物理地址 */
+};
+
+/**
+ * @brief struct mtt
+ * @details 定义了一个mtt结构体,用于地址转换
+ */
+struct mtt {
+ u32 mtt_layers; /**< mtt的级数,该值为0时表示不使用mtt做地址转换 */
+ u32 mtt_page_shift; /**< MTT的页大小 */
+ u32 buf_page_shift; /**< buffer页大小 */
+ dma_addr_t mtt_paddr; /**< 写入context中的物理地址 */
+ __be64 *mtt_vaddr; /**< 写入context中的虚拟地址 */
+ struct mtt_seg **mtt_seg; /**< 指向多级mtt */
+ enum mtt_data_type_e mtt_type;
+};
+
+/**
+ * @brief struct hmm_em_buf
+ * @details 定义一个用于HMM_EM的缓冲区结构体
+ */
+struct hmm_em_buf {
+ u32 length; /**< 缓冲区的长度 */
+ void *buf; /**< 缓冲区的指针 */
+ dma_addr_t dma_addr; /**< DMA地址 */
+ struct hmm_em_buf *next_buf; /**< 指向下一个缓冲区的指针 */
+};
+
+/**
+ * @brief struct hmm_em_chunk
+ * @details 定义一个用于HMM模型的结构体,包含缓冲区数量、引用计数和HMM缓冲区列表
+ */
+struct hmm_em_chunk {
+ u32 buf_num; /**< 缓冲区数量 */
+ u32 refcount; /**< 引用计数 */
+ struct hmm_em_buf em_buf_list; /**< HMM缓冲区列表 */
+};
+
+/**
+ * @brief struct hmm_em_table
+ * @details 定义一个用于HMM_EM的表结构体
+ */
+struct hmm_em_table {
+ u32 chunk_num; /**< 块的数量 */
+ u32 obj_num; /**< 对象的数量 */
+ u32 obj_size; /**< 对象的大小 */
+ int min_order; /**< 最小的顺序 */
+ struct mutex mutex; /**< 互斥锁,用于多线程同步 */
+ struct hmm_em_chunk **em_chunk; /**< 指向HMM_EM块的指针 */
+};
+
+/**
+ * @brief struct hmm_comp_priv
+ * @details 用于存储与HMM相关的私有信息
+ */
+struct hmm_comp_priv {
+ struct hmm_buddy mtt_buddy; /**< 用于存储HMM分配器的信息 */
+ struct hmm_em_table mtt_em_table; /**< 用于存储HMM表的信息 */
+ void *hwdev; /**< 用于存储硬件设备的指针 */
+ struct device *dev; /**< 用于存储dev设备的指针 */
+ u32 mtt_page_size; /**< 4K, 8K, 16K, 32K */
+ u32 mtt_page_shift; /**< 12, 13, 14, 15 */
+
+ struct hmm_service_cap dev_cap; /**< 用于存储HMM服务能力的信息 */
+};
+
+/* v100 sub did */
+#define HI_1823_V100_SUB_DEV_ID_EVB 0x0003 /**< 对应EVB设备 */
+#define HI_1823_V100_SUB_DEV_ID_COMPUTE_2X25 0x0051 /**< 对应2X25设备 */
+#define HI_1823_V100_SUB_DEV_ID_COMPUTE_4X25 0x0052 /**< 对应4X25设备 */
+#define HI_1823_V100_SUB_DEV_ID_COMPUTE_2X100 0x00A1 /**< 对应2X100设备 */
+
+/* v200 sub did */
+#define HI_1823_V200_SUB_DEV_ID_SLT 0x0401 /**< 对应SLT设备 */
+#define HI_1823_V200_SUB_DEV_ID_CLOUD 0x10B1 /**< 对应CLOUD设备 */
+#define HI_1823_V200_SUB_DEV_ID_SDI_BMS 0x11B1 /**< 对应SDI_BMS设备 */
+
+/* 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 MR_KEY_RIGHT_SHIFT_OFS 24 /**< 表示右移操作的偏移量 */
+#define MR_KEY_LEFT_SHIFT_OFS 8 /**< 表示左移键的偏移量 */
+
+/**
+ * @brief enum hmm_device_type
+ * @details 定义一个枚举类型,用于表示HMM设备的类型
+ */
+enum hmm_device_type {
+ HMM_DEV_TYPE_UNKNOWN, /**< 未知设备类型 */
+ HMM_DEV_TYPE_HI1823_V100, /**< HI1823 V100设备类型 */
+ HMM_DEV_TYPE_HI1823_V200, /**< HI1823 V200设备类型 */
+ HMM_DEV_TYPE_HI1825_V100
+};
+
+/**
+ * @brief struct rdma_verbs_cmd_com
+ * @details 定义一个RDMA verbs命令通信结构体
+ */
+typedef struct rdma_verbs_cmd_com {
+ union {
+ __be32 value;
+
+ struct {
+ __be32 version : 8;
+ __be32 sub_cmd : 8;
+ __be32 cmd_bitmask : 16;
+ } bs;
+ } dw0;
+
+ __be32 index;
+} rdma_verbs_cmd_com_s;
+
+/**
+ * @brief struct rdma_mpt_hw2sw_inbuf
+ * @details 用于存储RDMA设备硬件到软件的输入缓冲信息
+ */
+struct rdma_mpt_hw2sw_inbuf {
+ rdma_verbs_cmd_com_s com; /**< 通用命令结构体,包含了通用的命令信息 */
+
+ __be32 dmtt_flags; /**< 数据移动标志 */
+ __be32 dmtt_num; /**< 数据移动数量 */
+ __be32 dmtt_cache_line_start; /**< 数据移动缓存行起始位置 */
+ __be32 dmtt_cache_line_end; /**< 数据移动缓存行结束位置 */
+ __be32 dmtt_cache_line_size; /**< 数据移动缓存行大小 */
+};
+
+/**
+ * @brief struct rdma_mpt_modify_inbuf
+ * @details 定义一个RDMA修改内存保护区域的输入缓冲区结构体
+ */
+struct rdma_mpt_modify_inbuf {
+ rdma_verbs_cmd_com_s com; /**< 通用命令结构体,包含了通用的命令信息 */
+ __be32 new_key; /**< 新的密钥值 */
+ __be64 length; /**< 内存保护区域的长度 */
+ __be64 iova; /**< 内存保护区域的IO虚拟地址 */
+};
+
+/**
+ * @brief struct rdma_mpt_entry
+ * @details 定义一个RDMA多路径传输条目的结构体
+ */
+typedef struct rdma_mpt_entry {
+ struct roce_mpt_context
+ roce_mpt_ctx; /**< 包含了RoCE多路径传输的上下文信息 */
+} rdma_mpt_entry_s;
+
+enum hmm_rdma_type {
+ HMM_RDMA_MR_START = 0,
+ HMM_RDMA_DMA_MR = HMM_RDMA_MR_START,
+ HMM_RDMA_USER_MR,
+ HMM_RDMA_FRMR,
+ HMM_RDMA_FMR,
+ HMM_RDMA_PHYS_MR,
+ HMM_RDMA_RSVD_LKEY,
+ HMM_RDMA_SIG_MR,
+ HMM_RDMA_INDIRECT_MR,
+ HMM_RDMA_ODP_IMPLICIT_MR,
+ HMM_RDMA_ODP_EXPLICIT_MR,
+ HMM_RDMA_MR_END = 29,
+
+ HMM_RDMA_MW_START = 30,
+ HMM_RDMA_MW_TYPE_1 = HMM_RDMA_MW_START,
+ HMM_RDMA_MW_TYPE_2,
+ HMM_RDMA_MW_END = 39,
+};
+
+/**
+ * @brief struct hmm_rdma
+ * @details 定义了一个RDMA内存区域的结构体
+ */
+struct hmm_rdma {
+ struct mpt mpt; /**< 内存页表 */
+ struct mtt mtt; /**< 内存转换表 */
+ u64 iova; /**< mr指向内存的起始地址(虚拟地址,ZBVA时为0) */
+ u64 size; /**< mr指向内存的大小 */
+ u32 key; /**< mr对应的key */
+ u32 pdn; /**< mr绑定的pdn */
+ u32 access; /**< mr的访问权限 */
+ int enabled; /**< mr的状态,DISABLE、EN_SW、EN_HW */
+ // int mr_type; /**< mr类型 */
+ int type; /**< 类型,见 enum hmm_rdma_type */
+ u32 block_size;
+ u32 user_data[HMM_USER_DATA_LENGTH];
+};
+
+/**
+ * @brief struct rdma_mpt_sw2hw_inbuf
+ * @details 用于存储RDMA软件到硬件的输入缓冲信息
+ */
+struct rdma_mpt_sw2hw_inbuf {
+ rdma_verbs_cmd_com_s com; /**< 命令通用信息 */
+ struct rdma_mpt_entry mpt_entry; /**< 多路径入口信息 */
+};
+
+/**
+ * @brief 获取PCI设备的HMM设备类型
+ * @param pdev 要查询的PCI设备
+ *
+ * @return 返回设备的HMM设备类型
+ */
+enum hmm_device_type hmm_get_device_type(struct hinic5_lld_dev *lld_dev);
+
+/**
+ * @brief 获取HMM组件的私有信息
+ * @param hwdev 硬件设备的指针
+ * @param service_type 服务类型
+ *
+ * @return 返回HMM组件的私有信息结构体指针
+ */
+struct hmm_comp_priv *get_hmm_comp_priv(void *hwdev, u32 service_type);
+
+/**
+ * @brief 分配一个HMM MPT资源
+ * @param hwdev 硬件设备指针
+ * @param mpt 要分配的MPT结构体指针
+ * @param service_type 服务类型
+ * @param xid XID
+ *
+ * @return 成功返回0,失败返回错误码
+ */
+int hmm_mpt_alloc_templated(void *hwdev, struct mpt *mpt, u32 service_type,
+ u32 xid);
+
+/**
+ * @brief 分配一个HMM MPT资源
+ * @param hwdev 硬件设备指针
+ * @param mpt 要分配的MPT结构体指针
+ * @param service_type 服务类型
+ *
+ * @return 成功返回0,失败返回错误码
+ */
+static inline int hmm_mpt_alloc(void *hwdev, struct mpt *mpt, u32 service_type)
+{
+ return hmm_mpt_alloc_templated(hwdev, mpt, service_type,
+ CQM_INDEX_INVALID);
+}
+
+/**
+ * @brief 释放HMM模型参数表(MPT)所占用的内存。
+ * @param hwdev 硬件设备上下文
+ * @param mpt 要释放的模型参数表(MPT)
+ *
+ * @return 无
+ */
+void hmm_mpt_free(void *hwdev, struct mpt *mpt);
+
+/**
+ * @brief 此函数用于将数据写入HMM MTT
+ * @param hwdev 设备句柄
+ * @param mtt 内存转换表
+ * @param start_index 起始索引
+ * @param npages 页面数量
+ * @param page_list 页面列表
+ * @param service_type 服务类型
+ *
+ * @return 成功返回0,失败返回错误码
+ */
+int hmm_mtt_write(void *hwdev, struct mtt *mtt, u32 start_index, u32 npages,
+ u64 *page_list, u32 service_type);
+
+/**
+ * @brief 分配内存映射表转换(MMT)所需的内存
+ * @param hwdev 硬件设备的指针
+ * @param npages 需要分配的页面数量
+ * @param page_shift 页面移位值
+ * @param mtt 内存映射表转换的结构体指针
+ * @param service_type 服务类型
+ *
+ * @return 成功返回0,失败返回错误码
+ */
+int hmm_mtt_alloc(void *hwdev, u32 npages, u32 page_shift, struct mtt *mtt,
+ u32 service_type);
+
+/**
+ * @brief 释放HMM MTT资源
+ * @param hwdev 硬件设备指针
+ * @param mtt 待释放的MTT结构体指针
+ * @param service_type 服务类型
+ *
+ * @return 无
+ */
+void hmm_mtt_free(void *hwdev, struct mtt *mtt, u32 service_type);
+
+/**
+ * @brief 初始化HMM_MTT模块
+ * @param comp_priv 结构体指针,包含了HMM_MTT模块的私有信息
+ *
+ * @return 返回0表示初始化成功,返回其他值表示初始化失败
+ */
+int hmm_mtt_init(struct hmm_comp_priv *comp_priv);
+
+/**
+ * @brief 清理HMM组件的私有信息
+ * @param comp_priv 待清理的HMM组件的私有信息
+ *
+ * @details 此函数用于清理HMM组件的私有信息,释放内存等资源
+ */
+void hmm_mtt_cleanup(struct hmm_comp_priv *comp_priv);
+
+/**
+ * @brief 生成MTT签名
+ * @param mtt_base_gpa MTT基地址
+ * @param type MTT数据类型
+ *
+ * @return u64 生成的MTT签名
+ */
+u64 hmm_gen_mtt_sign(u64 mtt_base_gpa, enum mtt_data_type_e type);
+
+/**
+ * @brief 启用内存远程直接访问(RDMA)的内存注册(MR)和内存保护表(MPT)
+ * @param dev device设备
+ * @param hwdev 硬件设备
+ * @param mr RDMA内存注册
+ * @param channel 通道号
+ *
+ * @return 成功返回0,失败返回错误码
+ */
+int hmm_rdma_enable_mpt(struct hinic5_lld_dev *dev, void *hwdev,
+ struct hmm_rdma *mr, u16 channel);
+
+/**
+ * @brief 禁用内存保护表项
+ * @param dev device设备
+ * @param hwdev 设备硬件
+ * @param mr 结构体,表示RDMA内存区域
+ * @param service_type 服务类型
+ * @param channel 通道号
+ *
+ * @return int 返回0表示成功,否则表示失败
+ */
+int hmm_rdma_disable_mpt(struct hinic5_lld_dev *dev, void *hwdev,
+ struct hmm_rdma *mr, u32 service_type, u16 channel);
+
+#define CMTT_SIGN_MASK \
+ 0x7ff /**< 用于表示CMTT签名掩码,这个掩码用于在一个16位的数值中,提取出特定的位序列 */
+#define CMTT_SIGN_SHIFT0 3 /**< 表示CMTT签名的左移位数0 */
+#define CMTT_SIGN_SHIFT1 14 /**< 表示CMTT签名的左移位数1 */
+#define CMTT_SIGN_SHIFT2 25 /**< 表示CMTT签名的左移位数2 */
+
+#define DMTT_SIGN_MASK \
+ 0x3ff /**< 用于表示DMTT签名掩码,这个掩码用于在DMTT协议中生成一个10bit的校验值 */
+
+#define DMTT_ADD_SHIFT0 7 /**< 表示在DMTT中添加一个左移0位的操作 */
+#define DMTT_SIGN_SHIFT0 3 /**< 表示DMTT签名的左移位数0 */
+#define DMTT_SIGN_SHIFT1 6 /**< 表示DMTT签名的左移位数1 */
+#define DMTT_SIGN_SHIFT2 16 /**< 表示DMTT签名的左移位数2 */
+#define DMTT_SIGN_SHIFT3 26 /**< 表示DMTT签名的左移位数3 */
+
+#endif // HMM_COMMON_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_cqm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_cqm.h
new file mode 100644
index 000000000..1d2918902
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_cqm.h
@@ -0,0 +1,901 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2025 Huawei Technologies Co., Ltd */
+
+#ifndef HINIC5_CQM_H
+#define HINIC5_CQM_H
+
+#include <linux/types.h>
+#include <linux/completion.h>
+
+#include "hinic5_crm.h"
+#include "hinic5_vram_api.h"
+
+#define CQM_SUCCESS 0 /**< Success result code */
+#define CQM_FAIL (-1) /**< Failure result code */
+#define CQM_CONTINUE 1 /**< Continue result code */
+
+#define CQM_WQE_WF_NORMAL 0 /**< Normal WQE Format */
+#define CQM_WQE_WF_LINK 1 /**< Link WQE format */
+
+#define CQM_QUEUE_LINK_MODE 0 /**< 链式队列模式 */
+#define CQM_QUEUE_RING_MODE 1 /**< RING式队列模式 */
+#define CQM_QUEUE_TOE_SRQ_LINK_MODE 2 /**< SRQ队列模式 */
+#define CQM_QUEUE_RDMA_QUEUE_MODE 3 /**< RDMA队列模式 */
+
+/**
+ * @brief Link WQE common structure
+ */
+typedef struct tag_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; /**< 记录下一个页面的物理地址高32b,给芯片使用 */
+ u32 next_page_gpa_l; /**< 记录下一个页面的物理地址低32b,给芯片使用 */
+
+ u32 next_buffer_addr_h; /**< 记录下一个页面的虚拟地址高32b,给驱动使用 */
+ u32 next_buffer_addr_l; /**< 记录下一个页面的虚拟地址低32b,给驱动使用 */
+} cqm_linkwqe_s;
+
+/**
+ * @brief SRQ Link WQE structure
+ * @note wqe大小需要保证不超过普通RQE大小
+ */
+typedef struct tag_cqm_srq_linkwqe {
+ cqm_linkwqe_s linkwqe; /**< Link WQE common data */
+ u32 current_buffer_gpa_h; /**< 记录当前页面的物理地址高32b, 驱动释放container取消映射时使用 */
+ u32 current_buffer_gpa_l; /**< 记录当前页面的物理地址低32b, 驱动释放container取消映射时使用 */
+ u32 current_buffer_addr_h; /**< 记录当前页面的虚拟地址高32b,驱动释放container时使用 */
+ u32 current_buffer_addr_l; /**< 记录当前页面的虚拟地址低32b,驱动释放container时使用 */
+
+ u32 fast_link_page_addr_h; /**< 记录container地址所在fastlink 页的虚拟地址高32b,驱动释放fastlink时使用 */
+ u32 fast_link_page_addr_l; /**< 记录container地址所在fastlink 页的虚拟地址低32b,驱动释放fastlink时使用 */
+
+ u32 fixed_next_buffer_addr_h; /**< 记录下一个contianer的虚拟地址高32b,用于驱动资源释放,驱动不可修改 */
+ u32 fixed_next_buffer_addr_l; /**< 记录下一个contianer的虚拟地址低32b,用于驱动资源释放,驱动不可修改 */
+} cqm_srq_linkwqe_s;
+
+/**
+ * @brief 标准128B WQE的前64B
+ */
+typedef union tag_cqm_linkwqe_first64B {
+ cqm_linkwqe_s basic_linkwqe; /**< Link WQE common data */
+ cqm_srq_linkwqe_s toe_srq_linkwqe; /**< srq linkwqe结构 */
+ u32 value[16]; /**< 保留字段 */
+} cqm_linkwqe_first64B_s;
+
+/**
+ * @brief 标准128B WQE的后64B
+ */
+typedef struct tag_cqm_linkwqe_second64B {
+ u32 rsvd0[4]; /**< 第一个16B, Reserved */
+ u32 rsvd1[4]; /**< 第二个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; /**< 第三个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; /**< 第四个16B */
+} cqm_linkwqe_second64B_s;
+
+/**
+ * @brief 标准128B WQE结构
+ */
+typedef struct tag_cqm_linkwqe_128B {
+ cqm_linkwqe_first64B_s first64B; /**< 标准128B WQE的前64B */
+ cqm_linkwqe_second64B_s second64B; /**< 标准128B WQE的后64B */
+} cqm_linkwqe_128B_s;
+
+/**
+ * @brief AEQ类型定义
+ */
+typedef enum {
+ CQM_AEQ_BASE_T_NIC = 0, /**< NIC分15个event:0~14 */
+ CQM_AEQ_BASE_T_DMMU = 15, /**< DMMU分1个event:15 */
+ CQM_AEQ_BASE_T_ROCE = 16, /**< ROCE分32个event:16~47 */
+ CQM_AEQ_BASE_T_FC = 48, /**< FC分8个event:48~55 */
+ CQM_AEQ_BASE_T_IOE = 56, /**< IOE分8个event:56~63 */
+ CQM_AEQ_BASE_T_TOE = 64, /**< TOE分16个event:64~79 */
+ CQM_AEQ_BASE_T_UB = 80, /**< UB分16个event:80~95 */
+ CQM_AEQ_BASE_T_VBS = 96, /**< VBS分16个event:96~111 */
+ CQM_AEQ_BASE_T_IPSEC = 112, /**< IPSEC分16个event:112~127 */
+ CQM_AEQ_BASE_T_MAX = 128 /**< 最大定义128种event */
+} cqm_aeq_event_type_e;
+
+/**
+ * @brief CQM 业务扩展描述
+ */
+typedef struct tag_service_register_template {
+ u32 service_type; /**< 业务类型 */
+ u32 srq_ctx_size; /**< srq context大小 */
+ u32 scq_ctx_size; /**< scq context大小 */
+ void *service_handle; /**< ceq/aeq回调函数时传给service driver的指针 */
+ void (*shared_cq_ceq_callback)(void *service_handle, u32 cqn,
+ void *cq_priv); /**< ceq回调:shared cq */
+ void (*embedded_cq_ceq_callback)(
+ void *service_handle, u32 xid,
+ void *qpc_priv); /**< ceq回调:embedded cq */
+ void (*no_cq_ceq_callback)(void *service_handle, u32 xid, u32 qid,
+ void *qpc_priv); /**< ceq回调:no cq */
+ u8 (*aeq_level_callback)(void *service_handle, u8 event_type,
+ u8 *val); /**< aeq level回调 */
+ void (*aeq_callback)(void *service_handle, u8 event_type,
+ u8 *val); /**< aeq回调 */
+} service_register_template_s;
+
+/**
+ * @brief CQM object type
+ */
+typedef enum cqm_object_type {
+ CQM_OBJECT_ROOT_CTX = 0, /**< Root context. 留在以后兼容root ctx管理 */
+ CQM_OBJECT_SERVICE_CTX, /**< QPC, Service context, 连接管理对象 */
+ CQM_OBJECT_MPT, /**< RDMA Memory Protection Table */
+
+ CQM_OBJECT_NONRDMA_EMBEDDED_RQ =
+ 10, /**< 非RDMA业务的RQ,用LINKWQE管理 */
+ CQM_OBJECT_NONRDMA_EMBEDDED_SQ, /**< 非RDMA业务的SQ,用LINKWQE管理 */
+ CQM_OBJECT_NONRDMA_SRQ, /**< 非RDMA业务的SRQ,用MTT管理,但要CQM自己申请MTT */
+ CQM_OBJECT_NONRDMA_EMBEDDED_CQ, /**< 非RDMA业务的embedded CQ,用LINKWQE管理 */
+ CQM_OBJECT_NONRDMA_SCQ, /**< 非RDMA业务的SCQ,用LINKWQE管理 */
+
+ CQM_OBJECT_RESV = 20, /**< Reserved */
+
+ CQM_OBJECT_RDMA_QP = 30, /**< RDMA Queue Pair */
+ CQM_OBJECT_RDMA_SRQ, /**< RDMA Shared Receive Queue */
+ CQM_OBJECT_RDMA_SCQ, /**< RDMA Shared Completion Queue */
+
+ CQM_OBJECT_MTT = 50, /**< RDMA Memory Translation Table */
+ CQM_OBJECT_RDMARC, /**< RDMA Reliable Connection */
+} cqm_object_type_e;
+
+/**
+ * @brief BITMAP表申请的失败返回值
+ */
+#define CQM_INDEX_INVALID ~(0U)
+
+/**
+ * @brief 新增字段的定义兼容XID=0xFFFFFFFF的默认XID申请规则 宏命名为低3bit比较位
+ */
+#define CQM_XID_LOW_BIT_1_1_1 0x0 /**< mask is 0x7 */
+#define CQM_XID_LOW_BIT_0_1_1 0x4 /**< mask is 0x3 */
+#define CQM_XID_LOW_BIT_0_1_0 0x5 /**< mask is 0x2 */
+#define CQM_XID_LOW_BIT_0_0_1 0x6 /**< mask is 0x1 */
+#define CQM_XID_LOW_BIT_NONE 0x7 /**< mask is 0x0 */
+#define CQM_XID_SEARCH_RANGE 0x0
+#define CQM_XID_SEARCH_ALL 0x1
+
+#define CQM_XID_SEARCH_MODE_SHIFT 27
+#define CQM_XID_LB_MODE_SHIFT 24
+#define CQM_XID_LOW_BITS_SHIFT 21
+#define CQM_XID_SEARCH_MODE_MASK 0x1
+#define CQM_XID_LB_MODE_MASK 0x7
+#define CQM_XID_LOW_BITS_MASK 0x7
+#define CQM_DYNAMIC_XID_MASK 0x1FFFFF
+
+/**
+ * @brief 构造 XID
+ * @param[in] search_mode 搜索模式
+ * @param[in] lb_mode 负载均衡模式
+ * @param[in] xid_low XID的低两位
+ *
+ * @details search_mode: 0---指定XID范围查找,范围为[bp_start, bp_end);1---整个动态区查找
+ * lb_mode:
+ * 0--动态分配XID时,选择xid[2:0]=xid_low[2:0]
+ * 4--动态分配XID时,选择xid[1:0]=xid_low[1:0]
+ * 5--动态分配XID时,选择xid[0]=xid_low[0]
+ * 6--动态分配XID时,选择xid[1]=xid_low[1]
+ * 7--所有xid均可申请
+ * xid_low: 用于匹配的xid_low[2:0]
+ *
+ * @return 返回生成的XID
+ */
+#define CQM_DYNAMIC_XID_MOD(search_mode, lb_mode, xid_low) \
+ ((((search_mode)&CQM_XID_SEARCH_MODE_MASK) \
+ << CQM_XID_SEARCH_MODE_SHIFT) | \
+ (((lb_mode)&CQM_XID_LB_MODE_MASK) << CQM_XID_LB_MODE_SHIFT) | \
+ (((xid_low)&CQM_XID_LOW_BITS_MASK) << CQM_XID_LOW_BITS_SHIFT) | \
+ CQM_DYNAMIC_XID_MASK)
+
+#define CQM_RDMA_Q_ROOM_1 \
+ (1) /**< 为支持ROCE的Q buffer resize,第一个Q buffer空间 */
+#define CQM_RDMA_Q_ROOM_2 \
+ (2) /**< 为支持ROCE的Q buffer resize,第二个Q buffer空间 */
+
+#define CQM_HARDWARE_DOORBELL (1) /**< 当前Q选择的doorbell方式,硬件doorbell */
+#define CQM_SOFTWARE_DOORBELL (2) /**< 当前Q选择的doorbell方式,软件doorbell */
+#define CQM_SECURE_BUFFER_EN (1) /**< 标识Buffer是从安全内存中申请的 */
+
+/**
+ * @brief CQM buffer单节点结构
+ */
+typedef struct tag_cqm_buf_list {
+ void *va; /**< 虚拟地址 */
+ dma_addr_t pa; /**< 物理地址 */
+ u32 refcount; /**< buf的引用计数,内部buf管理用 */
+} cqm_buf_list_s;
+
+/**
+ * @brief CQM buffer单节点结构,适配WIN
+ */
+struct huge_buf_addr {
+ void *huge_buf_vaddr; /**< 虚拟地址 */
+ dma_addr_t huge_buf_paddr; /**< 物理地址 */
+ u32 huge_buf_size; /**< 单节点buffer的大小 */
+};
+
+/**
+ * @brief CQM buffers 管理结构
+ */
+typedef struct tag_cqm_buf {
+ cqm_buf_list_s *buf_list; /**< buffer 链表 */
+ cqm_buf_list_s
+ direct; /**< 将 buf_list 重新映射为连续的虚拟地址,其成员仅 va 有效 */
+ u32 page_number; /**< 总物理页数量 */
+ u32 buf_number; /**< buffer 链表长度 */
+ u32 buf_size; /**< buffer 大小 */
+#ifdef __WIN__
+ struct huge_buf_addr *bufs_addr; /**< buffer链表 */
+ u32 huge_buf_number; /**< buffer链表节点个数 */
+#endif
+ u32 secure_mem_flag; /**< 安全内存标志,默认为 0 (不使用安全内存) */
+ struct vram_buf_info buf_info;
+} cqm_buf_s;
+
+/**
+ * @brief CQM object 结构,对 context/queue/table 的抽象
+ */
+typedef struct tag_cqm_object {
+ u32 service_type; /**< 业务类型 */
+ u32 object_type; /**< 对象类型,如context,queue,mpt,mtt等 */
+ u32 object_size; /**< 对象大小,
+ 对于非RDMA的队列,是队列的深度;
+ 对于queue/ctx/MPT,单位Byte;
+ 对于MTT/RDMARC,单位entry个数;
+ 对于container,单位conainer个数 */
+ atomic_t refcount; /**< 引用计数 */
+ struct completion free; /**< 释放完成量 */
+ void *cqm_handle; /**< cqm_handle */
+} cqm_object_s;
+
+/**
+ * @brief QPC/MPT object
+ */
+typedef struct tag_cqm_qpc_mpt {
+ cqm_object_s object; /**< 对象基类 */
+ u32 xid; /**< XID.
+ xid[20:0] < 1M 时,表示静态申请的xid;
+ xid[20:0] 全1为动态申请;
+ xid[22:21] 指定低2bit;
+ xid[24:23] 为lb_mode;
+ xid[25]为search_mode */
+ dma_addr_t paddr; /**< QPC/MTT内存的物理地址 */
+ void *priv; /**< service driver的该对象的私有信息 */
+ u8 *vaddr; /**< QPC/MTT内存的虚拟地址 */
+} cqm_qpc_mpt_s;
+
+/**
+ * @brief queue header结构
+ */
+typedef struct tag_cqm_queue_header {
+ u64 doorbell_record; /**< SQ/RQ的db内容 */
+ u64 ci_record; /**< CQ的db内容 */
+ u64 rsv1; /**< 该区域为驱动和微码传递信息的自定义区 */
+ u64 rsv2; /**< 该区域为驱动和微码传递信息的自定义区 */
+} cqm_queue_header_s;
+
+/**
+ * @brief 队列管理结构
+ * @details 非 RDMA 业务,embeded 队列用 linkwqe 管理,SRQ 和 SCQ 用 MTT 管理,MTT 由 CQM 申请;
+ * RDMA 业务的队列,用 MTT 管理
+ */
+typedef struct tag_cqm_queue {
+ cqm_object_s object; /**< 对象基类 */
+ u32 index; /**< embeded队列、QP没有index,SRQ和SCQ有 */
+ void *priv; /**< service driver的该对象的私有信息 */
+ u32 current_q_doorbell; /**< 当前queue选择的doorbell类型,roce QP同时用HW/SW */
+ u32 current_q_room; /**< roce:当前有效的room buf */
+ cqm_buf_s q_room_buf_1; /**< nonrdma:只能选择q_room_buf_1为q_room_buf */
+ cqm_buf_s q_room_buf_2; /**< RDMA的CQ会重新分配queue room的大小 */
+ cqm_queue_header_s *q_header_vaddr; /**< queue header虚拟地址 */
+ dma_addr_t q_header_paddr; /**< queue header物理地址 */
+ u8 *q_ctx_vaddr; /**< SRQ和SCQ的ctx虚拟地址 */
+ dma_addr_t q_ctx_paddr; /**< SRQ和SCQ的ctx物理地址 */
+ u32 valid_wqe_num; /**< 创建成功的有效wqe个数 */
+ u8 *tail_container; /**< SRQ container的尾指针 */
+ u8 *head_container; /**< SRQ container的首针 */
+ u8 queue_link_mode; /**< 队列创建时确定连接模式:link,ring等 */
+} cqm_queue_s;
+
+/**
+ * @brief MTT/RDMARC管理结构
+ */
+typedef struct tag_cqm_mtt_rdmarc {
+ cqm_object_s object; /**< 对象基类 */
+ u32 index_base; /**< index_base */
+ u32 index_number; /**< index_number */
+ u8 *vaddr; /**< buffer虚拟地址 */
+} cqm_mtt_rdmarc_s;
+
+/**
+ * @brief 发送命令结构
+ */
+typedef struct tag_cqm_cmd_buf {
+ void *buf; /**< 命令buf虚拟地址 */
+ dma_addr_t dma; /**< 命令buf物理地址 */
+ u16 size; /**< 命令buf大小 */
+} cqm_cmd_buf_s;
+
+/**
+ * @brief 发送ACK方式定义
+ */
+typedef enum {
+ CQM_CMD_ACK_TYPE_CMDQ = 0, /**< ack回写到cmdq */
+ CQM_CMD_ACK_TYPE_SHARE_CQN = 1, /**< ack通过root ctx的scq上报 */
+ CQM_CMD_ACK_TYPE_APP_CQN = 2 /**< ack通过业务的scq上报 */
+} cqm_cmd_ack_type_e;
+
+/**
+ * @brief CQM 初始化
+ * @param[in] ex_handle 设备句柄
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_init(void *ex_handle);
+
+/**
+ * @brief CQM 反初始化
+ * @param[in] ex_handle 设备句柄
+ */
+void cqm5_uninit(void *ex_handle);
+
+/**
+ * @brief CQM 初始化指定 Fake VF
+ * @param[in] ex_handle 设备句柄
+ * @param[in] vf_id 待初始化的 function id
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ * @retval -EINVAL Invalid argument
+ */
+int cqm5_init_fake_vf(void *ex_handle, u32 vf_id);
+
+/**
+ * @brief 注册业务扩展能力
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_template 业务扩展描述
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_service_register(void *ex_handle,
+ service_register_template_s *service_template);
+
+/**
+ * @brief 注销业务扩展能力
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ */
+void cqm5_service_unregister(void *ex_handle, u32 service_type);
+
+/**
+ * @brief 声明设备管理的 Fake VF 数量
+ * @param[in] ex_handle 设备句柄
+ * @param[in] fake_vf_num_cfg Fake VF 数量,该值不能大于设备支持的最大值
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
+
+/**
+ * @brief 创建 FC SRQ
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] wqe_number wqe 数目
+ * @param[in] wqe_size wqe 大小
+ * @param[in] object_priv 对象私有数据指针
+ *
+ * @details 队列中有效wqe个数必须要满足传入的wqe个数。
+ * 因为linkwqe只能填在页尾,真实有效个数超过需求,需要告知业务多创建的个数
+ *
+ * @return 队列结构指针
+ */
+cqm_queue_s *cqm5_object_fc_srq_create(void *ex_handle, u32 service_type,
+ cqm_object_type_e object_type,
+ u32 wqe_number, u32 wqe_size,
+ void *object_priv);
+
+/**
+ * @brief 创建 RQ
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] init_rq_num container 数目
+ * @param[in] container_size container 大小
+ * @param[in] wqe_size wqe 大小
+ * @param[in] object_priv 对象私有数据指针
+ *
+ * @details 在使用SRQ时,RQ队列创建
+ *
+ * @return 队列结构指针
+ */
+cqm_queue_s *cqm5_object_recv_queue_create(void *ex_handle, u32 service_type,
+ cqm_object_type_e object_type,
+ u32 init_rq_num, u32 container_size,
+ u32 wqe_size, void *object_priv);
+
+/**
+ * @brief 创建 TOE SRQ
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] container_number container 数目
+ * @param[in] container_size container 大小
+ * @param[in] wqe_size wqe 大小
+ *
+ * @return 队列结构指针
+ */
+cqm_queue_s *cqm5_object_share_recv_queue_create(
+ void *ex_handle, u32 service_type, cqm_object_type_e object_type,
+ u32 container_number, u32 container_size, u32 wqe_size);
+
+/**
+ * @brief 创建 QPC/MPT
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] object_size 对象大小,单位Byte
+ * @param[in] object_priv 对象私有数据指针
+ * @param[in] index 根据该值申请预留的qpn,如果要自动分配需填入CQM_INDEX_INVALID
+ * @param[in] bitmap_start 范围申请xid的起始index
+ * @param[in] bitmap_end 范围申请xid的结束index
+ *
+ * @attention 此接口可能会休眠
+ *
+ * @return QPC/MPT 结构指针
+ */
+cqm_qpc_mpt_s *cqm5_object_qpc_mpt_create(void *ex_handle, u32 service_type,
+ cqm_object_type_e object_type,
+ u32 object_size, void *object_priv,
+ u32 index, u32 bitmap_start,
+ u32 bitmap_end);
+
+/**
+ * @brief 创建非RDMA业务的队列
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] wqe_number 包含link wqe的数目
+ * @param[in] wqe_size 定长,大小为2^n
+ * @param[in] object_priv 对象私有数据指针
+ *
+ * @attention 此接口可能会休眠
+ *
+ * @return 队列结构指针
+ */
+cqm_queue_s *cqm5_object_nonrdma_queue_create(void *ex_handle, u32 service_type,
+ cqm_object_type_e object_type,
+ u32 wqe_number, u32 wqe_size,
+ void *object_priv);
+
+/**
+ * @brief 创建RDMA业务的队列
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] object_size 对象大小
+ * @param[in] object_priv 对象私有数据指针
+ * @param[in] room_header_alloc 是否要申请queue room和header空间
+ * @param[in] xid 根据该值申请预留的qpn,如果要自动分配需填入CQM_INDEX_INVALID
+ * @param[in] bitmap_start 范围申请xid的起始index
+ * @param[in] bitmap_end 范围申请xid的结束index
+ *
+ * @attention 此接口可能会休眠
+ *
+ * @return 队列结构指针
+ */
+cqm_queue_s *cqm5_object_rdma_queue_create(void *ex_handle, u32 service_type,
+ 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 创建RDMA业务的 MTT/RDMARC
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] object_type 对象类型
+ * @param[in] index_base 起始index编号
+ * @param[in] index_number index数量
+ *
+ * @return MTT/RDMARC 结构指针
+ */
+cqm_mtt_rdmarc_s *cqm5_object_rdma_table_get(void *ex_handle, u32 service_type,
+ cqm_object_type_e object_type,
+ u32 index_base, u32 index_number);
+
+/**
+ * @brief 申请一个 cmd buffer
+ * @param[in] ex_handle 设备句柄
+ *
+ * @attention buffer大小固定 2K,buffer 内容没有清零,需要业务清零
+ *
+ * @return cmd buffer 指针
+ */
+cqm_cmd_buf_s *cqm5_cmd_alloc(void *ex_handle);
+
+/**
+ * @brief 释放一个 cmd buffer
+ * @param[in] ex_handle 设备句柄
+ * @param[in] cmd_buf 待释放的 cmd buffer 指针
+ */
+void cqm5_cmd_free(void *ex_handle, cqm_cmd_buf_s *cmd_buf);
+
+/**
+ * @brief 发送 cmd
+ * @param[in] ex_handle 设备句柄
+ * @param[in] mod 模块
+ * @param[in] cmd 命令字
+ * @param[in] buf_in 输入命令 buffer
+ * @param[out] buf_out 输出命令 buffer
+ * @param[out] out_param 命令返回的 udata(user data)
+ * @param[in] timeout 命令超时时间,单位ms
+ * @param[in] channel 调用者 channel id
+ *
+ * @details 以 box 方式发送一个 cmdq cmd
+ *
+ * @attention 该接口会挂完成量,造成休眠
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, cqm_cmd_buf_s *buf_in,
+ cqm_cmd_buf_s *buf_out, u64 *out_param, u32 timeout,
+ u16 channel);
+
+/**
+ * @brief 发送 cmd
+ * @param[in] ex_handle 设备句柄
+ * @param[in] mod 模块
+ * @param[in] cmd 命令字
+ * @param[in] cos_id CMDQ 队列
+ * @param[in] buf_in 输入命令 buffer
+ * @param[out] buf_out 输出命令 buffer
+ * @param[out] out_param 命令返回的 udata(user data)
+ * @param[in] timeout 命令超时时间,单位ms
+ * @param[in] channel 调用者 channel id
+ *
+ * @details 指定 CMDQ 队列并以 box 方式发送一个 cmdq cmd
+ *
+ * @attention 该接口会挂完成量,造成休眠
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_lb_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, u8 cos_id,
+ cqm_cmd_buf_s *buf_in, cqm_cmd_buf_s *buf_out,
+ u64 *out_param, u32 timeout, u16 channel);
+
+/**
+ * @brief 发送 cmd
+ * @param[in] ex_handle 设备句柄
+ * @param[in] mod 模块
+ * @param[in] cmd 命令字
+ * @param[in] buf_in 输入命令 buffer
+ * @param[out] out_param 命令返回的 udata(user data)
+ * @param[in] timeout 命令超时时间,单位ms
+ * @param[in] channel 调用者 channel id
+ *
+ * @details 以 imm 方式发送一个 cmdq cmd
+ *
+ * @attention 该接口会挂完成量,造成休眠
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_send_cmd_imm(void *ex_handle, u8 mod, u8 cmd, cqm_cmd_buf_s *buf_in,
+ u64 *out_param, u32 timeout, u16 channel);
+
+/**
+ * @brief 申请硬件 doorbell 和 dwqe
+ * @param[in] ex_handle 设备句柄
+ * @param[out] db_addr doorbell 物理地址
+ * @param[out] dwqe_addr dwqe 物理地址
+ *
+ * @details 申请一页硬件doorbell和dwqe,具有相同的index,得到的均为物理地址,每个function最多有1K个
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_db_addr_alloc(void *ex_handle, void __iomem **db_addr,
+ void __iomem **dwqe_addr);
+
+/**
+ * @brief 释放硬件 doorbell 和 dwqe
+ * @param[in] ex_handle 设备句柄
+ * @param[in] db_addr doorbell 物理地址
+ * @param[in] dwqe_addr dwqe 物理地址
+ */
+void cqm5_db_addr_free(void *ex_handle, const void __iomem *db_addr,
+ void __iomem *dwqe_addr);
+
+/**
+ * @brief 获得硬件 doorbell 虚拟地址
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ *
+ * @return doorbell 虚拟地址
+ */
+
+void *cqm5_get_db_addr(void *ex_handle, u32 service_type);
+
+/**
+ * @brief 获得硬件 doorbell 物理地址
+ * @param[in] ex_handle 设备句柄
+ * @param[out] addr 保存 doorbell 物理地址的指针
+ * @param[in] service_type 业务类型
+ *
+ * @details 获得硬件doorbell物理地址
+ *
+ * @return doorbell地址
+ */
+s32 cqm5_get_hardware_db_addr(void *ex_handle, u64 *addr,
+ enum hinic5_service_type service_type);
+
+/**
+ * @brief Ring a hardware DB
+ * @param[in] ex_handle 设备句柄
+ * @param[in] service_type 业务类型
+ * @param[in] db_count doorbell中超出64b的PI[7:0]
+ * @param[in] db The content of hardware doorbell
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_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 设备句柄
+ * @param[in] 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 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_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 设备句柄
+ * @param[in] object 对象指针
+ * @param[in] db_record The content of software doorbell
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_ring_software_db(cqm_object_s *object, u64 db_record);
+
+/**
+ * @brief bloom filter 增加引用计数
+ * @param[in] ex_handle 设备句柄
+ * @param[in] id bloom filter id
+ *
+ * @details 由 0 -> 1 时发送API置位
+ *
+ * @attention 此接口可能会休眠
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_bloomfilter_inc(void *ex_handle, u16 func_id, u64 id);
+
+/**
+ * @brief bloom filter 减少引用计数
+ * @param[in] ex_handle 设备句柄
+ * @param[in] id bloom filter id
+ *
+ * @details 减为 0 时发送 API 清零
+ *
+ * @attention 此接口可能会休眠
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_bloomfilter_dec(void *ex_handle, u16 func_id, u64 id);
+
+/**
+ * @brief 获取 SMF Timer spoke list 的基址
+ * @param[in] ex_handle 设备句柄
+ *
+ * @return 虚拟地址
+ */
+void *cqm5_timer_base(void *ex_handle);
+
+/**
+ * @brief 清零 SMF Timer spoke list
+ * @param[in] ex_handle 设备句柄
+ * @param[in] function_id function id
+ */
+void cqm5_function_timer_clear(void *ex_handle, u32 function_id);
+
+/**
+ * @brief 清零 hash buffer
+ * @param[in] ex_handle 设备句柄
+ * @param[in] global_funcid function id
+ */
+void cqm5_function_hash_buf_clear(void *ex_handle, s32 global_funcid);
+
+/**
+ * @brief SRQ 申请新的 container,创建后好挂链
+ * @param[in] common 队列结构指针
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_object_share_recv_queue_add_container(cqm_queue_s *common);
+
+/**
+ * @brief SRQ 申请新的 container,创建后不挂链,由业务完成挂链
+ * @param[in] common 队列结构指针
+ * @param[out] container_addr 返回的 container 地址
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_object_srq_add_container_free(cqm_queue_s *common,
+ u8 **container_addr);
+
+/**
+ * @brief 通过 index 获得对象
+ * @param[in] ex_handle 设备句柄
+ * @param[in] object_type 对象类型
+ * @param[in] index index支持qpn,mptn,scqn,srqn
+ * @param[in] bh 是否禁用中断下半部
+ *
+ * @return 对象指针
+ */
+cqm_object_s *cqm5_object_get(void *ex_handle, cqm_object_type_e object_type,
+ u32 index, bool bh);
+
+/**
+ * @brief 释放对象
+ * @param[in] object 对象指针
+ */
+void cqm5_object_put(cqm_object_s *object);
+
+/**
+ * @brief 删除对象
+ * @param[in] object 对象指针
+ *
+ * @details 删除创建的对象,该函数会休眠等待所有对该对象的操作完成才返回
+ *
+ * @attention 此接口可能会休眠
+ */
+void cqm5_object_delete(cqm_object_s *object);
+
+/**
+ * @brief 获得对象的所属 function ID
+ * @param[in] object 对象指针
+ *
+ * @return
+ * @retval >=0 function ID
+ * @retval -1 失败
+ */
+s32 cqm5_object_funcid(cqm_object_s *object);
+
+/**
+ * @brief 给对象申请一块新空间
+ * @param[in] object 对象指针
+ * @param[in] object_size 新buffer大小
+ *
+ * @details 目前只对roce业务有用,调整CQ的buffer大小,但cqn和cqc不变,
+ * 申请新的buffer空间,不释放旧buffer空间,当前有效buffer仍为旧buffer
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_object_resize_alloc_new(cqm_object_s *object, u32 object_size);
+
+/**
+ * @brief 给对象释放新申请buffer空间
+ * @param[in] object 对象指针
+ *
+ * @details 本函数释放新申请buffer空间,用于业务的异常处理分支
+ */
+void cqm5_object_resize_free_new(cqm_object_s *object);
+
+/**
+ * @brief 给对象释旧buffer空间
+ * @param[in] object 对象指针
+ *
+ * @details 本函数释放旧的buffer,并将当前有效buffer设置为新buffer
+ */
+void cqm5_object_resize_free_old(cqm_object_s *object);
+
+/**
+ * @brief 释放container
+ * @param[in] object 对象指针
+ * @param[in] container 要释放的container指针
+ *
+ * @details 释放container
+ */
+void cqm5_srq_used_rq_container_delete(cqm_object_s *object, u8 *container);
+
+/**
+ * @brief 获得对象buffer指定偏移处的物理地址和虚拟地址
+ * @param[in] object 对象指针
+ * @param[in] offset 对于rdma table,offset为index绝对编号
+ * @param[out] paddr 仅对rdma table才返回物理地址
+ *
+ * @details 仅支持rdma table查找,获得对象buffer指定偏移处的物理地址和虚拟地址
+ *
+ * @return u8 *buffer指定偏移处的虚拟地址
+ */
+u8 *cqm5_object_offset_addr(cqm_object_s *object, u32 offset,
+ dma_addr_t *paddr);
+
+/**
+ * @brief 创建 DTOE SRQ
+ * @param[in] ex_handle 设备句柄
+ * @param[in] contex_size 上下文大小
+ * @param[out] index_count 申请的 index 数量
+ * @param[out] index 申请的 index 起始
+ *
+ * @return 是否成功
+ * @retval 0 success
+ * @retval -1 failure
+ */
+s32 cqm5_dtoe_share_recv_queue_create(void *ex_handle, u32 contex_size,
+ u32 *index_count, u32 *index);
+
+/**
+ * @brief 释放 DTOE SRQ bitmap
+ * @param[in] ex_handle 设备句柄
+ * @param[in] index_count 释放的 index 数量
+ * @param[in] index 释放的 index 起始
+ */
+void cqm5_dtoe_free_srq_bitmap_index(void *ex_handle, u32 index_count,
+ u32 index);
+
+#endif /* HINIC5_CQM_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_service.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_service.h
new file mode 100644
index 000000000..8defffe7c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_service.h
@@ -0,0 +1,590 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef HINIC5_SERVICE_H
+#define HINIC5_SERVICE_H
+
+#include <linux/types.h>
+
+#include "base_type.h"
+
+/**
+ * @brief Service type
+ */
+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,
+
+ SERVICE_T_INTF = (1 << 15), /* Interrupt Resource Management Only */
+ SERVICE_T_CQM = (1 << 16),
+};
+
+/**
+ * @brief NIC service capability
+ */
+struct nic_service_cap {
+ u16 max_sqs; /**< 最大发送队列数量 */
+ u16 max_rqs; /**< 最大接收队列数量 */
+ u16 default_num_queues; /**< 默认队列数量 */
+};
+
+/**
+ * @brief PPA service capability
+ */
+struct ppa_service_cap {
+ u16 qpc_fake_vf_start; /**< 起始的虚拟函数号 */
+ u16 qpc_fake_vf_num; /**<可用的虚拟函数数量 */
+ u32 qpc_fake_vf_ctx_num; /**< 可用的虚拟函数上下文数量 */
+ u32 pctx_sz; /**< 上下文大小512B */
+ u32 bloomfilter_length; /**< 布隆过滤器长度 */
+ u8 bloomfilter_en; /**< 布隆过滤器使能标志 */
+ u8 rsvd;
+ u16 rsvd1;
+};
+
+/**
+ * @brief VBS service capability
+ * @details 描述VBS服务的能力的结构体
+ */
+struct vbs_service_cap {
+ u16 vbs_max_volq; /**< 最大的卷积队列数量 */
+ u16 vbs_main_pf_enable : 1; /**< 主PF是否启用 */
+ u16 vbs_vsock_pf_enable : 1; /**< vsock PF是否启用 */
+ u16 vbs_fushion_queue_pf_enable : 1; /**< 融合队列PF是否启用 */
+ u16 vbs_host_dma_data_cos : 3; /**< 主机DMA数据的优先级 */
+ u16 vbs_vmio_cpy_data_cos : 3; /**< VMIO复制数据的优先级 */
+ u16 vbs_volq_cos : 3; /**< 卷积队列的优先级 */
+ u16 rsvd1 : 4;
+ u32 vbs_child_ctx_num;
+ u32 vbs_hash_bucket_num;
+};
+
+/**
+ * @brief Migration service capability
+ */
+struct migr_service_cap {
+ u8 master_host_id; /**< 主机ID */
+ u8 rsvd[3];
+};
+
+/**
+ * @brief UB sdk capability
+ */
+struct ub_dev_cap_sdk_res {
+ u32 max_jfc; /**< 最大Job Function Controller数量 */
+ u32 max_jfr; /**< 最大Job Function Record数量 */
+ u32 max_tp; /**< 最大Transmission Port数量 */
+ u32 max_tpg; /**< 最大Transmission Port Group数量 */
+ u32 max_jetty; /**< 最大Jetty数量 */
+ u32 max_jetty_grp; /**< 最大Jetty Group数量 */
+ u32 max_mpts; /**< 最大Multi-Path Termination Point数量 */
+ u32 max_vtp; /**< 最大Virtual Transmission Port数量 */
+ u32 max_gid; /**< 最大GID数量 */
+ u32 max_utp; /**< 最大Unicast Transmission Port数量 */
+ u32 max_jfrc; /**< 最大Job Function Record Cache数量 */
+
+ u32 srqc_entry_sz; /**< Shared Receive Queue Controller条目大小 */
+ u32 mpt_entry_sz; /**< Multi-Path Termination Point条目大小 */
+ u32 cqc_entry_sz; /**< Completion Queue Controller条目大小 */
+ u32 qpc_entry_sz; /**< Queue Pair Context条目大小 */
+
+ u32 dmtt_cl_start; /**< Data Move To Target开始地址 */
+ u32 dmtt_cl_end; /**< Data Move To Target结束地址 */
+ u32 dmtt_cl_sz; /**< Data Move To Target大小 */
+
+ u32 cmtt_cl_start; /**< Control Move To Target开始地址 */
+ u32 cmtt_cl_end; /**< Control Move To Target结束地址 */
+ u32 cmtt_cl_sz; /**< Control Move To Target大小 */
+
+ u32 wqe_cl_start; /**< Work Request Element开始地址 */
+ u32 wqe_cl_end; /**< Work Request Element结束地址 */
+ u32 wqe_cl_sz; /**< Work Request Element大小 */
+};
+
+/**
+ * @brief UB net capability
+ */
+struct ub_net_dev_cap {
+ u32 is_tpf; /**< 是否支持透明转发 */
+ u32 vf_cnt; /**< 虚拟函数数量 */
+ u32 port_cnt; /**< 端口数量 */
+ u32 max_mtu; /**< 最大传输单元大小 */
+ u32 comp_vector_cnt; /**< 中断向量数量 */
+};
+
+/**
+ * @brief UB service capability
+ */
+struct ub_service_cap {
+ struct ub_dev_cap_sdk_res sdk_res; /**< 设备能力 - SDK */
+ struct ub_net_dev_cap net_dev_cap; /**< 网络设备能力 */
+};
+
+/**
+ * @brief JBOF service capability
+ */
+struct jbof_service_cap {
+ u32 max_parent_qpc_num; /**< 最大父QPC数量 */
+ u32 max_child_qpc_num; /**< 最大子QPC数量 */
+ u32 parent_qpc_size; /**< 父QPC大小 */
+ u32 child_qpc_size; /**< 子QPC大小 */
+ u32 hash_bucket_num; /**< 哈希桶数量 */
+};
+
+/**
+ * @brief 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 PF/VF ToE service resource
+ */
+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 TOE service capability
+ */
+struct toe_service_cap {
+ struct dev_toe_svc_cap dev_toe_cap;
+
+ bool alloc_flag;
+ u32 pctx_sz; /**< 1KB */
+ u32 scqc_sz; /**< 64B */
+};
+
+/**
+ * @brief PF FC service resource
+ */
+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 FC service capability
+ */
+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 */
+};
+
+/**
+ * @brief ROCE service capability
+ */
+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 RDMA service capability
+ */
+struct dev_rdma_svc_cap {
+ struct dev_roce_svc_own_cap roce_own_cap; /**< ROCE-only capability */
+};
+
+/**
+ * @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 RDMA service capability
+ */
+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 PF OVS service resource
+ */
+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 OVS service capability
+ */
+struct ovs_service_cap {
+ struct dev_ovs_svc_cap dev_ovs_cap;
+
+ u32 pctx_sz; /**< 512B */
+};
+
+/**
+ * @brief PF IPsec service resource
+ */
+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 IPsec service capability
+ */
+struct ipsec_service_cap {
+ struct dev_ipsec_svc_cap dev_ipsec_cap;
+ u32 sactx_sz; /**< 512B */
+};
+
+/**
+ * @brief Check if the device supports NIC
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if NIC is supported, false otherwise.
+ */
+bool hinic5_support_nic(void *hwdev, struct nic_service_cap *cap);
+
+/**
+ * @brief Check if the device supports OVS
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if OVS is supported, false otherwise.
+ */
+bool hinic5_support_ovs(void *hwdev, struct ovs_service_cap *cap);
+
+/**
+ * @brief Check if the device supports RoCE
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if RoCE is supported, false otherwise.
+ */
+bool hinic5_support_roce(void *hwdev, struct rdma_service_cap *cap);
+
+/**
+ * @brief Check if the device supports TOE
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if MACsec is supported, false otherwise.
+ */
+bool hinic5_support_toe(void *hwdev, struct toe_service_cap *cap);
+
+/**
+ * @brief Check if the device supports FC
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if FC is supported, false otherwise.
+ */
+bool hinic5_support_fc(void *hwdev, struct fc_service_cap *cap);
+
+/**
+ * @brief Check if the device supports VBS
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if VBS is supported, false otherwise.
+ */
+bool hinic5_support_vbs(void *hwdev, struct vbs_service_cap *cap);
+
+/**
+ * @brief Check if the device supports IPsec
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if IPsec is supported, false otherwise.
+ */
+bool hinic5_support_ipsec(void *hwdev, struct ipsec_service_cap *cap);
+
+/**
+ * @brief Check if the device supports Migration
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if Migration is supported, false otherwise.
+ */
+bool hinic5_support_migr(void *hwdev, struct migr_service_cap *cap);
+
+/**
+ * @brief Check if the device supports PPA
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if PPA is supported, false otherwise.
+ */
+bool hinic5_support_ppa(void *hwdev, struct ppa_service_cap *cap);
+
+/**
+ * @brief Check if the device supports vRoCE
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if vRoCE is supported, false otherwise.
+ */
+bool hinic5_support_vroce(void *hwdev, struct rdma_service_cap *cap);
+
+/**
+ * @brief Check if the device supports UB
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if UB is supported, false otherwise.
+ */
+bool hinic5_support_ub(void *hwdev, struct ub_service_cap *cap);
+
+/**
+ * @brief Check if the device supports JBOF
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if JBOF is supported, false otherwise.
+ */
+bool hinic5_support_jbof(void *hwdev, struct jbof_service_cap *cap);
+
+/**
+ * @brief Check if the device supports MACsec
+ * @param[in] hwdev device pointer to hwdev
+ *
+ * @return true if MACsec is supported, false otherwise.
+ */
+bool hinic5_support_macsec(void *hwdev);
+
+/**
+ * @brief Check if the device supports DMMU
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if DMMU is supported, false otherwise.
+ */
+bool hinic5_support_dmmu(void *hwdev, struct dmmu_service_cap *cap);
+
+/**
+ * @brief Check if the device supports Bifurcation
+ * @param[in] hwdev device pointer to hwdev
+ *
+ * @return true if Bifurcation is supported, false otherwise.
+ */
+bool hinic5_support_bifur(void *hwdev);
+
+/**
+ * @brief Check if the device supports HIHTR
+ * @param[in] hwdev device pointer to hwdev
+ *
+ * @return true if HIHTR is supported, false otherwise.
+ */
+bool hinic5_support_hihtr(void *hwdev);
+
+/**
+ * @brief Check if the device supports RDMA
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if RDMA is supported, false otherwise.
+ */
+bool hinic5_support_rdma(void *hwdev, struct rdma_service_cap *cap);
+
+/**
+ * @brief Check if RDMA is enabled
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] cap service capability
+ *
+ * @return true if RDMA is enabled, false otherwise.
+ */
+bool hinic5_is_rdma_en(void *hwdev, struct rdma_service_cap *cap);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_vram_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_vram_api.h
new file mode 100644
index 000000000..598ac178b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_vram_api.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef HINIC5_VRAM_API_H
+#define HINIC5_VRAM_API_H
+
+#if !defined(__UEFI__) && !defined(__WIN__)
+#include <linux/notifier.h>
+#include <linux/numa.h>
+#endif
+
+#define VRAM_NUMA_NODE0 0
+#define VRAM_NUMA_NODE1 1
+#define CQM_OVS_PAGESIZE_ORDER 9
+#define VRAM_NAME_APPLY_LEN 64
+
+struct vram_buf_info {
+ char buf_vram_name[VRAM_NAME_APPLY_LEN];
+ int use_vram;
+};
+
+#if defined(__UEFI__) || defined(__WIN__) || defined(__VMWARE__)
+#define hi5_vram_kalloc_node(name, size, numa) 0
+#define hi5_vram_kfree(vaddr, name, size)
+#define get5_use_vram_flag() 0
+#else
+
+/**
+ * @brief alloc vram memory
+ * @param name name of vram memory
+ * @param size size of vram memory
+ * @param numa vram numa node. if greater than environment numa num, apply for idle nodes
+ **/
+void __iomem *hi5_vram_kalloc_node(char *name, u64 size, u8 numa);
+/**
+ * @brief free vram memory
+ * @param vaddr virtual address of vram memory
+ * @param name name of vram memory
+ * @param size size of vram memory
+ **/
+void hi5_vram_kfree(void __iomem *vaddr, char *name, u64 size);
+/**
+ * @brief get use-vram flag
+ * @return
+ * - Zero for not-use-vram. Non-zero for use-vram.
+ **/
+int get5_use_vram_flag(void);
+
+#endif
+#endif /* 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/ossl/ossl_user.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_user.h
new file mode 100644
index 000000000..2df1664d6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_user.h
@@ -0,0 +1,13 @@
+#ifndef OSSL_USER_H
+#define OSSL_USER_H
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include "base_type.h"
+
+#ifndef dma_addr_t
+typedef __uint64_t dma_addr_t;
+#endif
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/vbs_kcompat.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/vbs_kcompat.h
new file mode 100644
index 000000000..279eb9c26
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/vbs_kcompat.h
@@ -0,0 +1,13 @@
+/**
+ * @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 2026/1/22
+ */
+#ifndef VBS_KCOMPAT_H
+#define VBS_KCOMPAT_H
+
+// vbs_kcompat.h是中间产物头文件
+
+#endif /* VBS_KCOMPAT_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_byteorder.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_byteorder.h
new file mode 100644
index 000000000..cf210533c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_byteorder.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK byte order for ARM architecture header file
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_BYTEORDER_ARM_H
+#define UDK_BYTEORDER_ARM_H
+
+#include <stdint.h>
+
+#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+
+static inline uint16_t udk_arch_bswap16(uint16_t _x)
+{
+ uint16_t x = _x;
+
+ asm volatile("rev16 %w0,%w1" : "=r"(x) : "r"(x));
+ return x;
+}
+
+#define udk_bswap16(x) \
+ ((uint16_t)(__builtin_constant_p(x) ? udk_constant_bswap16(x) : \
+ udk_arch_bswap16(x)))
+#else
+#define udk_bswap16(x) __builtin_bswap16(x)
+#endif
+
+#define udk_bswap32(x) __builtin_bswap32(x)
+#define udk_bswap64(x) __builtin_bswap64(x)
+
+#endif /* UDK_BYTEORDER_ARM_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_cycles.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_cycles.h
new file mode 100644
index 000000000..faf4fab26
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_cycles.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK cycles/timer for ARM architecture header file
+ * Author: -
+ * Create: 2021.4.19
+ */
+
+#ifndef UDK_CYCLES_ARM_H
+#define UDK_CYCLES_ARM_H
+
+#include <stdint.h>
+#include "udk_common.h"
+
+static udk_force_inline uint64_t udk_arm64_cntfrq(void)
+{
+ uint64_t freq;
+
+ asm volatile("mrs %0, cntfrq_el0" : "=r"(freq));
+ return freq;
+}
+
+static udk_force_inline uint64_t udk_arm64_cntvct(void)
+{
+ uint64_t tsc;
+
+ asm volatile("mrs %0, cntvct_el0" : "=r"(tsc));
+ return tsc;
+}
+
+static udk_force_inline uint64_t udk_rdtsc(void)
+{
+ return udk_arm64_cntvct();
+}
+
+#endif /* UDK_CYCLES_ARM_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_io.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_io.h
new file mode 100644
index 000000000..e9ffeb121
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_io.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK IO for ARM architecture header file
+ * Author: -
+ * Create: 2021.5.26
+ */
+
+#ifndef UDK_IO_ARM_H
+#define UDK_IO_ARM_H
+
+#include <stdint.h>
+#include "udk_common.h"
+#include "udk_membarrier.h"
+
+#define udk_io_wmb() udk_wmb()
+#define udk_io_rmb() udk_rmb()
+#define udk_io_mb() udk_mb()
+
+static udk_force_inline void udk_write64_relaxed(uint64_t val,
+ volatile void *addr)
+{
+ asm volatile("str %x[val], [%x[addr]]"
+ :
+ : [val] "r"(val), [addr] "r"(addr));
+}
+
+#endif /* UDK_IO_ARM_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_membarrier.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_membarrier.h
new file mode 100644
index 000000000..5d016cdb3
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/arm/udk_membarrier.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK memory barrier for ARM architecture header file
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_MEMBARRIER_ARM_H
+#define UDK_MEMBARRIER_ARM_H
+
+/**
+ * @brief Prefetch specific memory to all cache include L0 cache.
+ */
+static inline void udk_prefetch0(const volatile void *p)
+{
+ asm volatile("PRFM PLDL1KEEP, [%0]" : : "r"(p));
+}
+
+/**
+ * @brief Insert a hardware memory barrier to ensure no out-of-order write operations.
+ */
+#define udk_wmb() asm volatile("dmb oshst" : : : "memory")
+
+/**
+ * @brief Insert a hardware memory barrier to ensure no out-of-order read operations.
+ */
+#define udk_rmb() asm volatile("dmb oshld" : : : "memory")
+
+/**
+ * @brief Insert a hardware memory barrier to protect both read and write operations.
+ */
+#define udk_mb() asm volatile("dmb osh" : : : "memory")
+
+/**
+ * @brief Write memory Barriers for multiprocessors.
+ */
+#define udk_smp_wmb() asm volatile("dmb ishst" : : : "memory")
+
+/**
+ * @brief Read memory Barriers for multiprocessors.
+ */
+#define udk_smp_rmb() asm volatile("dmb ishld" : : : "memory")
+
+/**
+ * @brief Memory Barriers for multiprocessors.
+ */
+#define udk_smp_mb() asm volatile("dmb ish" : : : "memory")
+
+#endif /* UDK_MEMBARRIER_ARM_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_byteorder.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_byteorder.h
new file mode 100644
index 000000000..98ffa0d59
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_byteorder.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK byte order for x86 architecture header file
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_BYTEORDER_X86_H
+#define UDK_BYTEORDER_X86_H
+
+#include <stdint.h>
+
+static inline uint16_t udk_arch_bswap16(uint16_t _x)
+{
+ uint16_t x = _x;
+ asm volatile("xchgb %b[x1],%h[x2]" : [x1] "=Q"(x) : [x2] "0"(x));
+ return x;
+}
+
+static inline uint32_t udk_arch_bswap32(uint32_t _x)
+{
+ uint32_t x = _x;
+ asm volatile("bswap %[x]" : [x] "+r"(x));
+ return x;
+}
+
+static inline uint64_t udk_arch_bswap64(uint64_t _x)
+{
+ uint64_t x = _x;
+ asm volatile("bswap %[x]" : [x] "+r"(x));
+ return x;
+}
+
+#define UDK_CONSTANT_BSWAP16(v) \
+ ((uint16_t)((((uint16_t)(v)&UINT16_C(0x00ff)) << 8) | \
+ (((uint16_t)(v)&UINT16_C(0xff00)) >> 8)))
+
+#define UDK_CONSTANT_BSWAP32(v) \
+ ((uint32_t)((((uint32_t)(v)&UINT32_C(0x000000ff)) << 24) | \
+ (((uint32_t)(v)&UINT32_C(0x0000ff00)) << 8) | \
+ (((uint32_t)(v)&UINT32_C(0x00ff0000)) >> 8) | \
+ (((uint32_t)(v)&UINT32_C(0xff000000)) >> 24)))
+
+#define UDK_CONSTANT_BSWAP64(v) \
+ ((uint64_t)((((uint64_t)(v)&UINT64_C(0x00000000000000ff)) << 56) | \
+ (((uint64_t)(v)&UINT64_C(0x000000000000ff00)) << 40) | \
+ (((uint64_t)(v)&UINT64_C(0x0000000000ff0000)) << 24) | \
+ (((uint64_t)(v)&UINT64_C(0x00000000ff000000)) << 8) | \
+ (((uint64_t)(v)&UINT64_C(0x000000ff00000000)) >> 8) | \
+ (((uint64_t)(v)&UINT64_C(0x0000ff0000000000)) >> 24) | \
+ (((uint64_t)(v)&UINT64_C(0x00ff000000000000)) >> 40) | \
+ (((uint64_t)(v)&UINT64_C(0xff00000000000000)) >> 56)))
+
+/*
+ * Byte swap for an constant 16-bit value.
+ */
+static inline uint16_t udk_constant_bswap16(uint16_t x)
+{
+ return UDK_CONSTANT_BSWAP16(x);
+}
+
+/*
+ * Byte swap for an constant 32-bit value.
+ */
+static inline uint32_t udk_constant_bswap32(uint32_t x)
+{
+ return UDK_CONSTANT_BSWAP32(x);
+}
+
+/*
+ * Byte swap for an constant 64-bit value.
+ */
+static inline uint64_t udk_constant_bswap64(uint64_t x)
+{
+ return UDK_CONSTANT_BSWAP64(x);
+}
+
+#define udk_bswap16(x) \
+ ((uint16_t)(__builtin_constant_p(x) ? udk_constant_bswap16(x) : \
+ udk_arch_bswap16(x)))
+#define udk_bswap32(x) \
+ ((uint32_t)(__builtin_constant_p(x) ? udk_constant_bswap32(x) : \
+ udk_arch_bswap32(x)))
+#define udk_bswap64(x) \
+ ((uint64_t)(__builtin_constant_p(x) ? udk_constant_bswap64(x) : \
+ udk_arch_bswap64(x)))
+
+#endif /* UDK_BYTEORDER_X86_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_cycles.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_cycles.h
new file mode 100644
index 000000000..8ded0fee0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_cycles.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK cycles/timer for x86 architecture header file
+ * Author: -
+ * Create: 2021.4.19
+ */
+
+#ifndef UDK_CYCLES_X86_H
+#define UDK_CYCLES_X86_H
+
+#include <stdint.h>
+
+static inline uint64_t udk_x86_rdtsc(void)
+{
+ union {
+ uint64_t tsc_64;
+ struct {
+ uint32_t lo_32;
+ uint32_t hi_32;
+ };
+ } tsc;
+
+ asm volatile("rdtsc" : "=a"(tsc.lo_32), "=d"(tsc.hi_32));
+
+ return tsc.tsc_64;
+}
+
+static inline uint64_t udk_rdtsc(void)
+{
+ return udk_x86_rdtsc();
+}
+
+#endif /* UDK_CYCLES_X86_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_io.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_io.h
new file mode 100644
index 000000000..7f0c6e6a8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_io.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK IO for x86 architecture header file
+ * Author: -
+ * Create: 2021.5.26
+ */
+
+#ifndef UDK_IO_X86_H
+#define UDK_IO_X86_H
+
+#include <stdint.h>
+
+#include "udk_common.h"
+#include "udk_membarrier.h"
+
+#define udk_io_wmb() udk_compiler_barrier()
+#define udk_io_rmb() udk_compiler_barrier()
+#define udk_io_mb() udk_mb()
+
+static udk_force_inline void udk_write64_relaxed(uint64_t value,
+ volatile void *addr)
+{
+ *(volatile uint64_t *)addr = value;
+}
+
+#endif /* UDK_IO_X86_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_membarrier.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_membarrier.h
new file mode 100644
index 000000000..5ed9fe835
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/arch/x86/udk_membarrier.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK memory barrier for x86 architecture header file
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_MEMBARRIER_X86_H
+#define UDK_MEMBARRIER_X86_H
+
+#include <emmintrin.h>
+
+/**
+ * @brief Prefetch specific memory to all cache include L0 cache.
+ */
+static inline void udk_prefetch0(const volatile void *p)
+{
+ asm volatile("prefetcht0 %[p]" : : [p] "m"(*(const volatile char *)p));
+}
+
+/**
+ * @brief Insert a hardware memory barrier to ensure no out-of-order write operations.
+ */
+#define udk_wmb() _mm_sfence()
+
+/**
+ * @brief Insert a hardware memory barrier to ensure no out-of-order read operations.
+ */
+#define udk_rmb() _mm_lfence()
+
+/**
+ * @brief Insert a hardware memory barrier to protect both read and write operations.
+ */
+#define udk_mb() _mm_mfence()
+
+/**
+ * @brief Write memory Barriers for multiprocessors.
+ */
+#define udk_smp_wmb() asm volatile("" : : : "memory")
+
+/**
+ * @brief Read memory Barriers for multiprocessors.
+ */
+#define udk_smp_rmb() asm volatile("" : : : "memory")
+
+/**
+ * @brief Memory Barriers for multiprocessors.
+ */
+#define udk_smp_mb() asm volatile("lock addl $0, -128(%%rsp); " ::: "memory")
+
+/**
+ * @brief Compiler barrier.
+ */
+#define udk_compiler_barrier() \
+ do { \
+ asm volatile("" : : : "memory"); \
+ } while (0)
+
+#endif /* UDK_MEMBARRIER_X86_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_args.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_args.h
new file mode 100644
index 000000000..916ed496c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_args.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK args header file
+ * Author: -
+ * Create: 2021.5.6
+ */
+
+#ifndef UDK_ARGS_H
+#define UDK_ARGS_H
+
+#include <stdint.h>
+
+#define UDK_KVARGS_MAX 32
+#define UDK_KVARGS_PAIRS_DELIM ","
+#define UDK_KVARGS_KV_DELIM "="
+
+/**
+ * @brief 处理kv对象中的回调函数类型
+ *
+ * @details NA
+ *
+ * @return: 描述函数返回值.
+ * @retval >0 匹配
+ * @retval 负数 未匹配
+ */
+typedef int (*arg_handler_t)(const char *key, const char *value, void *opaque);
+
+/**
+ * @brief struct udk_kvargs_pair - kv pair
+ * @details NA
+ */
+struct udk_kvargs_pair {
+ char *key;
+ char *value;
+};
+
+/**
+ * @brief struct udk_kvargs - kv对象集合
+ * @details NA
+ */
+struct udk_kvargs {
+ char *str;
+ uint32_t count;
+ struct udk_kvargs_pair pairs[UDK_KVARGS_MAX];
+};
+
+/**
+ * @brief 解析udk库初始化的参数
+ *
+ * @param args 初始化的参数
+ * @param valid_keys keys数组
+ *
+ * @return: 返回解析后的结构化对象
+ */
+struct udk_kvargs *udk_kvargs_parse(const char *args,
+ const char *const valid_keys[]);
+
+/**
+ * @brief 处理解析的参数对象
+ *
+ * @param kvlist 解析的kv对象
+ * @param key_match 比对的key
+ * @param handler 校验的回调
+ * @param opaque_arg 传入回调的参数之一
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval -1 失败
+ */
+int udk_kvargs_process(const struct udk_kvargs *kvlist, const char *key_match,
+ arg_handler_t handler, void *opaque_arg);
+
+/**
+ * @brief 获取kb对象中匹配key的数量
+ *
+ * @param kvlist kv对象
+ * @param key_match 比较的key
+ *
+ * @return: 返回kv中匹配key的数量
+ */
+uint32_t udk_kvargs_count(const struct udk_kvargs *kvlist,
+ const char *key_match);
+
+/**
+ * @brief 释放kv对象申请的资源
+ *
+ * @param kvlist kv对象
+ *
+ * @return: NA
+ */
+void udk_kvargs_free(struct udk_kvargs *kvlist);
+
+#endif /* UDK_ARGS_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_atomic.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_atomic.h
new file mode 100644
index 000000000..f3d498384
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_atomic.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK atomic operations header file(generic, Architecture-independent)
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_ATOMIC_H
+#define UDK_ATOMIC_H
+
+#include <stdint.h>
+
+/* ------------------------- 16 bit atomic operations ------------------------- */
+
+/**
+ * @brief Atomic counter define.
+ */
+typedef struct {
+ volatile int16_t cnt;
+} udk_atomic16_t;
+
+/**
+ * @brief Initialize an atomic counter to 0.
+ */
+static inline void udk_atomic16_init(udk_atomic16_t *v)
+{
+ v->cnt = 0;
+}
+
+static inline int16_t udk_atomic16_read(const udk_atomic16_t *v)
+{
+ return v->cnt;
+}
+
+static inline void udk_atomic16_set(udk_atomic16_t *v, int16_t new_value)
+{
+ v->cnt = new_value;
+}
+
+/**
+ * @brief Add a 16-bit value to an atomic counter and return the before value.
+ */
+static inline int32_t udk_atomic16_add(udk_atomic16_t *v, int16_t inc)
+{
+ return __sync_fetch_and_add(&v->cnt, inc);
+}
+
+/**
+ * @brief Increment a 16-bit atomic counter by 1.
+ */
+static inline void udk_atomic16_inc(udk_atomic16_t *v)
+{
+ udk_atomic16_add(v, 1);
+}
+
+/**
+ * @brief Subtract a 16-bit value from an atomic counter.
+ */
+static inline void udk_atomic16_sub(udk_atomic16_t *v, int16_t dec)
+{
+ __sync_fetch_and_sub(&v->cnt, dec);
+}
+
+/**
+ * @brief Decrement a 16-bit atomic counter by 1.
+ */
+static inline void udk_atomic16_dec(udk_atomic16_t *v)
+{
+ udk_atomic16_sub(v, 1);
+}
+
+/**
+ * @brief udk_atomic16_cmpset, equivalent to(atomic):
+ * if (*dst == exp)
+ * *dst = src (all 16-bit words)
+ */
+static inline int udk_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp,
+ uint16_t src)
+{
+ return __sync_bool_compare_and_swap(dst, exp, src);
+}
+
+/**
+ * @brief Decrement a 16-bit counter by one and return true if the counter is equal to 0.
+ */
+static inline int udk_atomic16_dec_and_test(udk_atomic16_t *v)
+{
+ return __sync_sub_and_fetch(&v->cnt, 1) == 0;
+}
+
+/* ------------------------- 32 bit atomic operations ------------------------- */
+
+/**
+ * @brief Atomic counter define.
+ */
+typedef struct {
+ volatile int32_t cnt;
+} udk_atomic32_t;
+
+/**
+ * @brief Initialize an atomic counter to 0.
+ */
+static inline void udk_atomic32_init(udk_atomic32_t *v)
+{
+ v->cnt = 0;
+}
+
+/**
+ * @brief Read a 32-bit value from an atomic counter.
+ */
+static inline int32_t udk_atomic32_read(udk_atomic32_t *v)
+{
+ return v->cnt;
+}
+
+/**
+ * @brief Add a 32-bit value to an atomic counter.
+ */
+static inline void udk_atomic32_add(udk_atomic32_t *v, int32_t inc)
+{
+ __sync_fetch_and_add(&v->cnt, inc);
+}
+
+/**
+ * @brief Increment a 32-bit atomic counter by 1.
+ */
+static inline void udk_atomic32_inc(udk_atomic32_t *v)
+{
+ udk_atomic32_add(v, 1);
+}
+
+/**
+ * @brief Subtract a 32-bit value from an atomic counter.
+ */
+static inline void udk_atomic32_sub(udk_atomic32_t *v, int32_t dec)
+{
+ __sync_fetch_and_sub(&v->cnt, dec);
+}
+
+/**
+ * @brief Decrement a 32-bit atomic counter by 1.
+ */
+static inline void udk_atomic32_dec(udk_atomic32_t *v)
+{
+ udk_atomic32_sub(v, 1);
+}
+
+/**
+ * @brief Set an atomic counter to a new 32-bit value.
+ */
+static inline void udk_atomic32_set(udk_atomic32_t *v, int32_t new_value)
+{
+ v->cnt = new_value;
+}
+
+/**
+ * @brief udk_atomic32_cmpset, equivalent to(atomic):
+ * if (*dst == exp)
+ * *dst = src (all 32-bit words)
+ */
+static inline int udk_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp,
+ uint32_t src)
+{
+ return __sync_bool_compare_and_swap(dst, exp, src);
+}
+
+/**
+ * @brief Add a 32-bit value to an atomic counter and return the result.
+ */
+static inline int32_t udk_atomic32_add_return(udk_atomic32_t *v, int32_t inc)
+{
+ return __sync_add_and_fetch(&v->cnt, inc);
+}
+
+/**
+ * @brief Decrement a 32-bit counter by one and return true if the counter is equal to 0.
+ */
+static inline int udk_atomic32_dec_and_test(udk_atomic32_t *v)
+{
+ return __sync_sub_and_fetch(&v->cnt, 1) == 0;
+}
+
+/* ------------------------- 64 bit atomic operations ------------------------- */
+
+/**
+ * @brief Atomic counter define.
+ */
+typedef struct {
+ volatile int64_t cnt;
+} udk_atomic64_t;
+
+/**
+ * @brief Initialize an atomic counter to 0.
+ */
+static inline void udk_atomic64_init(udk_atomic64_t *v)
+{
+ v->cnt = 0;
+}
+
+/**
+ * @brief Read a 64-bit value from an atomic counter.
+ */
+static inline int64_t udk_atomic64_read(udk_atomic64_t *v)
+{
+ return v->cnt;
+}
+
+/**
+ * @brief Add a 64-bit value to an atomic counter.
+ */
+static inline void udk_atomic64_add(udk_atomic64_t *v, int64_t inc)
+{
+ __sync_fetch_and_add(&v->cnt, inc);
+}
+
+/**
+ * @brief Increment a 64-bit atomic counter by 1.
+ */
+static inline void udk_atomic64_inc(udk_atomic64_t *v)
+{
+ udk_atomic64_add(v, 1);
+}
+
+/**
+ * @brief udk_atomic64_cmpset, equivalent to(atomic):
+ * if (*dst == exp)
+ * *dst = src (all 64-bit words)
+ */
+static inline int udk_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp,
+ uint64_t src)
+{
+ return __sync_bool_compare_and_swap(dst, exp, src);
+}
+
+#endif /* UDK_ATOMIC_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_byteorder.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_byteorder.h
new file mode 100644
index 000000000..ef883287b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_byteorder.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK byte order header file
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_BYTEORDER_H
+#define UDK_BYTEORDER_H
+
+#include <endian.h>
+
+#ifndef USE_GCC_DEFAULT_ENDIAN
+
+#ifdef UDK_ARCH_ARM64
+#include "arch/arm/udk_byteorder.h"
+#else
+#include "arch/x86/udk_byteorder.h"
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+#define udk_cpu_to_le_16(x) (x)
+#define udk_cpu_to_le_32(x) (x)
+#define udk_cpu_to_le_64(x) (x)
+
+#define udk_cpu_to_be_16(x) udk_bswap16(x)
+#define udk_cpu_to_be_32(x) udk_bswap32(x)
+#define udk_cpu_to_be_64(x) udk_bswap64(x)
+
+#define udk_le_to_cpu_16(x) (x)
+#define udk_le_to_cpu_32(x) (x)
+#define udk_le_to_cpu_64(x) (x)
+
+#define udk_be_to_cpu_16(x) udk_bswap16(x)
+#define udk_be_to_cpu_32(x) udk_bswap32(x)
+#define udk_be_to_cpu_64(x) udk_bswap64(x)
+
+#else /* __BYTE_ORDER == __BIG_ENDIAN */
+
+#define udk_cpu_to_le_16(x) udk_bswap16(x)
+#define udk_cpu_to_le_32(x) udk_bswap32(x)
+#define udk_cpu_to_le_64(x) udk_bswap64(x)
+
+#define udk_cpu_to_be_16(x) (x)
+#define udk_cpu_to_be_32(x) (x)
+#define udk_cpu_to_be_64(x) (x)
+
+#define udk_le_to_cpu_16(x) udk_bswap16(x)
+#define udk_le_to_cpu_32(x) udk_bswap32(x)
+#define udk_le_to_cpu_64(x) udk_bswap64(x)
+
+#define udk_be_to_cpu_16(x) (x)
+#define udk_be_to_cpu_32(x) (x)
+#define udk_be_to_cpu_64(x) (x)
+
+#endif /* end __BYTE_ORDER == __LITTLE_ENDIAN */
+
+#else /* USE_GCC_DEFAULT_ENDIAN */
+
+#define udk_cpu_to_le_16(x) htole16(x)
+#define udk_cpu_to_le_32(x) htole32(x)
+#define udk_cpu_to_le_64(x) htole64(x)
+
+#define udk_cpu_to_be_16(x) htobe16(x)
+#define udk_cpu_to_be_32(x) htobe32(x)
+#define udk_cpu_to_be_64(x) htobe64(x)
+
+#define udk_le_to_cpu_16(x) le16toh(x)
+#define udk_le_to_cpu_32(x) le32toh(x)
+#define udk_le_to_cpu_64(x) le64toh(x)
+
+#define udk_be_to_cpu_16(x) be16toh(x)
+#define udk_be_to_cpu_32(x) be32toh(x)
+#define udk_be_to_cpu_64(x) be64toh(x)
+
+#endif /* end USE_GCC_DEFAULT_ENDIAN */
+
+#endif /* end UDK_BYTEORDER_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_common.h
new file mode 100644
index 000000000..478cc6bba
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_common.h
@@ -0,0 +1,243 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: udk common define
+ * Author: -
+ * Create: 2021.4.19
+ */
+#ifndef UDK_COMMON_H
+#define UDK_COMMON_H
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#define USEC_PER_MSEC 1000
+
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
+#define UDK_STD_C11 __extension__
+#else
+#define UDK_STD_C11
+#endif
+
+#ifdef UDK_ARCH_ARM64
+#define UDK_MAX_LCORE 256 /* arm 256 */
+#else
+#define UDK_MAX_LCORE 576 /**< x86 default 576 */
+#endif
+#define UDK_MAX_NUMA_NODES 8
+#define UDK_SOCKET_ID_ANY (-1) /**< Any NUMA socket. */
+
+#ifdef UDK_ARCH_ARM64
+#define UDK_CACHE_LINE_SIZE 128 /* aarch64 cacheline size */
+#else
+#define UDK_CACHE_LINE_SIZE 64 /**< default(x86) cacheline size */
+#endif
+
+#define UDK_CACHE_LINE_MASK (UDK_CACHE_LINE_SIZE - 1)
+
+#define UDK_CACHE_LINE_MIN_SIZE 64
+
+#undef UDK_HOT_REPLACE
+#define UDK_HOT_REPLACE 1
+
+#define UDK_DIM(a) (sizeof(a) / sizeof((a)[0]))
+
+#define UDK_PTR_ADD(ptr, x) ((void *)((uintptr_t)(ptr) + (x)))
+#define UDK_PTR_SUB(ptr, x) ((void *)((uintptr_t)(ptr) - (x)))
+#define UDK_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
+/*
+ * 功能描述:向下取整((val / align) * align)
+ * 如:align = 2,val < 2则返回0; 2 < val < 4则返回2,以此类推
+ */
+#define UDK_ALIGN_FLOOR(val, align) \
+ (typeof(val))((val) & (typeof(val))(~((typeof(val))((align)-1))))
+#define UDK_PTR_ALIGN_FLOOR(ptr, align) \
+ ((typeof(ptr))UDK_ALIGN_FLOOR((uintptr_t)(ptr), (align)))
+#define UDK_ALIGN_CEIL(val, align) \
+ UDK_ALIGN_FLOOR((typeof(val))((val) + ((typeof(val))(align)-1)), align)
+#define UDK_ALIGN(val, align) UDK_ALIGN_CEIL(val, align)
+#define UDK_PTR_ALIGN_CEIL(ptr, align) \
+ UDK_PTR_ALIGN_FLOOR((typeof(ptr))UDK_PTR_ADD((ptr), (align)-1), (align))
+#define UDK_PTR_ALIGN(ptr, align) UDK_PTR_ALIGN_CEIL(ptr, align)
+#define UDK_ALIGN_MUL_CEIL(v, mul) \
+ ((((v) + (typeof(v))(mul)-1) / ((typeof(v))(mul))) * (typeof(v))(mul))
+#define UDK_ALIGN_MUL_FLOOR(v, mul) \
+ (((v) / ((typeof(v))(mul))) * (typeof(v))(mul))
+#define UDK_ALIGN_MUL_NEAR(v, mul) \
+ ({ \
+ typeof(v) ceil = UDK_ALIGN_MUL_CEIL(v, mul); \
+ typeof(v) floor = UDK_ALIGN_MUL_FLOOR(v, mul); \
+ (ceil - (v)) > ((v)-floor) ? floor : ceil; \
+ })
+
+#ifndef likely
+#define likely(x) __builtin_expect(!!(x), 1)
+#endif /* likely */
+
+#ifndef unlikely
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif /* unlikely */
+
+#ifndef offsetof
+/** Return the offset of a field in a structure. */
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+#endif
+
+#define udk_aligned(a) __attribute__((__aligned__(a)))
+#define udk_cache_aligned udk_aligned(UDK_CACHE_LINE_SIZE)
+#define udk_cache_min_aligned udk_aligned(UDK_CACHE_LINE_MIN_SIZE)
+#define udk_packed __attribute__((__packed__))
+#define udk_unused __attribute__((__unused__))
+
+/* Force a function to be inlined */
+#define udk_force_inline inline __attribute__((always_inline))
+
+#define UDK_REF_VAR(x) (void)(x)
+
+#define UDK_PRIORITY_CLASS 120
+#define UDK_PRIORITY_LAST 65535
+#define UDK_PRIORITY(prio) UDK_PRIORITY_##prio
+
+/** Run function before main() with specified priority. */
+#ifndef UDK_INIT_PRIO
+#define UDK_INIT_PRIO(func, prio) \
+ static void __attribute__((constructor(UDK_PRIORITY(prio)), used)) \
+ func(void)
+#endif
+
+/** Run function before main() with low priority. */
+#define UDK_INIT(func) UDK_INIT_PRIO(func, LAST)
+
+/** macro for min and max */
+#define UDK_MIN(a, b) \
+ __extension__({ \
+ typeof(a) _a = (a); \
+ typeof(b) _b = (b); \
+ _a < _b ? _a : _b; \
+ })
+
+#define UDK_MAX(a, b) \
+ __extension__({ \
+ typeof(a) _a = (a); \
+ typeof(b) _b = (b); \
+ _a > _b ? _a : _b; \
+ })
+
+static inline uint32_t udk_bsf32(uint32_t v)
+{
+ return (uint32_t)__builtin_ctz(v);
+}
+
+#define UDK_MAKE_QWORD(val_h32, val_l32) \
+ ((((uint64_t)(val_h32)) << 32) | ((uint64_t)(val_l32)))
+
+#define UDK_BAD_IOVA ((uint64_t)-1)
+
+/* Structure alignment markers */
+__extension__ typedef void
+ *UDK_MARKER[0]; /**< Generic marker for any place in a structure. */
+__extension__ typedef uint8_t
+ UDK_MARKER8[0]; /**< Marker for 1B alignment in a structure. */
+__extension__ typedef uint16_t
+ UDK_MARKER16[0]; /**< Marker for 2B alignment in a structure. */
+__extension__ typedef uint32_t
+ UDK_MARKER32[0]; /**< Marker for 4B alignment in a structure. */
+__extension__ typedef uint64_t
+ UDK_MARKER64[0]; /**< Marker for 8B alignment in a structure. */
+
+/* ========debug======== */
+#ifdef UDK_ENABLE_ASSERT
+#define UDK_ASSERT(exp) UDK_VERIFY(exp)
+#else
+#define UDK_ASSERT(exp) \
+ do { \
+ } while (0)
+#endif
+
+#define udk_panic(...) udk_panic_handle(__func__, __VA_ARGS__)
+
+#define UDK_VERIFY(exp) \
+ do { \
+ if (unlikely(!(exp))) { \
+ udk_panic("line %d\tassert \"%s\" failed\n", __LINE__, \
+ #exp); \
+ } \
+ } while (0)
+
+#define UDK_BUILD_BUG_ON(condition) \
+ ((void)sizeof(char[1 - 2 * (!!(condition))]))
+
+/* ===========udk config============= */
+enum udk_proc_type_t {
+ UDK_PROC_PRIMARY = 0,
+ UDK_PROC_SECONDARY,
+ UDK_PROC_INVALID
+};
+
+/**
+ * @brief Aligns a 32-bit number to the next power of 2
+ * */
+static inline uint32_t udk_align32pow2(uint32_t x)
+{
+ uint32_t val = x;
+ val--;
+ val |= val >> 1; // 右移1位并与原值按位或,则这个数高2位为1.
+ val |= val >> 2; // 右移2位并与原值按位或,则这个数高4位为1.
+ val |= val >> 4; // 右移4位并与原值按位或,则这个数高8位为1.
+ val |= val >> 8; // 右移8位并与原值按位或,则这个数高16位为1.
+ val |= val >> 16; // 右移16位并与原值按位或,则这个数高32位为1.
+
+ return val + 1; // 加1则所有1前进一位变0,即2的N次幂.
+}
+
+static inline int udk_is_power_of_2(uint32_t n)
+{
+ return (n != 0) && ((n & (n - 1)) == 0);
+}
+
+/**
+ * @brief Generate a pseudo-random value between 0 and (1<<64)-1
+ */
+static inline uint64_t udk_rand(void)
+{
+ return UDK_MAKE_QWORD(lrand48(), lrand48());
+}
+
+static inline unsigned long int udk_get_ptr(const void *p)
+{
+#ifdef UDK_MEM_PTR_DEBUG
+ return (uintptr_t)p;
+#else
+ return !!p;
+#endif
+}
+
+int udk_process_type(void);
+
+/**
+ * @brief 初始化udk
+ * @param type: 初始化类型
+ *
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int udk_init(enum udk_proc_type_t type);
+
+/**
+ * @brief 反初始化udk
+ */
+void udk_deinit(void);
+
+/**
+ * @brief 遇到严重错误时,调用udk_panic_handle,输出调试信息
+ *
+ * @param func_name panic的函数名
+ * @param format 格式字符串
+ * @param ... 可变参数
+ *
+ * @return: NA
+ */
+void udk_panic_handle(const char *func_name, const char *format, ...);
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_cycles.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_cycles.h
new file mode 100644
index 000000000..d84d50c34
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_cycles.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK cycles/timer header file
+ * Author: -
+ * Create: 2021.4.19
+ */
+
+#ifndef UDK_CYCLES_H
+#define UDK_CYCLES_H
+
+#ifdef UDK_ARCH_ARM64
+#include "arch/arm/udk_cycles.h"
+#else
+#include "arch/x86/udk_cycles.h"
+#endif
+
+uint64_t udk_get_tsc_hz(void);
+
+/**
+ * @brief 获取cpu时钟cycle计数
+ *
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: cpu cycle计数
+ */
+static inline uint64_t udk_get_timer_cycles(void)
+{
+ return udk_rdtsc();
+}
+
+/**
+ * @brief 获取cpu 主频
+ *
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: cpu 主频
+ */
+static inline uint64_t udk_get_timer_hz(void)
+{
+ return udk_get_tsc_hz();
+}
+
+/**
+ * @brief 等待us微秒
+ *
+ *
+ * @details NA
+ * @param[in] us 微秒
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_delay_us(uint32_t us);
+
+/**
+ * @brief 等待us微秒
+ *
+ *
+ * @details NA
+ * @param[in] us 微秒
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_delay_ms(uint32_t ms);
+
+#endif /* UDK_CYCLES_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ethdev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ethdev.h
new file mode 100644
index 000000000..5d29a9266
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ethdev.h
@@ -0,0 +1,713 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk ether device interface
+ */
+
+#ifndef UDK_ETHDEV_H
+#define UDK_ETHDEV_H
+
+#include "udk_common.h"
+#include "udk_vdev.h"
+#include "udk_mbuf.h"
+#include "udk_mempool.h"
+
+#define UDK_ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */
+#define UDK_ETHDEV_QUEUE_STAT_CNTRS 128
+#define UDK_MAX_ETHPORTS 32
+#define UDK_MAX_QUEUES_PER_PORT 1024
+#define UDK_ETH_XSTATS_NAME_SIZE 64
+#define UDK_ETH_DEV_NO_OWNER 0
+#define UDK_ETH_MAX_COS 7
+
+#define UDK_ETH_DEV_FALLBACK_RX_RINGSIZE 512
+#define UDK_ETH_DEV_FALLBACK_TX_RINGSIZE 512
+#define UDK_ETH_DEV_FALLBACK_RX_NBQUEUES 1
+#define UDK_ETH_DEV_FALLBACK_TX_NBQUEUES 1
+
+#define UDK_ETH_DEV_RX_OFFLOAD_VLAN_STRIP 0x00000001
+#define UDK_ETH_DEV_RX_OFFLOAD_IPV4_CKSUM 0x00000002
+#define UDK_ETH_DEV_RX_OFFLOAD_UDP_CKSUM 0x00000004
+#define UDK_ETH_DEV_RX_OFFLOAD_TCP_CKSUM 0x00000008
+#define UDK_ETH_DEV_RX_OFFLOAD_JUMBO_FRAME 0x00000800
+
+#define UDK_ETH_DEV_TX_OFFLOAD_VLAN_INSERT 0x00000001
+#define UDK_ETH_DEV_TX_OFFLOAD_IPV4_CKSUM 0x00000002
+#define UDK_ETH_DEV_TX_OFFLOAD_UDP_CKSUM 0x00000004
+#define UDK_ETH_DEV_TX_OFFLOAD_TCP_CKSUM 0x00000008
+#define UDK_ETH_DEV_TX_OFFLOAD_TCP_TSO 0x00000020
+#define UDK_ETH_DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM \
+ 0x00000080 /**< Used for tunneling packet. */
+
+#define UDK_ETH_QUEUE_STATE_STOPPED 0
+
+#define MZ_UDK_ETH_DEV_DATA "udk_eth_dev_data"
+
+/**
+ * @brief enum udk_eth_dev_state - udk eth 虚拟设备状态
+ * @details NA
+ */
+enum udk_eth_dev_state {
+ UDK_ETH_DEV_UNUSED = 0,
+ UDK_ETH_DEV_ATTACHED,
+ UDK_ETH_DEV_REMOVED,
+};
+
+#define UDK_ETHDEV_LOG(level, ...) UDK_LOG(level, ETHDEV, "" __VA_ARGS__)
+
+#define UDK_FUNC_PTR_OR_ERR_HANDLE(func, handle) \
+ do { \
+ if ((func) == NULL) { \
+ handle; \
+ } \
+ } while (0)
+
+/**
+ * @brief Retrieve input packets from a reception queue of an Ethernet device.
+ */
+typedef uint16_t (*udk_eth_rx_burst_t)(void *rxq, struct udk_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+
+/**
+ * @brief Send output packets on a transmit queue of an Ethernet device.
+ */
+typedef uint16_t (*udk_eth_tx_burst_t)(void *txq, struct udk_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+
+/**
+ * @brief link-level information of an Ethernet port.
+ */
+__extension__ struct udk_eth_link {
+ uint32_t link_speed; /**< ETH_SPEED_NUM_ */
+ uint16_t link_duplex : 1; /**< ETH_LINK_[HALF/FULL]_DUPLEX */
+ uint16_t link_autoneg : 1; /**< ETH_LINK_[AUTONEG/FIXED] */
+ uint16_t link_status : 1; /**< ETH_LINK_[DOWN/UP] */
+} __attribute__((aligned(8))); /**< aligned for atomic64 read/write */
+
+/* speeds bitmap flags */
+#define ETH_LINK_SPEED_AUTONEG (0 << 0) /**< Auto negotiate (all speeds) */
+#define ETH_LINK_SPEED_FIXED (1 << 0) /**< Disable autoneg (fixed speed) */
+#define ETH_LINK_SPEED_10M_HD (1 << 1) /**< 10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M (1 << 2) /**< 10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD (1 << 3) /**< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M (1 << 4) /**< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G (1 << 5) /**< 1 Gbps */
+#define ETH_LINK_SPEED_2_5G (1 << 6) /**< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G (1 << 7) /**< 5 Gbps */
+#define ETH_LINK_SPEED_10G (1 << 8) /**< 10 Gbps */
+#define ETH_LINK_SPEED_20G (1 << 9) /**< 20 Gbps */
+#define ETH_LINK_SPEED_25G (1 << 10) /**< 25 Gbps */
+#define ETH_LINK_SPEED_40G (1 << 11) /**< 40 Gbps */
+#define ETH_LINK_SPEED_50G (1 << 12) /**< 50 Gbps */
+#define ETH_LINK_SPEED_56G (1 << 13) /**< 56 Gbps */
+#define ETH_LINK_SPEED_100G (1 << 14) /**< 100 Gbps */
+
+#define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see link_duplex). */
+#define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see link_duplex). */
+#define ETH_LINK_DOWN 0 /**< Link is down (see link_status). */
+#define ETH_LINK_UP 1 /**< Link is up (see link_status). */
+#define ETH_LINK_FIXED 0 /**< No auto negotiation (see link_autoneg). */
+#define ETH_LINK_AUTONEG 1 /**< Auto negotiated (see link_autoneg). */
+
+#define ETH_SPEED_NUM_NONE 0 /**< Not defined */
+#define ETH_SPEED_NUM_10M 10 /**< 10 Mbps */
+#define ETH_SPEED_NUM_100M 100 /**< 100 Mbps */
+#define ETH_SPEED_NUM_1G 1000 /**< 1 Gbps */
+#define ETH_SPEED_NUM_2_5G 2500 /**< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G 5000 /**< 5 Gbps */
+#define ETH_SPEED_NUM_10G 10000 /**< 10 Gbps */
+#define ETH_SPEED_NUM_20G 20000 /**< 20 Gbps */
+#define ETH_SPEED_NUM_25G 25000 /**< 25 Gbps */
+#define ETH_SPEED_NUM_40G 40000 /**< 40 Gbps */
+#define ETH_SPEED_NUM_50G 50000 /**< 50 Gbps */
+#define ETH_SPEED_NUM_56G 56000 /**< 56 Gbps */
+#define ETH_SPEED_NUM_100G 100000 /**< 100 Gbps */
+#define ETH_SPEED_NUM_200G 200000 /**< 200 Gbps */
+
+/**
+ * @brief struct udk_eth_rxmode - udk eth 设备的rx模式
+ * @details NA
+ */
+struct udk_eth_rxmode {
+ uint32_t max_rx_pkt_len; /**< Only used if JUMBO_FRAME enabled. */
+ uint64_t offloads;
+
+ uint64_t reserved_64s[2]; /**< Reserved for future fields */
+ void *reserved_ptrs[2]; /**< Reserved for future fields */
+};
+
+/**
+ * @brief configure the TX features of an Ethernet port.
+ * @details NA
+ */
+struct udk_eth_txmode {
+ uint64_t offloads;
+
+ uint64_t reserved_64s[2]; /**< Reserved for future fields */
+ void *reserved_ptrs[2]; /**< Reserved for future fields */
+};
+
+/**
+ * @brief configure an Ethernet port.
+ */
+struct udk_eth_conf {
+ uint32_t link_speeds;
+ struct udk_eth_rxmode rxmode; /**< Port RX configuration. */
+ struct udk_eth_txmode txmode; /**< Port TX configuration. */
+};
+
+/**
+ * @brief The data part, with no function pointers, associated with each ethernet device.
+ *
+ * This structure is safe to place in shared memory to be common among different
+ * processes in a multiprocess configuration.
+ */
+struct udk_eth_dev_data {
+ char name[UDK_DEV_NAME_MAX_LEN]; /**< Unique identifier name */
+
+ void **rx_queues; /**< Array of pointers to RX queues. */
+ void **tx_queues; /**< Array of pointers to TX queues. */
+ uint16_t nb_rx_queues; /**< Number of RX queues. */
+ uint16_t nb_tx_queues; /**< Number of TX queues. */
+
+ void *dev_private; /**< PMD-specific private data. */
+
+ struct udk_eth_link dev_link; /**< Link-level information & status. */
+ struct udk_eth_conf dev_conf; /**< Configuration applied to device. */
+ uint16_t mtu; /**< Maximum Transmission Unit. */
+ uint32_t min_rx_buf_size; /**< Common RX buffer size handled by all queues. */
+
+ uint64_t rx_mbuf_alloc_failed; /**< RX ring mbuf allocation failures. */
+ struct udk_ether_addr *mac_addrs; /**< Device Ethernet link address. */
+ uint16_t port_id; /**< Device [external] port identifier. */
+
+ __extension__ uint8_t
+ dev_started : 1; /**< Device state: STARTED(1) / STOPPED(0). */
+
+ uint8_t rx_queue_state
+ [UDK_MAX_QUEUES_PER_PORT]; /**< Queues state: STARTED(1) / STOPPED(0). */
+ uint8_t tx_queue_state
+ [UDK_MAX_QUEUES_PER_PORT]; /**< Queues state: STARTED(1) / STOPPED(0). */
+ uint32_t dev_flags; /**< Capabilities. */
+ int numa_node; /**< NUMA node connection. */
+
+ uint64_t reserved_64s[4]; /**< Reserved for future fields */
+ void *reserved_ptrs[4]; /**< Reserved for future fields */
+} udk_cache_aligned;
+
+/**
+ * @brief udk eth 设备的统计指标
+ * @details NA
+ */
+struct udk_eth_stats {
+ uint64_t ipackets; /**< Total number of successfully received packets. */
+ uint64_t opackets; /**< Total number of successfully transmitted packets. */
+ uint64_t ibytes; /**< Total number of successfully received bytes. */
+ uint64_t obytes; /**< Total number of successfully transmitted bytes. */
+ uint64_t imissed; /**< Total of RX packets dropped by the HW. */
+ uint64_t ierrors; /**< Total number of erroneous received packets. */
+ uint64_t oerrors; /**< Total number of failed transmitted packets. */
+ uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */
+ uint64_t q_ipackets
+ [UDK_ETHDEV_QUEUE_STAT_CNTRS]; /**< Total number of queue RX packets. */
+ uint64_t q_opackets
+ [UDK_ETHDEV_QUEUE_STAT_CNTRS]; /**< Total number of queue TX packets. */
+ uint64_t q_ibytes
+ [UDK_ETHDEV_QUEUE_STAT_CNTRS]; /**< Total number of successfully received queue bytes. */
+ uint64_t q_obytes
+ [UDK_ETHDEV_QUEUE_STAT_CNTRS]; /**< Total number of successfully transmitted queue bytes. */
+ uint64_t q_errors
+ [UDK_ETHDEV_QUEUE_STAT_CNTRS]; /**< Total number of queue packets received that are dropped. */
+};
+
+/**
+ * @brief udk eth 设备的统计指标
+ * @details NA
+ */
+struct udk_eth_xstat_name {
+ char name[UDK_ETH_XSTATS_NAME_SIZE]; /**< The statistic name. */
+};
+
+/**
+ * @brief struct udk_eth_rxconf - udk eth 设备的rx configuration
+ * @details NA
+ */
+struct udk_eth_rxconf {
+ uint64_t offloads;
+
+ uint64_t reserved_64s[2]; /**< Reserved for future fields */
+ void *reserved_ptrs[2]; /**< Reserved for future fields */
+};
+
+/**
+ * @brief struct udk_eth_txconf - udk eth 设备的tx configuration
+ * @details NA
+ */
+struct udk_eth_txconf {
+ uint64_t offloads;
+
+ uint64_t reserved_64s[2]; /**< Reserved for future fields */
+ void *reserved_ptrs[2]; /**< Reserved for future fields */
+};
+
+/**
+ * @brief struct udk_eth_xstat - udk eth 设备的xtat configuration
+ * @details NA
+ */
+struct udk_eth_xstat {
+ uint64_t idx; /**< The index in xstats name array. */
+ uint64_t value; /**< The statistic counter value. */
+};
+
+/**
+ * @brief struct udk_eth_desc_lim - udk eth 设备的描述符配置
+ * @details NA
+ */
+struct udk_eth_desc_lim {
+ uint16_t nb_max; /**< Max allowed number of descriptors. */
+ uint16_t nb_min; /**< Min allowed number of descriptors. */
+ uint16_t nb_align; /**< Number of descriptors should be aligned to. */
+};
+
+/**
+ * @brief struct udk_eth_dev_portconf - udk eth 设备的port configuration
+ * @details NA
+ */
+struct udk_eth_dev_portconf {
+ uint16_t burst_size; /**< Device-preferred burst size */
+ uint16_t ring_size; /**< Device-preferred size of queue rings */
+ uint16_t nb_queues; /**< Device-preferred number of queues */
+};
+
+/**
+ * @brief struct udk_eth_dev_info - udk eth 设备信息
+ * @details NA
+ */
+struct udk_eth_dev_info {
+ uint16_t min_mtu; /**< Minimum MTU allowed */
+ uint16_t max_mtu; /**< Maximum MTU allowed */
+ const uint32_t *dev_flags; /**< Device flags */
+ uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */
+ uint32_t max_rx_pktlen; /**< Maximum configurable length of RX pkt. */
+
+ uint16_t max_rx_queues; /**< Maximum number of RX queues. */
+ uint16_t max_tx_queues; /**< Maximum number of TX queues. */
+
+ uint16_t max_vfs; /**< Maximum number of VFs. */
+ uint64_t rx_offload_capa; /**< All RX offload capabilities including all per-queue ones */
+ uint64_t tx_offload_capa; /**< All TX offload capabilities including all per-queue ones */
+ uint64_t rx_queue_offload_capa; /**< Device per-queue RX offload capabilities. */
+ uint64_t tx_queue_offload_capa; /**< Device per-queue TX offload capabilities. */
+
+ struct udk_eth_rxconf default_rxconf; /**< Default RX configuration */
+ struct udk_eth_txconf default_txconf; /**< Default TX configuration */
+ struct udk_eth_desc_lim rx_desc_lim; /**< RX descriptors limits */
+ struct udk_eth_desc_lim tx_desc_lim; /**< TX descriptors limits */
+ uint32_t speed_capa; /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
+
+ uint16_t nb_rx_queues; /**< Configured Number of RX queues. */
+ uint16_t nb_tx_queues; /**< Configured Number of TX queues. */
+
+ struct udk_eth_dev_portconf
+ default_rxportconf; /**< Rx parameter recommendations */
+ struct udk_eth_dev_portconf
+ default_txportconf; /**< Tx parameter recommendations */
+
+ uint64_t dev_capa; /**< Generic device capabilities */
+
+ uint64_t reserved_64s[2]; /**< Reserved for future fields */
+ void *reserved_ptrs[2]; /**< Reserved for future fields */
+};
+
+struct udk_eth_dev;
+
+typedef int (*eth_dev_configure_t)(struct udk_eth_dev *dev);
+typedef int (*eth_dev_start_t)(struct udk_eth_dev *dev);
+typedef void (*eth_dev_stop_t)(struct udk_eth_dev *dev);
+typedef int (*eth_dev_set_link_up_t)(struct udk_eth_dev *dev);
+typedef int (*eth_dev_set_link_down_t)(struct udk_eth_dev *dev);
+typedef void (*eth_dev_close_t)(struct udk_eth_dev *dev);
+typedef int (*eth_link_update_t)(struct udk_eth_dev *dev, int wait_to_complete);
+
+typedef int (*eth_stats_get_t)(struct udk_eth_dev *dev,
+ struct udk_eth_stats *igb_stats);
+typedef int (*eth_stats_reset_t)(struct udk_eth_dev *dev);
+typedef int (*eth_xstats_get_t)(struct udk_eth_dev *dev,
+ struct udk_eth_xstat *stats, uint32_t n);
+typedef int (*eth_xstats_reset_t)(struct udk_eth_dev *dev);
+typedef int (*eth_xstats_get_names_t)(struct udk_eth_dev *dev,
+ struct udk_eth_xstat_name *xstats_names,
+ uint32_t size);
+
+typedef int (*eth_dev_infos_get_t)(struct udk_eth_dev *dev,
+ struct udk_eth_dev_info *info);
+typedef const uint32_t *(*eth_dev_supported_ptypes_get_t)(
+ struct udk_eth_dev *dev);
+typedef int (*eth_rx_queue_setup_t)(struct udk_eth_dev *dev,
+ uint16_t rx_queue_id, uint16_t nb_rx_desc,
+ unsigned int socket_id,
+ const struct udk_eth_rxconf *rx_conf,
+ struct udk_mempool *mb_pool);
+typedef int (*eth_tx_queue_setup_t)(struct udk_eth_dev *dev,
+ uint16_t tx_queue_id, uint16_t nb_tx_desc,
+ unsigned int socket_id,
+ const struct udk_eth_txconf *tx_conf);
+typedef void (*eth_queue_release_t)(void *queue);
+typedef uint32_t (*eth_rx_queue_used_count_t)(struct udk_eth_dev *dev,
+ uint16_t rx_queue_id);
+typedef uint32_t (*eth_tx_queue_free_count_t)(struct udk_eth_dev *dev,
+ uint16_t tx_queue_id);
+typedef void (*eth_tx_done_cleanup_t)(struct udk_eth_dev *dev,
+ uint16_t tx_queue_id);
+typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset);
+typedef int (*mtu_set_t)(struct udk_eth_dev *dev, uint16_t mtu);
+
+/**
+ * @brief struct udk_eth_dev_ops - udk eth设备的虚函数表对象
+ * @details 定义udk eth设备的能力
+ */
+struct udk_eth_dev_ops {
+ eth_dev_configure_t dev_configure; /**< Configure device. */
+ eth_dev_start_t dev_start; /**< Start device. */
+ eth_dev_stop_t dev_stop; /**< Stop device. */
+ eth_dev_set_link_up_t dev_set_link_up; /**< Device link up. */
+ eth_dev_set_link_down_t dev_set_link_down; /**< Device link down. */
+ eth_dev_close_t dev_close; /**< Close device. */
+ eth_link_update_t link_update; /**< Get device link state. */
+
+ mtu_set_t mtu_set; /**< Set MTU. */
+
+ eth_stats_get_t stats_get; /**< Get generic device statistics. */
+ eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */
+ eth_xstats_get_t xstats_get; /**< Get extended device statistics. */
+ eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */
+ eth_xstats_get_names_t
+ xstats_get_names; /**< Get names of extended statistics. */
+
+ eth_dev_infos_get_t dev_infos_get; /**< Get device info. */
+ eth_dev_supported_ptypes_get_t
+ dev_supported_ptypes_get; /**< Get supported packet types and identified by device */
+
+ eth_rx_queue_setup_t rx_queue_setup; /**< Set up device RX queue. */
+ eth_queue_release_t rx_queue_release; /**< Release RX queue. */
+ eth_rx_queue_used_count_t
+ rx_queue_used_count; /**< Get the number of used RX descriptors. */
+ eth_rx_descriptor_done_t rx_descriptor_done; /**< Check rxd DD bit. */
+
+ eth_tx_queue_setup_t tx_queue_setup; /**< Set up device TX queue. */
+ eth_queue_release_t tx_queue_release; /**< Release TX queue. */
+ eth_tx_queue_free_count_t
+ tx_queue_free_count; /**< Get the number of free RX descriptors. */
+ eth_tx_done_cleanup_t tx_done_cleanup; /**< Cleanup txq done mbufs. */
+};
+
+/**
+ * @brief struct udk_eth_dev - udk eth设备对象
+ * @details 定义udk eth设备对象
+ */
+struct udk_eth_dev {
+ udk_eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
+ udk_eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
+ struct udk_eth_dev_data *data; /**< Pointer to device data. */
+ const struct udk_eth_dev_ops *dev_ops; /**< Functions exported by PMD */
+ struct udk_vdev_device *device; /**< Backing device */
+ enum udk_eth_dev_state state; /**< Flag indicating the port state */
+
+ uint64_t reserved_64s[4]; /**< Reserved for future fields */
+ void *reserved_ptrs[4]; /**< Reserved for future fields */
+} udk_cache_aligned;
+
+extern struct udk_eth_dev udk_eth_devices[UDK_MAX_ETHPORTS];
+
+/**
+ * @brief 用户态接收报文
+ *
+ * @param port_id port index, range [0, UDK_MAX_ETHPORTS)
+ * @param queue_id rx queue index, range is get from attributes (struct cfg_cmd_dev_cap) from FW
+ * @param rx_pkts rx buffer数组
+ * @param nb_pkts rx_pkts数组长度
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回处理的pkt个数
+ */
+static inline uint16_t udk_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
+ struct udk_mbuf **rx_pkts,
+ const uint16_t nb_pkts)
+{
+ struct udk_eth_dev *dev = &udk_eth_devices[port_id];
+
+#ifdef UDK_ETHDEV_DEBUG
+ if (!udk_eth_dev_is_valid_port(port_id)) {
+ UDK_ETHDEV_LOG(ERR, "Invalid port_id=%u\n", port_id);
+ return 0;
+ }
+
+ UDK_FUNC_PTR_OR_ERR_HANDLE(*dev->rx_pkt_burst, return 0);
+
+ if (queue_id >= dev->data->nb_rx_queues) {
+ UDK_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
+ return 0;
+ }
+#endif
+
+ return (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id], rx_pkts,
+ nb_pkts);
+}
+
+/**
+ * @brief 用户态发送报文
+ *
+ * @param port_id port index, range [0, UDK_MAX_ETHPORTS)
+ * @param queue_id tx queue index, range is get from attributes (struct cfg_cmd_dev_cap) from FW
+ * @param rx_pkts tx buffer数组
+ * @param nb_pkts tx_pkts数组长度
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回处理的pkt个数
+ */
+static inline uint16_t udk_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
+ struct udk_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ struct udk_eth_dev *dev = &udk_eth_devices[port_id];
+
+#ifdef UDK_ETHDEV_DEBUG
+ if (!udk_eth_dev_is_valid_port(port_id)) {
+ UDK_ETHDEV_LOG(ERR, "Invalid port_id=%u\n", port_id);
+ return 0;
+ }
+ UDK_FUNC_PTR_OR_ERR_HANDLE(*dev->tx_pkt_burst, return 0);
+
+ if (queue_id >= dev->data->nb_tx_queues) {
+ UDK_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
+ return 0;
+ }
+#endif
+
+ return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts,
+ nb_pkts);
+}
+
+/**
+ * @brief 创建名称为name的udk eth设备对象
+ *
+ * @param name 名称
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回设备对象
+ * @retval NULL 创建失败
+ * @retval 设备对象指针 创建成功
+ */
+struct udk_eth_dev *udk_eth_dev_allocate(const char *name);
+
+/**
+ * @brief 通过名称查询udk eth设备对象
+ *
+ * @param name 名称
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回设备对象
+ * @retval NULL 不存在
+ * @retval 设备对象指针 存在
+ */
+struct udk_eth_dev *udk_eth_dev_allocated(const char *name);
+
+/**
+ * @brief 设置设备驱动加载状态
+ * @param dev: udk虚拟设备
+ */
+void udk_eth_dev_probing_finish(struct udk_eth_dev *dev);
+
+/**
+ * @brief 获取设备对应的numa id
+ * @param port_id: port index, range [0, UDK_MAX_ETHPORTS)
+ *
+ * @return port_id对应虚拟设备的numa id
+ */
+int udk_eth_dev_socket_id(uint16_t port_id);
+
+/**
+ * @brief 判断port id的有效性
+ * @param port_id: port index, range [0, UDK_MAX_ETHPORTS)
+ *
+ * @return
+ * @retval 0: 无效
+ * @retval 1: 有效
+ */
+int udk_eth_dev_is_valid_port(uint16_t port_id);
+
+int udk_eth_macaddr_get(uint16_t port_id, struct udk_ether_addr *mac_addr);
+
+/**
+ * @brief 由设备名查询port id
+ * @param name: 设备名称
+ * @param port_id: 返回查询到的port id
+ *
+ * @return
+ * @retval 0: 存在
+ * @retval 非0: 不存在
+ */
+int udk_eth_dev_get_port_by_name(const char *name, uint16_t *port_id);
+
+/**
+ * @brief 配置虚拟设备
+ * @param port_id: 设备对应的port id
+ * @param nb_rx_q: rx queue number
+ * @param nb_tx_q: tx queue number
+ * @param dev_conf: device config
+ *
+ * @return
+ * @retval 0: 成功
+ * @retval 非0: 失败错误码
+ */
+int udk_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
+ const struct udk_eth_conf *dev_conf);
+
+/**
+ * @brief 启动虚拟网卡
+ * @param port_id: 设备对应的port id
+ *
+ * @return
+ * @retval 0: 成功
+ * @retval 非0: 失败错误码
+ */
+int udk_eth_dev_start(uint16_t port_id);
+
+/**
+ * @brief 关闭虚拟网卡
+ * @param port_id: 设备对应的port id
+ *
+ * @return
+ * @retval 0: 成功
+ * @retval 非0: 失败错误码
+ */
+void udk_eth_dev_close(uint16_t port_id);
+
+/**
+ * @brief 创建虚拟设备的rx queue资源
+ * @param port_id: returned by vpmd_virtdev_create
+ * @param rx_queue_id: queue index, range is get from attributes (struct cfg_cmd_dev_cap) from FW
+ * @param nb_rx_desc: rx description
+ * @param socket_id: numa id
+ * @param rx_conf: rx config
+ * @param mp: mempool
+ *
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int udk_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
+ uint16_t nb_rx_desc, unsigned int socket_id,
+ const struct udk_eth_rxconf *rx_conf,
+ struct udk_mempool *mp);
+
+/**
+ * @brief 创建虚拟设备的tx queue资源
+ * @param port_id: returned by vpmd_virtdev_create
+ * @param tx_queue_id: queue index, range is set by attributes (struct cfg_cmd_dev_cap) from FW
+ * @param nb_tx_desc: tx description
+ * @param socket_id: numa id
+ * @param tx_conf: tx config
+ *
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int udk_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
+ uint16_t nb_tx_desc, unsigned int socket_id,
+ const struct udk_eth_txconf *tx_conf);
+
+/**
+ * @brief 获取free的tx queue数量
+ *
+ * @param port_id port index, range [0, UDK_MAX_ETHPORTS)
+ * @param queue_id queue index, range is set by attributes (struct cfg_cmd_dev_cap) from FW
+ *
+ * @return: 返回空闲的queue数量
+ */
+uint32_t udk_eth_tx_queue_free_count_get(uint16_t port_id, uint16_t queue_id);
+
+/**
+ * @brief 执行tx queue结束的cleanup动作
+ *
+ * @param port_id port index, range [0, UDK_MAX_ETHPORTS)
+ * @param queue_id queue id, range is set by attributes (struct cfg_cmd_dev_cap) from FW
+ *
+ * @return: NA.
+ */
+void udk_eth_tx_done_cleanup(uint16_t port_id, uint16_t queue_id);
+
+/**
+ * @brief 获取指标名称
+ *
+ * @param port_id port index, range [0, UDK_MAX_ETHPORTS)
+ * @param xstats_names 保存指标名称
+ * @param size 可保存的个数
+ *
+ * @return: 返回保存的指标名称个数
+ */
+int udk_eth_xstats_get_names(uint16_t port_id,
+ struct udk_eth_xstat_name *xstats_names,
+ unsigned int size);
+
+/**
+ * @brief 获取udk eth设备的统计数据
+ *
+ * @param port_id port index, range [0, UDK_MAX_ETHPORTS)
+ * @param xstats 保存指标的对象
+ * @param n 可保存指标的个数
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval < 0 错误码
+ * @retval >= 0 获取的指标数量
+ */
+int udk_eth_xstats_get(uint16_t port_id, struct udk_eth_xstat *xstats,
+ uint32_t n);
+
+/**
+ * @brief 卸载虚拟网卡
+ * @param dev: 虚拟设备
+ *
+ * @return
+ * @retval 0: 成功
+ * @retval 非0: 失败错误码
+ */
+int udk_dev_remove(struct udk_vdev_device *dev);
+
+/**
+ * @brief 释放port资源
+ * @param eth_dev: 虚拟设备
+ *
+ * @return
+ * @retval 0: 成功
+ * @retval 非0: 失败错误码
+ */
+int udk_eth_dev_release_port(struct udk_eth_dev *eth_dev);
+
+/**
+ * @brief 停止虚拟网卡
+ * @param port_id: 设备对应的port id
+ *
+ * @return
+ * @retval 0: 成功
+ * @retval 非0: 失败错误码
+ */
+void udk_eth_dev_stop(uint16_t port_id);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ether.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ether.h
new file mode 100644
index 000000000..cf7858161
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ether.h
@@ -0,0 +1,116 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk ether interface
+ */
+
+#ifndef UDK_ETHER_H
+#define UDK_ETHER_H
+
+#include <stdint.h>
+#include "udk_byteorder.h"
+#include "udk_common.h"
+
+#define UDK_ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */
+#define UDK_ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */
+#define UDK_ETHER_CRC_LEN 4 /**< Length of Ethernet CRC. */
+#define UDK_ETHER_HDR_LEN \
+ (UDK_ETHER_ADDR_LEN * 2 + \
+ UDK_ETHER_TYPE_LEN) /**< Length of Ethernet header. */
+#define UDK_ETHER_MIN_LEN 64 /**< Minimum frame len, including CRC. */
+#define UDK_ETHER_MAX_LEN 1518 /**< Maximum frame len, including CRC. */
+#define UDK_ETHER_MTU \
+ ((UDK_ETHER_MAX_LEN - UDK_ETHER_HDR_LEN) - \
+ UDK_ETHER_CRC_LEN) /**< Ethernet MTU. */
+#define UDK_ETHER_MIN_MTU 68 /**< Minimum MTU for IPv4 packets, see RFC 791. */
+
+#define UDK_PKT_TX_TCP_SEG (1ULL << 50)
+#define UDK_IPV4_HDR_IHL_MASK \
+ 0x0f /**< IP header length mask for version_ihl field */
+#define UDK_IPV4_IHL_MULTIPLIER \
+ 4 /**< IHL field defines header length in number of 4-byte word */
+#define UDK_ETHER_ADDR_ALIGN 2
+
+/**
+ * @brief struct udk_ether_addr - udk eth设备地址
+ * @details NA
+ */
+struct udk_ether_addr {
+ uint8_t addr_bytes[UDK_ETHER_ADDR_LEN];
+} udk_aligned(UDK_ETHER_ADDR_ALIGN);
+
+#define UDK_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
+
+/**
+ * @brief struct udk_ipv4_hdr - ipv4头对象
+ * @details ipv4头的各种属性
+ */
+struct udk_ipv4_hdr {
+ uint8_t version_ihl;
+ uint8_t type_of_service;
+ uint16_t total_length;
+ uint16_t packet_id;
+ uint16_t fragment_offset;
+ uint8_t time_to_live;
+ uint8_t next_proto_id;
+ uint16_t hdr_checksum;
+ uint32_t src_addr;
+ uint32_t dst_addr;
+} udk_packed;
+
+/**
+ * @brief struct udk_ipv4_psd_header - 计算ipv4 checsum的伪头部
+ * @details NA
+ */
+struct udk_ipv4_psd_header {
+ uint32_t src_addr; /**< IP address of source host. */
+ uint32_t dst_addr; /**< IP address of destination host. */
+ uint8_t zero; /**< zero. */
+ uint8_t proto; /**< L4 protocol type. */
+ uint16_t len; /**< L4 length. */
+};
+
+/**
+ * @brief Check if an Ethernet address is filled with 0.
+ */
+static inline int udk_is_zero_ether_addr(const struct udk_ether_addr *ea)
+{
+ const uint16_t *word = (const uint16_t *)ea;
+
+ return (word[0] | word[1] | word[2]) ==
+ 0; /* ether addr 6Byte = 2Byte * 3 */
+}
+
+/**
+ * @brief Check if two Ethernet addresses are same.
+ */
+static inline int udk_is_same_ether_addr(const struct udk_ether_addr *ea_a,
+ const struct udk_ether_addr *ea_b)
+{
+ const uint16_t *word_a = (const uint16_t *)ea_a;
+ const uint16_t *word_b = (const uint16_t *)ea_b;
+
+ // ether addr 6Byte = 2Byte * 3
+ return ((word_a[0] ^ word_b[0]) | (word_a[1] ^ word_b[1]) |
+ (word_a[2] ^ word_b[2])) == 0;
+}
+
+/**
+ * @brief Copy an Ethernet address from src to dst.
+ */
+static inline void udk_ether_addr_copy(const struct udk_ether_addr *src_ea,
+ struct udk_ether_addr *dst_ea)
+{
+ *dst_ea = *src_ea;
+}
+
+/**
+ * @brief Return the length of IPv4 header
+ */
+static inline uint8_t udk_ipv4_hdr_len(const struct udk_ipv4_hdr *ipv4_hdr)
+{
+ return (uint8_t)((ipv4_hdr->version_ihl & UDK_IPV4_HDR_IHL_MASK) *
+ UDK_IPV4_IHL_MULTIPLIER);
+}
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_io.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_io.h
new file mode 100644
index 000000000..57080a755
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_io.h
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk IO interface
+ */
+
+#ifndef UDK_IO_H
+#define UDK_IO_H
+
+#include "udk_common.h"
+#ifdef UDK_ARCH_ARM64
+#include "arch/arm/udk_io.h"
+#else
+#include "arch/x86/udk_io.h"
+#endif
+
+static udk_force_inline void udk_write64(uint64_t value, volatile void *addr)
+{
+ udk_io_wmb();
+ udk_write64_relaxed(value, addr);
+}
+
+#endif /* UDK_IO_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_log.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_log.h
new file mode 100644
index 000000000..8bbd040dc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_log.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK log header file
+ * Author: -
+ * Create: 2021.4.19
+ */
+#ifndef UDK_LOG_H
+#define UDK_LOG_H
+
+#include <stdint.h>
+#include <stdarg.h>
+
+#define MAX_LOG_LEN 1024
+#define MAX_PATH_LEN 256
+#define UDK_ERRBUF_SZ 256
+
+#define UDK_LOGTYPE_MALLOC 1 /**< Log related to malloc. */
+#define UDK_LOGTYPE_RING 2 /**< Log related to ring. */
+#define UDK_LOGTYPE_MEMPOOL 3 /**< Log related to mempool. */
+#define UDK_LOGTYPE_TIMER 4 /**< Log related to timers. */
+#define UDK_LOGTYPE_HASH 5 /**< Log related to hash table. */
+#define UDK_LOGTYPE_VDEV 6 /**< Log related to virtual device */
+#define UDK_LOGTYPE_ETHDEV 7 /**< Log related to ether device */
+#define UDK_LOGTYPE_MEMZONE 8 /**< Log related to memzone. */
+#define UDK_LOGTYPE_COMMON 9 /**< Log related to common. */
+#define UDK_LOGTYPE_MBUF 10 /**< Log related to mbuf. */
+#define UDK_LOGTYPE_USRNL 11 /**< Log related to user netlink. */
+#define UDK_LOGTYPE_MHEAP 12 /**< Log related to mheap. */
+
+#define UDK_LOGTYPE_USER1 15 /**< User-defined log type 1. */
+#define UDK_LOGTYPE_USER2 16 /**< User-defined log type 2. */
+#define UDK_LOGTYPE_USER3 17 /**< User-defined log type 3. */
+#define UDK_LOGTYPE_USER4 18 /**< User-defined log type 4. */
+#define UDK_LOGTYPE_USER5 19 /**< User-defined log type 5. */
+#define UDK_LOGTYPE_USER6 20 /**< User-defined log type 6. */
+#define UDK_LOGTYPE_USER7 21 /**< User-defined log type 7. */
+#define UDK_LOGTYPE_USER8 22 /**< User-defined log type 8. */
+#define UDK_LOGTYPE_USER9 23 /**< User-defined log type 9. */
+#define UDK_LOGTYPE_USER10 24 /**< User-defined log type 10. */
+#define UDK_LOGTYPE_USER11 25 /**< User-defined log type 11. */
+#define UDK_LOGTYPE_USER12 26 /**< User-defined log type 12. */
+#define UDK_LOGTYPE_FIRST_EXT_ID 27
+
+/* Can't use 0, as it gives compiler warnings */
+#define UDK_LOG_EMERG 0 /**< System is unusable. */
+#define UDK_LOG_ALERT 1 /**< Action must be taken immediately. */
+#define UDK_LOG_CRIT 2 /**< Critical conditions. */
+#define UDK_LOG_ERR 3 /**< Error conditions. */
+#define UDK_LOG_WARNING 4 /**< Warning conditions. */
+#define UDK_LOG_NOTICE 5 /**< Normal but significant condition. */
+#define UDK_LOG_INFO 6 /**< Informational. */
+#define UDK_LOG_DEBUG 7 /**< Debug-level messages.*/
+#define UDK_LOG_MAX_LEVEL 8 /**< Max-level. */
+
+/**
+ * @brief 日志metadata信息对象
+ * @details NA
+ */
+struct log_pos {
+ const char *func;
+ int line;
+};
+
+/**
+ * @brief 日志初始化
+ *
+ * @param[in] log_tag log标识字符串
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_log_init(const char *log_tag);
+
+/**
+ * @brief 设置日志等级
+ *
+ * @param[in] level 日志等级
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_log_set_global_level(uint32_t level);
+
+/**
+ * @brief 获取日志等级
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回日志等级
+ */
+uint32_t udk_log_get_global_level(void);
+
+/**
+ * @brief 设置模块日志等级
+ *
+ * @param[in] id 日志模块id
+ * @param[in] level 日志等级
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_log_set_level(uint32_t id, uint32_t level);
+
+/**
+ * @brief 获取模块日志等级
+ *
+ * @param[in] id 日志模块
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 返回值1 描述返回值1的意义
+ * @retval 返回值2 描述返回值2的意义
+ */
+uint32_t udk_log_get_level(uint32_t id);
+
+/**
+ * @brief 写入日志
+ *
+ * @param[in] pos 日志metadata对象
+ * @param[in] level 日志等级
+ * @param[in] id 日志模块
+ * @param[in] format 格式字符串
+ * @param[in] ap 可变参数
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回写入的字节数.
+ */
+int udk_vlog(const struct log_pos *pos, uint32_t level, uint32_t id,
+ const char *format, va_list ap);
+
+/**
+ * @brief 函数简要说明
+ *
+ * @details NA
+ *
+ * @param[in] function 函数名
+ * @param[in] line 代码行
+ * @param[in] logtype 日志类型
+ * @param[in] format 格式字符串
+ * @param[in] ... 可变参数
+ *
+ * @attention: NA
+ *
+ * @return: 返回写入的字节数
+ */
+int udk_log(const char *function, int line, uint32_t level, uint32_t logtype,
+ const char *format, ...)
+
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2))
+ __attribute__((cold))
+#endif
+ __attribute__((format(printf, 5, 6)));
+
+/**
+ * @brief struct log_ratelimit_state - 日志限速对象
+ *
+ * @details 定义日志限速的配置
+ */
+struct log_ratelimit_state {
+ uint64_t interval;
+ int unit;
+ int burst;
+ int printed;
+ int missed;
+ uint64_t begin;
+};
+
+#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \
+ static struct log_ratelimit_state name = { \
+ .unit = 0, \
+ .interval = (interval_init), \
+ .burst = (burst_init), \
+ .missed = 0, \
+ .printed = 0, \
+ }
+
+/**
+ * @brief 判断是否限速
+ *
+ * @param[in] func 限速函数名
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回是否限速
+ * @retval 1 不限速
+ * @retval 0 限速
+ */
+int ratelimit(const char *func);
+
+/**
+ * @brief 设置限速
+ *
+ * @param[in] interval 时间间隔(以s为单位)
+ * @param[in] burst 冲击配置
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_set_ratelimit_para(uint64_t interval, int burst);
+
+#define UDK_LOG_SRV(l, t, ...) \
+ udk_log(__func__, __LINE__, UDK_LOG_##l, UDK_LOGTYPE_##t, \
+ #t ": " __VA_ARGS__)
+#define UDK_LOG(l, t, ...) \
+ udk_log(__func__, __LINE__, UDK_LOG_##l, UDK_LOGTYPE_##t, \
+ #t ": " \
+ "udk " __VA_ARGS__)
+
+#define UDK_LOG_LIMIT(l, t, ...) \
+ do { \
+ if (ratelimit(__func__) != 0) { \
+ udk_log(__func__, __LINE__, UDK_LOG_##l, \
+ UDK_LOGTYPE_##t, #t ": " __VA_ARGS__); \
+ } \
+ } while (0)
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_malloc.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_malloc.h
new file mode 100644
index 000000000..c348b4230
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_malloc.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK malloc header file
+ * Author: -
+ * Create: 2021.4.19
+ */
+
+#ifndef UDK_MALLOC_H
+#define UDK_MALLOC_H
+
+#include <stdint.h>
+
+/**
+ * @brief 释放内存
+ *
+ * @param[in] addr 地址
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_free(void *addr);
+
+/**
+ * @brief 支持numa socket申请内存
+ *
+ * @param[in] size 大小
+ * @param[in] align 对齐标准
+ * @param[in] socket numa socket
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 申请失败
+ * @retval 非NULL指针 申请到的内存
+ */
+void *udk_malloc_socket(size_t size, uint32_t align, int socket);
+
+/**
+ * @brief 申请内存
+ *
+ * @param[in] size 大小
+ * @param[in] align 对齐标准
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 申请失败
+ * @retval 非NULL指针 申请到的内存
+ */
+void *udk_malloc(size_t size, uint32_t align);
+
+/**
+ * @brief 支持numa socket申请内存,且清零
+ *
+ * @param[in] size 大小
+ * @param[in] align 对齐标准
+ * @param[in] socket numa socket
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 申请失败
+ * @retval 非NULL指针 申请到的内存
+ */
+void *udk_zmalloc_socket(size_t size, uint32_t align, int socket);
+
+/**
+ * @brief 申请内存,且清零
+ *
+ * @param[in] size 大小
+ * @param[in] align 对齐标准
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 申请失败
+ * @retval 非NULL指针 申请到的内存
+ */
+void *udk_zmalloc(size_t size, uint32_t align);
+
+/**
+ * @brief 判断是否可以使用外部内存
+ *
+ * @param[in] socket_id numa socket id
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 可以
+ * @retval -1 不可以
+ */
+int udk_malloc_heap_socket_is_external(int socket_id);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mbuf.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mbuf.h
new file mode 100644
index 000000000..3ebd84f70
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mbuf.h
@@ -0,0 +1,513 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk mbuf interface
+ */
+
+#ifndef UDK_MBUF_H
+#define UDK_MBUF_H
+
+#include "udk_mempool.h"
+#include "udk_common.h"
+#include "udk_atomic.h"
+
+#define UDK_MBUF_DEFAULT_MEMPOOL_OPS "udk_ring_mp_mc"
+#define UDK_PKTMBUF_HEADROOM 128
+
+#define PKT_RX_VLAN (1ULL << 0)
+#define PKT_RX_RSS_HASH (1ULL << 1)
+#define PKT_RX_VLAN_STRIPPED (1ULL << 6)
+#define PKT_RX_IP_CKSUM_UNKNOWN 0
+#define PKT_RX_IP_CKSUM_BAD (1ULL << 4)
+#define PKT_RX_IP_CKSUM_GOOD (1ULL << 7)
+#define PKT_RX_L4_CKSUM_BAD (1ULL << 3)
+#define PKT_RX_L4_CKSUM_GOOD (1ULL << 8)
+
+#define PKT_TX_VLAN (1ULL << 57)
+#define PKT_TX_IP_CKSUM (1ULL << 54)
+#define PKT_TX_TCP_CKSUM (1ULL << 52)
+#define PKT_TX_UDP_CKSUM (3ULL << 52)
+#define PKT_TX_TCP_SEG (1ULL << 50)
+#define PKT_TX_IPV6 (1ULL << 56)
+#define PKT_TX_OUTER_IPV6 (1ULL << 60)
+
+#define UDK_PTYPE_L3_IPV4 0x00000010
+#define UDK_PTYPE_L3_IPV4_EXT 0x00000030
+#define UDK_PTYPE_L4_FRAG 0x00000300
+#define UDK_PTYPE_L3_IPV6 0x00000040
+#define UDK_PTYPE_L4_SCTP 0x00000400
+#define UDK_PTYPE_L4_UDP 0x00000200
+#define UDK_PTYPE_TUNNEL_VXLAN 0x00003000
+#define UDK_PTYPE_L4_TCP 0x00000100
+#define UDK_PTYPE_TUNNEL_NVGRE 0x00004000
+#define UDK_PTYPE_L4_ICMP 0x00000500
+#define UDK_PTYPE_L2_ETHER_LLDP 0x00000004
+#define UDK_PTYPE_L2_ETHER_ARP 0x00000003
+#define UDK_PTYPE_L2_ETHER 0x00000001
+
+/** Mbuf having an external buffer attached. shinfo in mbuf must be filled. */
+#define EXT_ATTACHED_MBUF (1ULL << 61)
+/** Indirect attached mbuf */
+#define IND_ATTACHED_MBUF (1ULL << 62)
+/** Alignment constraint of mbuf private area. */
+#define UDK_MBUF_PRIV_ALIGN 8
+/** Returns TRUE if given mbuf is direct, or FALSE otherwise. */
+#define UDK_MBUF_DIRECT(mb) \
+ (!((mb)->ol_flags & (IND_ATTACHED_MBUF | EXT_ATTACHED_MBUF)))
+
+typedef void (*udk_mbuf_extbuf_free_callback_t)(void *addr, void *opaque);
+
+/**
+ * @brief struct udk_pktmbuf_pool_private - pkt buffer配置对象
+ * @details NA
+ */
+struct udk_pktmbuf_pool_private {
+ uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf. */
+ uint16_t mbuf_priv_size; /**< Size of private area in each mbuf. */
+ uint32_t flags; /**< reserved for future use. */
+};
+
+/**
+ * @brief struct udk_mbuf_ext_shared_info - buffer共享信息
+ * @details NA
+ */
+struct udk_mbuf_ext_shared_info {
+ udk_mbuf_extbuf_free_callback_t free_cb;
+ void *fcb_opaque;
+ uint16_t refcnt;
+};
+
+/**
+ * @brief struct udk_mbuf_sched - buffe调度对象
+ * @details NA
+ */
+struct udk_mbuf_sched {
+ uint32_t queue_id;
+ uint8_t traffic_class;
+ uint8_t color;
+ uint16_t reserved;
+};
+
+/**
+ * The generic udk_mbuf, containing a packet mbuf.
+ */
+struct udk_mbuf {
+ UDK_MARKER cacheline0;
+
+ void *buf_addr; /**< Virtual address of segment buffer. */
+ uint64_t
+ buf_iova udk_aligned(sizeof(uint64_t)); /**< physical address */
+
+ /** next 8 bytes are initialised on RX descriptor rearm */
+ UDK_MARKER64 rearm_data;
+ uint16_t data_off;
+ udk_atomic16_t refcnt_atomic;
+ uint16_t nb_segs; /**< Number of segments. */
+ uint16_t port;
+
+ uint64_t ol_flags; /**< Offload features. */
+
+ /** remaining bytes are set on RX when pulling packet from descriptor */
+ UDK_MARKER rx_descriptor_fields1;
+
+ UDK_STD_C11
+ union {
+ uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */
+ __extension__ struct {
+ uint32_t l2_type : 4; /**< (Outer) L2 type. */
+ uint32_t l3_type : 4; /**< (Outer) L3 type. */
+ uint32_t l4_type : 4; /**< (Outer) L4 type. */
+ uint32_t tun_type : 4; /**< Tunnel type. */
+ UDK_STD_C11
+ union {
+ uint8_t inner_esp_next_proto;
+ __extension__ struct {
+ uint8_t inner_l2_type : 4; /**< Inner L2 type. */
+ uint8_t inner_l3_type : 4; /**< Inner L3 type. */
+ };
+ };
+ uint32_t inner_l4_type : 4; /**< Inner L4 type. */
+ };
+ };
+
+ uint32_t pkt_len; /**< Total pkt len: sum of all segments. */
+ uint16_t data_len; /**< Amount of data in segment buffer. */
+ uint16_t vlan_tci; /**< VLAN TCI (CPU order), valid if PKT_RX_VLAN is set. */
+
+ UDK_STD_C11
+ union {
+ union {
+ uint32_t rss; /**< RSS hash result if RSS enabled */
+ struct {
+ union {
+ struct {
+ uint16_t hash;
+ uint16_t id;
+ };
+ uint32_t lo; /**< Second 4 flexible bytes */
+ };
+ uint32_t hi; /**< First 4 flexible bytes or FD ID, dependent on PKT_RX_FDIR_* flag in ol_flags. */
+ } fdir; /**< Filter identifier if FDIR enabled */
+ struct udk_mbuf_sched
+ sched; /* Hierarchical scheduler : 8 bytes */
+ struct {
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint16_t txq;
+ } txadapter; /**< Eventdev ethdev Tx adapter */
+ uint32_t usr;
+ } hash; /**< hash information */
+ };
+
+ uint16_t vlan_tci_outer; /**< Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
+ uint16_t buf_len; /**< Length of segment buffer. */
+ struct udk_mempool *pool; /**< Pool from which mbuf was allocated. */
+
+ /**< second cache line - fields only used in slow path or on TX */
+ UDK_MARKER cacheline1 udk_cache_min_aligned;
+
+ struct udk_mbuf *next; /**< Next segment of scattered packet. */
+
+ /** fields to support TX offloads */
+ UDK_STD_C11
+ union {
+ uint64_t tx_offload;
+ __extension__ struct {
+ uint64_t l2_len : 7;
+ uint64_t l3_len : 9;
+ uint64_t l4_len : 8;
+ uint64_t tso_segsz : 16;
+ uint64_t outer_l3_len : 9;
+ uint64_t outer_l2_len : 7;
+ };
+ };
+
+ /** Shared data for external buffer attached to mbuf. */
+ struct udk_mbuf_ext_shared_info *shinfo;
+
+ uint16_t priv_size;
+ uint16_t timesync;
+ uint32_t dynfield0;
+
+ UDK_STD_C11
+ union {
+ void *userdata; /**< Can be used for external metadata */
+ uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */
+ };
+
+ uint32_t internal; /**< internal use mbuf, app set it to 0 */
+ uint32_t dynfield1[5]; /**< Reserved for dynamic fields. */
+} udk_cache_aligned;
+
+/** Points to an offset into the data in the mbuf */
+#define udk_pktmbuf_mtod_offset(m, t, o) \
+ ((t)((char *)(m)->buf_addr + (m)->data_off + (o)))
+
+/** Points the start of the data in the mbuf */
+#define udk_pktmbuf_mtod(m, t) udk_pktmbuf_mtod_offset(m, t, 0)
+
+/** Returns the length of the segment. */
+#define udk_pktmbuf_data_len(m) ((m)->data_len)
+
+/**
+ * @brief Returns the default IO address of the beginning of the mbuf data.
+ */
+static inline uint64_t udk_mbuf_data_iova_default(const struct udk_mbuf *mb)
+{
+ return mb->buf_iova + UDK_PKTMBUF_HEADROOM;
+}
+
+/**
+ * @brief Returns the IO address of the beginning of the mbuf data.
+ */
+static inline uint64_t udk_mbuf_data_iova(const struct udk_mbuf *mb)
+{
+ return mb->buf_iova + mb->data_off;
+}
+
+static inline uint16_t udk_mbuf_refcnt_read(const struct udk_mbuf *m)
+{
+ return (uint16_t)(udk_atomic16_read(&m->refcnt_atomic));
+}
+
+static inline void udk_mbuf_refcnt_set(struct udk_mbuf *m, uint16_t new_value)
+{
+ udk_atomic16_set(&m->refcnt_atomic, (int16_t)new_value);
+}
+
+#ifdef UDK_MBUF_DEBUG
+#define udk_mbuf_sanity_check(m, is_header) mbuf_sanity_check(m, is_header)
+#else
+#define udk_mbuf_sanity_check(m, is_header) \
+ do { \
+ } while (0)
+#endif
+
+static udk_force_inline void
+udk_mbuf_raw_sanity_check(udk_unused const struct udk_mbuf *m)
+{
+ UDK_ASSERT(udk_mbuf_refcnt_read(m) == 1);
+ UDK_ASSERT((m)->next == NULL);
+ UDK_ASSERT((m)->nb_segs == 1);
+ udk_mbuf_sanity_check(m, 0);
+}
+
+#define UDK_MBUF_RAW_ALLOC_CHECK(m) udk_mbuf_raw_sanity_check(m)
+
+static inline uint16_t udk_pktmbuf_data_room_size(struct udk_mempool *mp)
+{
+ struct udk_pktmbuf_pool_private *mbp_priv =
+ (struct udk_pktmbuf_pool_private *)udk_mempool_get_priv(mp);
+
+ return mbp_priv->mbuf_data_room_size;
+}
+
+/**
+ * @brief Get the application private size of mbufs stored in a pktmbuf_pool.
+ */
+static inline uint16_t udk_pktmbuf_priv_size(struct udk_mempool *mp)
+{
+ struct udk_pktmbuf_pool_private *mbp_priv;
+
+ mbp_priv = (struct udk_pktmbuf_pool_private *)udk_mempool_get_priv(mp);
+ return mbp_priv->mbuf_priv_size;
+}
+
+static inline void udk_pktmbuf_reset_headroom(struct udk_mbuf *m)
+{
+ m->data_off = (uint16_t)UDK_MIN((uint16_t)UDK_PKTMBUF_HEADROOM,
+ (uint16_t)m->buf_len);
+ return;
+}
+
+#define UDK_MBUF_INVALID_PORT ((uint16_t)-1)
+
+/**
+ * @brief reset mbuf属性
+ *
+ * @param[in] m mbuf对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_pktmbuf_reset(struct udk_mbuf *m)
+{
+ m->next = NULL;
+ m->vlan_tci = 0;
+ m->vlan_tci_outer = 0;
+ m->pkt_len = 0;
+ m->tx_offload = 0;
+ m->nb_segs = 1;
+ m->port = UDK_MBUF_INVALID_PORT;
+
+ m->ol_flags = 0;
+ m->packet_type = 0;
+ udk_pktmbuf_reset_headroom(m);
+
+ m->data_len = 0;
+
+ udk_mbuf_sanity_check(m, 1);
+
+ return;
+}
+
+static inline struct udk_mbuf *udk_mbuf_raw_alloc(struct udk_mempool *mp)
+{
+ struct udk_mbuf *m = NULL;
+ if (udk_mempool_get_bulk(mp, (void **)&m, 1) < 0) {
+ return NULL;
+ }
+ UDK_MBUF_RAW_ALLOC_CHECK(m);
+ return m;
+}
+
+/**
+ * @brief Decrease reference counter and unlink a mbuf segment.
+ */
+static udk_force_inline struct udk_mbuf *
+udk_pktmbuf_prefree_seg(struct udk_mbuf *m)
+{
+ udk_mbuf_sanity_check(m, 0);
+
+ UDK_ASSERT(udk_mbuf_refcnt_read(m) <= 1);
+
+ if (likely(udk_mbuf_refcnt_read(m) == 1)) {
+ if (m->next != NULL) {
+ m->next = NULL;
+ m->nb_segs = 1;
+ }
+ return m;
+ }
+ return NULL;
+}
+
+/**
+ * @brief Put mbuf back into its original mempool.
+ */
+static udk_force_inline void udk_mbuf_raw_free(struct udk_mbuf *m)
+{
+ UDK_ASSERT(UDK_MBUF_DIRECT(m));
+ UDK_MBUF_RAW_ALLOC_CHECK(m);
+ udk_mempool_put(m->pool, m);
+ return;
+}
+
+/**
+ * @brief 释放mbuf对象
+ *
+ * @param[in] m mbuf对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static udk_force_inline void udk_pktmbuf_free_seg(struct udk_mbuf *m)
+{
+ m = udk_pktmbuf_prefree_seg(m);
+ if (likely(m != NULL)) {
+ udk_mbuf_raw_free(m);
+ }
+
+ return;
+}
+
+/**
+ * @brief 初始化mbuf对象
+ *
+ * @param[in] mp mempool
+ * @param[in] opaque_arg
+ * @param[in] _m
+ * @param[in] i
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_pktmbuf_init(struct udk_mempool *mp, void *opaque_arg, void *_m,
+ uint32_t i);
+
+/**
+ * @brief 申请一个mbuf对象
+ *
+ * @param[in] mp mempool
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+struct udk_mbuf *udk_pktmbuf_alloc(struct udk_mempool *mp);
+
+/**
+ * @brief 批量申请mbuf对象
+ *
+ * @param[in] mp mempool
+ * @param[out] mbufs 保存mbuf的数组
+ * @param[in] count mbufs可以保存的数量
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回申请到的数量
+ */
+int udk_pktmbuf_alloc_bulk(struct udk_mempool *mp, struct udk_mbuf **mbufs,
+ uint32_t count);
+
+/**
+ * @brief 释放mbuf
+ *
+ * @param[in] m mbuf对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_pktmbuf_free(struct udk_mbuf *m);
+
+/**
+ * @brief 创建mbuf的mempool
+ *
+ * @param[in] name 名称
+ * @param[in] mbp_size mbuf mempool的size配置对象
+ * @param[in] socket_id numa id
+ * @param[in] flags 创建标志
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+struct udk_mempool *
+udk_pktmbuf_pool_create(const char *name,
+ struct udk_pktmbuf_pool_size *mbp_size, int socket_id,
+ uint32_t flags);
+
+/**
+ * @brief 指定ops创建mbuf的mempool
+ *
+ * @param[in] name 名称
+ * @param[in] mbp_size mbuf mempool的size配置对象
+ * @param[in] socket_id numa id
+ * @param[in] ops_name ops名称
+ * @param[in] flags 创建标志
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+struct udk_mempool *udk_pktmbuf_pool_create_by_ops(
+ const char *name, struct udk_pktmbuf_pool_size *mbp_size, int socket_id,
+ const char *ops_name, uint32_t flags);
+
+/**
+ * @brief 校验mbuf的合法性
+ *
+ * @param[in] m mbuf对象
+ * @param[in] is_header 是否校验header
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void mbuf_sanity_check(const struct udk_mbuf *m, int is_header);
+
+/**
+ * @brief 输出mbuf的信息
+ *
+ * @param[in] f 文件
+ * @param[in] m mbuf对象
+ * @param[in] dump_len 可输出的长度
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_pktmbuf_dump(FILE *f, const struct udk_mbuf *m, uint32_t dump_len);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_membarrier.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_membarrier.h
new file mode 100644
index 000000000..76454b3d1
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_membarrier.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK memory barrier header file
+ * Author: -
+ * Create: 2021.4.20
+ */
+
+#ifndef UDK_MEMBARRIER_H
+#define UDK_MEMBARRIER_H
+
+#ifdef UDK_ARCH_ARM64
+#include "arch/arm/udk_membarrier.h"
+#else
+#include "arch/x86/udk_membarrier.h"
+#endif
+
+#endif /* UDK_MEMBARRIER_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mempool.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mempool.h
new file mode 100644
index 000000000..1926748eb
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_mempool.h
@@ -0,0 +1,603 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK mempool header file
+ * Author: -
+ * Create: 2021.5.11
+ */
+
+#ifndef UDK_MEMPOOL_H
+#define UDK_MEMPOOL_H
+
+#include <sys/queue.h>
+#include "securec.h"
+#include "udk_common.h"
+#include "udk_memzone.h"
+#include "udk_spinlock.h"
+#include "udk_log.h"
+
+#ifdef UDK_MEMPOOL_DEBUG
+/**
+ * @brief struct udk_mempool_debug_stats - mempool 相关的统计数据
+ * @details NA
+ */
+struct udk_mempool_debug_stats {
+ uint64_t put_bulk;
+ uint64_t put_objs;
+ uint64_t get_success_bulk;
+ uint64_t get_success_objs;
+ uint64_t get_fail_bulk;
+ uint64_t get_fail_objs;
+ uint64_t get_success_blks;
+ uint64_t get_fail_blks;
+} udk_cache_aligned;
+
+#endif
+#define UDK_MEMPOOL_ERR 1
+#define UDK_MEMPOOL_OK 0
+
+#define UDK_MEMPOOL_CACHE_MAX_SIZE 512
+
+#define UDK_MEMPOOL_ALIGN UDK_CACHE_LINE_SIZE
+#define UDK_MEMPOOL_ALIGN_MASK (UDK_MEMPOOL_ALIGN - 1)
+
+/**
+ * @brief struct udk_mempool_objsz - 描述mempool中元素的信息
+ * @details NA
+ */
+struct udk_mempool_objsz {
+ uint32_t elt_size; /**< Size of an element. */
+ uint32_t header_size; /**< Size of header (before elt). */
+ uint32_t trailer_size; /**< Size of trailer (after elt). */
+ uint32_t total_size; /**< Total size of an object (header + elt + trailer). */
+};
+
+#define UDK_MEMPOOL_MZ_MAGIC "UDK"
+#define UDK_MEMPOOL_MZ_PREFIX UDK_MEMPOOL_MZ_MAGIC "MP_"
+/** Maximum length of a memory pool's name. */
+#define UDK_MEMPOOL_NAMESIZE \
+ ((UDK_RING_NAMESIZE - sizeof(UDK_MEMPOOL_MZ_PREFIX)) + 1)
+
+/** "MP_<name>" */
+#define UDK_MEMPOOL_MZ_FORMAT UDK_MEMPOOL_MZ_PREFIX "%s"
+
+/** A list of memory where objects are stored */
+STAILQ_HEAD(udk_mempool_memhdr_list, udk_mempool_memhdr);
+
+typedef void(udk_mempool_memchunk_free_cb_t)(struct udk_mempool_memhdr *memhdr,
+ const void *opaque);
+
+/**
+ * @brief struct udk_mempool_memhdr - 描述mempool header的结构
+ * @details NA
+ */
+struct udk_mempool_memhdr {
+ STAILQ_ENTRY(udk_mempool_memhdr) next; /**< Next in list. */
+ struct udk_mempool *mp; /**< The mempool owning the chunk */
+ void *addr; /**< Virtual address of the chunk */
+ UDK_STD_C11
+ union {
+ uint64_t iova; /**< IO address of the chunk */
+ uint64_t phys_addr; /**< Physical address of the chunk */
+ };
+
+ size_t len; /**< length of the chunk */
+ udk_mempool_memchunk_free_cb_t *free_cb; /**< Free callback */
+ void *opaque; /**< Argument passed to the free callback */
+};
+
+STAILQ_HEAD(udk_mempool_objhdr_list, udk_mempool_objhdr);
+
+/**
+ * @brief struct udk_mempool_cache - mempool cache
+ * @details NA
+ */
+struct udk_mempool_cache {
+ uint32_t size; /**< Size of the cache */
+ uint32_t flushthresh; /**< Threshold before we flush excess elements */
+ uint32_t len; /**< Current cache count */
+ /**
+ * Cache is allocated to this size to allow it to overflow in certain
+ * cases to avoid needless emptying of cache.
+ */
+ void *objs[UDK_MEMPOOL_CACHE_MAX_SIZE * 3]; /**< Cache objects */
+} udk_cache_aligned;
+
+/**
+ * @brief struct udk_mempool_info - mempool info
+ * @details NA
+ */
+struct udk_mempool_info {
+ /** Number of objects in the contiguous block */
+ uint32_t contig_block_size;
+} udk_cache_aligned;
+
+/**
+ * @brief struct udk_mempool - mempool 对象
+ * @details NA
+ */
+struct udk_mempool {
+ char name[UDK_MEMZONE_NAMESIZE]; /**< Name of mempool. */
+ UDK_STD_C11
+ union {
+ void *pool_data; /**< Ring or pool to store objects. */
+ uint64_t pool_id; /**< External mempool identifier. */
+ };
+ void *pool_config; /**< optional args for ops alloc. */
+ const struct udk_memzone *mz; /**< Mem zone where pool is allocated. */
+ uint32_t flags; /**< Flags of the mempool. */
+ int socket_id; /**< Socket id passed at create. */
+ uint32_t size; /**< Max size of the mempool. */
+ uint32_t cache_size; /**< Size of per-lcore default local cache. */
+
+ uint32_t elt_size; /**< Size of an element. */
+ uint32_t header_size; /**< Size of header (before elt). */
+ uint32_t trailer_size; /**< Size of trailer (after elt). */
+
+ uint32_t private_data_size; /**< Size of private data. */
+ int32_t ops_index;
+
+ struct udk_mempool_cache *local_cache; /**< Per-lcore local cache */
+
+ uint32_t populated_size; /**< Number of populated objects. */
+ struct udk_mempool_objhdr_list elt_list; /**< List of objects in pool */
+ uint32_t nb_mem_chunks; /**< Number of memory chunks */
+ struct udk_mempool_memhdr_list mem_list; /**< List of memory chunks */
+
+#ifdef UDK_MEMPOOL_DEBUG
+ /* Per-lcore statistics. */
+ struct udk_mempool_debug_stats stats[UDK_MAX_LCORE];
+#endif
+} udk_cache_aligned;
+
+#define UDK_MEMPOOL_F_NO_SPREAD \
+ 0x0001 /**< Do not spread among memory channels */
+#define UDK_MEMPOOL_F_NO_CACHE_ALIGN \
+ 0x0002 /**< Do not align objs on cache lines */
+#define UDK_MEMPOOL_F_SP_PUT 0x0004 /**< Default put is "single-producer" */
+#define UDK_MEMPOOL_F_SC_GET 0x0008 /**< Default get is "single-consumer" */
+#define UDK_MEMPOOL_F_POOL_CREATED 0x0010 /**< Internal: pool is created */
+#define UDK_MEMPOOL_F_NO_IOVA_CONTIG \
+ 0x0020 /**< Don't need IOVA contiguous objs */
+#define UDK_MEMPOOL_F_LOCK 0x0080 /**< use pthread lock */
+#define UDK_MEMPOOL_F_IOVA_CONTIG 0x0100 /**< need IOVA contiguous objs */
+
+/**
+ * @brief 输出mempool的统计信息
+ *
+ * @param[in] f 文件
+ * @param[in] mp mempool对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_mempool_dump(FILE *f, struct udk_mempool *mp);
+
+#define UDK_MEMPOOL_OPS_NAMESIZE 32 /**< Max length of ops struct name. */
+#define UDK_MEMPOOL_POPULATE_F_ALIGN_OBJ \
+ 0x0001 /**< Align objects on addresses multiple of total_elt_sz. */
+
+/** Prototype for implementation specific data provisioning function. */
+typedef int (*udk_mempool_alloc_t)(struct udk_mempool *mp);
+/** Free the opaque private data pointed to by mp->pool_data pointer. */
+typedef void (*udk_mempool_free_t)(struct udk_mempool *mp);
+/** Enqueue an object into the external pool. */
+typedef int (*udk_mempool_enqueue_t)(struct udk_mempool *mp,
+ void *const *obj_table, uint32_t n);
+/** Dequeue an object from the external pool. */
+typedef int (*udk_mempool_dequeue_t)(struct udk_mempool *mp, void **obj_table,
+ uint32_t n);
+/** Dequeue a number of contiguous object blocks from the external pool. */
+typedef int (*udk_mempool_dequeue_contig_blocks_t)(struct udk_mempool *mp,
+ void **first_obj_table,
+ uint32_t n);
+/** Return the number of available objects in the external pool. */
+typedef uint32_t (*udk_mempool_get_count)(const struct udk_mempool *mp);
+/** Calculate memory size required to store given number of objects. */
+typedef ssize_t (*udk_mempool_calc_mem_size_t)(const struct udk_mempool *mp,
+ uint32_t obj_num,
+ uint32_t pg_shift,
+ size_t *min_chunk_size,
+ size_t *align);
+/** Function to be called for each populated object. */
+typedef void(udk_mempool_populate_obj_cb_t)(struct udk_mempool *mp,
+ void *opaque, void *vaddr,
+ uint64_t iova);
+
+/** Structure for mempool obj op populating */
+struct udk_mempool_op_populate_info {
+ uint32_t max_objs;
+ void *vaddr;
+ uint64_t iova;
+ size_t len;
+ udk_mempool_populate_obj_cb_t *obj_cb;
+ void *obj_cb_arg;
+};
+
+/** Populate memory pool objects using provided memory chunk. */
+typedef int (*udk_mempool_populate_t)(
+ struct udk_mempool *mp, struct udk_mempool_op_populate_info *info);
+/** Get some additional information about a mempool. */
+typedef int (*udk_mempool_get_info_t)(const struct udk_mempool *mp,
+ struct udk_mempool_info *info);
+
+/**
+ * @brief Structure defining mempool operations structure
+ */
+struct udk_mempool_ops {
+ char name[UDK_MEMPOOL_OPS_NAMESIZE]; /**< Name of mempool ops struct. */
+ udk_mempool_alloc_t alloc; /**< Allocate private data. */
+ udk_mempool_free_t free; /**< Free the external pool. */
+ udk_mempool_enqueue_t enqueue; /**< Enqueue an object. */
+ udk_mempool_dequeue_t dequeue; /**< Dequeue an object. */
+ udk_mempool_get_count get_count; /**< Get qty of available objs. */
+ /** Optional callback to calculate memory size required to store specified number of objects. */
+ udk_mempool_calc_mem_size_t calc_mem_size;
+ /** Optional callback to populate mempool objects using provided memory chunk. */
+ udk_mempool_populate_t populate;
+ /** Get mempool info */
+ udk_mempool_get_info_t get_info;
+ /** Dequeue a number of contiguous object blocks. */
+ udk_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
+} udk_cache_aligned;
+
+#define UDK_MEMPOOL_MAX_OPS_IDX 16 /**< Max registered ops structs */
+
+/**
+ * @brief Structure storing the table of registered ops structs
+ */
+struct udk_mempool_ops_table {
+ udk_spinlock_t sl; /**< Spinlock for add/delete. */
+ uint32_t num_ops; /**< Number of used ops structs in the table. */
+ /** Storage for all possible ops structs. */
+ struct udk_mempool_ops ops[UDK_MEMPOOL_MAX_OPS_IDX];
+} udk_cache_aligned;
+
+extern struct udk_mempool_ops_table g_udk_mempool_ops_table;
+
+/**
+ * @brief Structure storing out paras for calculating mem size
+ */
+struct udk_mempool_size_out_para {
+ size_t *min_chunk_size;
+ size_t *align;
+};
+
+/* mempool operations. */
+
+int udk_mempool_register_ops(const struct udk_mempool_ops *h);
+
+int udk_mempool_ops_alloc(struct udk_mempool *mp);
+
+void udk_mempool_ops_free(struct udk_mempool *mp);
+
+ssize_t udk_mempool_ops_calc_mem_size(const struct udk_mempool *mp,
+ uint32_t obj_num, uint32_t pg_shift,
+ size_t *min_chunk_size, size_t *align);
+
+int udk_mempool_ops_populate(struct udk_mempool *mp,
+ struct udk_mempool_op_populate_info *info);
+
+uint32_t udk_mempool_ops_get_count(const struct udk_mempool *mp);
+
+int udk_mempool_ops_get_info(const struct udk_mempool *mp,
+ struct udk_mempool_info *info);
+
+static inline struct udk_mempool_ops *udk_mempool_get_ops(int ops_index)
+{
+ UDK_VERIFY((ops_index >= 0) && (ops_index < UDK_MEMPOOL_MAX_OPS_IDX));
+
+ return &g_udk_mempool_ops_table.ops[ops_index];
+}
+
+static inline int udk_mempool_ops_enqueue_bulk(struct udk_mempool *mp,
+ void *const *obj_table,
+ uint32_t n)
+{
+ struct udk_mempool_ops *ops;
+
+ ops = udk_mempool_get_ops(mp->ops_index);
+ return ops->enqueue(mp, obj_table, n);
+}
+
+static inline int udk_mempool_ops_dequeue_bulk(struct udk_mempool *mp,
+ void **obj_table, uint32_t n)
+{
+ struct udk_mempool_ops *ops;
+
+ ops = udk_mempool_get_ops(mp->ops_index);
+ return ops->dequeue(mp, obj_table, n);
+}
+
+#define UDK_MEMPOOL_REGISTER_OPS(ops) \
+ UDK_INIT(mp_hdlr_init_##ops) \
+ { \
+ (void)udk_mempool_register_ops(&(ops)); \
+ }
+
+typedef void(udk_mempool_ctor_t)(struct udk_mempool *, void *);
+typedef int(udk_mempool_obj_cb_t)(struct udk_mempool *mp, void *opaque,
+ void *obj, uint32_t obj_idx);
+
+/**
+ * @brief struct udk_pktmbuf_pool_size - mempool packet buffer size
+ * @details NA
+ */
+struct udk_pktmbuf_pool_size {
+ uint32_t n;
+ uint32_t cache_size;
+ uint32_t priv_size;
+ uint16_t data_room_size;
+};
+
+/**
+ * @brief struct udk_mempool_size - mempool size info
+ * @details NA
+ */
+struct udk_mempool_size {
+ uint32_t n;
+ uint32_t elt_size;
+ uint32_t cache_size;
+ uint32_t private_data_size;
+};
+
+/**
+ * @brief struct udk_mp_obj_init - mempool init对象
+ * @details NA
+ */
+struct udk_mp_obj_init {
+ udk_mempool_ctor_t *mp_init;
+ void *mp_init_arg;
+ udk_mempool_obj_cb_t *obj_init;
+ void *obj_init_arg;
+};
+
+#define UDK_MEMPOOL_HEADER_SIZE(mp, cs) \
+ (sizeof(*(mp)) + \
+ (((cs) == 0) ? 0 : \
+ (sizeof(struct udk_mempool_cache) * UDK_MAX_LCORE)))
+
+static inline void *udk_mempool_get_priv(struct udk_mempool *mp)
+{
+ return (char *)mp + UDK_MEMPOOL_HEADER_SIZE(mp, mp->cache_size);
+}
+
+/**
+ * @brief 返还object对象到mempool
+ *
+ * @param[in] mp mempool
+ * @param[in] obj 对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_mempool_put(struct udk_mempool *mp, void *obj);
+
+/**
+ * @brief 从mempool中获取object对象
+ *
+ * @param[in] mp mempool
+ * @param[out] obj_table 保存获取的对象
+ * @param[in] n obj_table可以保存的数量
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 从cache中获取
+ * @retval >0 从非cache中获取的数量
+ */
+int udk_mempool_get_bulk(struct udk_mempool *mp, void **obj_table, uint32_t n);
+
+/**
+ * @brief 释放mempool
+ *
+ * @param[in] mp mempool
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_mempool_free(struct udk_mempool *mp);
+
+/**
+ * @brief 查询mempool中已保存的object个数
+ *
+ * @param[in] mp mempool
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回可用的object数量
+ */
+uint32_t udk_mempool_avail_count(const struct udk_mempool *mp);
+
+/**
+ * @brief 查询mempool中可使用的object槽位数量
+ *
+ * @param[in] mp mempool
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回可用的object空闲槽位数量
+ */
+uint32_t udk_mempool_in_use_count(const struct udk_mempool *mp);
+
+/**
+ * @brief 根据名称查询mempool
+ *
+ * @param[in] name 名称
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 不存在
+ * @retval 非NULL 存在
+ */
+struct udk_mempool *udk_mempool_lookup(const char *name);
+
+/**
+ * @brief 创建mempool
+ *
+ * @param[in] name 名称
+ * @param[in] mp_size mempool size
+ * @param[in] mp_obj_init 初始化参数对象
+ * @param[in] socket_id numa id
+ * @param[in] flags 创建标志
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+struct udk_mempool *udk_mempool_create(const char *name,
+ struct udk_mempool_size *mp_size,
+ struct udk_mp_obj_init *mp_obj_init,
+ int socket_id, uint32_t flags);
+
+/**
+ * @brief 初始化mempool size参数
+ *
+ * @param[in] mp_size mempool size
+ * @param[in] n 数量
+ * @param[in] elt_size element size
+ * @param[in] cache_size cache size
+ * @param[in] private_data_size 私有数据size
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_mempool_size_init(struct udk_mempool_size *mp_size, uint32_t n,
+ uint32_t elt_size, uint32_t cache_size,
+ uint32_t private_data_size);
+
+/**
+ * @brief 初始化mempool object参数
+ *
+ * @param[in] mp_obj_init object init参数对象
+ * @param[in] mp_init constructor函数指针
+ * @param[in] mp_init_arg mp_init回调参数
+ * @param[in] obj_init object 初始化回调
+ * @param[in] obj_init_arg obj_init回调参数
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_mempool_obj_init(struct udk_mp_obj_init *mp_obj_init,
+ udk_mempool_ctor_t *mp_init, void *mp_init_arg,
+ udk_mempool_obj_cb_t *obj_init, void *obj_init_arg);
+
+/**
+ * @brief 创建mempool
+ *
+ * @param[in] name 名称
+ * @param[in] mp_size mempool size
+ * @param[in] mp_obj_init 初始化参数对象
+ * @param[in] socket_id numa id
+ * @param[in] flags 创建标志
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+struct udk_mempool *
+udk_mempool_create_empty(const char *name,
+ struct udk_pktmbuf_pool_size *mbp_size,
+ uint32_t elt_size, int socket_id, uint32_t flags);
+
+/**
+ * @brief 迭代mempool中的object 触发回调
+ *
+ * @param[in] mp mempool
+ * @param[in] obj_cb 回调
+ * @param[in] obj_cb_arg 回调参数
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回object的数量(回调的次数)
+ */
+uint32_t udk_mempool_obj_iter(struct udk_mempool *mp,
+ udk_mempool_obj_cb_t *obj_cb, void *obj_cb_arg);
+
+/**
+ * @brief 获取mempool对应的page size
+ *
+ * @param[in] mp mempool
+ * @param[out] pg_sz 保存page size
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_mempool_get_page_size(struct udk_mempool *mp, size_t *pg_sz);
+
+/**
+ * @brief 设置mempool ops对象
+ *
+ * @param[in] mp mempool
+ * @param[in] name 名称
+ * @param[in] pool_config pool config
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_mempool_set_ops_byname(struct udk_mempool *mp, const char *name,
+ void *pool_config);
+
+/**
+ * @brief 创建mempool对应的资源,并初始化状态
+ *
+ * @param[in] mp mempool
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_mempool_populate_default(struct udk_mempool *mp);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_memzone.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_memzone.h
new file mode 100644
index 000000000..a7af78c8a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_memzone.h
@@ -0,0 +1,121 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk memzone interface
+ */
+
+#ifndef UDK_MEMZONE_H
+#define UDK_MEMZONE_H
+
+#include "udk_common.h"
+
+#define UDK_MAX_MEMZONE 2560
+
+#define UDK_MEMZONE_2MB 0x00000001
+#define UDK_MEMZONE_1GB 0x00000002
+#define UDK_MEMZONE_16MB 0x00000100
+#define UDK_MEMZONE_16GB 0x00000200
+#define UDK_MEMZONE_256KB 0x00010000
+#define UDK_MEMZONE_256MB 0x00020000
+#define UDK_MEMZONE_512MB 0x00040000
+#define UDK_MEMZONE_4GB 0x00080000
+#define UDK_MEMZONE_SIZE_HINT_ONLY 0x00000004
+#define UDK_MEMZONE_IOVA_CONTIG 0x00100000
+
+#define UDK_MEMZONE_NAMESIZE 32 /**< Maximum length of memory zone name. */
+
+struct udk_memzone {
+ char name[UDK_MEMZONE_NAMESIZE]; /**< Name of the memory zone. */
+
+ uint64_t iova; /**< Start IO address. */
+
+ UDK_STD_C11
+ union {
+ void *addr; /**< Start virtual address. */
+ uint64_t addr_64; /**< Makes sure addr is always 64-bits */
+ };
+ size_t len; /**< Length of the mem zone. */
+ uint64_t hugepage_sz; /**< The page size of underlying memory */
+ int32_t socket_id; /**< NUMA socket ID. */
+ uint32_t flags; /**< Characteristics of this mem zone. */
+} __attribute__((__packed__));
+
+struct socket_info {
+ const char *name;
+ size_t len;
+ int socket_id;
+ uint32_t flags;
+};
+
+/**
+ * @brief 根据名称查询memzone
+ *
+ * @param[in] name 名称
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 不存在
+ * @retval 非NULL 存在
+ */
+const struct udk_memzone *udk_memzone_lookup(const char *name);
+
+/**
+ * @brief 创建memzone
+ *
+ * @param[in] name memzone名称
+ * @param[in] len 申请内存的长度
+ * @param[in] socket_id numa socket id
+ * @param[in] flags 申请标志
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+const struct udk_memzone *udk_memzone_reserve(const char *name, size_t len,
+ int socket_id, uint32_t flags);
+
+/**
+ * @brief 支持对齐能力的创建memzone
+ *
+ * @param[in] name memzone名称
+ * @param[in] len 申请内存的长度
+ * @param[in] socket_id numa socket id
+ * @param[in] flags 申请标志
+ * @param[in] align 对齐标准
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
+ */
+const struct udk_memzone *udk_memzone_reserve_aligned(const char *name,
+ size_t len, int socket_id,
+ uint32_t flags,
+ uint32_t align);
+
+/**
+ * @brief 释放memzone资源
+ *
+ * @param[in] mz memzone对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_memzone_free(const struct udk_memzone *mz);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ops.h
new file mode 100644
index 000000000..a5266c35c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ops.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: UDK operations header file
+ * Author: -
+ * Create: 2021.4.19
+ */
+
+#ifndef UDK_OPERATIONS_H
+#define UDK_OPERATIONS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "udk_ring.h"
+#include "udk_memzone.h"
+#include "udk_mempool.h"
+#include "udk_mbuf.h"
+
+/**
+ * @brief struct udk_melem - udk 内存对象
+ * @details NA
+ */
+struct udk_melem {
+ void *addr; /**< virtual address */
+ uint64_t iova; /**< IO address */
+ uint64_t page_sz; /**< page size of underlying memory */
+ int socket_id; /**< NUMA socket ID */
+ int rsvd;
+};
+
+/**
+ * @brief struct udk_callback_ops - udk 内存操作虚函数表
+ * @details NA
+ */
+struct udk_callback_ops {
+ /* udk_malloc */
+ void (*free)(void *addr);
+ void *(*malloc_socket)(const char *type, size_t size, uint32_t align,
+ int32_t socket_arg);
+
+ /* udk_ring */
+ struct udk_ring *(*ring_create)(const char *name, uint32_t count,
+ int32_t socket_id, uint32_t flags);
+ struct udk_ring *(*ring_lookup)(const char *name);
+ void (*ring_free)(struct udk_ring *r);
+ int (*ring_dequeue)(struct udk_ring *r, void **obj_p);
+ int (*ring_enqueue)(struct udk_ring *r, void *obj);
+ int (*ring_full)(const struct udk_ring *r);
+ void (*ring_dump)(FILE *f, const struct udk_ring *r);
+ uint32_t (*ring_count)(const struct udk_ring *r);
+ uint32_t (*ring_free_count)(const struct udk_ring *r);
+
+ /* udk_memzone */
+ int (*memzone_free)(const struct udk_memzone *mz);
+ const struct udk_memzone *(*memzone_lookup)(const char *name);
+ const struct udk_memzone *(*memzone_reserve)(const char *name,
+ size_t len, int socket_id,
+ uint32_t flags);
+ const struct udk_memzone *(*memzone_reserve_aligned)(const char *name,
+ size_t len,
+ int socket_id,
+ uint32_t flags,
+ uint32_t align);
+
+ /* udk_mempool */
+ int (*mempool_get_bulk)(struct udk_mempool *mp, void **obj_table,
+ uint32_t n);
+ void (*mempool_put)(struct udk_mempool *mp, void *obj);
+ void (*mempool_free)(struct udk_mempool *mp);
+ uint32_t (*mempool_avail_count)(const struct udk_mempool *mp);
+ uint32_t (*mempool_in_use_count)(const struct udk_mempool *mp);
+ struct udk_mempool *(*mempool_lookup)(const char *name);
+ struct udk_mempool *(*mempool_create)(
+ const char *name, uint32_t n, uint32_t elt_size,
+ uint32_t cache_size, uint32_t private_data_size,
+ udk_mempool_ctor_t *mp_init, void *mp_init_arg,
+ udk_mempool_obj_cb_t *obj_init, void *obj_init_arg,
+ int socket_id, uint32_t flags);
+
+ /* udk_mbuf */
+ struct udk_mbuf *(*pktmbuf_alloc)(struct udk_mempool *mp);
+ int (*pktmbuf_alloc_bulk)(struct udk_mempool *pool,
+ struct udk_mbuf **mbufs, uint32_t count);
+ void (*pktmbuf_free)(struct udk_mbuf *m);
+ struct udk_mempool *(*pktmbuf_pool_create)(
+ const char *name, struct udk_pktmbuf_pool_size *mbp_size,
+ int socket_id);
+
+ int (*mheap_alloc)(const char *type, size_t size, int socket_arg,
+ unsigned int flags, size_t align, size_t bound,
+ bool contig, struct udk_melem *mem);
+ int (*mheap_free)(void *addr);
+};
+
+extern struct udk_callback_ops g_udk_reg_ops;
+
+/**
+ * @brief 注册udk memory相关虚函数表
+ *
+ * @param[in] reg_ops 注册的虚函数表对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int32_t udk_register_ops(struct udk_callback_ops *reg_ops);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_pci.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_pci.h
new file mode 100644
index 000000000..71caaabee
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_pci.h
@@ -0,0 +1,46 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk pci header file
+ */
+
+#ifndef UDK_PCI_H
+#define UDK_PCI_H
+
+#include <stdint.h>
+#include <inttypes.h>
+
+/** Formatting string for PCI device identifier: e.g.: 0000:00:01.0 */
+#define UDK_PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define UDK_PCI_FMT_NVAL 4
+
+/**
+ * @brief struct udk_pci_addr - pci相关属性
+ * @details NA
+ */
+/* to be obsoleted */
+struct udk_pci_addr {
+ uint32_t domain; /**< Device domain */
+ uint8_t bus; /**< Device bus */
+ uint8_t devid; /**< Device ID */
+ uint8_t function; /**< Device function */
+ uint8_t rsvd;
+};
+
+/**
+ * @brief 解析包含pci信息的字符串
+ *
+ * @param[in] str 待解析的字符串
+ * @param[out] addr 保存解析结果的对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_pci_addr_parse(const char *str, struct udk_pci_addr *addr);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ring.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ring.h
new file mode 100644
index 000000000..fa1919747
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_ring.h
@@ -0,0 +1,249 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk ring header file
+ */
+
+#ifndef UDK_RING_H
+#define UDK_RING_H
+
+#include <stdint.h>
+#include <pthread.h>
+
+#include "udk_common.h"
+#include "udk_memzone.h"
+#include "udk_rwlock.h"
+
+#define UDK_TAILQ_RING_NAME "UDK_RING"
+#define UDK_RING_MZ_PREFIX "RG_"
+/** The maximum length of a ring name. */
+#define UDK_RING_NAMESIZE \
+ ((UDK_MEMZONE_NAMESIZE - sizeof(UDK_RING_MZ_PREFIX)) + 1)
+#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
+#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
+#define RING_F_LOCK 0x0080 /**< Use pthread lock or lock free */
+
+enum udk_ring_queue_behavior {
+ UDK_RING_QUEUE_FIXED =
+ 0, /**< Enq/Deq a fixed number of items from a ring */
+ UDK_RING_QUEUE_VARIABLE /**< Enq/Deq as many items as possible from ring */
+};
+
+enum udk_ring_sync_type {
+ UDK_RING_SYNC_MT, /**< multi-thread safe */
+ UDK_RING_SYNC_ST, /**< single-thread only */
+ UDK_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
+ UDK_RING_SYNC_MT_HTS, /**< multi-thread head/tail sync */
+};
+
+struct udk_ring_headtail {
+ volatile uint32_t head;
+ volatile uint32_t tail;
+ UDK_STD_C11
+ union {
+ enum udk_ring_sync_type sync_type;
+ uint32_t single;
+ };
+};
+
+union udk_ring_rts_poscnt {
+ uint64_t raw udk_aligned(8);
+ struct {
+ uint32_t cnt;
+ uint32_t pos;
+ } val;
+};
+
+struct udk_ring_rts_headtail {
+ volatile union udk_ring_rts_poscnt tail;
+ enum udk_ring_sync_type sync_type;
+ uint32_t htd_max;
+ volatile union udk_ring_rts_poscnt head;
+};
+
+union udk_ring_hts_pos {
+ uint64_t raw udk_aligned(8);
+ struct {
+ uint32_t head;
+ uint32_t tail;
+ } pos;
+};
+
+/**
+ * @brief head/tail sync mode
+ */
+struct udk_ring_hts_headtail {
+ volatile union udk_ring_hts_pos ht;
+ enum udk_ring_sync_type sync_type;
+};
+
+struct udk_ring_queue_para {
+ uint32_t n; /**< number */
+ enum udk_ring_queue_behavior behavior;
+ uint32_t is_sc_sp; /**< is Single Consumer or Single Producer */
+};
+
+struct udk_ring {
+ char name[UDK_MEMZONE_NAMESIZE] udk_cache_aligned;
+ uint32_t flags;
+ const struct udk_memzone *memzone;
+ uint32_t size;
+ uint32_t mask;
+ uint32_t capacity;
+ pthread_mutex_t lock;
+
+ char pad0 udk_cache_aligned;
+
+ /** producer status */
+ UDK_STD_C11
+ union {
+ struct udk_ring_headtail prod;
+ struct udk_ring_hts_headtail hts_prod;
+ struct udk_ring_rts_headtail rts_prod;
+ } udk_cache_aligned;
+
+ char pad1 udk_cache_aligned;
+
+ /** consumer status */
+ union {
+ struct udk_ring_headtail cons;
+ struct udk_ring_hts_headtail hts_cons;
+ struct udk_ring_rts_headtail rts_cons;
+ } udk_cache_aligned;
+
+ char pad2 udk_cache_aligned;
+};
+
+/**
+ * @brief 创建ring
+ *
+ * @param[in] name ring名称
+ * @param[in] count 个数
+ * @param[in] socket_id numa id
+ * @param[in] flags 创建标识
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 创建失败
+ * @retval 非NULL 成功
+ */
+struct udk_ring *udk_ring_create(const char *name, uint32_t count,
+ int32_t socket_id, uint32_t flags);
+
+/**
+ * @brief 查询ring对象
+ *
+ * @param[in] name 查询名称标志
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval NULL 不存在
+ * @retval 非NULL 存在
+ */
+struct udk_ring *udk_ring_lookup(const char *name);
+
+/**
+ * @brief 释放ring
+ *
+ * @param[in] r ring对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_ring_free(struct udk_ring *r);
+
+/**
+ * @brief 从ring中出队object
+ *
+ * @param[in] r ring对象
+ * @param[in] obj_p 出队对象保存的位置
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 出队的个数
+ */
+int udk_ring_dequeue(struct udk_ring *r, void **obj_p);
+
+/**
+ * @brief 从ring中入队object
+ *
+ * @param[in] r ring对象
+ * @param[in] obj 入队对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+int udk_ring_enqueue(struct udk_ring *r, void *obj);
+
+/**
+ * @brief 判断ring是否满
+ *
+ * @param[in] r ring对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 1 满
+ * @retval 0 非满
+ */
+int udk_ring_full(struct udk_ring *r);
+
+/**
+ * @brief 输出ring信息到文件f
+ *
+ * @param[in] f 文件
+ * @param[in] r ring对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+void udk_ring_dump(FILE *f, const struct udk_ring *r);
+
+/**
+ * @brief 返回ring中可消费的object个数
+ *
+ * @param[in] r ring对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回
+ */
+uint32_t udk_ring_count(const struct udk_ring *r);
+
+/**
+ * @brief 查询ring中可用的槽位数量
+ *
+ * @param[in] r ring对象
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回可用的槽位数量
+ */
+uint32_t udk_ring_free_count(const struct udk_ring *r);
+
+#endif /* UDK_RING_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_rwlock.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_rwlock.h
new file mode 100644
index 000000000..bbe209f43
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_rwlock.h
@@ -0,0 +1,148 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk rwlock header file
+ */
+
+#ifndef UDK_RWLOCK_H
+#define UDK_RWLOCK_H
+
+#ifndef UDK_ARCH_ARM64
+#include <emmintrin.h>
+#else
+#include <stdint.h>
+#endif
+
+/**
+ * @brief udk封装的读写锁
+ * @details NA
+ */
+typedef struct {
+ volatile int32_t cnt; /**< -1 when W lock held, > 0 when R locks held. */
+} udk_rwlock_t;
+
+/**
+ * @brief 初始化锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_rwlock_init(udk_rwlock_t *rwl)
+{
+ rwl->cnt = 0;
+}
+
+/**
+ * @brief 主动放弃CPU
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_pause(void)
+{
+#ifdef UDK_ARCH_ARM64
+ asm volatile("yield" ::: "memory");
+#else
+ _mm_pause();
+#endif
+}
+
+/**
+ * @brief 抢占写锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_rwlock_write_lock(udk_rwlock_t *rwl)
+{
+ int32_t x;
+ int success = 0;
+
+ while (success == 0) {
+ x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
+ /* write or read lock is held */
+ if (x != 0) {
+ udk_pause();
+ continue;
+ }
+ success = __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED);
+ }
+}
+
+/**
+ * @brief 释放写锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_rwlock_write_unlock(udk_rwlock_t *rwl)
+{
+ __atomic_store_n(&rwl->cnt, 0, __ATOMIC_RELEASE);
+}
+
+/**
+ * @brief 抢占读锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_rwlock_read_lock(udk_rwlock_t *rwl)
+{
+ int32_t x;
+ int success = 0;
+
+ while (success == 0) {
+ x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
+ /* write lock is held */
+ if (x < 0) {
+ udk_pause();
+ continue;
+ }
+ success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED);
+ }
+}
+
+/**
+ * @brief 释放读锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_rwlock_read_unlock(udk_rwlock_t *rwl)
+{
+ __atomic_fetch_sub(&rwl->cnt, 1, __ATOMIC_RELEASE);
+}
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_spinlock.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_spinlock.h
new file mode 100644
index 000000000..5c31c9db5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_spinlock.h
@@ -0,0 +1,102 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description : udk spinlock interface
+ */
+
+#ifndef UDK_SPINLOCK_H
+#define UDK_SPINLOCK_H
+
+#include "udk_rwlock.h"
+
+/**
+ * @brief udk封装的锁
+ * @details NA
+ */
+typedef struct {
+ volatile int locked; /**< lock status 0 = unlocked, 1 = locked */
+} udk_spinlock_t;
+
+/** initialize spinlock in static way */
+#define UDK_SPINLOCK_INITIALIZER \
+ { \
+ 0 \
+ }
+
+/**
+ * @brief 初始化锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_spinlock_init(udk_spinlock_t *sl)
+{
+ sl->locked = 0;
+}
+
+/**
+ * @brief 抢占锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_spinlock_lock(udk_spinlock_t *sl)
+{
+ int exp = 0;
+
+ while (!__atomic_compare_exchange_n(
+ &sl->locked, &exp, 1, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
+ while (__atomic_load_n(&sl->locked, __ATOMIC_RELAXED) != 0) {
+ udk_pause();
+ }
+ exp = 0;
+ }
+}
+
+/**
+ * @brief 释放锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: NA
+ */
+static inline void udk_spinlock_unlock(udk_spinlock_t *sl)
+{
+ __atomic_store_n(&sl->locked, 0, __ATOMIC_RELEASE);
+}
+
+/**
+ * @brief 尝试抢占锁
+ *
+ * @param sl 锁对象指针
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回抢占结果
+ * @retval 0 抢占失败
+ * @retval 1 抢占成功
+ */
+static inline int udk_spinlock_trylock(udk_spinlock_t *sl)
+{
+ int exp = 0;
+ return __atomic_compare_exchange_n(&sl->locked, &exp, 1, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
+}
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_usrnl.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_usrnl.h
new file mode 100644
index 000000000..4e9ddcc8d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_usrnl.h
@@ -0,0 +1,219 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
+ * Description : udk usrnl interface
+ */
+
+#ifndef UDK_USRNL_H
+#define UDK_USRNL_H
+
+#ifndef __KERNEL__
+#include <stdint.h>
+#include <stdbool.h>
+
+/** max length usrnl cmd header */
+#define USRNL_CMD_HDR_LEN_MAX 128
+
+/** max length usrnl cmd buffer that include header and data */
+#define USRNL_CMD_BUF_LEN_MAX 2048
+
+/** get header length usrnl_cmd_buf */
+#define USRNL_CMD_HDR_LEN(cmd) ((cmd)->hdr_size)
+
+/** get buffer(header + data) length usrnl_cmd_buf */
+#define USRNL_CMD_BUF_LEN(cmd) \
+ (USRNL_NLA_ALIGN((cmd)->data_size + (cmd)->hdr_size))
+
+/** get buffer(header + data) address of usrnl_cmd_buf */
+#define USRNL_CMD_BUF_ADDR(cmd) ((cmd)->hdr_ptr)
+
+/** get data length usrnl_cmd_buf */
+#define USRNL_CMD_DATA_LEN(cmd) ((cmd)->data_size)
+
+/** get data address usrnl_cmd_buf */
+#define USRNL_CMD_DATA_ADDR(cmd, type) ((type)((void *)(cmd)->data_ptr))
+
+/** get address of data start plus offset usrnl_cmd_buf */
+#define USRNL_CMD_DATA_ADDR_OFFSET(cmd, type, offset) \
+ ((type)(void *)((cmd)->data_ptr + (offset)))
+
+/**
+ * @brief command buffer api for upper layer lib and app
+ */
+struct usrnl_cmd_buf {
+ void *buf; /**< start address of cmd_buf, can not modify after allocated */
+ char *data_ptr; /**< start address of data */
+ char *hdr_ptr; /**< start address of header */
+ uint16_t data_size; /**< data length */
+ uint16_t hdr_size; /**< header length */
+};
+
+/**
+ * @brief alloc a cmd_buf from a cmd pool
+ *
+ * @param usrnl_hdl owner of cmd pool
+ * @param size 0: use max cmd_buf size USRNL_CMD_BUF_LEN_MAX; other: the size of cmd_buf
+ *
+ * @retval null failed
+ * @retval other the cmd_buf address
+ */
+struct usrnl_cmd_buf *usrnl_cmd_pool_alloc(void *usrnl_hdl, uint16_t size);
+
+/**
+ * @brief release a cmd_buf from back to cmd pool
+ *
+ * @param usrnl_hdl owner of cmd pool
+ * @param buf 0: the cmd_buf to be released
+ */
+void usrnl_cmd_pool_free(void *usrnl_hdl, struct usrnl_cmd_buf *buf);
+
+/**
+ * @brief create a netlink with kernel using family name
+ *
+ * @param usrnl_hdl the return value of usrnl
+ *
+ * @retval 0 success
+ * @retval negative error_code
+ */
+int32_t usrnl_create(void **usrnl_hdl, const char *nl_family_name);
+
+/**
+ * @brief destroy a netlink
+ *
+ * @param usrnl_hdl the usrnl to be destroyed
+ */
+void usrnl_destroy(void *usrnl_hdl);
+
+/**
+ * @brief send a message to cmdq via kernel netlink and get response
+ *
+ * @param usrnl_hdl the usrnl that the netlink belongs to
+ * @param cmd_in command buffer
+ * @param rsp_out response buffer
+ *
+ * @retval 0 success
+ * @retval negative linux base error code
+ */
+int32_t usrnl_exec_cmdq_cmd(void *usrnl_hdl, struct usrnl_cmd_buf *cmd_in,
+ struct usrnl_cmd_buf *rsp_out);
+
+/**
+ * @brief send a message to mpu via kernel netlink and get response
+ *
+ * @param usrnl_hdl the usrnl that the netlink belongs to
+ * @param cmd_in command buffer
+ * @param rsp_out response buffer
+ *
+ * @retval 0 success
+ * @retval negative linux base error code
+ */
+int32_t usrnl_exec_mgmt_msg(void *usrnl_hdl, struct usrnl_cmd_buf *cmd_in,
+ struct usrnl_cmd_buf *rsp_out);
+
+/**
+ * @brief send a message to driver via kernel netlink and get response
+ *
+ * @param usrnl_hdl the usrnl that the netlink belongs to
+ * @param cmd_in command buffer
+ * @param rsp_out response buffer
+ *
+ * @retval 0 success
+ * @retval negative linux base error code
+ */
+int32_t usrnl_exec_drv_cmd(void *usrnl_hdl, struct usrnl_cmd_buf *cmd_in,
+ struct usrnl_cmd_buf *rsp_out);
+
+/**
+ * @brief send a message to vf via kernel netlink and get response
+ *
+ * @param usrnl_hdl the usrnl that the netlink belongs to
+ * @param cmd_in command buffer
+ * @param rsp_out response buffer
+ *
+ * @retval 0 success
+ * @retval negative linux base error code
+ */
+int32_t usrnl_exec_vf_cmd(void *usrnl_hdl, struct usrnl_cmd_buf *cmd_in,
+ struct usrnl_cmd_buf *rsp_out);
+
+/**
+ * @brief block netlink and get flush netlink-sockets status during sdi NanoOS hot replace.
+ *
+ * @param flag true : block netlink; false : non-block netlink
+ * @param usrnl_hdl the usrnl that the netlink belongs to
+ *
+ * @retval 0 success
+ * @retval negative linux base error code
+ */
+int32_t netlink_block_and_get_flush_status(bool flag, void *usrnl_hdl);
+
+#endif
+
+/** cmdq_direct_resp or cmdq_detail_resp */
+#define USRNL_CMDQ_DIRECT (0)
+#define USRNL_CMDQ_DETAIL (1)
+
+#define USRNL_GENL_ATTR_MAX (__USRNL_GENL_ATTR_MAX - 1)
+
+/**
+ * @brief usrnl message cmd and header definitions
+ */
+enum usrnl_dev_cmd {
+ USRNL_DEV_CMD_UNSPEC,
+ USRNL_DEV_MPU_CMD_EXECUTE, /**< to mpu */
+ USRNL_DEV_VF_CMD_EXECUTE, /**< to vf's mailbox */
+ USRNL_DEV_DRV_CMD_EXECUTE, /**< to driver's resource init */
+ USRNL_DEV_CMDQ_CMD_EXECUTE /**< to ucode via cmdq */
+};
+
+enum usrnl_genl_attr {
+ USRNL_GENL_ATTR_UNSPEC,
+ USRNL_GENL_ATTR, /**< u32 port number within datapath */
+ __USRNL_GENL_ATTR_MAX
+};
+
+/**
+ * @brief netlink driver/mpu/cmdq message header definitions
+ */
+struct usrnl_common_msg_hdr {
+ // DW0
+ unsigned int cmd : 16; /**< user defined command */
+ unsigned int
+ msg_len : 11; /**< total message length, maximum (2 << 11) -1 */
+ unsigned int module : 5; /**< module id */
+
+ // DW1
+ unsigned int
+ src_func_idx : 16; /**< source function id, for pf to up this means msg_id */
+ unsigned int rsp_type : 8; /**< rsvd2 */
+ unsigned int err_code : 8; /**< rsvd1 */
+};
+
+typedef struct usrnl_common_msg_hdr usrnl_drv_msg_hdr_s;
+typedef struct usrnl_common_msg_hdr usrnl_mpu_msg_hdr_s;
+typedef struct usrnl_common_msg_hdr usrnl_cmdq_msg_hdr_s;
+
+#define USRNL_FILL_DRV_MSG_HDR(hdr, dcmd, len) \
+ do { \
+ (hdr)->cmd = (dcmd); \
+ (hdr)->msg_len = (len); \
+ } while (0)
+
+#define USRNL_FILL_MPU_MSG_HDR(hdr, upcmd, len, mod, func_id) \
+ do { \
+ (hdr)->cmd = (upcmd); \
+ (hdr)->msg_len = (len); \
+ (hdr)->module = (mod); \
+ (hdr)->src_func_idx = (func_id); \
+ } while (0)
+
+#define USRNL_FILL_CMDQ_MSG_HDR(hdr, ccmd, len, mod, func_id) \
+ do { \
+ (hdr)->cmd = (ccmd); \
+ (hdr)->msg_len = (len); \
+ (hdr)->module = (mod); \
+ (hdr)->src_func_idx = (func_id); \
+ (hdr)->rsp_type = USRNL_CMDQ_DIRECT; \
+ } while (0)
+
+#endif /* UDK_USRNL_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_vdev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_vdev.h
new file mode 100644
index 000000000..2e968a146
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/urts/udk_vdev.h
@@ -0,0 +1,147 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+ * Description: virtual dev interface
+ * Author: -
+ * Create: 2021.4.19
+ */
+
+#ifndef UDK_VDEV_H
+#define UDK_VDEV_H
+
+#include <sys/queue.h>
+
+#define UDK_DEV_NAME_MAX_LEN 64
+
+struct udk_vdev_driver;
+
+/**
+ * @brief struct udk_vdev_device - udk虚拟设备抽象
+ * @details udk库封装的虚拟设备对象
+ */
+struct udk_vdev_device {
+ TAILQ_ENTRY(udk_vdev_device) next; /**< Next attached vdev */
+ char name[UDK_DEV_NAME_MAX_LEN]; /**< Name of the device. */
+ const struct udk_vdev_driver
+ *driver; /**< Driver assigned after probing */
+ int numa_node; /**< NUMA node connection */
+ char *args;
+};
+
+/**
+ * @brief 加载虚拟设备驱动
+ *
+ * @param[in] dev: udk 虚拟设备
+*
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+typedef int(udk_vdev_probe_t)(struct udk_vdev_device *dev);
+
+/**
+ * @brief 卸载虚拟设备驱动
+ *
+ * @param[in] dev: udk 虚拟设备
+*
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
+ */
+typedef int(udk_vdev_remove_t)(struct udk_vdev_device *dev);
+
+/**
+ * @brief struct udk_vdev_driver - udk虚拟设备驱动对象
+ * @details udk库封装的虚拟设备驱动对象,支持驱动的加载、卸载
+ */
+struct udk_vdev_driver {
+ udk_vdev_probe_t *probe; /**< Virtual device probe function. */
+ udk_vdev_remove_t *remove; /**< Virtual device remove function. */
+};
+
+/**
+ * @brief 获取设备名称
+ *
+ * @param dev udk虚拟设备
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回设备名称
+ */
+static inline const char *
+udk_vdev_device_name(const struct udk_vdev_device *dev)
+{
+ if (dev != NULL) {
+ return dev->name;
+ }
+ return NULL;
+}
+
+/**
+ * @brief 获取驱动加载参数
+ *
+ * @param dev udk虚拟设备
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 返回驱动加载参数
+ */
+static inline const char *
+udk_vdev_device_args(const struct udk_vdev_device *dev)
+{
+ if (dev != NULL) {
+ return dev->args;
+ }
+ return "";
+}
+
+/**
+ * @brief Initialize a driver specified by name.
+ *
+ * @param name The pointer to a driver name to be initialized.
+ * @param args The pointer to arguments used by driver initialization.
+ *
+ * @retval 0 success
+ * @retval negative error
+ */
+int udk_vdev_init(const char *name, const char *args,
+ struct udk_vdev_driver *driver);
+
+/**
+ * @brief Uninitialized a driver specified by name.
+ *
+ * @param name The pointer to a driver name to be uninitialized.
+ *
+ * @retval 0 success
+ * @retval negative error
+ */
+int udk_vdev_uninit(const char *name);
+
+/**
+ * @brief 获取驱动加载状态
+ *
+ * @param dev udk虚拟设备
+ *
+ * @details NA
+ *
+ * @attention: NA
+ *
+ * @return: 描述函数返回值.
+ * @retval 1 已加载
+ * @retval 0 未加载
+ */
+int udk_vdev_is_probed(const struct udk_vdev_device *dev);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_dfx_u_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_dfx_u_api.h
new file mode 100644
index 000000000..4dc0cb0d9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_dfx_u_api.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description: Note that non-dfx versions do not provide the interface.
+ * Create: 2025-11-14 // TODO: 后续使用cmake dfx宏进行文件编译隔离
+ */
+
+#ifndef HRN3_DFX_U_API_H
+#define HRN3_DFX_U_API_H
+
+#include <infiniband/driver.h>
+#include <stdint.h>
+
+enum roce_attack_type {
+ ROCE_ATTACK_DWQE = 0,
+ ROCE_ATTACK_SQDB,
+ ROCE_ATTACK_SOFT_SQDB,
+ ROCE_ATTACK_SOFT_RQDB,
+ ROCE_ATTACK_DWQE_ENTRY,
+ ROCE_ATTACK_INVALID,
+};
+
+struct roce_attack_info {
+ enum roce_attack_type attack_type;
+ uint64_t attack_value;
+ uint64_t attack_mask;
+ uint32_t attack_arr[16];
+};
+
+/**
+ * Post a send work request to the specified QP with attack information.
+ *
+ * @param qp Pointer to the target queue pair (QP).
+ * @param wr Pointer to the send work request to be posted.
+ * @param bad_wr Pointer to a pointer that will be updated with the first failed work request.
+ * @param attack_info Structure containing attack type, value, and mask for injection.
+ * @return
+ * - zero: if success.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int32_t roce5_dfx_post_send_with_attack(struct ibv_qp *qp,
+ struct ibv_send_wr *wr,
+ struct ibv_send_wr **bad_wr,
+ struct roce_attack_info attack_info);
+
+/**
+ * Post a recv work request to the specified QP with attack information.
+ *
+ * @param qp Pointer to the target queue pair (QP).
+ * @param wr Pointer to the recv work request to be posted.
+ * @param bad_wr Pointer to a pointer that will be updated with the first failed work request.
+ * @param attack_info Structure containing attack type, value, and mask for injection.
+ * @return
+ * - zero: if success.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int32_t roce5_dfx_post_recv_with_attack(struct ibv_qp *qp,
+ struct ibv_recv_wr *wr,
+ struct ibv_recv_wr **bad_wr,
+ struct roce_attack_info attack_info);
+#endif /* HRN3_DFX_U_API_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_u_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_u_api.h
new file mode 100644
index 000000000..6bc203270
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hrn5_u_api.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description:
+ * Create: 2022-6-17
+ */
+
+#ifndef HRN3_U_API_H
+#define HRN3_U_API_H
+
+#include <infiniband/driver.h>
+#include <stdint.h>
+
+#define ROCE_QUERY_QPC_BUF_SIZE 512
+#define ROCE_BOND_TX_PORT_MIN 0
+#define ROCE_BOND_TX_PORT_MAX 7
+#define ROCE_UDP_SRC_PORT_MIN 0
+#define ROCE_UDP_SRC_PORT_MAX 65535
+
+struct roce_bond_port_info {
+ int original_port_num;
+ char original_port[8];
+ int rsvd1;
+
+ int alive_port_num;
+ char alive_port[8];
+ int rsvd2;
+};
+
+struct roce_srq_info {
+ int srqn; /* 当前查询srq 序号 */
+ int max_wqe_num; /* srq的队列大小 */
+ int head; /* 可使用的wqe索引 */
+ int tail; /* 最后一个可使用的wqe索引值 */
+ int next_wqe_idx; /* 网卡下一个使用的wqe索引值 */
+ int recv_wqe_num; /* srq中已post的wqe个数 */
+ int completed_wqe_num; /* srq中已完成但未poll的wqe个数 */
+};
+
+/**
+ * Get the bond tx port from a qp.
+ *
+ * @param qp The pointer of qp.
+ * @param[out] tx_port The bond tx port gotten.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_query_qp_tx_port(struct ibv_qp *qp, int *tx_port);
+
+/**
+ * Set the bond tx port from a qp.
+ *
+ * @param qp The pointer of qp.
+ * @param tx_port The bond tx port setted.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_set_qp_tx_port(struct ibv_qp *qp, int tx_port);
+
+/**
+ * Get the bond port information from a ib device.
+ *
+ * @param context The ib device information.
+ * @param[out] bond_port_info The bond port information gotten.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_query_bond_port_info(struct ibv_context *context,
+ struct roce_bond_port_info *bond_port_info);
+
+/**
+ * Set the udp source port from a qp.
+ *
+ * @param qp The pointer of qp.
+ * @param udp_src_port The udp source port setted.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_set_qp_udp_src_port(struct ibv_qp *qp, int udp_src_port);
+
+/**
+ * Get the udp source port from a qp.
+ *
+ * @param qp The pointer of qp.
+ * @param[out] udp_src_port The udp source port gotten.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_query_qp_udp_src_port(struct ibv_qp *qp, int *udp_src_port);
+
+/**
+ * Get the rx port from a qp.
+ *
+ * @param qp The pointer of qp.
+ * @param[out] rx_port The rx port gotten.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_query_qp_rx_port(struct ibv_qp *qp, int *rx_port);
+
+/**
+ * Get the srq information from a srq.
+ *
+ * @param srq The pointer of srq.
+ * @param[out] srq_info The srq information gotten.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_query_srq_entry(struct ibv_srq *srq, struct roce_srq_info *srq_info);
+
+/**
+ * Get the srq container size from a srq.
+ *
+ * @param srq The pointer of srq.
+ * @param[out] srq_container_size The srq container size gotten.
+ * @return
+ * - zero: if successful.
+ * - not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_get_srq_container_size(struct ibv_srq *srq, int *srq_container_size);
+
+/**
+ * Get the version of firmware.
+ *
+ * @param void Do not need any param.
+ * @return
+ * - fw_ver: firmware version.
+ * - ROCE_ERR_VER: the error firmware version.
+ */
+uint64_t roce_query_driver_version(void);
+
+/**
+ * Dump the qp dfx messages to libroce5.log
+ *
+ * @param qp The pointer of qp.
+ * @return void
+ */
+void roce5_dfx_dump(struct ibv_qp *qp);
+
+#endif // HRN3_U_API_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hyper_roce_extend.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hyper_roce_extend.h
new file mode 100644
index 000000000..21854af0f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/hyper_roce_extend.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ *
+ * File Name : roce_uld_api.h
+ * Version : v1.0
+ * Created : 2026/01/01
+ * Last Modified : 2026/01/01
+ * Description : RoCE Upper Layer Driver Kernel API
+ */
+
+#ifndef HYPER_ROCE_EXTEND_H
+#define HYPER_ROCE_EXTEND_H
+
+#include <infiniband/verbs.h>
+
+enum roce_hyper_mode {
+ ROCE_HYPER_MODE_DISABLE,
+ ROCE_HYPER_MODE_UDP,
+ ROCE_HYPER_MODE_AR,
+};
+
+/**
+ * @brief 用户提供的hyper roce特性修改值
+ */
+struct hyper_roce_qp_attr {
+ struct ibv_qp *qp; /**< QP句柄,指向需要修改或查询的QP对象 */
+ uint32_t udp_src_port; /**< 源UDP端口号 */
+ uint32_t type; /**< 高阶RoCE类型,取值范围:enum ibv_hyroce_feature_type */
+ uint32_t version; /**< 高阶RoCE版本,取值范围:enum ibv_hyroce_feature_version */
+ uint32_t sack_enable;
+ /**< 选择性重传开关,0-关闭,1-开启 */ /* 高阶RoCE特性 */
+ uint32_t lb_mode; /**< 负载均衡模式,取值范围:enum ibv_lb_mode 类型 */
+ uint32_t flowlet_pkg_num; /**< 每个子流(flowlet)的包个数,用于流切分 */
+ uint32_t path_num; /**< 多路径的路径个数 */
+ uint32_t interval; /**< UDP端口号递增间隔,用于区分不同路径 */
+ uint32_t path_rr_enable; /**< 路径是否支持轮询(RR)选择网络端口,0-不支持,1-支持 */
+ uint32_t cc_mode; /**< 指示多路径模式 0-single mode,1-path-wise mode,2-connection-wise mode; */
+ uint32_t port_rr_enable; /**< 是否开启网口侧端口轮询(RR)逐包功能,0-关闭,1-开启 */
+ uint32_t srp_range; /**< TX(发送)方向最大重传报文个数 */
+ uint32_t oor_range; /**< RX(接收)方向乱序重传窗口的报文个数 */
+};
+
+/**
+ * @brief Enable hyper roce.
+ *
+ * @param qp The pointer of qp.
+ * @param[in] mode The mode of hyper roce(disable, udp, ar).
+ * @param[in] enable_sack The sack enbale flag.
+ * @return
+ * @retval zero: if successful.
+ * @retval not zero: if the parameter check fail or the cmd executes fail.
+ */
+int roce_set_qp_hyper_mode(struct ibv_qp *qp, enum roce_hyper_mode mode,
+ bool enable_sack);
+
+/**
+ * @brief Modify the hyper_roce feature.
+ *
+ * @param context The ib device information.
+ * @param[in] attr The modification value provided by the user.
+ * @param[in] attr_mask The mask of the feature to be modified.
+ * @return
+ * @retval zero: if successful.
+ * @retval not zero: if the parameter check fail or the cmd executes fail.
+ */
+int hyper_roce_modify_qp_extend(struct ibv_context *context,
+ struct hyper_roce_qp_attr *attr, int attr_mask);
+#endif /* HYPER_ROCE_EXTEND_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_kernel_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_kernel_api.h
new file mode 100644
index 000000000..46f145411
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_kernel_api.h
@@ -0,0 +1,536 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ *
+ * File Name : roce_uld_api.h
+ * Version : v1.0
+ * Created : 2025/09/02
+ * Last Modified : 2025/09/02
+ * Description : RoCE Upper Layer Driver Kernel API
+ */
+
+#ifndef ROCE_ULD_KERNEL_API_H
+#define ROCE_ULD_KERNEL_API_H
+
+#include <rdma/ib_verbs.h>
+#include "base_type.h"
+#include "hinic5_lld.h"
+#include "hmm_common.h"
+
+/* mpt创建模式 */
+typedef enum {
+ ROCE_ULD_MPT_NORMAL = 0,
+ ROCE_ULD_MPT_WITHOUT_MTT = 1
+} ROCE5_MPT_MODE;
+
+typedef void *roce_uld_handle;
+
+/* 设置cos的类型 */
+typedef enum {
+ ROCE5_COS_SET_TYPE_CLASS = 0, /* 通过tclass设置cos值 */
+ ROCE5_COS_SET_TYPE_COS = 1 /* 直接设置cos值 */
+} ROCE5_COS_SET_TYPE;
+
+/* 设置申请mpt xid的模式 */
+typedef enum {
+ ROCE_MPT_XID_SEQUENTIAL = 0, /* 连续申请,默认 */
+ ROCE_MPT_XID_ODD = 1, /* 仅申请奇数xid */
+ ROCE_MPT_XID_EVEN = 2 /* 仅申请偶数xid */
+} ROCE5_MPT_XID_MODE;
+
+/* ------------ 弱函数实现,用户可重载的接口 begin ------------ */
+/**
+ * @brief RoCE 驱动扩展,用于在mr注册获取umem内存失败时,用户定制注册MR行为
+ * @details RoCE对外提供的可重载接口,用于在mr注册获取umem内存失败时,用户定制注册MR行为。
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @see roce5_uld_dereg_user_mr
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_reg_user_mr(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户定制注册MR行为的解注册操作
+ * @details RoCE对外提供的可重载接口,用于用户定制注册MR行为的解注册操作。
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @see roce5_uld_reg_user_mr
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_dereg_user_mr(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户定制qp_modify行为的可扩展操作
+ * @param handle RoCE重载接口上下文句柄
+ * @param attr qp属性修改结构体指针,由调用者申请内存并初始化 @see ib_qp_attr
+ * @param attr_mask qp属性修改掩码 @see ib_qp_attr_mask
+ * @param udata 用户数据结构体指针,由调用者申请内存并初始化 @see ib_udata
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_qp_modify(roce_uld_handle handle, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户ioctl到驱动的总入口
+ * @details RoCE对外提供的可重载接口,用于用户ioctl到驱动的总入口
+ * @param handle RoCE重载接口上下文句柄
+ * @param buf_in 用户传入的输入缓冲区
+ * @param in_size 输入缓冲区的大小
+ * @param buf_out 用于返回结果的输出缓冲区
+ * @param out_size 输出缓冲区的大小
+ * @attention 只支持1825
+ * @see roce5_adm_dfx_uld_extend
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_adm_dfx_uld_extend(roce_uld_handle handle, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动remove时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动remove时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ */
+void roce5_uld_rdev_remove(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动add时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动add时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_rdev_add(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动销毁qp时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动销毁qp时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_qp_destroy(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动创建qp时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动创建qp时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @attention shadow场景,业务需要使用ULD接口对mtt和db_dma_handle需要完整赋值,因为平台不感知shadow场景的queue buffer实际部署位置
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_qp_create(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态接口,获取qp所属port口
+ * @details 用户基于handle,获取qp的port口属性
+ * @param handle RoCE重载接口上下文句柄
+ * @param port 出参,获取port口属性
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_qp_get_port(roce_uld_handle handle, u8 *port);
+
+/**
+ * @brief RoCE内核态 destroy cq前修改进行自定义参数处理
+ * @details RoCE内核态 destroy cq前修改进行自定义参数处理
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @attention shadow_cq场景,平台不感知shadow场景的cq buffer实际部署位置
+ */
+void roce5_uld_cq_destroy(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态 create cq前修改进行自定义参数处理
+ * @details RoCE内核态 create cq前修改进行自定义参数处理
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @attention shadow_cq场景,业务需要使用ULP接口对mtt和db_dma_handle需要完整赋值,因为平台不感知shadow场景的cq buffer实际部署位置
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_cq_create(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户初始化驱动级别的资源
+ * @details RoCE对外提供的可重载接口,用于用户初始化驱动级别的资源
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_service_init(void);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户去初始化驱动级别的资源
+ * @details RoCE对外提供的可重载接口,用于用户去初始化驱动级别的资源
+ * @attention 只支持1825
+ */
+void roce5_uld_service_exit(void);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户获取一个mr需要创建的qp个数
+ * @details RoCE对外提供的可重载接口,用于用户获取一个mr需要创建的qp个数
+ * @param handle RoCE重载接口上下文句柄
+ * @param buf_in 输入参数的缓冲区指针
+ * @param buf_in_len 输入参数缓冲区的长度
+ * @param buf_out 输出参数的缓冲区指针,用于存储查询到的QP数量信息
+ * @param buf_out_len 输出缓冲区的长度
+ * @param buf_out_size 输出参数的大小指针,用于返回实际写入输出缓冲区的数据大小。
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+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);
+/* ------------ 弱函数实现,用户可重载的接口 end ------------ */
+
+/**
+ * @brief 获取注册MR时驱动传下来的虚拟地址
+ * @details 获取注册MR时驱动传下来的虚拟地址
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于0 失败
+ * @retval 其他 虚拟地址
+ */
+u64 roce5_mr_virt_addr_get(roce_uld_handle handle);
+
+/**
+ * @brief 设置注册MR时传递给微码的虚拟地址
+ * @details 设置注册MR时传递给微码的虚拟地址
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_mr_virt_addr_set(roce_uld_handle handle, u64 virt_addr);
+
+/**
+ * @brief 获取注册MR时设置的用户数据
+ * @details 获取注册MR时设置的用户数据
+ * @param handle RoCE重载接口上下文句柄
+ * @param user_data 用户数据指针,由调用者申请内存
+ * @param user_data_len 用户据数据长度
+ * @attention 只支持1825
+ * @retval 大于0 实际获取到的用户数据长度
+ * @retval 其他 执行失败
+ */
+int roce5_mr_user_data_get(roce_uld_handle handle, u8 *user_data,
+ u32 user_data_len);
+
+/**
+ * @brief 创建mpt,并将用户自定义数据存入mr信息中
+ * @details 创建mpt,并将用户自定义数据存入mr信息中,根据mode,指定否创建mtt
+ * @param handle RoCE重载接口上下文句柄
+ * @param mode 指定创建mpt的mode,当前支持0:正常mpt,1:不创建mtt @see ROCE5_MPT_MODE
+ * @param user_data 用户数据指针,如无用户数据,则传入NULL即可
+ * @param user_data_len 用户据数据长度
+ * @param mpt_xid_mode mpt xid负载均衡模式用于匹配的低两位。 @see ROCE5_MPT_XID_MODE
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_mpt_alloc_and_init(roce_uld_handle handle, int mode, u8 *user_data,
+ u32 user_data_len, u32 mpt_xid_mode);
+
+/**
+ * @brief 销毁mpt
+ * @details 销毁mpt
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+void roce5_mpt_destroy(roce_uld_handle handle);
+
+/**
+ * @brief 将mpt数据发送给微码
+ * @details 通过cmdq发送给微码mpt相关信息,会将userdata一同发送给微码进行处理
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_mpt_enable(roce_uld_handle handle);
+
+/**
+ * @brief 获取当前的function id
+ * @details 获取当前的function id
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 大于等于0 实际function id
+ * @retval 小于0 执行失败
+ */
+int roce5_uld_get_func_id(roce_uld_handle handle);
+
+/**
+ * @brief RoCE重载场景下,与mpu的mailbox通信接口
+ * @details RoCE重载场景下,与mpu的mailbox通信接口
+ * @param handle RoCE重载接口上下文句柄
+ * @param cmd 提供给ulp的mailbox命令字
+ * @param buf_in 输入消息缓冲区指针
+ * @param in_size 输入消息大小
+ * @param buf_out 输出消息缓冲区指针
+ * @param out_size 作为输入参数,表示输出消息缓冲区大小,作为输出参数,表示实际输出消息大小
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+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);
+
+/**
+ * @brief RoCE内核态获取roce device中uld自定义结构体空间,大小为64B,不允许越界访问
+ * @details RoCE内核态获取roce device中uld自定义结构体空间
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce device中uld自定义结构体空间指针
+ */
+u8 *roce5_get_rdev_uld_def(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态获取hwdev
+ * @details RoCE内核态获取hwdev
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce device中hwdev结构体空间指针
+ */
+void *roce5_uld_get_rdev_hwdev(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态获取ib_dev
+ * @details RoCE内核态获取ib_dev
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce device中ib_device的结构体指针
+ */
+struct ib_device *roce5_uld_get_rdev_ibdev(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态获取lld_dev
+ * @details RoCE内核态获取lld_dev
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce device中lld_dev结构体指针
+ */
+struct hinic5_lld_dev *roce5_uld_get_rdev_lld_dev(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态查看bond_dev的slave_cnt数
+ * @details RoCE内核态查看bond_dev的slave_cnt数
+ * @param handle RoCE重载接口上下文句柄
+ * @param slave_cnt 出参,返回slave_cnt值
+ * @param bond_en 出参,若未使能bond设备,则slave cnt会置0,bond_en也置0
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_rdev_bond_dev_slave_cnt(roce_uld_handle handle,
+ u32 *slave_cnt, uint8_t *bond_en);
+
+/**
+ * @brief RoCE内核态获取roce qp中uld自定义结构体空间,大小为64B,不允许越界访问
+ * @details RoCE内核态获取roce qp中uld自定义结构体空间
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce qp中uld自定义结构体空间指针
+ */
+u8 *roce5_get_rqp_uld_def(roce_uld_handle handle);
+
+typedef struct {
+ u32 qpn; /* 当前处理的qpn */
+ u32 qp_type; /* 当前处理的qp类型,参考ib_qp_type */
+ u8 *dgid; /* 当前qp对端的dgid */
+} roce_uld_qp_info;
+
+/**
+ * @brief RoCE内核态获取qp info
+ * @details RoCE内核态获取qp info
+ * @param handle RoCE重载接口上下文句柄
+ * @param qp_info 出参获取的qp信息,失败时不做修改
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_qp_info(roce_uld_handle handle, roce_uld_qp_info *qp_info);
+
+/**
+ * @brief RoCE内核态获取roce cq中uld自定义结构体空间,大小为64B,不允许越界访问
+ * @details RoCE内核态获取roce cq中uld自定义结构体空间
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce cq中uld自定义结构体空间指针
+ */
+u8 *roce5_get_rcq_uld_def(roce_uld_handle handle);
+
+/**
+ * @brief RoCE内核态 modify qp前修改tx bond hash attr
+ * @details RoCE内核态 modify qp前修改tx bond hash attr
+ * @param handle RoCE重载接口上下文句柄
+ * @param tx_bond_hash bond端口hash值,仅低4bit有效
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_modify_qp_tx_bond_hash(roce_uld_handle handle, u32 tx_bond_hash);
+
+/**
+ * @brief RoCE内核态 modify qp前修改tclass和cos的值
+ * @details RoCE内核态 modify qp前修改tclass和cos的值
+ * @param handle RoCE重载接口上下文句柄
+ * @param attr modify qp时的属性
+ * @param type 设置cos值的类型 @see ROCE5_COS_SET_TYPE
+ * @param value 具体类型对应的数值
+ * @attention 只支持1825
+ * @attention 类型为tclass时,value由dscp+ecn组成,低2bit为ecn,高6bit为dscp
+ * @attention 类型为cos时,cos范围为0-7
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_cos_set(roce_uld_handle handle, struct ib_qp_attr *attr, u8 type,
+ u8 value);
+
+/**
+ * @brief 判断具体流程中RoCE内核态驱动是否支持某属性
+ * @details 固件获取的能力与驱动的支持能力取交集
+ * @param handle RoCE重载接口上下文句柄
+ * @param feature 具体流程支持的属性
+ * @attention 只支持1825
+ * @retval 等于1 该流程支持某属性
+ * @retval 等于0 该流程不支持某属性
+ */
+int roce5_support_uld_kernel_feature(roce_uld_handle handle, u64 feature);
+
+/**
+ * @brief RoCE内核态 设置mpt xid申请的模式
+ * @details RoCE内核态 设置mpt xid申请的模式
+ * @param handle RoCE重载接口上下文句柄
+ * @param mode 申请mpt xid的模式 @see ROCE5_MPT_XID_MODE
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_set_mpt_xid_mode(roce_uld_handle handle, u8 mode);
+
+/**
+ * @brief RoCE内核态获取当前QP对端的目的GID
+ * @details RoCE内核态获取当前QP对端的目的GID,通过二级指针返回,指向驱动内部内存,调用者不可释放
+ * @param handle RoCE重载接口上下文句柄
+ * @param dgid 出参,dgid内存地址的指针,由驱动内部赋值
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_dgid(roce_uld_handle handle, u8 **dgid);
+
+/**
+ * @brief RoCE内核态modify QP前设置bond端口的tx哈希值
+ * @details RoCE内核态modify QP前设置bond端口的tx哈希值,仅低4bit有效
+ * @param handle RoCE重载接口上下文句柄
+ * @param bond_tx_hash_value bond端口tx哈希值,仅低4bit有效
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_set_bond_tx_hash_value(roce_uld_handle handle,
+ u32 bond_tx_hash_value);
+
+/**
+ * @brief RoCE内核态获取MR中ULD自定义字段的地址和长度
+ * @details RoCE内核态获取MR中ULD自定义字段的地址和长度,通过二级指针返回,指向驱动内部内存,调用者不可释放
+ * @param handle RoCE重载接口上下文句柄
+ * @param self_def 出参,ULD自定义字段内存地址的指针,由驱动内部赋值
+ * @param self_def_len 出参,ULD自定义字段的字节数
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_mr_uld_self_def(roce_uld_handle handle, u8 **self_def,
+ u32 *self_def_len);
+
+/**
+ * @brief RoCE内核态获取MR的RDMA内存区信息
+ * @details RoCE内核态获取当前MR的RDMA内存区信息,通过二级指针返回hmm_rdma结构体,指向驱动内部内存,调用者不可释放
+ * @param handle RoCE重载接口上下文句柄
+ * @param rdmamr_ptr 出参,RDMA内存区信息的结构体指针,由驱动内部赋值,调用者不可释放 @see hmm_rdma
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_rdmamr(roce_uld_handle handle, struct hmm_rdma **rdmamr_ptr);
+
+/**
+ * @brief RoCE内核态设置QP的重传超时时间
+ * @details RoCE内核态设置当前QP属性中的ack_timeout值,暂用于计算侧,待计算方案确认后再回退
+ * @param handle RoCE重载接口上下文句柄
+ * @param ack_to 重传超时时间值,即ack_timeout
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_set_qp_attr_ack_to(roce_uld_handle handle, u32 ack_to);
+
+/**
+ * @brief RoCE内核态获取当前QP的状态
+ * @details RoCE内核态获取当前QP的状态,通过出参返回qp_state值
+ * @param handle RoCE重载接口上下文句柄
+ * @param out_qp_state 出参,当前QP的状态值
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_qp_state(roce_uld_handle handle, u8 *out_qp_state);
+
+/**
+ * @brief RoCE内核态获取设备配置的端口数
+ * @details RoCE内核态获取rdev中配置的端口数量,通过出参返回
+ * @param handle RoCE重载接口上下文句柄
+ * @param out_cfg_num_ports 出参,设备配置的端口数
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_config_num_ports(roce_uld_handle handle,
+ int *out_cfg_num_ports);
+
+/**
+ * @brief RoCE内核态获取MR的内存长度
+ * @details RoCE内核态获取handle中MR对应的内存长度,通过出参返回
+ * @param handle RoCE重载接口上下文句柄
+ * @param length 出参,MR对应的内存长度,单位字节
+ * @attention 只支持1825
+ * @retval 等于0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_get_handle_length(roce_uld_handle handle, u64 *length);
+
+/**
+ * @brief RoCE内核态打印错误日志
+ * @details RoCE内核态打印错误日志,当handle有效时调用ROCE_DEV_ERR输出设备级日志,handle无效时调用ROCE_ERR输出全局日志。
+ * @param handle RoCE重载接口上下文句柄,可为NULL
+ * @param fmt 格式化字符串
+ * @param ... 格式化参数
+ * @attention 只支持1825
+ */
+#define roce5_uld_print_kernel_err(handle, fmt, ...) \
+ roce5_uld_print_kernel_err_impl(handle, __func__, __LINE__, fmt, \
+ ##__VA_ARGS__)
+
+void roce5_uld_print_kernel_err_impl(roce_uld_handle handle, const char *func,
+ int line, const char *fmt, ...);
+
+#endif /* ROCE_ULD_KERNEL_API_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_user_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_user_api.h
new file mode 100644
index 000000000..dd0d8d3fb
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/roce/roce_uld_user_api.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ *
+ * File Name : roce_uld_api.h
+ * Version : v1.0
+ * Created : 2025/09/02
+ * Last Modified : 2025/09/02
+ * Description : RoCE Upper Layer Driver User API
+ */
+
+#ifndef ROCE_ULD_USER_API_H
+#define ROCE_ULD_USER_API_H
+
+#include <infiniband/verbs.h>
+
+typedef void *roce_uld_handle;
+
+#define ROCE_WR_OPCODE_BASE_MASK 0xFF
+#define ROCE_WR_OPCODE_BASE_GET(opcode) ((opcode)&ROCE_WR_OPCODE_BASE_MASK)
+#define ROCE_WR_OPCODE_OVERLAY_OFFSET 8
+#define ROCE_WR_OPCODE_OVERLAY_GET(opcode) \
+ ((opcode) >> ROCE_WR_OPCODE_OVERLAY_OFFSET)
+#define ROCE_WR_OPCODE_OVERLAY_SET(overlay_op) \
+ ((overlay_op) << ROCE_WR_OPCODE_OVERLAY_OFFSET)
+/* 叠加功能的opcode */
+#define ROCE_WR_OVERLAY_INLINE_REDUCE_OP 1
+#define ROCE_WR_OVERLAY_MAX_OP 8
+
+/* 1825支持的扩展opcode定义 */
+typedef enum {
+ /* 0-63 预留兼容标准ib的opcode */
+ ROCE_WR_FLUSH = 64, /* david场景下的flush */
+
+ ROCE_WR_BASE_EXTEND_BUTT = 255, /* 基础功能范围 0~255 */
+
+ /* 叠加功能区域 占用bit8-bit11 */
+ ROCE_WR_INLINE_REDUCE_OVER_WRITE =
+ (ROCE_WR_OPCODE_OVERLAY_SET(ROCE_WR_OVERLAY_INLINE_REDUCE_OP) |
+ IBV_WR_RDMA_WRITE),
+ ROCE_WR_INLINE_REDUCE_OVER_WRITE_WITH_IMM =
+ (ROCE_WR_OPCODE_OVERLAY_SET(ROCE_WR_OVERLAY_INLINE_REDUCE_OP) |
+ IBV_WR_RDMA_WRITE_WITH_IMM),
+
+ ROCE_WR_OVERLAY_OPCODE_BUTT =
+ ROCE_WR_OPCODE_OVERLAY_SET(ROCE_WR_OVERLAY_MAX_OP),
+} ROCE_WR_OPCODE;
+
+/* ------------ 弱函数实现,用户可重载的接口 begin ------------ */
+/**
+ * @brief RoCE 驱动扩展,用于用户定制post_send时的wqe处理操作
+ * @details RoCE对外提供的可重载接口,用于用户定制post_send时的wqe处理操作
+ * @param wqe_handle 本次wqe的句柄,用于用户在重载函数中对wqe进行操作
+ * @param wr 用户发送的wr
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_post_send_handle_wqe(roce_uld_handle wqe_handle,
+ struct ibv_send_wr *wr);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动销毁qp时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动销毁qp时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ */
+void roce5_uld_qp_destroy(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动创建qp时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动创建qp时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0 执行成功
+ * @retval 其他 执行失败
+ */
+int roce5_uld_qp_create(roce_uld_handle handle);
+
+/**
+ * @brief RoCE 驱动扩展,用于用户在驱动重置qp时的自定义操作
+ * @details RoCE对外提供的可重载接口,用于用户在驱动重置qp时的自定义操作
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ */
+void roce5_uld_qp_2rst(roce_uld_handle handle);
+/* ------------ 弱函数实现,用户可重载的接口 end ------------ */
+
+/**
+ * @brief 定制post_send时的wqe处理操作,对wqe task段填入一个4B的自定义值
+ * @details 定制post_send时的wqe处理操作,对wqe task段填入一个4B的自定义值,在微码处理wqe时获取处理
+ * @param wqe_handle 本次wqe的句柄,用于用户在重载函数中对wqe进行操作
+ * @param data 用户自定义值
+ * @attention 只支持1825
+ * @retval 无
+ */
+void roce5_uld_wqe_task_set(roce_uld_handle wqe_handle, uint32_t data);
+
+/**
+ * @brief RoCE用户态获取roce qp中uld自定义结构体空间,大小为64B,不允许越界访问
+ * @details RoCE用户态获取roce qp中uld自定义结构体空间
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于NULL 获取失败
+ * @retval 非NULL roce qp中uld自定义结构体空间指针
+ */
+uint8_t *roce5_get_rqp_uld_def(roce_uld_handle handle);
+
+/**
+ * @brief RoCE用户态获取roce qp中ibv_qp_type
+ * @details RoCE用户态获取roce qp中ibv_qp_type
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 0表示成功获取
+ * @retval 非0表示获取ibv_qp_type失败
+ */
+int roce5_get_rqp_ibv_qp_type(roce_uld_handle handle,
+ enum ibv_qp_type *qp_type);
+
+/**
+ * @brief RoCE用户态设置wqe task段的tsl字段
+ * @details RoCE用户态设置wqe task段的tsl字段
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @attention task_len以8B为单位,最大不超过0x1F。
+ * @attention 单个wqe设置时不能重复调用
+ * @retval 无
+ */
+void roce5_wqe_ctrl_tsl_set(roce_uld_handle handle, uint8_t task_len);
+
+/**
+ * @brief RoCE用户态设置wqe task段的cl字段
+ * @details RoCE用户态设置wqe task段的cl字段
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @attention cqe_len以8B为单位,最大不超过0xF,通常为1
+ * @attention 单个wqe设置时不能重复调用
+ * @retval 无
+ */
+void roce5_wqe_ctrl_cl_set(roce_uld_handle handle, uint8_t cqe_len);
+
+/**
+ * @brief 判断具体流程中RoCE用户态驱动是否支持某属性
+ * @details 由内核态传入的固件获取的能力与驱动的支持能力取交集
+ * @param handle RoCE重载接口上下文句柄
+ * @param feature 具体流程支持的属性
+ * @attention 只支持1825
+ * @retval 等于1 该流程支持某属性
+ * @retval 等于0 该流程不支持某属性
+ */
+int roce5_support_uld_user_feature(roce_uld_handle handle, uint64_t feature);
+
+/**
+ * @brief 根据ibv_qp或者context构造用户态handle值,二者不同时为NULL,可以有一个为NULL
+ * @details 优先使用ibv_qp构造handle,若上层只有ibv_context信息,则基于ibv_context构造handle
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于0,表示handle构造完成
+ */
+int roce5_uld_construct_handle(roce_uld_handle *handle, struct ibv_qp *qp,
+ struct ibv_context *context);
+
+/**
+ * @brief 释放用户创建的handle
+ * @details 释放用户通过construct构造出来的handle
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于0,表示handle已经释放
+ */
+int roce5_uld_destroy_handle(roce_uld_handle *handle);
+
+/**
+ * @brief 提供uld接口,使用netlink跨态
+ * @param handle RoCE重载接口上下文句柄
+ * @attention 只支持1825
+ * @retval 等于0,用户命令字下发成功
+ */
+int roce5_uld_do_driver_cmd(roce_uld_handle handle, void *buf_in,
+ size_t buf_in_len, void *buf_out,
+ size_t buf_out_len);
+
+/**
+ * @brief roce用户态post send函数
+ * @param ibv_qp OFED 用户态qp数据结构
+ * @param wr 用户下发的wr链
+ * @param bad_wr,出参,如果wr链上的wr有问题,返回有问题的wr
+ */
+int32_t roce5_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr,
+ struct ibv_send_wr **bad_wr);
+
+/**
+ * @brief 上层uld handle函数使用申请和释放次数,debug功能
+ */
+void roce5_uld_debug_alloc_destroy_cnt(void);
+/**
+ * @brief RoCE用户态打印错误日志
+ * @details RoCE用户态打印错误日志,当handle有效时调用LOG_ROCE_DEV_ERR输出设备级日志,handle无效时调用LOG_ROCE_ERR输出全局日志。
+ * @param handle RoCE重载接口上下文句柄,可为NULL
+ * @param fmt 格式化字符串
+ * @param ... 格式化参数
+ * @attention 只支持1825
+ */
+#define roce5_uld_print_user_err(handle, fmt, ...) \
+ roce5_uld_print_user_err_impl(handle, __func__, __LINE__, fmt, \
+ ##__VA_ARGS__)
+
+void roce5_uld_print_user_err_impl(roce_uld_handle handle, const char *func,
+ int line, const char *fmt, ...);
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ccp/ccp_algo_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ccp/ccp_algo_format.h
new file mode 100644
index 000000000..77a51c2db
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ccp/ccp_algo_format.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: CCP数据结构
+ * Create: 2025-06
+ */
+
+#ifndef CCP_ALGO_FORMAT_H
+#define CCP_ALGO_FORMAT_H
+
+/******************************************************************************
+ CCP算法枚举
+******************************************************************************/
+#define CCP_CC_ALGO_DCQCN 0
+#define CCP_CC_ALGO_LDCP 1
+#define CCP_CC_ALGO_IPQCN 2
+#define CCP_CC_ALGO_MIBO 3
+#define CCP_CC_ALGO_CAQM 4
+#define CCP_CC_ALGO_USER_A 6
+#define CCP_CC_ALGO_USER_B 7
+#define CCP_CC_ALGO_MAX 8 /**< 最大8种算法 */
+
+#define CCP_SERVICE_ROCE 0
+#define CCP_SERVICE_UB 1
+#define CCP_SERVICE_UBC 2
+#define CCP_SERVICE_HYPERROCE 3
+#define CCP_SERVICE_MAX 4
+
+#define CCP_ALGO_MODE_CWND 0
+#define CCP_ALGO_MODE_RATE 1
+
+#define CCP_DCQCN_VERSION_BASE 0
+#define CCP_DCQCN_VERSION_UBCNET 1
+
+/* SML LT
+ * FPGA/ESL-PV
+ * COMM: |--RoCE 4*16B--|--UB 8*16B--|--UBC 1*16B--|
+ * ALGO: |--RoCE 4*8*16B--|--UB 8*8*16B--|--UBC 16*16B--|
+ * ASIC
+ * COMM: |--RoCE 32*16B--|--UB 8*16B--|--UBC 1*16B--|
+ * ALGO: |--RoCE 32*8*16B--|--UB 8*8*16B--|--UBC 16*16B--|
+ */
+#if (defined(PLATFORM_MODE_ESL_PV) || defined(HI1823V200))
+#define CCP_MAX_FUNC_NUM 4
+#elif defined(PLATFORM_MODE_FPGA)
+#define CCP_MAX_FUNC_NUM 8
+#else
+#define CCP_MAX_FUNC_NUM 32 // 扩充SML表资源需要修改
+#endif
+
+#define CCP_COMM_PARA_ROCE_NUM CCP_MAX_FUNC_NUM
+#define CCP_COMM_PARA_UB_NUM 8
+#define CCP_COMM_PARA_UBC_NUM 1
+#define CCP_ALGO_PARA_ROCE_NUM (CCP_MAX_FUNC_NUM * 8)
+#define CCP_ALGO_PARA_UB_NUM (CCP_COMM_PARA_UB_NUM * 8)
+#define CCP_ALGO_PARA_UBC_NUM 16
+
+#define CCP_COMM_PARA_UB_OFST CCP_COMM_PARA_ROCE_NUM
+#define CCP_COMM_PARA_UBC_OFST (CCP_COMM_PARA_UB_OFST + CCP_COMM_PARA_UB_NUM)
+#define CCP_ALGO_PARA_ROCE_OFST (CCP_COMM_PARA_UBC_OFST + CCP_COMM_PARA_UBC_NUM)
+#define CCP_ALGO_PARA_UB_OFST (CCP_ALGO_PARA_ROCE_OFST + CCP_ALGO_PARA_ROCE_NUM)
+#define CCP_ALGO_PARA_UBC_OFST (CCP_ALGO_PARA_UB_OFST + CCP_ALGO_PARA_UB_NUM)
+#define CCP_PARA_NUM_MAX (CCP_ALGO_PARA_UBC_OFST + CCP_ALGO_PARA_UBC_NUM)
+
+#define CCP_LT_GET_INDEX(index_h, index_l) (((index_h) << 3) | (index_l))
+#define CCP_ROCE_ALGO_GET_INDEX(pf_id, algo_id) \
+ (CCP_LT_GET_INDEX(pf_id, algo_id) + CCP_ALGO_PARA_ROCE_OFST)
+#define CCP_UB_ALGO_GET_INDEX(algo_id, param_id) \
+ (CCP_LT_GET_INDEX(algo_id, param_id) + CCP_ALGO_PARA_UB_OFST)
+#define CCP_UBC_ALGO_GET_INDEX(param_id) ((param_id) + CCP_ALGO_PARA_UBC_OFST)
+
+#define CCP_COMM_PARAM_INDEX_GET(type, ccp_param_idx, algo_id) \
+ ((type) == CCP_SERVICE_ROCE ? \
+ (ccp_param_idx) : \
+ ((type) == CCP_SERVICE_UB ? \
+ ((algo_id) + CCP_COMM_PARA_UB_OFST) : \
+ CCP_COMM_PARA_UBC_OFST))
+
+#define CCP_COMM_PARAM_INDEX_VALID(type, ccp_param_idx, algo_id) \
+ ((type) == CCP_SERVICE_ROCE ? \
+ ((ccp_param_idx) < CCP_COMM_PARA_ROCE_NUM) : \
+ ((type) == CCP_SERVICE_UB ? \
+ ((algo_id) < CCP_COMM_PARA_UB_NUM) : \
+ ((type) == CCP_SERVICE_UBC ? 1 : 0)))
+
+#define CCP_ALGO_PARAM_INDEX_GET(type, ccp_param_idx, algo_id, param_id) \
+ ((type) == CCP_SERVICE_ROCE ? \
+ CCP_ROCE_ALGO_GET_INDEX(ccp_param_idx, algo_id) : \
+ ((type) == CCP_SERVICE_UB ? \
+ CCP_UB_ALGO_GET_INDEX(algo_id, param_id) : \
+ CCP_UBC_ALGO_GET_INDEX(param_id)))
+
+#define CCP_ALGO_PARAM_INDEX_VALID(type, ccp_param_idx, algo_id, param_id) \
+ ((type) == CCP_SERVICE_ROCE ? \
+ (CCP_LT_GET_INDEX((ccp_param_idx), (algo_id)) < \
+ CCP_ALGO_PARA_ROCE_NUM) : \
+ ((type) == CCP_SERVICE_UB ? \
+ (CCP_LT_GET_INDEX((algo_id), (param_id)) < \
+ CCP_ALGO_PARA_UB_NUM) : \
+ ((type) == CCP_SERVICE_UBC ? \
+ ((param_id) < CCP_ALGO_PARA_UBC_NUM) : \
+ 0)))
+
+#define CCP_SML_CTX_XID(service_type, xid) \
+ (((service_type) == CCP_SERVICE_ROCE ? CCP_SML_CTX_ROCE_OFFSET : \
+ CCP_SML_CTX_UBC_OFFSET) + \
+ (xid))
+
+/* roce dcqcn与ipqcn的算法参数结构 */
+typedef struct ccp_dcqcn_ipqcn_para {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 12;
+ u32 min_rate : 12;
+ u32 token_period : 8;
+#else
+ u32 token_period : 8; /* token更新周期,1825无需本参数,考虑1823兼容性保留 */
+ u32 min_rate : 12; /* 最小发送速率,MBps, 支持[0, 4GBps] */
+ u32 rsvd : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rate_inc_period : 10; /* 增速的周期,us */
+ u32 rsvd1 : 7;
+ u32 alpha_dec_period : 10; /* α的更新周期,us */
+ u32 rsvd0 : 5;
+#else
+ u32 rsvd0 : 5;
+ u32 alpha_dec_period : 10; /* α的更新周期,us */
+ u32 rsvd1 : 7;
+ u32 rate_inc_period : 10; /* 增速的周期,us */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rate_inc_ai : 8;
+ u32 rate_inc_hai : 8;
+ u32 rate_dec_period : 8;
+ u32 min_cnp_period : 8;
+#else
+ u32 min_cnp_period : 8; /* cnp聚合周期,接收端参数,us */
+ u32 rate_dec_period : 8; /* 降速的周期,us */
+ u32 rate_inc_hai : 8; /* 超快速增长的时候使用的参数,MBps */
+ u32 rate_inc_ai : 8; /* 加性增长的时候使用的参数,MBps */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 gita_shift : 4;
+ u32 rate_target_clamp : 1;
+ u32 rsvd : 1;
+ u32 initial_alpha : 10;
+ u32 rate_first_set : 16;
+#else
+ u32 rate_first_set : 16; /* 首次降速时配置的速率,MBps */
+ u32 initial_alpha : 10; /* 首次降速时配置的alpha */
+ u32 rsvd : 1;
+ u32 rate_target_clamp : 1; /* 特性flag:置位时,连续收到cnp,每次cnp都调整rate_target; 不置位时,仅首次cnp调整rate_target */
+ u32 gita_shift : 4; /* gita偏移, α更新参数 */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+} ccp_dcqcn_ipqcn_para_s;
+
+typedef ccp_dcqcn_ipqcn_para_s ccp_dcqcn_para_s;
+typedef ccp_dcqcn_ipqcn_para_s ccp_ipqcn_para_s;
+
+/* ubc dcqcn的算法参数结构 */
+typedef struct ccp_dcqcn_ubcnet_para {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tkp_shift : 8;
+ u32 fast_recovery_thr : 8;
+ u32 ai : 16;
+#else
+ u32 ai : 16; /* additive_increase,Mbps,加性增长的时候使用的参数 */
+ u32 fast_recovery_thr : 8; /* 快速恢复增速的步数阈值 */
+ u32 tkp_shift : 8; /* token更新周期偏移 */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 alpha_dec_period : 16;
+ u32 min_rate_shift : 8;
+ u32 rate_inc_period_shift : 8;
+#else
+ u32 rate_inc_period_shift : 8; /* 速率的更新周期偏移,period = 1 << shift */
+ u32 min_rate_shift : 8; /* 最小速率的移位,粒度Mbps,有效范围[0, 31] */
+ u32 alpha_dec_period : 16; /* α的更新周期,us */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 max_rate : 32;
+#else
+ u32 max_rate : 32; /* 最大速率,Mbps */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 alpha_max_shift : 8;
+ u32 rate_dec_period : 8;
+ u32 alpha_min : 8;
+ u32 gita_shift : 8;
+#else
+ u32 gita_shift : 8; /* gita偏移,α更新参数,gita = 1 / (1 << g_shift) */
+ u32 alpha_min : 8; /* 定义α的最小值 */
+ u32 rate_dec_period : 8; /* 处理cnp减速的周期,us */
+ u32 alpha_max_shift : 8; /* α最大值的偏移,初始alpha = alpha_max - 1 */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+} ccp_dcqcn_ubcnet_para_s;
+
+/* dcqcn算法的公共上下文 */
+typedef struct ccp_algo_dcqcn_ctx {
+ u32 algo_ctx_value[7]; /* 算法内部使用的ctx信息 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 version : 1; /* 0:base版本; 1:ubc_net版本 */
+ u32 rsvd : 31;
+#else
+ u32 rsvd : 31;
+ u32 version : 1;
+#endif
+ };
+ u32 dw7_value;
+ };
+} ccp_algo_dcqcn_ctx_s;
+
+typedef struct ccp_ldcp_para {
+ u32 rsvd0[2]; /* 预留8B,与1823版本兼容需要 */
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u8 wnd_min; /* 粒度为8B,减1配置 */
+ u8 init_wnd; /* 粒度为MTU/4,减1配置 */
+ u8 alpha; /* MTU/16粒度,减1配置 */
+ u8 beta; /* 粒度为MTU/32,减1配置 */
+#else
+ u8 beta;
+ u8 alpha;
+ u8 init_wnd;
+ u8 wnd_min;
+#endif
+ };
+ u32 dw2_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u8 gamma; /* 粒度为4B,减1配置 */
+ u8 eta; /* 粒度1/256,减1配置 */
+ u16 rsvd1;
+#else
+ u16 rsvd1;
+ u8 eta;
+ u8 gamma;
+#endif
+ };
+ u32 dw3_value;
+ };
+} ccp_ldcp_para_s;
+
+typedef struct ccp_caqm_para {
+ u32 rsvd0[2]; /* 预留8B,与1823版本兼容需要 */
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u8 wnd_min;
+ u8 init_wnd;
+ u8 alpha;
+ u8 beta;
+#else
+ u8 beta;
+ u8 alpha;
+ u8 init_wnd;
+ u8 wnd_min;
+#endif
+ };
+ u32 dw2_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u8 cc_unit;
+ u8 eta;
+ u16 rsvd1;
+#else
+ u16 rsvd1;
+ u8 eta;
+ u8 cc_unit;
+#endif
+ };
+ u32 dw3_value;
+ };
+} ccp_caqm_para_s;
+
+typedef struct ccp_comm_param {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 bypass : 2; /* 0-非bypass,1-不设置协议bypass,2-配置协议bypass */
+ u32 algo_mode : 1; /* 算法模式:0-cwnd,1-rate */
+ u32 hdr_type : 3; /* 报文头类型:0-ldcp/1-caqm/2-ext_hdr */
+ u32 flow_ctrl_unit : 2; /* 流控单元:0-single qp,1-ip */
+ u32 tx_send_byte_en : 1; /* 协议维护数据发送量(自增长绝对值) */
+ u32 rtt_mode : 3; /* rtt采集方式:0-protocol/1-IFA */
+ u32 algo_ctx_size : 1; /* 算法上下文大小:0-32Byte/1-48Byte */
+ u32 ecn_cnp_en : 1; /* 收到ecn是否要发RX事件让框架回CNP */
+ u32 cnp_period : 8; /* 框架回CNP的周期 */
+ u32 cnp_prio_enable : 1; /* CNP是否走单独的cos和优先级 */
+ u32 cnp_cos : 3; /* CNP敲doorbell使用的cos */
+ u32 cnp_prio : 3; /* CNP走的优先级 */
+ u32 rtt_req_event_mode : 1; /* rtt_req_event_mode default:0 0:disable 1:enable */
+ u32 rsvd : 2;
+#else
+ u32 rsvd : 2;
+ u32 rtt_req_event_mode : 1;
+ u32 cnp_prio : 3;
+ u32 cnp_cos : 3;
+ u32 cnp_prio_enable : 1;
+ u32 cnp_period : 8;
+ u32 ecn_cnp_en : 1;
+ u32 algo_ctx_size : 1;
+ u32 rtt_mode : 3;
+ u32 tx_send_byte_en : 1;
+ u32 flow_ctrl_unit : 2;
+ u32 hdr_type : 3;
+ u32 algo_mode : 1;
+ u32 bypass : 2;
+
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rtt_rsp_prio_enable : 1; /* RTT是否走单独的cos和优先级 */
+ u32 rtt_rsp_prio : 3; /* RTT走的优先级 */
+ u32 slow_path_psn_threshold : 8;
+ u32 rsvd : 20;
+#else
+ u32 rsvd : 20;
+ u32 slow_path_psn_threshold : 8;
+ u32 rtt_rsp_prio : 3;
+ u32 rtt_rsp_prio_enable : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+ u32 rsvd[2];
+} ccp_comm_param_s;
+
+typedef union ccp_algo_param {
+ ccp_dcqcn_ubcnet_para_s dcqcn_ubcnet;
+ ccp_dcqcn_para_s dcqcn;
+ ccp_ipqcn_para_s ipqcn;
+ ccp_ldcp_para_s ldcp;
+ ccp_caqm_para_s caqm;
+ u32 dw[16];
+} ccp_algo_param_u;
+#endif /* CCP_ALGO_FORMAT_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/hmm_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/hmm_cmd_defs.h
new file mode 100644
index 000000000..d9a11c2b7
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/hmm_cmd_defs.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2030. All rights reserved.
+ * Description : hmm cmd define
+ * Author : /
+ * Create : 2025/11/21
+ * Notes :
+ * History : None
+ */
+#ifndef HMM_CMD_DEFS_H
+#define HMM_CMD_DEFS_H
+
+/**
+ * @brief enum rdma_hmm_cmd
+ * @details 此枚举类型定义了RDMA HMM模块中使用的各种命令代码
+ */
+enum rdma_hmm_cmd {
+ RDMA_CMD_SW2HW_MPT =
+ 0x70, /**< 将软件的多路径项(MPT)转换为硬件的多路径项 */
+ RDMA_CMD_HW2SW_MPT = 0x71, /**< 将硬件的多路径项转换为软件的多路径项 */
+ RDMA_CMD_MODIFY_MPT = 0x72, /**< 修改多路径项 */
+ RDMA_CMD_QUERY_MPT = 0x73, /**< 查询多路径项 */
+ RDMA_CMD_FLUSH_TPT = 0x74, /**< 刷新传输页表项 */
+ RDMA_CMD_SYNC_TPT = 0x75 /**< 同步传输页表项 */
+};
+
+#define HMM_RDMA_USER_DATA_LENGTH 6 // mr_attr userdata段大小
+#define DAVID_PATH_MAX_NUM 0x4 // 单个david和dpu总线侧最大路径数
+
+#pragma pack(4)
+typedef struct tag_hmm_verbs_cmd_header {
+ union {
+ u32 value;
+
+ struct {
+ u32 version : 8;
+ u32 sub_cmd : 8;
+ u32 cmd_bitmask : 16; // CMD_TYPE_BITMASK_E
+ } bs;
+ } dw0;
+
+ u32 index; // qpn/cqn/srqn/mpt_index/gid idx
+
+ u32 opt;
+
+ union {
+ u32 value;
+
+ struct {
+ u32 cmd_type : 8;
+ u32 rsvd : 7;
+ u32 seg_ext : 1;
+ u32 cmd_len : 16; // verbs cmd total len(include cmd_com),unit:byte
+ } bs;
+ } dw3;
+} hmm_verbs_cmd_header_s;
+
+typedef struct tag_hmm_verbs_mr_attr {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 buf_page_size : 4; /* Page_size of the buffer */
+ u32 mtt_layer_num : 3; /* Mtt level */
+ u32 mtt_page_size : 4; /* Page_size of mtt */
+ u32 rsvd2 : 3;
+ u32 david_en : 1;
+ u32 zbva : 1; /* The value 1 indicates that ZBVA is supported, that is, iova = 0. */
+ u32 access_lr : 1; /* 1: Indicates that the local read permission is supported. */
+ u32 access_lw : 1; /* The value 1 indicates that the local write permission is supported. */
+ u32 access_rr : 1; /* 1: Indicates that the remote read permission is supported. */
+ u32 access_rw : 1; /* 1: The remote write permission is supported. */
+ u32 access_ra : 1; /* The value 1 indicates that the remote Atomic permission is supported. */
+ u32 bpd : 1; /* 1: Bound to pd */
+ u32 bqp : 1; /* 1: Bound to qp */
+ u32 dif_mode : 1;
+ u32 rkey : 1;
+ u32 pa : 1; /* Flag bit of DMA_MR */
+ u32 r_w : 1; /* Mr or mw. The value 1 indicates MR, and the value 0 indicates MW. */
+ u32 remote_invalid_en : 1; /* Indicates whether to support the remote INVALID operation. */
+ u32 invalid_en : 1; /* Indicates whether to support the INVALID operation. */
+ u32 fast_reg_en : 1; /* Indicates whether the FRMR operation is supported. */
+ u32 remote_access_en : 1; /* Indicates whether the FRMR can specify remote rights. */
+ u32 access_bind : 1; /* Whether the mr supports the binding of the mw */
+#else
+ u32 access_bind : 1; /* Whether the mr supports the binding of the mw */
+ u32 remote_access_en : 1; /* Indicates whether the FRMR can specify remote rights. */
+ u32 fast_reg_en : 1; /* Indicates whether the FRMR operation is supported. */
+ u32 invalid_en : 1; /* Indicates whether to support the INVALID operation. */
+ u32 remote_invalid_en : 1; /* Indicates whether to support the remote INVALID operation. */
+ u32 r_w : 1; /* Mr or mw */
+ u32 pa : 1; /* Flag bit of DMA_MR */
+ u32 rkey : 1;
+ u32 dif_mode : 1;
+ u32 bqp : 1; /* 1: Bound to qp */
+ u32 bpd : 1; /* 1: Bound to pd */
+ u32 access_ra : 1; /* The value 1 indicates that the remote Atomic permission is supported. */
+ u32 access_rw : 1; /* 1: The remote write permission is supported. */
+ u32 access_rr : 1; /* 1: Indicates that the remote read permission is supported. */
+ u32 access_lw : 1; /* The value 1 indicates that the local write permission is supported. */
+ u32 access_lr : 1; /* 1: Indicates that the local read permission is supported. */
+ u32 zbva : 1; /* The value 1 indicates that ZBVA is supported, that is, iova = 0. */
+ u32 david_en : 1;
+ u32 rsvd2 : 3;
+ u32 mtt_page_size : 4; /* Page_size of mtt */
+ u32 mtt_layer_num : 3; /* Number of mtt levels */
+ u32 buf_page_size : 4; /* Page_size of the buffer */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 so_ro : 2;
+ u32 dma_attr_idx : 6;
+ u32 sector_size : 1;
+ u32 ep : 3;
+ u32 qpn : 20;
+#else
+ u32 qpn : 20; /* Qp bound to mw */
+ u32 ep : 3;
+ u32 sector_size : 1; /* 0:512B, 1:4KB */
+ u32 dma_attr_idx : 6; /* Dma attribute index */
+ u32 so_ro : 2; /* Dma order-preserving flag */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 status : 4;
+ u32 indirect_mr : 1;
+ u32 cos : 3;
+ u32 block_size : 6;
+ u32 pdn : 18;
+#else
+ u32 pdn : 18; /* Pd bound to mr or mw */
+ u32 block_size : 6; /* 2^(page_size+12) + 8*block_size */
+ u32 cos : 3;
+ u32 indirect_mr : 1;
+ u32 status : 4; /* Mpt status. Valid values are VALID, FREE, and INVALID. */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 mkey : 8;
+ u32 sw_dif_en : 1;
+ u32 page_mode : 1;
+ u32 fbo : 22;
+#else
+ u32 fbo : 22;
+ u32 page_mode : 1;
+ u32 sw_dif_en : 1;
+ u32 mkey : 8; /* The index is not included. */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4~5 */
+ union {
+ u64 iova; /* Start address of mr or mw */
+ struct {
+ u32 iova_hi; /* Upper 32 bits of the start address of mr or mw */
+ u32 iova_lo; /* Lower 32 bits of the start address of mr or mw */
+ } dw4;
+ };
+
+ /* DW6~7 */
+ union {
+ u64 length; /* Length of mr or mw */
+ struct {
+ u32 length_hi; /* Length of mr or mw */
+ u32 length_lo; /* Length of mr or mw */
+ } dw6;
+ };
+
+ /* DW8~9 */
+ union {
+ u64 mtt_base_addr; /* Mtt base address (pa),low 3bits(gpa_sign) */
+ struct {
+ u32 mtt_base_addr_hi; /* Mtt base address (pa) upper 32 bits */
+ u32 mtt_base_addr_lo; /* Lower 32 bits of mtt base address (pa),low 3bits(gpa_sign) */
+ } dw8;
+ };
+
+ /* DW10 */
+ union {
+ u32 mr_mkey; /* This parameter is valid for MW. */
+ u32 mw_cnt; /* This parameter is valid when the MR is used. */
+ };
+
+ /* DW11 */
+ u32 mtt_sz;
+
+ /* DW12~17 */
+ u32 userdata[HMM_RDMA_USER_DATA_LENGTH];
+} hmm_verbs_mr_attr_s;
+
+typedef struct tag_hmm_verbs_mtt_cacheout_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 */
+} hmm_verbs_mtt_cacheout_info_s;
+#pragma pack()
+
+typedef struct tag_hmm_uni_cmd_mpt_hw2sw {
+ hmm_verbs_cmd_header_s com;
+ hmm_verbs_mtt_cacheout_info_s dmtt_cache;
+} hmm_uni_cmd_mpt_hw2sw_s;
+
+typedef struct tag_hmm_uni_cmd_sw2hw_mpt {
+ hmm_verbs_cmd_header_s com;
+ hmm_verbs_mr_attr_s mr_attr;
+} hmm_uni_cmd_mpt_sw2hw_s;
+
+#define HMM_CMDQ_CREAT_MR_LOAD_PERMISSION_SPF global_spram_f11
+#define HMM_CMDQ_CREAT_MR_LOAD_PERMISSION_SPF_ID 11
+
+#define HMM_CMDQ_CREAT_MR_LOAD_TID_FE_SPF global_spram_f6
+#define HMM_CMDQ_CREAT_MR_LOAD_TID_FE_SPF_ID 6
+
+typedef struct {
+ u16 rsvd0 : 1;
+ u16 ubc_port_id : 3; /* 当前port_id,用于选取oq_id, 并不要求和端口号严格对应 */
+ u16 david_ue_id : 12; /* 分配给当前David的逻辑上第一个UBC port口的fe */
+} david_port_ue_s;
+
+/**
+ * @brief struct mptc_david - david fe信息
+ * @details david直通场景需要mptc携带david fe等相关信息
+ */
+typedef struct mptc_david {
+ /* DW0 ~ DW1 */
+ david_port_ue_s david_port_ue[DAVID_PATH_MAX_NUM];
+
+ struct {
+ u32 david_en : 1; /* 标识当前func是否具有david直通能力,使能后可以不走david */
+ u32 at_flag : 1; /* 用于记录使用TID0还是使用TID1 */
+ u32 rsvd4 : 2;
+ u32 active_port_num : 4; /* 当前有效的UBC Port平面个数 */
+ u32 rsvd5 : 2;
+ u32 david_id : 6; /* 模板表中的david id,表示当前David在PoD内统一编号,用于对不同david做OQ限速 */
+ u32 rsvd6 : 16;
+ } dw2;
+} mptc_david_s;
+#endif /* HMM_CMD_DEFS_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/qos_base_mpu_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/qos_base_mpu_defs.h
new file mode 100644
index 000000000..8e8a5e721
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/qos_base_mpu_defs.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: qos_base_mpu_defs.h header file
+ * Create: 2025/9/1
+ */
+
+#ifndef QOS_BASE_MPU_DEFS_H
+#define QOS_BASE_MPU_DEFS_H
+
+/**< max func/VM number */
+#ifdef RESOURCE_MODE_CLIP
+#define CFM_FUNC_MAX_NUM 64 /**< PF8个(其后24个为保留扩展PF使用) + VF32个 */
+#define CFM_VM_MAX_NUM 96
+#else /**< 1823V200/1825V100均为下述规格 */
+#define CFM_FUNC_MAX_NUM 4096
+#define CFM_VM_MAX_NUM 1024
+#endif
+
+/**< 1825芯片代次,CAR最大桶深未跟随xQM,故单独定义 */
+#define CFM_QOS_CAR_XBS_MAX_VALUE (320 * 8 * 1000) /* *< unit:kbps, 2560Mbps */
+
+/**< macro for qos */
+#ifndef HI1825V100
+#define CFM_QOS_CIR_MIN_VALUE 1000
+#define CFM_QOS_CIR_MAX_VALUE (400 * 1000 * 1000) /**< unit:kbps, 400Gbps */
+#define CFM_QOS_PIR_MIN_VALUE 1000
+#define CFM_QOS_PIR_MAX_VALUE (400 * 1000 * 1000) /**< unit:kbps, 400Gbps */
+
+#define CFM_QOS_CBS_MIN_VALUE 1000
+#define CFM_QOS_CBS_MAX_VALUE (320 * 8 * 1000) /**< unit:kbps, 2560Mbps */
+#define CFM_QOS_PBS_MIN_VALUE 1000
+#define CFM_QOS_PBS_MAX_VALUE (320 * 8 * 1000) /**< unit:kbps, 2560Mbps */
+
+#define CFM_QOS_P_CIR_MIN_VALUE 1000
+#define CFM_QOS_P_CIR_MAX_VALUE (128 * 1000 * 1000) /**< unit:pps, 128Mpps */
+#define CFM_QOS_P_PIR_MIN_VALUE 1000
+#define CFM_QOS_P_PIR_MAX_VALUE (128 * 1000 * 1000) /**< unit:pps, 128Mpps */
+
+#define CFM_QOS_P_CBS_MIN_VALUE 1000
+#define CFM_QOS_P_CBS_MAX_VALUE (1000 * 1000) /**< unit:pps, 1Mpps */
+#define CFM_QOS_P_PBS_MIN_VALUE 1000
+#define CFM_QOS_P_PBS_MAX_VALUE (1000 * 1000) /**< unit:pps, 1Mpps */
+#else
+#define CFM_QOS_CIR_MIN_VALUE 1000
+#define CFM_QOS_CIR_MAX_VALUE (800 * 1000 * 1000) /**< unit:kbps, 800Gbps */
+#define CFM_QOS_PIR_MIN_VALUE 1000
+#define CFM_QOS_PIR_MAX_VALUE (800 * 1000 * 1000) /**< unit:kbps, 800Gbps */
+
+#define CFM_QOS_CBS_MIN_VALUE 1000
+#define CFM_QOS_CBS_MAX_VALUE (4 * 1000 * 1000) /**< unit:kbps, 4Gbps */
+#define CFM_QOS_PBS_MIN_VALUE 1000
+#define CFM_QOS_PBS_MAX_VALUE (4 * 1000 * 1000) /**< unit:kbps, 4Gbps */
+
+#define CFM_QOS_P_CIR_MIN_VALUE 1000
+#define CFM_QOS_P_CIR_MAX_VALUE (300 * 1000 * 1000) /**< unit:pps, 300Mpps */
+#define CFM_QOS_P_PIR_MIN_VALUE 1000
+#define CFM_QOS_P_PIR_MAX_VALUE (300 * 1000 * 1000) /**< unit:pps, 300Mpps */
+
+#define CFM_QOS_P_CBS_MIN_VALUE 1000
+#define CFM_QOS_P_CBS_MAX_VALUE (1000 * 1000) /**< unit:pps, 1Mpps */
+#define CFM_QOS_P_PBS_MIN_VALUE 1000
+#define CFM_QOS_P_PBS_MAX_VALUE (1000 * 1000) /**< unit:pps, 1Mpps */
+#endif
+
+#define CFM_QOS_GET_VM_LIMIT_EN_BW(cir, pir) \
+ ((((cir) == CFM_QOS_CIR_MAX_VALUE) && \
+ ((pir) == CFM_QOS_PIR_MAX_VALUE)) ? \
+ CFM_QOS_DISABLE : \
+ CFM_QOS_ENABLE)
+
+#define CFM_QOS_GET_VM_LIMIT_EN_PPS(cir, pir) \
+ ((((cir) == CFM_QOS_P_CIR_MAX_VALUE) && \
+ ((pir) == CFM_QOS_P_PIR_MAX_VALUE)) ? \
+ CFM_QOS_DISABLE : \
+ CFM_QOS_ENABLE)
+
+#define CFM_QOS_PARAM_ILGL_BPS(cir, xir, cbs, xbs) \
+ (((cir) < CFM_QOS_CIR_MIN_VALUE) || ((cir) > CFM_QOS_CIR_MAX_VALUE) || \
+ ((xir) < CFM_QOS_PIR_MIN_VALUE) || ((xir) > CFM_QOS_PIR_MAX_VALUE) || \
+ ((cbs) < CFM_QOS_CBS_MIN_VALUE) || ((cbs) > CFM_QOS_CBS_MAX_VALUE) || \
+ ((xbs) < CFM_QOS_PBS_MIN_VALUE) || ((xbs) > CFM_QOS_PBS_MAX_VALUE))
+
+#define CFM_QOS_PARAM_ILGL_PPS(cir, xir, cbs, xbs) \
+ (((cir) < CFM_QOS_P_CIR_MIN_VALUE) || \
+ ((cir) > CFM_QOS_P_CIR_MAX_VALUE) || \
+ ((xir) < CFM_QOS_P_PIR_MIN_VALUE) || \
+ ((xir) > CFM_QOS_P_PIR_MAX_VALUE) || \
+ ((cbs) < CFM_QOS_P_CBS_MIN_VALUE) || \
+ ((cbs) > CFM_QOS_P_CBS_MAX_VALUE) || \
+ ((xbs) < CFM_QOS_P_PBS_MIN_VALUE) || \
+ ((xbs) > CFM_QOS_P_PBS_MAX_VALUE))
+
+#define CFM_QOS_PARAM_ILGL_FUNC_ID(func_id) ((func_id) >= CFM_FUNC_MAX_NUM)
+
+#define CFM_QOS_PARAM_ILGL_VM_ID(vm_id) ((vm_id) >= CFM_VM_MAX_NUM)
+
+typedef enum tag_cfm_qos_enable {
+ CFM_QOS_DISABLE = 0,
+ CFM_QOS_ENABLE
+} cfm_qos_enable_e;
+
+typedef enum tag_cfm_qos_apply_mode {
+ CFM_QOS_APPLY_MODE_TX_BW = 0,
+ CFM_QOS_APPLY_MODE_TX_PPS,
+ CFM_QOS_APPLY_MODE_TX_BW_WITH_MQM_PRF, /**< deprecated */
+ CFM_QOS_APPLY_MODE_RX_BW,
+ CFM_QOS_APPLY_MODE_RX_PPS
+} cfm_qos_apply_mode_e;
+
+typedef struct tag_cfm_qos_policing_cmd {
+ u32 index; /**< index reuse, vm_id/vnicgpp_id/func_id/vnic_id */
+ u32 apply_mode; /**< 0:TX_BW; 1:TX_PPS; 3:RX_BW; 4:RX_PPS */
+ u32 profile_id; /**< deprecated */
+ u32 cir;
+ u32 cbs;
+ u32 pir;
+ u32 pbs;
+} cfm_qos_policing_cmd_s;
+
+#endif /* QOS_BASE_MPU_DEFS_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd.h
new file mode 100644
index 000000000..519b9a62c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2023. All rights reserved.
+ * Description: cqm common command interface define.
+ * Author: None
+ * Create: 2015/11/13
+ */
+#ifndef CQM_NPU_CMD_H
+#define CQM_NPU_CMD_H
+
+typedef enum {
+ CQM_CMD_T_INVALID = 0,
+ CQM_CMD_T_BAT_UPDATE = 1,
+ CQM_CMD_T_CLA_UPDATE = 2,
+ CQM_CMD_T_BLOOMFILTER_SET = 3,
+ CQM_CMD_T_BLOOMFILTER_CLEAR = 4,
+ CQM_CMD_T_COMPACT_SRQ_UPDATE = 5,
+ CQM_CMD_T_CLA_CACHE_INVALID = 6,
+ CQM_CMD_T_BLOOMFILTER_INIT = 7,
+ CQM_CMD_T_CLA_RESET = 8, /* Reset VF's CLA */
+ CQM_CMD_T_MAX
+} cqm_cmd_type_e;
+
+#endif /* CQM_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd_defs.h
new file mode 100644
index 000000000..68a8295c8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cqm/cqm_npu_cmd_defs.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2023. All rights reserved.
+ * Description: cqm common command interface define.
+ * Author: None
+ * Create: 2015/11/13
+ */
+#ifndef CQM_NPU_CMD_DEFS_H
+#define CQM_NPU_CMD_DEFS_H
+
+#if defined(__LINUX__) || defined(__VMWARE__)
+#include <linux/types.h>
+#else
+#include "typedef.h"
+#endif
+
+typedef struct tag_cqm_cla_cache_invalid_cmd {
+ u32 gpa_h;
+ u32 gpa_l;
+
+ u32 cache_size; /* CLA cache size=4096B */
+
+ u32 smf_id;
+ u32 func_id;
+} cqm_cla_cache_invalid_cmd_s;
+
+typedef struct tag_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;
+} cqm_cla_update_cmd_s;
+
+typedef struct tag_cqm_cla_reset_cmd {
+ u32 func_id;
+ u32 rsvd1;
+
+ u32 rsvd[0x20]; /* Reserve 2 dwords for each BAT entries */
+} cqm_cla_reset_cmd_s;
+
+typedef struct tag_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;
+} cqm_bloomfilter_cmd_s;
+
+#define CQM_BAT_MAX_SIZE 256
+typedef struct tag_cqm_cmdq_bat_update {
+ u32 offset; // byte offset,16Byte aligned
+ u32 byte_len; // max size: 256byte
+ u8 data[CQM_BAT_MAX_SIZE];
+ u32 smf_id;
+ u32 func_id;
+} cqm_bat_update_cmd_s;
+
+typedef struct tag_cqm_bloomfilter_init_cmd {
+ u32 bloom_filter_len; // 16Byte aligned
+ u32 bloom_filter_addr;
+} cqm_bloomfilter_init_cmd_s;
+
+typedef struct tag_compact_srq_update_cmd {
+ u32 srqid;
+ u32 data[32];
+} compact_srq_update_cmd_s;
+
+#endif /* CQM_CMDQ_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_qsfp_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_qsfp_defs.h
new file mode 100644
index 000000000..b45809d79
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_qsfp_defs.h
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
+ * Description: sfp data definition
+ * Create: 2024-04-15
+ */
+
+#ifndef EEPROM_QSFP_DEFS_H
+#define EEPROM_QSFP_DEFS_H
+
+typedef struct {
+ /* offset 0 */
+ u8 ucId; /* identifier (1 Byte), the definition of identifier field is the same as page 00h byte 128 */
+
+ /* offset 1~2 */
+ struct {
+ u8 ucRsvd1;
+
+ u8 ucDataNotReady : 1; /* indicate transceiver has not yet achieved power up and monitor data is
+ * not ready. Bit remains high until data is ready to be read at which time
+ * the device sets the bit low. 2 bit 0
+ */
+ u8 ucIntL : 1; /* digital state of the IntL interrupt output pin. 2 bit 1 */
+ u8 ucRsvd2 : 6; /* reserved. 2[7:2] */
+ } stStatus;
+
+ /* offset 3~21 */
+ struct {
+ /* channel status interrupt flags, offset 3~5 */
+ u8 ucRxTxLos;
+ u8 ucTxFault;
+ u8 ucReserved2; /* reserved, 5 */
+
+ /* module monitor interrupt flags, offset 6~8 */
+ struct {
+ u8 ucReserved1 : 4; /* reserved, 6[3:0] */
+ u8 ucLTempWarningLow : 1; /* latched low temperature warning, 6 bit 4 */
+ u8 ucLTempWarningHigh : 1; /* latched high temperature warning, 6 bit 5 */
+ u8 ucLTempAlarmLow : 1; /* latched low temperature alarm, 6 bit 6 */
+ u8 ucLTempAlarmHigh : 1; /* latched high temperature alarm, 6 bit 7 */
+
+ u8 ucReserved2 : 4; /* reserved, 7[3:0] */
+ u8 ucLVccWarningLow : 1; /* latched low supply voltage warning, 7 bit 4 */
+ u8 ucLVccWarningHigh : 1; /* latched high supply voltage warning, 7 bit 5 */
+ u8 ucLVccAlarmLow : 1; /* latched low supply voltage alarm, 7 bit 6 */
+ u8 ucLVccAlarmHigh : 1; /* latched high supply voltage alarm, 7 bit 7 */
+
+ u8 ucReserved3; /* reserved, 8 */
+ } stModMtIntFlags;
+
+ /* channel monitor interrupt flags, offset 9~21 */
+ struct {
+ /* channel power monitor interrupt flags */
+ /* channel 2 Rx power monitor interrupt flags */
+ u8 ucLRx2PowerWarningLow : 1; /* latched low RX power warning, channel 2, 9 bit 0 */
+ u8 ucLRx2PowerWarningHigh : 1; /* latched high RX power warning, channel 2, 9 bit 1 */
+ u8 ucLRx2PowerAlarmLow : 1; /* latched low RX power alarm, channel 2, 9 bit 2 */
+ u8 ucLRx2PowerAlarmHigh : 1; /* latched high RX power alarm, channel 2, 9 bit 3 */
+
+ /* channel 1 Rx power monitor interrupt flags */
+ u8 ucLRx1PowerWarningLow : 1; /* latched low RX power warning, channel 1, 9 bit 4 */
+ u8 ucLRx1PowerWarningHigh : 1; /* latched high RX power warning, channel 1, 9 bit 5 */
+ u8 ucLRx1PowerAlarmLow : 1; /* latched low RX power alarm, channel 1, 9 bit 6 */
+ u8 ucLRx1PowerAlarmHigh : 1; /* latched high RX power alarm, channel 1, 9 bit 7 */
+
+ /* channel 4 Rx power monitor interrupt flags */
+ u8 ucLRx4PowerWarningLow : 1; /* latched low RX power warning, channel 4, 10 bit 0 */
+ u8 ucLRx4PowerWarningHigh : 1; /* latched high RX power warning, channel 4, 10 bit 1 */
+ u8 ucLRx4PowerAlarmLow : 1; /* latched low RX power alarm, channel 4, 10 bit 2 */
+ u8 ucLRx4PowerAlarmHigh : 1; /* latched high RX power alarm, channel 4, 10 bit 3 */
+
+ /* channel 3 Rx power monitor interrupt flags */
+ u8 ucLRx3PowerWarningLow : 1; /* latched low RX power warning, channel 3, 10 bit 4 */
+ u8 ucLRx3PowerWarningHigh : 1; /* latched high RX power warning, channel 3, 10 bit 5 */
+ u8 ucLRx3PowerAlarmLow : 1; /* latched low RX power alarm, channel 3, 10 bit 6 */
+ u8 ucLRx3PowerAlarmHigh : 1; /* latched high RX power alarm, channel 3, 10 bit 7 */
+
+ /* channel bias monitor interrupt flags */
+ /* channel 2 Tx bias monitor interrupt flags */
+ u8 ucLTx2BiasWarningLow : 1; /* latched low TX bias warning, channel 2, 11 bit 0 */
+ u8 ucLTx2BiasWarningHigh : 1; /* latched high TX bias warning, channel 2, 11 bit 1 */
+ u8 ucLTx2BiasAlarmLow : 1; /* latched low TX bias alarm, channel 2, 11 bit 2 */
+ u8 ucLTx2BiasAlarmHigh : 1; /* latched high TX bias alarm, channel 2, 11 bit 3 */
+
+ /* channel 1 Tx bias monitor interrupt flags */
+ u8 ucLTx1BiasWarningLow : 1; /* latched low TX bias warning, channel 1, 11 bit 4 */
+ u8 ucLTx1BiasWarningHigh : 1; /* latched high TX bias warning, channel 1, 11 bit 5 */
+ u8 ucLTx1BiasAlarmLow : 1; /* latched low TX bias alarm, channel 1, 11 bit 6 */
+ u8 ucLTx1BiasAlarmHigh : 1; /* latched high TX bias alarm, channel 1, 11 bit 7 */
+
+ /* channel 4 Tx bias monitor interrupt flags */
+ u8 ucLTx4BiasWarningLow : 1; /* latched low TX bias warning, channel 4, 12 bit 0 */
+ u8 ucLTx4BiasWarningHigh : 1; /* latched high TX bias warning, channel 4, 12 bit 1 */
+ u8 ucLTx4BiasAlarmLow : 1; /* latched low TX bias alarm, channel 4, 12 bit 2 */
+ u8 ucLTx4BiasAlarmHigh : 1; /* latched high TX bias alarm, channel 4, 12 bit 3 */
+
+ /* channel 3 Tx bias monitor interrupt flags */
+ u8 ucLTx3BiasWarningLow : 1; /* latched low TX bias warning, channel 3, 12 bit 4 */
+ u8 ucLTx3BiasWarningHigh : 1; /* latched high TX bias warning, channel 3, 12 bit 5 */
+ u8 ucLTx3BiasAlarmLow : 1; /* latched low TX bias alarm, channel 3, 12 bit 6 */
+ u8 ucLTx3BiasAlarmHigh : 1; /* latched high TX bias alarm, channel 3, 12 bit 7 */
+
+ u8 ucReserved1
+ [2]; /* reserved channel monitor flags, set 3 */
+ u8 ucReserved2
+ [2]; /* reserved channel monitor flags, set 4 */
+ u8 ucReserved3
+ [2]; /* reserved channel monitor flags, set 5 */
+ u8 ucReserved4
+ [2]; /* reserved channel monitor flags, set 6 */
+
+ u8 ucReserved5; /* reserved */
+ } stChMtIntFlags;
+ } stIntFlags;
+
+ /* module monitoring values, offset 22~33 */
+ struct {
+ u8 ucTemperatureMSB; /* internally measured module temperature */
+ u8 ucTemperatureLSB; /* internally measured module temperature */
+ u8 ucReserved1[2];
+ u8 ucSupplyVol[2];
+ u8 ucReserved2[6];
+ } stModMtValues;
+
+ /* channel monitoring values, offset 34~81 */
+ struct {
+ u8 ucRxPow[8];
+ u8 ucTxBias[8];
+ u8 ucTxPow[8];
+ u8 ucReserved2[8]; /* reserved channel monitor set 4, 58~65 */
+ u8 ucReserved3[8]; /* reserved channel monitor set 5, 66~73 */
+ u8 ucReserved4[8]; /* reserved channel monitor set 6, 74~81 */
+ } stChMtValues;
+
+ /* reserved (4 Bytes), offset 82~85 */
+ u8 ucReserved1[4];
+
+ /* control bytes, offset 86~99 */
+ struct {
+ u8 ucTxDisable;
+ u8 ucRxRateSelect;
+ u8 ucTxRateSelect;
+
+ u8 ucRx4ApplicationSelect; /* software application select per SFF-8079, Rx channel 4 (optional) */
+ u8 ucRx3ApplicationSelect; /* software application select per SFF-8079, Rx channel 3 (optional) */
+ u8 ucRx2ApplicationSelect; /* software application select per SFF-8079, Rx channel 2 (optional) */
+ u8 ucRx1ApplicationSelect; /* software application select per SFF-8079, Rx channel 1 (optional) */
+
+ u8 ucPowerOverRide : 1; /* override of LPMode signal setting the power mode with software. 93 bit 0 */
+ u8 ucPowerSet : 1; /* power set to low power mode. Default 0. 93 bit 1 */
+ u8 ucReserverd2 : 6; /* reserved, 93[7:2] */
+
+ u8 ucTx4ApplicationSelect; /* software application select per SFF-8079, Tx channel 4 (optional), 94 */
+ u8 ucTx3ApplicationSelect; /* software application select per SFF-8079, Tx channel 3 (optional), 95 */
+ u8 ucTx2ApplicationSelect; /* software application select per SFF-8079, Tx channel 2 (optional), 96 */
+ u8 ucTx1ApplicationSelect; /* software application select per SFF-8079, Tx channel 1 (optional), 97 */
+
+ u8 ucReserverd3[2]; /* reserved, 98~99 */
+ } stCtrlBytes;
+
+ /* module and channel masks, 100~106 */
+ struct {
+ u8 ucMRx1LOS : 1; /* masking bit for RX LOS indicator, channel 1, 100 bit 0 */
+ u8 ucMRx2LOS : 1; /* masking bit for RX LOS indicator, channel 2, 100 bit 1 */
+ u8 ucMRx3LOS : 1; /* masking bit for RX LOS indicator, channel 3, 100 bit 2 */
+ u8 ucMRx4LOS : 1; /* masking bit for RX LOS indicator, channel 4, 100 bit 3 */
+
+ u8 ucMTx1LOS : 1; /* masking bit for TX LOS indicator, channel 1 (optional), 100 bit 4 */
+ u8 ucMTx2LOS : 1; /* masking bit for TX LOS indicator, channel 2 (optional), 100 bit 5 */
+ u8 ucMTx3LOS : 1; /* masking bit for TX LOS indicator, channel 3 (optional), 100 bit 6 */
+ u8 ucMTx4LOS : 1; /* masking bit for TX LOS indicator, channel 4 (optional), 100 bit 7 */
+
+ u8 ucMTx1Fault : 1; /* masking bit for TX fault indicator, channel 1, 101 bit 0 */
+ u8 ucMTx2Fault : 1; /* masking bit for TX fault indicator, channel 2, 101 bit 1 */
+ u8 ucMTx3Fault : 1; /* masking bit for TX fault indicator, channel 3, 101 bit 2 */
+ u8 ucMTx4Fault : 1; /* masking bit for TX fault indicator, channel 4, 101 bit 3 */
+ u8 ucReserverd1 : 4; /* reserved, 101[7:4] */
+
+ u8 ucReserverd2; /* reserved, 102 */
+
+ u8 ucReserverd3 : 4; /* reserved, 103[3:0] */
+
+ u8 ucMTempWarningLow : 1; /* masking bit for low temperature warning, 103 bit 4 */
+ u8 ucMTempWarningHigh : 1; /* masking bit for high temperature warning, 103 bit 5 */
+ u8 ucMTempAlarmLow : 1; /* masking bit for low temperature alarm, 103 bit 6 */
+ u8 ucMTempAlarmHigh : 1; /* masking bit for high temperature alarm, 103 bit 7 */
+
+ u8 ucReserverd4 : 4; /* reserved, 104[3:0] */
+
+ u8 ucMVccWarningLow : 1; /* masking bit for low Vcc warning, 104 bit 4 */
+ u8 ucMVccWarningHigh : 1; /* masking bit for high Vcc warning, 104 bit 5 */
+ u8 ucMVccAlarmLow : 1; /* masking bit for low Vcc alarm, 104 bit 6 */
+ u8 ucMVccAlarmHigh : 1; /* masking bit for high Vcc alarm, 104 bit 7 */
+
+ u8 ucReserverd5[2]; /* reserved, 105~106 */
+ } stModAndChMasks;
+
+ /* reserved (12 Bytes), offset 107~118 */
+ u8 ucReserverd[12];
+
+ /* change entry area (optional) (4 Bytes), offset 119~122 */
+ u8 ucChangeEntryArea[4];
+
+ /* entry area (optional) (4 Bytes), offset 123~126 */
+ u8 ucEntryArea[4];
+
+ /* page select byte, offset 127 */
+ u8 ucPageSelect;
+} qsfp_lower_page_s;
+
+/* Page 00h consists of the serial ID and is used for read only identification information.
+ * The serial ID is divided into the Base_ID fields, extended ID fields and vendor specific ID fields.
+ */
+typedef struct {
+ /* offset 128~191 */
+ struct {
+ u8 ucId; /* identifier type of serial transceiver */
+ u8 ucIdExt; /* extended identifier of serial transceiver */
+ u8 ucConnector; /* code for connector type */
+ u8 aucTransceiver
+ [8]; /* code for electronic compatibility or optical compatibility */
+ u8 ucEncoding; /* code for serial encoding algorithm */
+ u8 ucBrNominal; /* nominal bit rate, units of 100 MBits/s. */
+ u8 ucRateIdentifier; /* type of rate select functionality */
+ u8 ucLengthSmfKm; /* link length supported for single mode fiber, units of km */
+ u8 ucLengthE50um; /* link length supported for EBW 50/125 um fiber, units of 2 m */
+ u8 ucLength50um; /* link length supported for 50/125 um fiber, units of 1 m */
+ u8 ucLength62p5um; /* link length supported for 62.5/125 um fiber, units of 1 m */
+ u8 ucLengthCopper; /* link length supported for copper, units of 1m */
+ u8 ucDeviceTech; /* device technology */
+ u8 aucVendorName[16]; /* ASCII */
+ u8 ucExtTransceiver; /* the extended transceiver codes define the electronic or
+ * optical interfaces for InfiniBand that are supported
+ */
+ u8 aucVendorOUI[3]; /* QSFP vendor IEEE company ID */
+ u8 aucVendorPN[16]; /* part number provided by QSFP vendor (ASCII) */
+ u8 aucVendorRev
+ [2]; /* revision level for part number provided by vendor (ASCII) */
+ u8 aucWaveLength
+ [2]; /* nominal laser wavelength (Wavelength = value / 20 in nm) */
+ u8 aucWaveLengthTolerance
+ [2]; /* guaranteed range of laser wavelength (+/- value) from nominal
+ * wavelength.(Wavelength Tol. = value/200 in nm)
+ */
+ u8 ucMaxCaseTemp; /* maximum case temperature in degrees C. */
+ u8 ucCcBase; /* check code for base ID fields (addresses 128-190) */
+ } stBaseIdFields;
+
+ /* offset 192~223 */
+ struct {
+ u8 aucOptions[4]; /* rate select, TX disable, TX fault, LOS */
+ u8 aucVendorSN[16]; /* serial number provided by vendor (ASCII) */
+ u8 aucDateCode[8]; /* vendor's manufacturing date code */
+ u8 ucDiagMonitorType; /* indicate which type of diagnostic monitoring is implemented (if any) in the
+ * transceiver. Bit 1, 0 reserved
+ */
+ u8 ucEnhancedOptions; /* indicate which optional enhanced features are implemented in the transceiver */
+ u8 ucBrNominal;
+ u8 ucCcExt; /* check code for the extended ID fields (addresses 192-222) */
+ } stExtIdFields;
+
+ /* offset 224~255 */
+ struct {
+ u8 aucVendorSpecEeprom[32]; /* vendor specific EEPROM */
+ } stVendorSpecIdFields;
+} qsfp_upper_page0_s;
+
+typedef struct {
+ u8 ucCcAPPS; /* check code for the AST; the check code shall be the
+ * low order 8 bits of the sum of the contents of all the
+ * bytes from byte 129 to byte 255, inclusive.
+ */
+ u8 ucASTTableLength : 6; /* a 6-bit binary number, TL, specifies how many
+ * application table entries are defined in bytes 130-255
+ * addresses. TL is valid between 0 (1 entry) and 62 (for
+ * a total of 63 entries).
+ */
+ u8 ucReserved : 2; /* reserved 129[7:6] */
+
+ u8 ucApplicationCode0
+ [2]; /* definition of first application supported, offset 130~131 */
+ u8 ucOtherTableEntries[122]; /* other table entries, offset 132~253 */
+ u8 ucApplicationCodeTL
+ [2]; /* definition of last application supported, 254~255 */
+} qsfp_upper_page1_s;
+
+/* Page 02 is optionally provided as user writable EEPROM. The host system may read or write this memory for
+ * any purpose. If bit 4 of Page 00 byte 129 is set, however, the first 10 bytes of Table 02h, bytes128-137 will be
+ * used to store the CLEI code for the module.
+ */
+typedef struct {
+ u8 aucUserEeprom[128];
+} qsfp_upper_page2_s;
+
+/* The upper memory map page 03h contains module thresholds, channel thresholds and masks, and optional
+ * channel controls.
+ */
+typedef struct {
+ /* 128~223 */
+ struct {
+ /* module thresholds (48 Bytes), offset 128~175 */
+ u8 aucTempAlarmHigh[2]; /* MSB at low address */
+ u8 aucTempAlarmLow[2]; /* MSB at low address */
+ u8 aucTempWarningHigh[2]; /* MSB at low address */
+ u8 aucTempWarningLow[2]; /* MSB at low address */
+
+ u8 aucReserved1[8];
+
+ u8 aucVccAlarmHigh[2]; /* MSB at low address */
+ u8 aucVccAlarmLow[2]; /* MSB at low address */
+ u8 aucVccWarningHigh[2]; /* MSB at low address */
+ u8 aucVccWarningLow[2]; /* MSB at low address */
+
+ u8 aucReserved2[24]; /* offset 152~175 */
+
+ /* channel thresholds (48 Bytes), 176~223 */
+ u8 aucRxPwrAlarmHigh[2]; /* MSB at low address */
+ u8 aucRxPwrAlarmLow[2]; /* MSB at low address */
+ u8 aucRxPwrWarningHigh[2]; /* MSB at low address */
+ u8 aucRxPwrWarningLow[2]; /* MSB at low address */
+
+ u8 aucTxBiasAlarmHigh[2]; /* MSB at low address */
+ u8 aucTxBiasAlarmLow[2]; /* MSB at low address */
+ u8 aucTxBiasWarningHigh[2]; /* MSB at low address */
+ u8 aucTxBiasWarningLow[2]; /* MSB at low address */
+
+ u8 aucTxPwrAlarmHigh[2]; /* MSB at low address */
+ u8 aucTxPwrAlarmLow[2]; /* MSB at low address */
+ u8 aucTxPwrWarningHigh[2]; /* MSB at low address */
+ u8 aucTxPwrWarningLow[2]; /* MSB at low address */
+
+ u8 aucReserved4
+ [8]; /* reserved thresholds for channel parameter set 4 */
+ u8 aucReserved5
+ [8]; /* reserved thresholds for channel parameter set 5 */
+ u8 aucReserved6
+ [8]; /* reserved thresholds for channel parameter set 6 */
+ } stAlarmWarnTh;
+
+ /* 224~225 */
+ u8 aucReserved1[2];
+
+ /* 226~239 */
+ u8 aucVendorSpecificChannelControls
+ [14]; /* vendor specific channel controls (14 Bytes) */
+
+ /* 240~241 */
+ struct {
+ u8 ucTx1SQDisable : 1; /* Tx squelch disable, channel 1 (optional), 240 bit 0 */
+ u8 ucTx2SQDisable : 1; /* Tx squelch disable, channel 2 (optional), 240 bit 1 */
+ u8 ucTx3SQDisable : 1; /* Tx squelch disable, channel 3 (optional), 240 bit 2 */
+ u8 ucTx4SQDisable : 1; /* Tx squelch disable, channel 4 (optional), 240 bit 3 */
+
+ u8 ucRx1SQDisable : 1; /* Rx squelch disable, channel 1 (optional), 240 bit 4 */
+ u8 ucRx2SQDisable : 1; /* Rx squelch disable, channel 2 (optional), 240 bit 5 */
+ u8 ucRx3SQDisable : 1; /* Rx squelch disable, channel 3 (optional), 240 bit 6 */
+ u8 ucRx4SQDisable : 1; /* Rx squelch disable, channel 4 (optional), 240 bit 7 */
+
+ u8 ucRsvd : 4; /* reserved 241[3:0] */
+ u8 ucRx1OutputDisable : 1; /* Rx output disable, channel 1 (optional), 241 bit 4 */
+ u8 ucRx2OutputDisable : 1; /* Rx output disable, channel 2 (optional), 241 bit 5 */
+ u8 ucRx3OutputDisable : 1; /* Rx output disable, channel 3 (optional), 241 bit 6 */
+ u8 ucRx4OutputDisable : 1; /* Rx output disable, channel 4 (optional), 241 bit 7 */
+ } stOptChCtrls;
+
+ /* 242~253 */
+ struct {
+ /* channel 2 power mointer mask, 242[3:0] */
+ u8 ucMRx2PowerWarningLow : 1; /* masking bit for low RX power warning, channel 2, 242 bit 0 */
+ u8 ucMRx2PowerWarningHigh : 1; /* masking bit for high RX power warning, channel 2, 242 bit 1 */
+ u8 ucMRx2PowerAlarmLow : 1; /* masking bit for low RX power alarm, channel 2, 242 bit 2 */
+ u8 ucMRx2PowerAlarmHigh : 1; /* masking bit for high RX power alarm, channel 2, 242 bit 3 */
+
+ /* channel 1 power mointer mask, 242[7:4] */
+ u8 ucMRx1PowerWarningLow : 1; /* masking bit for low RX power warning, channel 1, 242 bit 4 */
+ u8 ucMRx1PowerWarningHigh : 1; /* masking bit for high RX power warning, channel 1, 242 bit 5 */
+ u8 ucMRx1PowerAlarmLow : 1; /* masking bit for low RX power alarm, channel 1, 242 bit 6 */
+ u8 ucMRx1PowerAlarmHigh : 1; /* masking bit for high RX power alarm, channel 1, 242 bit 7 */
+
+ /* channel 4 power mointer mask, 243[3:0] */
+ u8 ucMRx4PowerWarningLow : 1; /* masking bit for low RX power warning, channel 4, 243 bit 0 */
+ u8 ucMRx4PowerWarningHigh : 1; /* masking bit for high RX power warning, channel 4, 243 bit 1 */
+ u8 ucMRx4PowerAlarmLow : 1; /* masking bit for low RX power alarm, channel 4, 243 bit 2 */
+ u8 ucMRx4PowerAlarmHigh : 1; /* masking bit for high RX power alarm, channel 4, 243 bit 3 */
+
+ /* channel 3 power mointer mask, 243[7:4] */
+ u8 ucMRx3PowerWarningLow : 1; /* masking bit for low RX power warning, channel 3, 243 bit 4 */
+ u8 ucMRx3PowerWarningHigh : 1; /* masking bit for high RX power warning, channel 3, 243 bit 5 */
+ u8 ucMRx3PowerAlarmLow : 1; /* masking bit for low RX power alarm, channel 3, 243 bit 6 */
+ u8 ucMRx3PowerAlarmHigh : 1; /* masking bit for high RX power alarm, channel 3, 243 bit 7 */
+
+ /* channel 2 Bias mointer mask, 244[3:0] */
+ u8 ucMTx2BiasWarningLow : 1; /* masking bit for low TX bias warning, channel 2, 244 bit 0 */
+ u8 ucMTx2BiasWarningHigh : 1; /* masking bit for low TX bias warning, channel 2, 244 bit 1 */
+ u8 ucMTx2BiasAlarmLow : 1; /* masking bit for low TX bias alarm, channel 2, 244 bit 2 */
+ u8 ucMTx2BiasAlarmHigh : 1; /* masking bit for high TX bias alarm, channel 2, 244 bit 3 */
+
+ /* channel 1 Bias mointer mask, 244[7:4] */
+ u8 ucMTx1BiasWarningLow : 1; /* masking bit for low TX bias warning, channel 1, 244 bit 4 */
+ u8 ucMTx1BiasWarningHigh : 1; /* masking bit for low TX bias warning, channel 1, 244 bit 5 */
+ u8 ucMTx1BiasAlarmLow : 1; /* masking bit for low TX bias alarm, channel 1, 244 bit 6 */
+ u8 ucMTx1BiasAlarmHigh : 1; /* masking bit for high TX bias alarm, channel 1, 244 bit 7 */
+
+ /* channel 4 Bias mointer mask, 245[3:0] */
+ u8 ucMTx4BiasWarningLow : 1; /* masking bit for low TX bias warning, channel 4, 245 bit 0 */
+ u8 ucMTx4BiasWarningHigh : 1; /* masking bit for low TX bias warning, channel 4, 245 bit 1 */
+ u8 ucMTx4BiasAlarmLow : 1; /* masking bit for low TX bias alarm, channel 4, 245 bit 2 */
+ u8 ucMTx4BiasAlarmHigh : 1; /* masking bit for high TX bias alarm, channel 4, 245 bit 3 */
+
+ /* channel 3 Bias mointer mask, 245[7:4] */
+ u8 ucMTx3BiasWarningLow : 1; /* masking bit for low TX bias warning, channel 3, 245 bit 4 */
+ u8 ucMTx3BiasWarningHigh : 1; /* masking bit for low TX bias warning, channel 3, 245 bit 5 */
+ u8 ucMTx3BiasAlarmLow : 1; /* masking bit for low TX bias alarm, channel 3, 245 bit 6 */
+ u8 ucMTx3BiasAlarmHigh : 1; /* masking bit for high TX bias alarm, channel 3, 245 bit 7 */
+
+ u8 ucReserverd1[2]; /* reserved channel monitor masks, set 3 */
+ u8 ucReserverd2[2]; /* reserved channel monitor masks, set 4 */
+ u8 ucReserverd3[2]; /* reserved channel monitor masks, set 5 */
+ u8 ucReserverd4[2]; /* reserved channel monitor masks, set 6 */
+ } stChMtMasks;
+
+ /* reserved, offset 254~255 */
+ u8 aucReserved2[2]; /* reserved (2 Bytes) */
+} qsfp_upper_page3_s;
+
+/* QSFP has a total of 640-byte data structures
+ * low-end 128 bytes, high-end 4 pages, each page 128 bytes, high-end 512 bytes total
+ */
+struct qsfp_info_t {
+ qsfp_lower_page_s qsfp_low_page; /* QSFP lower 128-byte data */
+ qsfp_upper_page0_s
+ qsfp_high_page_0; /* QSFP high-end page 00 128-byte data */
+ qsfp_upper_page1_s
+ qsfp_high_page_1; /* QSFP high-end page 01 128-byte data */
+ qsfp_upper_page2_s
+ qsfp_high_page_2; /* QSFP high-end page 02 128-byte data */
+ qsfp_upper_page3_s
+ qsfp_high_page_3; /* QSFP high-end page 03 128-byte data */
+};
+
+#endif // EEPROM_QSFP_DEFS_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_sfp_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_sfp_defs.h
new file mode 100644
index 000000000..82d9281a3
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/eeprom_sfp_defs.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
+ * Description: sfp data definition
+ * Create: 2024-04-13
+ */
+
+#ifndef EEPROM_SFP_DEFS_H
+#define EEPROM_SFP_DEFS_H
+
+typedef struct tagSfpDataFieldA0_S {
+ /* 0~63 */
+ struct {
+ u8 ucId;
+ u8 ucIdExt;
+ u8 ucConnector;
+ u8 aucTransceiver[8];
+ u8 ucEncoding;
+ u8 ucBrNominal; /* nominal signalling rate, units of 100MBd. */
+ u8 ucRateIdentifier; /* type of rate select functionality */
+ u8 ucLengthSmfKm; /* link length supported for single mode fiber, units of km */
+ u8 ucLengthSmf; /* link length supported for single mode fiber, units of 100 m */
+ u8 ucLengthSmfOm2; /* link length supported for 50 um OM2 fiber, units of 10 m */
+ u8 ucLengthSmfOm1; /* link length supported for 62.5 um OM1 fiber, units of 10 m */
+ u8 ucLengthCable; /* link length supported for copper or direct attach cable, units of m */
+ u8 ucLengthOm3; /* link length supported for 50 um OM3 fiber, units of 10 m */
+ u8 aucVendorName[16]; /* ASCII */
+ u8 ucTransceiver; /* code for electronic or optical compatibility */
+ u8 aucVendorOui[3]; /* SFP vendor IEEE company ID */
+ u8 aucVendorPn[16]; /* part number provided by SFP vendor (ASCII) */
+ u8 aucVendorRev
+ [4]; /* revision level for part number provided by vendor (ASCII) */
+ u8 aucWaveLength
+ [2]; /* laser wavelength (passive/active cable specification compliance) */
+ u8 ucUnAllocated;
+ u8 ucCcBase; /* check code for base ID fields (addresses 0 to 62) */
+ } stBaseIdFields;
+
+ /* 64~95 */
+ struct {
+ u8 aucOptions[2];
+ u8 ucBrMax;
+ u8 ucBrMin;
+ u8 aucVendorSn[16];
+ u8 aucDateCode[8];
+ u8 ucDiagMonitorType;
+ u8 ucEnhancedOptions;
+ u8 ucSff8472Compliance;
+ u8 ucCcExt;
+ } stExtIdFields;
+
+ /* 96~255 */
+ struct {
+ u8 aucVendorSpecEeprom[32];
+ u8 aucRsvd[128];
+ } stVendorSpecIdFields;
+} SfpDataFieldA0_S;
+
+#define ELABEL_BOM_SIZE 14
+#define ITEM_CHECK_SUM_SIZE 2
+#define ELABEL_BOM_EXT_SIZE 3
+
+/* SFP electronic label item format */
+typedef struct tagSfp_elabel_item {
+ u8 bom[ELABEL_BOM_SIZE]; /* 14bytes bom zone */
+ u8 check_sum0[ITEM_CHECK_SUM_SIZE]; /* 2bytes checksum1 */
+ u8 bom_ext[ELABEL_BOM_EXT_SIZE]; /* 3bytes extended bom zone */
+ u8 check_sum1[ITEM_CHECK_SUM_SIZE]; /* 2byts checksum2 */
+} Sfp_elabel_item_t;
+
+/* user region format of the SFP page A2 register, electronic labels occupy part of the space in the zone */
+typedef struct tagSfp_a2_usr_region {
+ u8 reserve0[16];
+ Sfp_elabel_item_t item; /* 21-byte item code */
+ u8 reserve1[6];
+ u8 model[40]; /* 40-byte model field */
+ u8 rev[6]; /* 6-byte rev field */
+ u8 reserve2[27];
+ u8 check_sum; /* 1-byte verification, used to verify stdver and stdtype */
+ u8 std_ver; /* electronic label version */
+ u8 std_type[2]; /* electronic label storage format */
+} Sfp_a2_usr_region_t;
+
+typedef struct tagSfpDataFieldA2_S {
+ /* 0~119 */
+ struct {
+ /* 0~39 */
+ struct {
+ u8 aucTempAlarmHigh[2];
+ u8 aucTempAlarmLow[2];
+ u8 aucTempWarningHigh[2];
+ u8 aucTempWarningLow[2];
+
+ u8 aucVccAlarmHigh[2];
+ u8 aucVccAlarmLow[2];
+ u8 aucVccWarningHigh[2];
+ u8 aucVccWarningLow[2];
+
+ u8 aucBiasAlarmHigh[2];
+ u8 aucBiasAlarmLow[2];
+ u8 aucBiasWarningHigh[2];
+ u8 aucBiasWarningLow[2];
+
+ u8 aucTxAlarmHigh[2];
+ u8 aucTxAlarmLow[2];
+ u8 aucTxWarningHigh[2];
+ u8 aucTxWarningLow[2];
+
+ u8 aucRxAlarmHigh[2];
+ u8 aucRxAlarmLow[2];
+ u8 aucRxWarningHigh[2];
+ u8 aucRxWarningLow[2];
+ } stAlarmWarnTh;
+
+ /* 40~95 */
+ u8 aucUnAllocated0[16];
+ u8 aucExtCalConstants[36];
+ u8 aucUnAllocated1[3];
+ u8 ucCcDmi;
+
+ /* 96~105 */
+ struct {
+ u8 aucTemp[2];
+ u8 aucVcc[2];
+ u8 aucTxBias[2];
+ u8 aucTxPower[2];
+ u8 aucRxPower[2];
+ } stDiag;
+
+ /* 106~109 */
+ u8 aucUnAllocated2[4];
+
+ /* 110 */
+ union {
+ struct {
+ u8 ucDataRdyBarState : 1;
+ u8 ucRxLos : 1;
+ u8 ucTxFaultState : 1;
+ u8 ucSoftRateSelectState : 1;
+ u8 ucRateSelectState : 1;
+ u8 ucRsState : 1;
+ u8 ucSoftTxDisableSelect : 1;
+ u8 ucTxDisableState : 1;
+ } bits;
+ u8 value;
+ } stStatusCtrl;
+ /* 111 */
+ u8 ucRsvd;
+
+ /* 112~113 */
+ struct {
+ /* 112 */
+ u8 ucTxAlarmLow : 1;
+ u8 ucTxAlarmHigh : 1;
+ u8 ucTxBiasAlarmLow : 1;
+ u8 ucTxBiasAlarmHigh : 1;
+ u8 ucVccAlarmLow : 1;
+ u8 ucVccAlarmHigh : 1;
+ u8 ucTempAlarmLow : 1;
+ u8 ucTempAlarmHigh : 1;
+
+ /* 113 */
+ u8 ucRsvd : 6;
+ u8 ucRxAlarmLow : 1;
+ u8 ucRxAlarmHigh : 1;
+ } stAlarm;
+
+ /* 114~115 */
+ u8 aucUnAllocated3[2];
+
+ /* 116~117 */
+ struct {
+ /* 116 */
+ u8 ucTxWarnLo : 1;
+ u8 ucTxWarnHi : 1;
+ u8 ucBiasWarnLo : 1;
+ u8 ucBiasWarnHi : 1;
+ u8 ucVccWarnLo : 1;
+ u8 ucVccWarnHi : 1;
+ u8 ucTempWarnLo : 1;
+ u8 ucTempWarnHi : 1;
+
+ /* 117 */
+ u8 ucRsvd : 6;
+ u8 ucRxWarnLo : 1;
+ u8 ucRxWarnHi : 1;
+ } stWarning;
+
+ /* 118~119 */
+ u8 aucExtStatusAndCtrl[2];
+ } stDiag;
+
+ /* 120~255 */
+ struct {
+ u8 aucVendorSpec[8];
+ Sfp_a2_usr_region_t aucUserEeprom;
+ u8 aucVendorCtrl[8];
+ } stGeneralUseFields;
+} SfpDataFieldA2_S;
+
+/* SFP structure used in standard SFF-8472 Rev 10.4 */
+typedef struct tagSfpInfo_S {
+ SfpDataFieldA0_S stSfpInfoA0;
+ SfpDataFieldA2_S stSfpInfoA2;
+} SfpInfo_S;
+
+typedef SfpDataFieldA0_S tag_ncsi_sfp_data_fielda0;
+typedef SfpDataFieldA2_S tag_ncsi_sfp_data_fielda2;
+
+#endif // EEPROM_SFP_DEFS_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd.h
new file mode 100644
index 000000000..85ccdbdbc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_inband_cmd.h
+ * Version : Initial Draft
+ * Creation time : 2023/09/22
+ * Last Modified :
+ * Description : MCTP protocol out-of-band commands
+ */
+
+#ifndef MPU_OUTBAND_MCTP_CMD_H
+#define MPU_OUTBAND_MCTP_CMD_H
+
+/**
+ * @brief MCTP command code
+ */
+typedef enum {
+ RESERVED_ID = 0, /**< Reserved for future use */
+ SET_ENDPOINT_ID =
+ 0x01, /**< Set end point id @see struct res_data_eidset */
+ GET_ENDPOINT_ID =
+ 0x02, /**< Get end point id @see struct res_data_eidget */
+ GET_ENDPOINT_UUID =
+ 0x03, /**< Get end point uuid @see struct mctp_pcie_header */
+ GET_MCTP_VERSION_SUPPORT =
+ 0x04, /**< Get MCTP version support @see struct mctp_ver_type */
+ GET_MESSAGE_TYPE_SUPPORT = 0x05, /**< Get message type support */
+ GET_VENDOR_DEFINED_MESSAGE_SUPPORT =
+ 0x06, /**< Get vendor defined message support */
+ RESOLVE_ENDPOINT_ID = 0x07, /**< resolve endpoint id */
+ ALLOCATE_ENDPOINT_IDS =
+ 0x08, /**< Allocate endpoint ids, @see struct mctp_pcie_header */
+ ROUTING_INFORMATION_UPDATE = 0x09, /**< Routing endpoint ids */
+ GET_ROUTING_TABLE_ENTRIES =
+ 0x0a, /**< Get routing table entries, @see struct res_data_routing_tbl_get */
+ PREPARE_FOR_ENDPOINT_DISCOVERY =
+ 0x0b, /**< Prepare for endpoint discovery */
+ ENDPOINT_DISCOVERY = 0x0c, /**< Discovery endpoint */
+ DISCOVERY_NOTIFY = 0x0d, /**< Discovery Notify */
+ GET_NETWORK_ID = 0x0e, /**< Get network id */
+ QUERY_HOP = 0x0f, /**< Query HOP */
+ RESOVLE_ENDPOINT_UUID = 0x10 /**< resolve endpoint uuid */
+} mctp_cmd_type;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd_defs.h
new file mode 100644
index 000000000..8f280bd30
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_mctp_cmd_defs.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_inband_cmd_defs.h
+ * Version : Initial Draft
+ * Creation time : 2023/09/22
+ * Last Modified :
+ * Description : MCTP protocol out-of-band command related structure
+ */
+#ifndef MPU_OUTBAND_MCTP_CMD_DEFS_H
+#define MPU_OUTBAND_MCTP_CMD_DEFS_H
+
+#define MAX_NUM_ROUTING_TBL 5
+#define MAX_NUM_PHY_ADDR_SIZE 2
+
+/**
+ * @brief Define a struct named mctp_endpoint
+ */
+typedef struct {
+ u8 port_index; /**< Port index */
+ u8 eid; /**< Endpoint ID */
+ u16 bdf; /**< Bus, Device, Function */
+ u32 version; /**< MCTP version */
+ u8 discovery; /**< Discovery status */
+ u8 mc_id; /**< Management controller ID */
+ u16 mc_bdf; /**< Management controller Bus, Device, Function */
+ u8 trans_tag; /**< Transport layer tag */
+ u8 ctrl_msg_iid; /**< Control message instance ID */
+ u8 mc_inst_id; /**< Management controller instance ID */
+ u8 pcie_type; /**< PCIe device type */
+ u8 *msg; /**< Pointer to message buffer */
+ u8 rsv0; /**< Reserved */
+ u8 first_pkt_flag; /**< First packet flag */
+ u16 pkt_cnt; /**< Packet count */
+ u8 *mctp_rcv_buf; /**< Pointer to MCTP receive buffer */
+ u8 *mctp_send_buf; /**< Pointer to MCTP send buffer */
+ u16 rcv_offset; /**< Receive buffer offset */
+ u16 send_offset; /**< Send buffer offset */
+ u8 breq; /**< Request or response flag */
+ u8 rq; /**< MCTP control message rq field */
+ u8 cmd_code; /**< MCTP control header command code */
+ u8 msg_type; /**< MCTP control header message type */
+ u8 msg_tag; /**< MCTP control header message tag */
+ u8 tag_owner; /**< MCTP control header tag owner */
+} mctp_endpoint;
+
+/**
+ * @brief Define a struct named res_data_eidset
+ */
+typedef struct {
+ u8 complete_code; /**< The completion status of the EID set operation */
+
+ u8 eid_alloc_stat : 2; /**< The allocation status of the EID */
+ u8 rsv1 : 2; /**< Reserved for future use */
+ u8 eid_assign_stat : 2; /**< The assignment status of the EID */
+ u8 rsv2 : 2; /**< Reserved for future use */
+
+ u8 eid_set; /**< The EID set */
+
+ u8 eid_pool_size; /**< The size of the EID pool */
+} res_data_eidset;
+
+/**
+ * @brief Define the structure type as req_data_eidset
+ */
+typedef struct {
+ u8 operate : 2; /**< The eid set mode */
+ u8 rsv1 : 6; /**< Reserved for future use */
+ u8 eid; /**< The eid to be set */
+} req_data_eidset;
+
+/**
+ * @brief Define the structure type as res_data_eidget
+ */
+typedef struct {
+ u8 complete_code; /**< The complete code of the event */
+
+ u8 eid; /**< The endpoint identifier */
+
+ u8 eid_type : 2; /**< The eid type. 0:dynamic EID, 1:static EID */
+ u8 rsv1 : 2;
+ u8 endpoint_type : 2; /**< The endpoint type. 0:normal ep, 1:bus owner/brige */
+ u8 rsv2 : 2; /**< Reserved for future use */
+
+ u8 medium_info; /**< The medium info */
+} res_data_eidget;
+
+/**
+ * @brief Define the structure type as mctp_pcie_header
+ */
+typedef struct {
+ u16 length : 10; /**< The data length */
+ u16 rsv3 : 2; /**< Reserved for future use */
+ u16 attr : 2; /**< The attribute */
+ u16 ep : 1; /**< The error present */
+ u16 td : 1; /**< The owner of the tag field */
+
+ u8 rsv2 : 4; /**< Reserved for future use */
+ u8 tc : 3; /**< The traffic class */
+ u8 rsv1 : 1; /**< Reserved for future use */
+
+ u8 tpye : 5; /**< The message type */
+ u8 fmt : 2; /**< The message format */
+ u8 rsv : 1; /**< Reserved for future use */
+
+ u8 msg_code; /**< The MCTP message code. 0111_1111b */
+
+ u8 vdm_code : 4; /**< The VDM code */
+ u8 pad_len : 2; /**< The pad len of message */
+ u8 rsv4 : 2; /**< Reserved for future use */
+
+ u16 pci_request_id; /**< The pci request id, filled by hardware */
+
+ u16 vendor; /**< The vendor id */
+
+ u16 pci_target_id; /**< The pci target id */
+} mctp_pcie_header;
+
+/**
+ * @brief Define the structure type as res_resolve_eid
+ */
+typedef struct {
+ u8 complete_code; /**< The complete code of the event */
+ u8 bridge_eid; /**< The bridge eid */
+ u8 phy_addr[MAX_NUM_PHY_ADDR_SIZE]; /**< The physical address */
+} res_resolve_eid;
+
+/**
+ * @brief Define the structure type as mctp_ver_type
+ */
+typedef struct {
+ u8 major_ver; /**< The major version */
+ u8 minor_ver; /**< The minor version */
+ u8 update_ver; /**< The update version */
+ u8 pre_ver; /**< The previous version */
+} mctp_ver_type;
+
+/**
+ * @brief Define the structure type as routing_tbl_format
+ */
+typedef struct {
+ unsigned char size_of_EID_range; /**< The size of EID range */
+
+ unsigned char start_EID; /**< The start eid */
+
+ unsigned char port_num : 5; /**< The port number */
+ unsigned char dyna_static : 1; /**< The dynamic static */
+ unsigned char entry_type : 2; /**< The entry type */
+
+ unsigned char phy_binding_type; /**< The physical binding type */
+
+ unsigned char phy_media_type; /**< The physical media type */
+
+ unsigned char phy_addr_size; /**< The physical address size */
+
+ unsigned char
+ phy_addr[MAX_NUM_PHY_ADDR_SIZE]; /**< The physical address */
+} routing_tbl_format;
+
+/**
+ * @brief Define the structure type as res_data_routing_info_update_entry
+ */
+typedef struct {
+ u8 entry_type : 4; /**< The entry type */
+ u8 rsv : 4;
+ u8 size_eid_range; /**< The size of EID range */
+ u8 first_eid_in_eid_range; /**< The first eid */
+ u8 phy_addr[MAX_NUM_PHY_ADDR_SIZE]; /**< The physical address */
+} res_data_routing_info_update_entry;
+
+/**
+ * @brief Define the structure type as res_data_routing_tbl_get
+ */
+typedef struct {
+ unsigned char complete_code; /**< The complete code of event */
+
+ unsigned char next_enty_handle; /**< The next enty handle */
+
+ unsigned char num_routing_tbl; /**< The number of routing table */
+
+ routing_tbl_format routing_tbl
+ [MAX_NUM_ROUTING_TBL]; /**< Support saving 5 routing information */
+} res_data_routing_tbl_get;
+
+/**
+ * @brief Define the structure type as resolve_uuid_message_entry_format
+ */
+typedef struct {
+ u8 eid; /**< Endpoint ID */
+ u8 phy_transport_binding_type_id; /**< The physical transport binding type id */
+ u8 phy_media_type_id; /**< The physical transport type id */
+ u8 phy_addr_size; /**< The physical address size */
+ u8 phy_addr[MAX_NUM_PHY_ADDR_SIZE]; /**< The physical addresss */
+} resolve_uuid_message_entry_format;
+
+/**
+ * @brief Define the structure type as res_requry_hop_data
+ */
+typedef struct {
+ u8 complete_code; /**< The complete code of event */
+ u8 next_bridge_eid; /**< Next bridge eid */
+ u8 message_type; /**< Message type */
+ u16 max_incoming_transmission_unit_size; /**< Max incoming transmission unit size */
+ u16 max_outcoming_transmission_unit_size; /**< Max outcoming transmission unit size */
+} res_requry_hop_data;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd.h
new file mode 100644
index 000000000..685866a37
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_outband_ncsi_cmd.h
+ * Version : Initial Draft
+ * Creation time : 2023/09/22
+ * Last Modified :
+ * Description : NCSI protocol out-of-band commands
+ */
+#ifndef MPU_OUTBAND_NCSI_CMD_H
+#define MPU_OUTBAND_NCSI_CMD_H
+
+/**
+ * @brief NCSI protocol out-of-band operation commands
+ *
+ */
+typedef enum {
+ NCSI_CLEAR_INITIAL_STATE =
+ 0x00, /**< ncsi clear initial state command @see struct tg_clear_initial_state */
+ NCSI_SELECT_PACKAGE, /**< ncsi select packag command @see struct tg_select_package */
+ NCSI_DESELECT_PACKAGE, /**< ncsi deselect packag command @see struct tg_deselect_package */
+ NCSI_ENABLE_CHANNEL, /**< ncsi enable channel command @see struct tg_enable_channel */
+ NCSI_DISABLE_CHANNEL, /**< ncsi disable channel command @see struct tg_disable_channel */
+ NCSI_RESET_CHANNEL =
+ 0x05, /**< ncsi reset channel command @see struct tg_reset_channel */
+ NCSI_ENABLE_CHANNEL_NETWORK_TX, /**< ncsi enable channel network TX command @see struct tg_enable_chn_tx */
+ NCSI_DISABLE_CHANNEL_NETWORK_TX, /**< ncsi disable channel network TX command @see struct tg_disable_chn_tx */
+ NCSI_AEN_ENABLE, /**< ncsi AEN enable command @see struct tg_enable_aen */
+ NCSI_SET_LINK, /**< ncsi set link command @see struct tg_set_link */
+ NCSI_GET_LINK_STATUS =
+ 0x0a, /**< ncsi get link status command @see struct tg_get_link_status */
+ NCSI_SET_VLAN_FILTER, /**< ncsi set vlan filter command @see struct tg_set_vlan_filter */
+ NCSI_ENABLE_VLAN, /**< ncsi enable vlan command @see struct tg_enable_vlan */
+ NCSI_DISABLE_VLAN, /**< ncsi disable VLAN command @see struct tg_disable_vlan */
+ NCSI_SET_MAC_ADDRESS, /**< ncsi get MAC Address command @see struct tg_set_mac_address */
+ NCSI_ENABLE_BROADCAST_FILTERING =
+ 0x10, /**< ncsi enable broadcast filter command
+ @see struct tg_enable_broadcast */
+ NCSI_DISABLE_BROADCAST_FILTERING, /**< ncsi disbale broadcast filter command
+ @see struct tg_disable_broadcast */
+ NCSI_ENABLE_GLOBAL_MULTICAST_FILTERING, /**< ncsi enable global multicast filter command
+ @see struct tg_enable_multicast */
+ NCSI_DISABLE_GLOBAL_MULTICAST_FILTERING, /**< ncsi disable global multicast filter command
+ @see struct tg_disable_multicast */
+ NCSI_SET_NCSI_FLOW_CONTROL, /**< ncsi set ncsi flow control command
+ @see struct tg_set_flow_control */
+ NCSI_GET_VERSION_ID =
+ 0x15, /**< ncsi get version id command @see struct tg_get_version_id */
+ NCSI_GET_CAPABILITIES, /**< ncsi get capabilities command @see struct tg_get_capabilities */
+ NCSI_GET_PARAMETERS, /**< ncsi get parameters command @see struct tg_get_parameters */
+ NCSI_GET_CONTROLLER_PACKET_STATISTICS, /**< ncsi get controller packet statistics command
+ @see struct tg_get_packet_statistics */
+ NCSI_GET_NCSI_STATISTICS, /**< request the packet statistics specific to the NC-SI command
+ @see struct tg_get_ncsi_statistics */
+ NCSI_GET_NCSI_PASSTHROUGH_STATISTICS =
+ 0x1a, /**< request NC-SI Pass-through packet statistics command
+ @see struct tg_get_passthrough_statistics */
+ NCSI_GET_CHANNEL_STATE, /**< ncsi get channel state command
+ @see struct tg_get_channel_state */
+ NCSI_GET_REGISTER_VALUE, /**< ncsi get register value command
+ @see struct tg_get_register_value */
+ NCSI_SET_FWD_ACT, /**< ncsi set Fwd Act command @see struct tg_set_fwd_act */
+ NCSI_SET_FILTER_MODE = 0X1E, /**< reserved */
+ NCSI_SET_ARP_IP, /**< reserved */
+ NCSI_UPDATE_FIRMWARE, /**< reserved */
+ NCSI_GET_INVENTORY_INFO = 0x4e, /**< ncsi get inventory info command
+ @see struct tg_get_inventory_info */
+ NCSI_OEM_COMMAND =
+ 0x50, /**< ncsi oem command response @see struct tg_ncsi_oem_cmd_req */
+ NCSI_AEN_COMMAND = 0xff /**< reserved */
+} NCSI_CMD_E;
+
+/**
+ * @brief NCSI protocol out-of-band operation response
+ *
+ */
+typedef enum {
+ NCSI_CLEAR_INITIAL_STATE_RSP =
+ 0x80, /**< ncsi clear initial state response
+ @see struct tg_clear_initial_state_rsp */
+ NCSI_SELECT_PACKAGE_RSP, /**< ncsi select packag response @see struct tg_select_package_rsp */
+ NCSI_DESELECT_PACKAGE_RSP, /**< ncsi deselect packag response
+ @see struct tg_deselect_package_rsp */
+ NCSI_ENABLE_CHANNEL_RSP, /**< ncsi enable channel response @see struct tg_enable_channel_rsp */
+ NCSI_DISABLE_CHANNEL_RSP, /**< ncsi disable channel response
+ @see struct tg_disable_channel_rsp */
+ NCSI_RESET_CHANNEL_RSP, /**< ncsi reset channel response @see struct tg_reset_channel_rsp */
+ NCSI_ENABLE_CHANNEL_NETWORK_TX_RSP, /**< ncsi enable channel network TX response
+ @see struct tg_enable_chn_tx_rsp */
+ NCSI_DISABLE_CHANNEL_NETWORK_TX_RSP, /**< ncsi disable channel network TX response
+ @see struct tg_disable_chn_tx_rsp */
+ NCSI_AEN_ENABLE_RSP, /**< ncsi AEN enable response @see struct tg_enable_aen_rsp */
+ NCSI_SET_LINK_RSP, /**< ncsi set link response @see struct tg_set_link_rsp */
+ NCSI_GET_LINK_STATUS_RSP, /**< ncsi get link status response @see struct tg_get_link_status_rsp */
+ NCSI_SET_VLAN_FILTER_RSP, /**< ncsi set vlan filter response @see struct tg_set_vlan_filter_rsp */
+ NCSI_ENABLE_VLAN_RSP, /**< ncsi enable vlan response @see struct tg_enable_vlan_rsp */
+ NCSI_DISABLE_VLAN_RSP, /**< ncsi disable VLAN response @see struct tg_disable_vlan */
+ NCSI_SET_MAC_ADDRESS_RSP, /**< ncsi get MAC Address response @see struct tg_set_mac_address_rsp */
+ NCSI_ENABLE_BROADCAST_FILTERING_RSP =
+ 0x90, /**< enable broadcast filter response
+ @see struct tg_enable_broadcast_rsp */
+ NCSI_DISABLE_BROADCAST_FILTERING_RSP, /**< ncsi disbale broadcast filter response
+ @see struct tg_disable_broadcast_rsp */
+ NCSI_ENABLE_GLOBAL_MULTICAST_FILTERING_RSP, /**< ncsi enable global multicast filter response
+ @see struct tg_enable_multicast_rsp */
+ NCSI_DISABLE_GLOBAL_MULTICAST_FILTERING_RSP, /**< ncsi disable global multicast filter response
+ @see struct tg_disable_multicast_rsp */
+ NCSI_SET_NCSI_FLOW_CONTROL_RSP, /**< ncsi set ncsi flow control response
+ @see struct tg_set_flow_control_rsp */
+ NCSI_GET_VERSION_ID_RSP, /**< ncsi get version id response @see struct tg_get_version_id_rsp */
+ NCSI_GET_CAPABILITIES_RSP, /**< ncsi get capabilities response
+ @see struct tg_get_capabilities_rsp */
+ NCSI_GET_PARAMETERS_RSP, /**< ncsi get parameters response @see struct tg_get_parameters_rsp */
+ NCSI_GET_CONTROLLER_PACKET_STATISTICS_RSP, /**< ncsi get controller packet statistics response
+ @see struct tg_get_packet_statistics_rsp */
+ NCSI_GET_NCSI_STATISTICS_RSP, /**< request the packet statistics specific to the NC-SI command
+ @see struct tg_get_ncsi_statistics_rsp */
+ NCSI_GET_NCSI_PASSTHROUGH_STATISTICS_RSP, /**< request NC-SI Pass-through packet statistics response
+ @see struct tg_get_passthrough_statistics_rsp */
+ NCSI_GET_CHANNEL_STATE_RSP, /**< ncsi get channel state response
+ @see struct tg_get_channel_state_rsp */
+ NCSI_GET_REGISTER_VALUE_RSP, /**< ncsi get regiset value response
+ @see struct tg_get_register_value_rsp */
+ NCSI_SET_FWD_ACT_RSP, /**< ncsi set Fwd Act response @see struct tg_set_fwd_act_rsp */
+ NCSI_SET_FILTER_MODE_RSP = 0X9E, /**< reserved */
+ NCSI_SET_ARP_IP_RSP, /**< reserved */
+ NCSI_UPDATE_FIRMWARE_RSP, /**< reserved */
+ NCSI_GET_INVENTORY_INFO_RSP =
+ 0xCE, /**< ncsi get inventory info response
+ @see struct tg_get_inventory_info_rsp */
+ NCSI_OEM_COMMAND_RSP =
+ 0xD0 /**< ncsi oem command response @see struct tg_ncsi_oem_cmd_req */
+} NCSI_CMD_RSP_E;
+
+/* ncsi oem命令sub id低8位,huawei_id高8位 */
+/**
+ * @brief ncsi oem命令sub id低8位,huawei_id高8位
+ *
+ */
+typedef enum {
+ OEM_GET_NETWORK_INTERFACE_BDF =
+ 0x1, /**< oem get network interface bdf response
+ @see struct tg_oem_get_bdf_rsp */
+ OEM_GET_PART_NUMBER = 0x2, /**< reserved */
+ OEM_GET_DRIVER_NAME = 0x4, /**< reserved */
+ OEM_GET_PCIE_ABILITY =
+ 0x5, /**< oem get the pcie interface ability response
+ @see struct tg_oem_get_pcie_ability_rsp */
+ OEM_GET_PCIE_STATUS = 0x6, /**< oem get the pcie interface status
+ @see struct tg_oem_get_pcie_status_rsp */
+ OEM_GET_NETWORK_INTERFACE_DATA_RATE = 0x7, /**< reserved */
+ OEM_GET_NETWORK_INTERFACE_MEDIA_TYPE =
+ 0x9, /**< oem get network interface media type response
+ @see struct tag_oem_get_network_interface_media_type_rsp */
+ OEM_GET_JUNCTION_TEMP =
+ 0xa, /**< oem get the junction temperature response
+ @see struct tag_oem_get_junction_temp_rsp */
+ OEM_GET_OPTICAL_MODULE_TEMP =
+ 0xb, /**< oem get the optical module temperature response
+ @see struct tag_oem_get_opt_modu_temp_rsp */
+ OEM_GET_ERR_CODE =
+ 0xc, /**< oem get the err code response @see struct tag_oem_get_err_code_rsp */
+ OEM_GET_NETWORK_INTERFACE_TRANS_CABLE_INFO =
+ 0xd, /**< oem get the transceiver or cable information response
+ @see struct tag_oem_get_trans_or_cable_info_rsp */
+ OEM_ENABLE_LLDP_CAPTURE = 0xe, /**< oem enable LLDP capture response
+ @see struct tag_oem_enable_lldp_capture_rsp */
+ OEM_GET_LLDP_CAPBILITY = 0xf, /**< oem get lldp capbility response
+ @see struct tag_oem_get_lldp_capbility_rsp */
+ OEM_GET_HW_OEM_CMD_CAPABILITY =
+ 0x11, /**< oem get oem command capbility response
+ @see struct tag_oem_get_oem_command_cap_resp */
+ OEM_GET_LLDP_TX_CAPBILITY =
+ 0x13, /**< oem enable/disable lldp tx @see struct tag_oem_get_lldp_tx_capbility_rsp */
+ OEM_ENABLE_LLDP_TX =
+ 0x14, /**< oem get lldp tx cap @see struct tag_oem_enable_lldp_tx_rsp */
+ OEM_GET_LOG_INFO =
+ 0x15, /**< oem get log info response @see struct tag_oem_get_log_info_rsp */
+ OEM_GET_NEW_LOG_INFO = 0x16,
+ OEM_SET_OPTICAL_MODULE_SWITCH =
+ 0x19, /**< oem enable/disable optical_module
+ @see struct tag_set_optical_module_switch_rsp */
+ OEM_SET_OPTICAL_MODULE_POWER =
+ 0x1a, /**< oem enable/disable optical_module power
+ @see struct tag_set_optical_module_power_rsp */
+ OEM_GET_PCIE_ALARM_INFO = 0x1b, /**< oem get pcie alarm info
+ @see struct tag_oem_get_pcie_alarm_info_rsp */
+ OEM_GET_XSFP_PRESENT_STATUS =
+ 0x20, /**< oem get sfp present status response @see struct tag_oem_get_xsfp_status_rsp */
+} OEM_SUB_CMD_ID_NIC_PUB_E;
+
+/* ncsi oem命令sub id(nic info) */
+/**
+ * @brief ncsi oem命令sub id(nic info)
+ *
+ */
+typedef enum {
+ OEM_GET_NETWORK_INTERFACE_MAC_ADDR =
+ 0x100, /**< oem get netork interface mac addr response
+ @see struct tag_oem_get_netork_interface_mac_addr_rsp */
+ OEM_GET_NETWORK_INTERFACE_IP_ADDR = 0x101, /**< reserved */
+ OEM_GET_NETWORK_INTERFACE_DCBX =
+ 0x102, /**< oem get networ interface dcbx response
+ @see struct tag_oem_get_network_interface_dcbx_rsp */
+ OEM_GET_NETWORK_DEFAULT_MAC_ADDR =
+ 0x104 /**< oem get default mac addr response
+ @see struct tag_oem_get_default_mac_addr_rsp */
+} OEM_SUB_CMD_ID_NIC_INFO_E;
+
+/* base configuration(NIC) */
+typedef enum {
+ OEM_ENABLE_LLDP_OVER_NCSI =
+ 0x40A, /**< oem enable lldp over ncsi command
+ @see struct tag_oem_enable_lldp_over_ncsi
+ @see struct tag_oem_enable_lldp_over_ncsi_resp */
+ OEM_GET_LLDP_OVER_NCSI_STATUS =
+ 0x40B, /**< oem enable lldp over ncsi command
+ @see struct tag_oem_get_lldp_over_ncsi_status
+ @see struct tag_oem_get_lldp_over_ncsi_status_resp */
+ OEM_ENABLE_LOW_POWER_MODE =
+ 0x40C, /**< oem enable low power mode command
+ @see struct tag_oem_enable_low_power_mode
+ @see struct tag_oem_enable_low_power_mode_resp */
+ OEM_GET_LOW_POWER_MODE_STATUS =
+ 0x40D /**< oem get low power mode status command
+ @see struct tag_oem_get_low_power_mode_status
+ @see struct tag_oem_enable_low_power_mode_resp */
+} OEM_SUB_CMD_ID_BASE_CFG_NIC;
+
+/* Stateless compute configuration NIC */
+typedef enum {
+ OEM_SET_VOLATILE_MAC = 0x508, /**< ncsi oem set volatile mac command
+ @see struct tag_oem_set_volatile_mac
+ @see struct tag_oem_set_volatile_mac_resp */
+ OEM_GET_VOLATILE_MAC = 0x509 /**< ncsi oem get volatile mac command
+ @see struct tag_oem_get_volatile_mac
+ @see struct tag_oem_get_volatile_mac_resp */
+} OEM_SUB_CMD_ID_NIC_STATELESS_CFG_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_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd_defs.h
new file mode 100644
index 000000000..2ab9a0c47
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_outband_ncsi_cmd_defs.h
+ * Version : Initial Draft
+ * Creation time : 2023/09/22
+ * Last Modified :
+ * Description : NCSI protocol out-of-band command related structure
+ */
+#ifndef MPU_OUTBAND_NCSI_CMD_DEFS_H
+#define MPU_OUTBAND_NCSI_CMD_DEFS_H
+
+#include "base_type.h"
+
+#pragma pack(1)
+
+typedef enum {
+ COMMAND_COMPLETED = 0x00, /**< command completed */
+ COMMAND_FAILED = 0x01, /**< command failed */
+ COMMAND_UNAVAILABLE = 0x02, /**< command unavailable */
+ COMMAND_UNSPORRTED = 0x03 /**< command unsporrted */
+} NCSI_RESPONSE_CODE_E;
+
+typedef enum {
+ NO_ERROR = 0x00, /**< no error */
+ INTERFACE_INIT_REQUIRED = 0x01, /**< interface init required */
+ INVALID_PARA = 0x02, /**< invalid parameter */
+ CHAN_NOT_READY = 0x03, /**< channel not ready */
+ PKG_NOT_READY = 0x04, /**< package not ready */
+ INVALID_PAYLOAD_LEN = 0x05, /**< invalid payload len */
+ FLOW_CONTROL_UNSUPPORTED = 0x09, /**< flow control unsupported */
+ CHECKSUM_ERR = 0xA, /**< check sum error */
+ LINK_STATUS_ERROR = 0xA06, /**< set or get link status failed */
+ VLAN_TAG_INVALID = 0xB07, /**< vlan tag invalid */
+ MAC_Add_IS_ZERO = 0xE08, /**< mac add is zero */
+ GET_INVENTORY_INFO_ERROR = 0xE09, /**< get inventory info error */
+ UNSUPPORTED_COMMAND_TYPE =
+ 0x7FFF /**< the command type is unsupported only when the response code is 0x03 */
+} NCSI_REASON_CODE_E;
+
+typedef enum {
+ NCSI_RMII_TYPE = 1, /**< rmii client */
+ NCSI_MCTP_TYPE = 2, /**< MCTP client */
+ NCSI_AEN_TYPE = 3 /**< AEN client */
+} NCSI_CLIENT_TYPE_E;
+
+/**
+ * @brief ncsi ctrl packet header
+ *
+ */
+typedef struct tag_ncsi_ctrl_packet_header {
+ u8 mc_id; /**< management control ID */
+ u8 head_revision; /**< head revision */
+ u8 reserved0; /**< reserved */
+ u8 iid; /**< instance ID */
+ u8 pkt_type; /**< packet type */
+#ifdef NCSI_BIG_ENDIAN
+ u8 pkg_id : 3; /**< packet ID */
+ u8 inter_chan_id : 5; /**< channel ID */
+#else
+ u8 inter_chan_id : 5; /**< channel ID */
+ u8 pkg_id : 3; /**< packet ID */
+#endif
+#ifdef BD_BIG_ENDIAN
+ u8 reserved1 : 4; /**< reserved1 */
+ u8 payload_len_hi : 4; /**< payload len have 12bits */
+#else
+ u8 payload_len_hi : 4; /**< payload len have 12bits */
+ u8 reserved1 : 4; /**< reserved1 */
+#endif
+ u8 payload_len_lo; /**< payload len lo */
+ u32 reserved2; /**< reserved2 */
+ u32 reserved3; /**< reserved3 */
+} ncsi_ctrl_pkt_header_s;
+
+#define NCSI_MAX_PAYLOAD_LEN 1500
+#define NCSI_MAC_LEN 6
+/* get dafault mac address(huawei_id:0x1, sub_id:0x04) */
+#define MAC_ADDRESS_NUM (6) // 有定义,后面可以搞
+
+/**
+ * @brief ncsi clear initial state command struct defination
+ *
+ */
+typedef struct tag_ncsi_ctrl_packet {
+ ncsi_ctrl_pkt_header_s packet_head; /**< ncsi ctrl packet header */
+ u8 payload[NCSI_MAX_PAYLOAD_LEN]; /**< ncsi ctrl packet payload */
+} ncsi_ctrl_packet_s;
+
+/**
+ * @brief ethernet header description
+ *
+ */
+typedef struct tag_ethernet_header {
+ u8 dst_addr[NCSI_MAC_LEN]; /**< ethernet destination address */
+ u8 src_addr[NCSI_MAC_LEN]; /**< ethernet source address */
+ u16 ether_type; /**< ethernet type */
+} ethernet_header_s;
+
+/**
+ * @brief ncsi common packet description
+ *
+ */
+typedef struct tg_ncsi_common_packet {
+ ethernet_header_s frame_head; /**< common packet ethernet frame header */
+ ncsi_ctrl_packet_s ctrl_packet; /**< common packet ncsi ctrl packet */
+} ncsi_common_packet_s, *p_ncsi_common_packet_s;
+
+/**
+ * @brief ncsi clear initial state command struct defination
+ *
+ */
+typedef struct tag_ncsi_client_info {
+ u32 type; /**< client info type of ncsi media @see enum NCSI_CLIENT_TYPE_E */
+ u8 bmc_mac[NCSI_MAC_LEN]; /**< client info BMC mac addr */
+ u8 ncsi_mac[NCSI_MAC_LEN]; /**< client info local mac addr */
+ u8 reserve[2]; /**< client info reserved, Four-byte alignment */
+ u32 rsp_len; /**< client info include pad */
+ ncsi_common_packet_s ncsi_packet_rsp; /**< ncsi common packet response */
+} ncsi_client_info_s;
+
+#pragma pack()
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd.h
new file mode 100644
index 000000000..1bbca9205
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_outband_smbus_cmd.h
+ * Version : Initial Draft
+ * Creation time : 2023/09/22
+ * Last Modified :
+ * Description : SMBUS protocol out-of-band commands
+ */
+
+#ifndef MPU_OUTBAND_SMBUS_CMD_H
+#define MPU_OUTBAND_SMBUS_CMD_H
+
+/**
+ * @brief SMBUS command code
+ */
+
+/* SMBUS 命令字, 操作码定义,与平台保持一致 */
+typedef enum {
+ SMB_OPC_ABILITY =
+ 0x0, /**< collect ability info,connect to bmc framework @see smb_ability_s */
+ SMB_OPC_DEVICE_HEALTH =
+ 0x1, /**< get device health status @see struct smb_device_health_s */
+ SMB_OPC_ERR_CODE =
+ 0x2, /**< get error code when status is not 0 @see smb_com_res_s */
+ SMB_OPC_TEMP = 0x3, /**< get temperature @see smb_temperature_s */
+ SMB_OPC_FIRMWARE_VER =
+ 0x05, /**< get fw version @see smb_firmware_ver_s */
+ SMB_OPC_TEMP_THRESHOLD =
+ 0x7, /**< set or get temp threshold @see smb_temp_threshold_data_s */
+ SMB_OPC_LOG = 0x0C, /**< get log @see smb_log_s */
+ SMB_OPC_LAST_WORD = 0x0D, /**< get last word @see smb_log_s */
+ SMB_OPC_ROUTING_INSPEC = 0x0E, /**< get inspec info @see smb_log_s */
+ SMB_OPC_BOARD_ID = 0x0F, /**< get borad id @see smb_board_id_s */
+ SMB_OPC_PCB_ID = 0x10, /**< get pcb id @see smb_pcb_id_s */
+ SMB_OPC_SET_EEPROM_WP =
+ 0x31, /**< set EEPROM write protect status @see smb_eeprom_wp_rsp_s */
+
+ /* SLT opcode define add opc need modify get tx len */
+ SMB_SLT_OPC_WR =
+ 0x50, /**< STL write reg data @see smb_read_write_reg_s */
+ SMB_SLT_OPC_RD =
+ 0x51, /**< STL read reg data @see smb_read_write_reg_s */
+ SMB_SLT_OPC_TEMP = 0x52, /**< reversed */
+
+ SMB_OPC_MAC_ADDR = 0x404, /**< get mac addr @see smb_mac_addr_s */
+ SMB_OPC_WORK_MAC_ADDR =
+ 0x408, /**< get work mac addr @see smb_mac_addr_s */
+ SMB_OPC_PHYPORT_LINK_INFO =
+ 0x409, /**< get phyport link info @see smb_xsfp_present_status_rep_s */
+ SMB_OPC_PCIE_UBC_CAP_INFO =
+ 0x410, /**< get pcie/ubc info @see smb_pcie_ubc_info_s */
+ SMB_OPC_PCIE_UBC_INFO =
+ 0x411, /**< get pcie/ubc info @see smb_pcie_ubc_info_s */
+ SMB_OPC_GET_XSFP_STATIC_INFO =
+ 0x412, /**< get xsfp static info @see smb_xsfp_dynamic_info_rep_s */
+ SMB_OPC_GET_XSFP_DYNAMIC_INFO =
+ 0x413, /**< get xsfp dynamic info @see smb_xsfp_static_info_rep_s */
+ SMB_OPC_XSFP_PERSENT_STATUS =
+ 0x414, /**< get xsfp present status @see smb_xsfp_present_status_rep_s */
+ SMB_OPC_XSFP_DOWN_TIME_INFO =
+ 0x415, /**< get xsfp down-time info @see smb_xsfp_down_time_info_rep_s */
+ SMB_OPC_XSFP_DOWN_TIME_SERDES_INFO =
+ 0x416, /**< get xsfp down-time serdes info @see smb_xsfp_down_time_serdes_info_rep_s */
+ SMB_OPC_SET_SLOT_ID =
+ 0x4F0, /**< set slot_id @see smb_pcie_ubc_info_s */
+ SMB_OPC_SET_PORT_NUM =
+ 0x4F1, /**< set port num @see smb_respon_header_s */
+ SMB_OPC_GET_PORT_NUM =
+ 0x4F2, /**< get port num @see smb_get_port_num_s */
+ SMB_OPC_CONVERGE_PORT_INFO =
+ 0x4F3, /**< get converge port info @see smb_converge_port_info_rep_s */
+ SMB_OPC_CONVERGE_XSFP_INFO =
+ 0x4F4, /**< get converge port info @see smb_converge_xsfp_info_rep_s */
+ SMB_OPC_GET_FIRMWARE_VER_STR =
+ 0x0030, /**< get fiemware version string @see smb_firmware_ver_str_s */
+ SMB_OPC_PCIE_DFX = 0xffffffff, /* pcie dfx带外暂时不实现 */
+
+ /* MAG */
+ SMB_OPC_SFP_TEMP_THRESHOLD =
+ 0x8, /**< get or set sfp temp threshold addr @see smb_sfp_temp_threshold_s */
+ /* 注意:SMB_PANGEA_V6_OPC_SFP_TEMP该命令字对应opcode与1872中使用的SMB_OPC_PCB_ID命令字的opcode存在冲突,经讨论,
+ 针对SMB_PANGEA_V6_OPC_SFP_TEMP该仅在1825盘古场景上使用的命令字在后续使用时再行确定具体opcode值 */
+ SMB_PANGEA_V6_OPC_SFP_TEMP =
+ 0x10, /**< PANGEA_V6 get sfp temp @see smb_sfp_temp_threshold_s */
+ SMB_PANGEA_V6_OPC_PHY_TEMP = 0x15, /**< not supported */
+ SMB_OPC_SFP_TEMP =
+ 0x400, /**< get sfp temperature @see smb_sfp_temp_s */
+ SMB_OPC_LINK_STATUS =
+ 0x403, /**< get link status @see smb_link_stat_s */
+ SMB_OPC_PHY_TEMP = 0x405, /**< not supported */
+ SMB_OPC_RESTORE_VER = 0x406, /**< mpu restore version */
+ SMB_OPC_SFP_ID = 0x407, /**< get sfp id @see smb_sfp_id_s */
+
+ /* IMU */
+ IMU_MCU_OPC_GET_SPU_TEMP =
+ 0x10f0, /**< get Totem temperature @see smb_spu_temp_s */
+ IMU_MCU_OPC_SET_SPU_FREQ_UP, /**< set Totem frequency up @see smb_spu_freq_resp_s */
+ IMU_MCU_OPC_SET_SPU_FREQ_DOWN, /**< set Totem frequency down @see smb_spu_freq_resp_s */
+ IMU_MCU_OPC_ENABLE_PWRLIMIT, /**< enable powerlimit @see smb_spu_pwrlimit_en_s */
+ IMU_MCU_OPC_DISABLE_PWRLIMIT, /**< disable powerlimit @see smb_spu_pwrlimit_en_s */
+ IMU_MCU_OPC_GET_SPU_RAS_INFO_NUM, /**< get Totem RAS info num @see smb_spu_ras_num_s */
+ IMU_MCU_OPC_GET_SPU_RAS_INFO, /**< get Totem RAS info @see smb_spu_ras_s */
+
+ /* DFT */
+ SMB_DFT_OPC_EQUIP = 0x04FE, /**< DFT equip test and use */
+} SMBUS_OP_CODE_E;
+
+/* smbus equip sub_opcode使用:装备命令字 opcode = 0x04FE */
+typedef enum {
+ SMB_SUB_OPC_DIE_ID = 0x1,
+ SMB_SUB_OPC_SRAM_MBIST = 0x2,
+ SMB_SUB_OPC_DCIP_TEST = 0x3,
+ SMB_SUB_OPC_VPD_SET = 0x4,
+ SMB_SUB_OPC_VPD_GET = 0x5,
+ SMB_SUB_OPC_RESET = 0x6,
+ SMB_SUB_OPC_GUID_SET = 0x7,
+ SMB_SUB_OPC_GUID_GET = 0x8,
+ SMB_SUB_OPC_I2C_TEST = 0x9,
+
+ SMB_SUB_OPC_SET_LOOPBACK = 0x10,
+ SMB_SUB_OPC_GET_SNR = 0x11,
+
+ SMB_SUB_OPC_PRBS = 0x20,
+ SMB_SUB_OPC_MAC_SET = 0x21,
+ SMB_SUB_OPC_MAC_GET = 0x22,
+ SMB_SUB_OPC_EFUSE_BURN = 0x23,
+ SMB_SUB_OPC_LED_SET = 0x24,
+ SMB_SUB_OPC_POWER_GET = 0x25,
+ SMB_SUB_OPC_GPIO_TEST = 0x26,
+
+ SMB_SUB_OPC_H2H = 0x40,
+} smbus_equip_sub_opcode_e;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd_defs.h
new file mode 100644
index 000000000..44dfa026d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_outband_smbus_cmd_defs.h
@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_outband_smbus_cmd_defs.h
+ * Version : Initial Draft
+ * Creation time : 2023/09/22
+ * Last Modified :
+ * Description : SMBUS protocol out-of-band command related structure
+ */
+
+#ifndef MPU_OUTBAND_SMBUS_CMD_DEFS_H
+#define MPU_OUTBAND_SMBUS_CMD_DEFS_H
+
+#include "ethmac_api.h"
+#include "mpu_inband_cmd_defs.h"
+#include "mpu_outband_ncsi_cmd_defs.h"
+
+#define SMB_SINGLE_SLICE_LOG_LEN 48
+#define MAX_PORT_LEN 8
+#define SMB_MAC_ADDR_INFO_LEN (48)
+#define SMB_SPU_RAS_LEN (12)
+#define SMB_PCIE_UBC_INFO_LEN (48)
+#define SMB_PCIE_UBC_INFO_SIZE (4)
+#define SMB_MAX_PCIE_UBC_INFO_MAX_SIZE 96
+
+#define SMB_PORT_NUM 24
+#define SFP_MAX_PORT_NUM 8 /* 光模块端口数 */
+#define SMB_INFO_MEMORY_LEN 128
+
+#define SMB_VERSION_INFO_MAX_LEN 48
+
+/* 带外管理公共的响应消息头 */
+typedef struct {
+ u16 errcode;
+ u16 opcode;
+ u32 total_length;
+ u32 length;
+} smb_respon_header_s;
+
+typedef struct {
+ u16 req_para;
+ u16 opcode;
+ u32 offset;
+ u32 length;
+} smb_request_header_s;
+
+/* 带外管理消息头部 */
+typedef struct {
+ u16 reserved;
+ u16 opcode;
+} smb_ctrl_header_s;
+
+/*
+ * 巡检信息文件结构: smb_inspec_data_header + TLV + TLV + ...
+ * 对于每个Tag,如果出现多次,则表明该Tag是数组
+ */
+#define SMB_INSPEC_DATA_MAGIC_NUM 0x418deb6f
+typedef struct {
+ u32 magic_num; /**< SMB_INSPEC_DATA_MAGIC_NUM */
+ u32 data_size; /**< 巡检信息总长度(不含该头) */
+} smb_inspec_data_header;
+
+typedef enum {
+ SMB_INSPEC_FW_VERSIONS, /**< smb_inspec_fw_versions */
+ SMB_INSPEC_BASIC_INFO, /**< smb_inspec_basic_info */
+ SMB_INSPEC_RES_USAGE, /**< smb_inspec_res_usage */
+ SMB_INSPEC_CELL_INFO, /**< chip_cell_info_s */
+ SMB_INSPEC_IPSU_PKT_ERR_CNT, /**< ipsurx_pkt_err_cnt_s */
+ SMB_INSPEC_BOARD_INFO, /**< struct hinic5_board_info */
+ SMB_INSPEC_MAG_PORT_STATS, /**< struct mag_port_stats */
+ SMB_INSPEC_MPU_COUNTER, /**< SRAM_COUNTER_BASE */
+ SMB_INSPEC_NPU_COUNTER, /**< flash_crucial_header_s + crucial_ctr_range_s + npu counters */
+} smb_inspec_data_tag_e;
+
+typedef struct {
+ u32 tag : 8; /**< smb_inspec_data_tag_e */
+ u32 len : 24;
+ u8 val[0];
+} smb_inspec_tlv;
+
+/* SMB_INSPEC_FW_VERSIONS */
+typedef struct {
+ u32 mpu_version;
+ u32 npu_version;
+ u32 reserved[18]; /**< 预留18个u32来扩展 */
+} smb_inspec_fw_versions;
+
+/* SMB_INSPEC_BASIC_INFO */
+typedef struct {
+ u16 pcie_cap;
+ u16 port_num;
+ u16 port_speed_mode;
+ u16 work_mode;
+ u16 sub_work_mode;
+ u16 reserved;
+ u16 link_status[MAX_PORT_LEN];
+ u16 port_mode[MAX_PORT_LEN];
+ u16 speed[MAX_PORT_LEN];
+} smb_inspec_basic_info;
+
+/* SMB_INSPEC_RES_USAGE */
+typedef struct {
+ u32 cpu_usage;
+ u32 memory_usage;
+ u32 usage_unit; /**< 4bytes 当前单位为1/10000 */
+} smb_inspec_res_usage;
+
+/* SMB_INSPEC_CELL_INFO */
+typedef struct {
+ u32 total_cell_num;
+ u32 free_cell_num;
+ u32 pdm_glb_num;
+ u32 cpi_octl_cell_num;
+ u32 leak_cell_num;
+ u32 fq_free_oeid_num;
+} chip_cell_info_s;
+
+/* SMB_INSPEC_IPSU_PKT_ERR_CNT */
+typedef struct {
+ u32 abort_bf_ipsurx_cnt;
+ u32 sop_sop_err_cnt;
+ u32 dmac_zero_cnt;
+ u32 da_sa_equal_cnt;
+ u32 arp_posi_ilgl_cnt;
+ u32 ipv4_ver_ilgl_cnt;
+ u32 ipv4_ihl_ilgl_cnt;
+ u32 ipv4_sip_ilgl_cnt;
+ u32 ipv4_dip_ilgl_cnt;
+ u32 ipv6_ver_ilgl_cnt;
+ u32 ipv6_sip_ilgl_cnt;
+ u32 ipv6_dip_ilgl_cnt;
+ u32 tcp_land_ilgl_cnt;
+ u32 rocev1_dgid_ilgl_cnt;
+ u32 rocev1_sgid_ilgl_cnt;
+ u32 rocev1_ipver_ilgl_cnt;
+ u32 rocev1_nxhdr_ilgl_cnt;
+ u32 roce_dqp_ilgl_cnt;
+ u32 eth_len_ilgl_cnt;
+ u32 pkt_min_len_ilgl_cnt;
+ u32 pkt_max_len_ilgl_cnt;
+ u32 ipv4_cs_ilgl_cnt;
+ u32 tcp_cs_ilgl_cnt;
+ u32 udp_cs_ilgl_cnt;
+ u32 igmp_cs_ilgl_cnt;
+ u32 icmpv4_cs_ilgl_cnt;
+ u32 icmpv6_cs_ilgl_cnt;
+ u32 sctp_cs_ilgl_cnt;
+ u32 fc_crc_ilgl_cnt;
+ u32 rocev1_plen_ilgl_cnt;
+ u32 ib_icrc_ilgl_cnt;
+ u32 smac_ilgl_cnt;
+ u32 ipv6_udp_cs_zero_cnt;
+ u32 rocev2_ipv4_frag_ilgl_cnt;
+ u32 rocev2_ipv4_udp_cs_ilgl_cnt;
+ u32 rocev2_ipv6_udp_cs_ilgl_cnt;
+ u32 to_up_pkt_ilgl_cnt;
+ u32 to_bmc_only_pkt_ilgl_cnt;
+} ipsurx_pkt_err_cnt_s;
+
+#pragma pack(1) /* 一字节对齐 */
+
+typedef struct {
+ smb_inspec_data_header header;
+
+ smb_inspec_tlv fw_ver_tlv;
+ smb_inspec_fw_versions fw_ver_data;
+
+ smb_inspec_tlv basic_info_tlv;
+ smb_inspec_basic_info basic_info_data;
+
+ smb_inspec_tlv res_usage_tlv;
+ smb_inspec_res_usage res_usage_data;
+
+ smb_inspec_tlv cell_info_tlv;
+ chip_cell_info_s cell_info_data;
+
+ smb_inspec_tlv ipsurx_pkt_err_cnt_tlv;
+ ipsurx_pkt_err_cnt_s ipsurx_pkt_err_cnt_data;
+
+ smb_inspec_tlv board_info_tlv;
+ struct hinic5_board_info board_info_data;
+} smb_inspec_info_s;
+
+typedef union {
+ /* 保证结构体的每个成员的大小为32 */
+ struct {
+ u16 id;
+ u8 type;
+ u8 reserved;
+ u16 cap_num;
+ u16 opc_data[(SMB_SINGLE_SLICE_LOG_LEN - 6) / 2];
+ } first_frame;
+ struct {
+ u16 opc_data[SMB_SINGLE_SLICE_LOG_LEN / 2];
+ } other_frame;
+} ability_data_u;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ ability_data_u ability_data;
+ u32 crc32;
+} smb_ability_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 health_status;
+ u32 crc32;
+} smb_device_health_s;
+
+/* Define the common struct 32bytes data u16,example:errcode */
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 data[SMB_SINGLE_SLICE_LOG_LEN];
+ u32 crc32;
+} smb_com_res_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ s16 temp; /* 需要将实际温度扩大10倍发送给master */
+ u32 crc32;
+} smb_temperature_s;
+
+/* 阈值 */
+typedef struct {
+ s32 max_temp; /**< 芯片核温阈值 */
+ s32 min_temp; /**< 芯片核温阈值 */
+} smb_temp_threshold_data_s;
+
+/* 核温阈值 */
+typedef struct {
+ smb_ctrl_header_s header;
+ u32 op_type; /**< 0:读阈值;1:写阈值 */
+ smb_temp_threshold_data_s
+ temp_threshold_data; /**< temperature threshold @see smb_temp_threshold_data_s */
+ u32 crc32;
+} smb_temp_threshold_s;
+
+/* Define the struct read_log 48bytes log,lastword?rrespec */
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 log_data[SMB_SINGLE_SLICE_LOG_LEN]; /* master 读日志的长度能力小于该值需要按照master能力处理 */
+ u32 crc32;
+} smb_log_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u16 board_id;
+ u32 crc32;
+} smb_board_id_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 pcb_id;
+ u32 crc32;
+} smb_pcb_id_s;
+
+typedef struct {
+ smb_respon_header_s header;
+ u8 eeprom_wp_enable;
+ u32 crc32;
+} smb_eeprom_wp_req_s;
+
+typedef struct {
+ smb_respon_header_s header;
+ u32 crc32;
+} smb_eeprom_wp_rsp_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ s16 phy_temp_data[SMB_PORT_NUM];
+ u32 crc32;
+} smb_phy_temp_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ s16 sfp_temp_data[SMB_PORT_NUM];
+ u32 crc32;
+} smb_sfp_temp_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u16 sfp_id_data[SFP_MAX_PORT_NUM];
+ u32 rsvd0;
+ u32 rsvd1;
+ u32 crc32;
+} smb_sfp_id_s;
+
+typedef struct {
+ smb_ctrl_header_s header;
+ u32 op_type; /**< 0:读阈值;1:写阈值 */
+ smb_temp_threshold_data_s
+ sfp_threshold_data; /**< temperature threshold @see smb_temp_threshold_data_s */
+ u32 crc32;
+} smb_sfp_temp_threshold_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 link_stat[SMB_PORT_NUM];
+ u32 crc32;
+} smb_link_stat_s;
+
+typedef struct {
+ u8 major;
+ u8 minor;
+ u8 revison; /* revison若不涉及则填0xff */
+} firmware_ver_data_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ firmware_ver_data_s ver_data;
+ u32 crc32;
+} smb_firmware_ver_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 version_str[SMB_VERSION_INFO_MAX_LEN];
+ u32 crc32;
+} smb_firmware_ver_str_s;
+
+/* DFT带外管理公共的响应消息头 */
+typedef struct {
+ u16 errcode;
+ u16 opcode;
+ u32 total_length;
+ u32 length;
+ u16 sub_opcode;
+} smb_dft_respon_header_s;
+
+/* DFT带外管理消息头部 */
+typedef struct {
+ u8 flag;
+ u8 req_para;
+ u16 opcode;
+ u32 offset;
+ u32 length;
+ u16 sub_opcode;
+} smb_dft_ctrl_header_s;
+
+/* SMB_SUB_OPC_DIE_ID 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_die_id_req_s;
+
+#define SMB_DIE_ID_MAX_LEN 32
+/* SMB_SUB_OPC_DIE_ID 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u8 die_id[SMB_DIE_ID_MAX_LEN]; // SMB_DIE_ID_MAX_LEN
+ u32 crc32;
+} smb_die_id_rsp_s;
+
+/* SMB_SUB_OPC_SRAM_MBIST 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_sram_mbist_req_s;
+
+/* SMB_SUB_OPC_SRAM_MBIST 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 result;
+ u32 fail_vector_index;
+ u32 fail_test_index;
+ u32 bist_fail_data;
+ u32 die1_result;
+ u32 die1_fail_vector_index;
+ u32 die1_fail_test_index;
+ u32 die1_bist_fail_data;
+ u32 crc32;
+} smb_sram_mbist_rsp_s;
+
+/* SMB_SUB_OPC_DCIP_TEST 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_dcip_test_req_s;
+
+/* SMB_SUB_OPC_DCIP_TEST 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 status;
+ u32 crc32;
+} smb_dcip_test_rsp_s;
+
+#define SMB_DFT_PAYLOAD_MAX_LEN 46
+#define LEN_OF_VPD_KEYWORD 2
+#define SMB_VPD_ITEM_NUM 10
+#define SMB_VPD_INFO_LEN 128
+#define SMB_DFT_GET_VPD_TOTAL_LEN 130
+#define SMB_DFT_PAYLOAD_MAX_LEN 46
+/* SMB_SUB_OPC_VPD_SET 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u8 wr_data[SMB_DFT_PAYLOAD_MAX_LEN];
+ u32 crc32;
+} smb_vpd_set_req_s;
+
+typedef struct {
+ u8 key[LEN_OF_VPD_KEYWORD];
+ u8 len;
+ u8 rsvd;
+ u8 data[SMB_VPD_INFO_LEN];
+} vpd_info;
+
+typedef struct {
+ vpd_info vpd_item[SMB_VPD_ITEM_NUM];
+ u32 rsvd;
+} smbus_vpd_info_s;
+
+typedef struct {
+ u8 data[SMB_VPD_INFO_LEN];
+ u32 key_type;
+ u16 key_len;
+ u16 rsvd;
+} smbus_single_vpd_info_s;
+
+/* SMB_SUB_OPC_VPD_SET 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 crc32;
+} smb_vpd_set_rsp_s;
+
+/* SMB_SUB_OPC_VPD_GET 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_vpd_get_req_s;
+
+/* SMB_SUB_OPC_VPD_GET 命令字响应报文结构体 */
+typedef union {
+ struct {
+ u16 vpd_len;
+ u8 data[SMB_DFT_PAYLOAD_MAX_LEN - 2];
+ } first_frame;
+ struct {
+ u8 data[SMB_DFT_PAYLOAD_MAX_LEN];
+ } other_frame;
+} vpd_data_s;
+
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ vpd_data_s vpd_data;
+ u32 crc32;
+} smb_vpd_get_rsp_s;
+
+/* SMB_SUB_OPC_RESET 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_reset_req_s;
+
+/* SMB_SUB_OPC_RESET 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 status; // 0:复位上电后没有恢复出厂过,1:复位上电后恢复出厂过且成功了,2:复位上电后恢复出厂过但失败了,3:复位过程中
+ u32 crc32;
+} smb_reset_rsp_s;
+
+#define SMBUS_GUID_SN_MAX_LEN 8
+/* SMB_SUB_OPC_GUID_SET 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u8 guid_sn[SMBUS_GUID_SN_MAX_LEN];
+ u32 crc32;
+} smb_guid_set_req_s;
+
+/* SMB_SUB_OPC_GUID_SET 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 crc32;
+} smb_guid_set_rsp_s;
+
+/* SMB_SUB_OPC_GUID_GET 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_guid_get_req_s;
+
+/* SMB_SUB_OPC_GUID_GET 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u8 guid_sn[SMBUS_GUID_SN_MAX_LEN];
+ u32 crc32;
+} smb_guid_get_rsp_s;
+
+/* SMB_SUB_OPC_I2C_TEST 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_i2c_test_req_s;
+
+/* SMB_SUB_OPC_I2C_TEST 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 crc32;
+} smb_i2c_test_rsp_s;
+
+/* SMB_SUB_OPC_SET_LOOPBACK 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u8 port_id;
+ u32 crc32;
+} smb_set_sfp_loopbackmode_req_s;
+
+/* SMB_SUB_OPC_SET_LOOPBACK 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 crc32;
+} smb_set_sfp_loopbackmode_rsp_s;
+
+/* SMB_SUB_OPC_GET_SNR 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u8 macro_id;
+ u8 lane_id;
+ u32 crc32;
+} smb_get_serdes_snr_req_s;
+
+/* SMB_SUB_OPC_GET_SNR 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 snr_valid;
+ u64 snr_metric;
+ u64 snr_metric_his_min;
+ u64 snr_err_avg;
+ u64 snr_cycles_avg;
+ u64 snr_heh_avg;
+ u32 crc32;
+} smb_get_serdes_snr_rsp_s;
+
+// prbs test
+typedef struct {
+ smb_dft_ctrl_header_s header;
+ u8 macro_id;
+ u8 lane_mask;
+ u8 direction;
+ u8 prbs_type;
+ u32 crc32;
+} smb_prbs_req_s;
+
+typedef struct {
+ smb_dft_respon_header_s header;
+ u8 lane_mask;
+ u8 code_speed[8];
+ u32 errcnt_bits[8];
+ u32 crc32;
+} smb_dft_prbs_error_code_s;
+
+// mac wirte
+typedef struct {
+ smb_dft_ctrl_header_s header;
+ u8 mac_addr[MAC_ADDRESS_NUM];
+ u32 crc32;
+} smb_set_mac_addr_s;
+
+// mac read
+typedef struct {
+ smb_dft_respon_header_s header;
+ u8 all_mac[SMB_DFT_PAYLOAD_MAX_LEN];
+ u32 crc32;
+} smb_get_mac_addr_s;
+
+#define SMBUS_EFUSE_SINGLE_LEN 46
+#define SMBUS_EFUSE_BURN_DATA_TOTAL_LEN 256
+
+typedef struct {
+ u32 data_len; // 当前的长度
+ u32 opt_type; // 当前烧写类型
+ u8 data[SMBUS_EFUSE_BURN_DATA_TOTAL_LEN];
+} smb_efuse_info_s;
+
+typedef struct {
+ smb_dft_ctrl_header_s header;
+ u8 data[SMBUS_EFUSE_SINGLE_LEN];
+ u32 crc32;
+} smb_single_efuse_info_s;
+
+typedef struct { // led set
+ smb_dft_ctrl_header_s header;
+ u8 port_id;
+ u8 mode;
+ u32 crc32;
+} smb_led_set_req_s;
+
+/* SMB_SUB_OPC_POWER_GET 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u32 crc32;
+} smb_power_req_s;
+
+/* SMB_SUB_OPC_POWER_GET 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u32 power;
+ u32 crc32;
+} smb_power_rsp_s;
+
+/* SMB_SUB_OPC_GPIO_TEST 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u8 pin;
+ u8 pin_val;
+ u32 crc32;
+} smb_pin_req_s;
+
+/* SMB_SUB_OPC_GPIO_TEST 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u8 pin_val;
+ u32 crc32;
+} smb_pin_rsp_s;
+
+/* SMB_SUB_OPC_H2H 命令字请求报文结构体 */
+typedef struct {
+ smb_dft_ctrl_header_s ctrl_header;
+ u8 port_id;
+ u32 crc32;
+} smb_h2h_req_s;
+
+/* SMB_SUB_OPC_H2H 命令字响应报文结构体 */
+typedef struct {
+ smb_dft_respon_header_s res_header;
+ u64 right_pkt_cnt;
+ u64 err_pkt_cnt;
+ u32 crc32;
+} smb_h2h_rsp_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ s16 spu_tsensor_temp;
+ u32 crc32;
+} smb_spu_temp_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 pwrlimit_en; /**< 0:open 1:close */
+ u32 crc32;
+} smb_spu_pwrlimit_en_s;
+
+typedef struct {
+ smb_respon_header_s header;
+ u8 num_item;
+ u32 crc32;
+} smb_spu_ras_num_s;
+
+typedef struct {
+ smb_respon_header_s header;
+ u32 ras_info[SMB_SPU_RAS_LEN]; // 每4B为 imu_to_mcu_ras_info_s 结构
+ u32 crc32;
+} smb_spu_ras_s;
+
+typedef struct {
+ smb_request_header_s header;
+ u8 slot_id;
+ u32 crc32;
+} smb_set_slot_id_req_s;
+
+#pragma pack()
+
+/* 获取MAC addr */
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 mac_addr[SMB_MAC_ADDR_INFO_LEN];
+ u32 crc32;
+} smb_mac_addr_s;
+
+typedef struct {
+ smb_respon_header_s header;
+ u8 link_info;
+ u8 ex_speed;
+ u16 rsvd;
+ u32 crc32;
+} smb_phyport_link_info_rep_s;
+
+typedef struct {
+ smb_request_header_s header;
+ u8 port_id;
+} smb_phyport_link_info_req_s;
+
+typedef struct {
+ smb_respon_header_s header;
+ u32 status;
+ u32 crc32;
+} smb_xsfp_present_status_rep_s;
+
+typedef struct {
+ smb_request_header_s header;
+ u8 port_id;
+} smb_xsfp_present_status_req_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u8 link_width;
+ u8 link_speed;
+ u16 rsvd;
+ u32 crc32;
+} smb_pcie_ubc_info_s;
+
+typedef struct {
+ smb_respon_header_s res_header;
+ u16 spu_freq;
+ u8 spu_freq_status;
+ u8 rsvd;
+ u32 crc32;
+} smb_spu_freq_resp_s;
+
+/* Define the struct read_write_reg 5*4bytes */
+typedef struct {
+ u32 addr_h;
+ u32 addr_l;
+ u32 data_h;
+ u32 data_l;
+} smb_rw_reg_payload_s;
+
+typedef struct {
+ smb_ctrl_header_s header;
+ smb_rw_reg_payload_s payload;
+ u32 crc32;
+} smb_read_write_reg_s;
+
+typedef struct {
+ u32 port_speed;
+ u8 link_speed;
+} smb_speed_map_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_mpu_intf.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_mpu_intf.h
new file mode 100644
index 000000000..27d091b09
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_mpu_intf.h
@@ -0,0 +1,36 @@
+#ifndef NIC_MIG_MPU_INTF_H
+#define NIC_MIG_MPU_INTF_H
+
+#include "nic_cfg_comm.h"
+
+#ifndef MAX_CEQ_PER_FUNC
+#define MAX_CEQ_PER_FUNC 0x20
+#endif
+
+/**
+ * @brief 定义一个枚举类型,用于表示MSIX控制寄存器的操作类型。
+ * @details
+ * 这个枚举类型包含两个成员,分别表示获取和设置MSIX控制寄存器的操作。
+ */
+enum mig_nic_msix_op {
+ MSIX_CTRL_CSR_GET, /**< 获取MSIX控制寄存器的值 */
+ MSIX_CTRL_CSR_SET /**< 设置MSIX控制寄存器的值 */
+};
+
+#define MAX_CMDQ_NUM 0x4 /**< 最大cmdq数量*/
+
+#define MAX_SQ_NUM 0x40 /**< 最大sq数量 */
+
+/**
+ * @struct mig_nic_mac_vlan
+ * @brief 定义一个结构体,用于存储网卡的MAC地址、VLAN ID和保留字段
+ * @details 该结构体主要用于网络设备的配置和管理,包含了MAC地址、VLAN ID和保留字段。
+ */
+struct mig_nic_mac_vlan {
+ u8 mac[6]; /**< MAC地址,长度为6字节 */
+ u16 vlan_id; /**< VLAN ID,用于标识网络中的不同网络 */
+ u16 rsvd; /**< 保留字段,当前未使用 */
+};
+
+#define MIG_FAST_MSG_MAX_PAGE_SIZE (256 * 1024)
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_npu_intf.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_npu_intf.h
new file mode 100644
index 000000000..9554ef58c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mig_npu_intf.h
@@ -0,0 +1,175 @@
+#ifndef NIC_MIG_INTF_H
+#define NIC_MIG_INTF_H
+
+#include "nic_cfg_comm.h"
+
+/**
+ * @brief enum nic_mig_q_type
+ * @details migrate queue type info for nic migration
+ */
+enum nic_mig_q_type {
+ NIC_MIG_SQ, /**< Send Queue */
+ NIC_MIG_RQ, /**< Receive Queue */
+ NIC_MIG_CMDQ, /**< Command Queue */
+ NIC_MIG_MAX, /**< Max Queue Type */
+};
+
+/**< if sq num < 30, one cmdq is enough, is sq is 30~60, need to read 2 rounds */
+#define MAX_SQ_NUM 0x40 /**< max sq num */
+#define MAX_RQ_NUM 0x40 /**< max rq num */
+#define MAX_CMDQ_NUM 0x4 /**< max cmdq num */
+
+#define SQ_RQ_CTX_SIZE 0x40 /**< sq/rq context size */
+
+#define CTX_BUF_LEN 0x400 /**< context buffer length */
+
+#define MAX_CTX_NUM (CTX_BUF_LEN / SQ_RQ_CTX_SIZE) /**< max context number */
+
+/**
+ * @brief struct nic_mig_q_ctx
+ * @details migrate queue ctx for nic migration
+ */
+struct nic_mig_q_ctx {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 16; /**< reserved */
+ u32 queue_type : 2; /**< queue type */
+ u32 opcode : 1; /**< opcode */
+ u32 func_id : 13; /**< function id */
+#else
+ u32 func_id : 13; /**< function id */
+ u32 opcode : 1; /**< opcode */
+ u32 queue_type : 2; /**< queue type */
+ u32 rsvd : 16; /**< reserved */
+#endif
+ } bs;
+ u32 value; /**< context value */
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 16; /**< reserved */
+ u32 queue_num : 8; /**< queue number */
+ u32 start_queue_id : 8; /**< start queue id */
+#else
+ u32 start_queue_id : 8; /**< start queue id */
+ u32 queue_num : 8; /**< queue number */
+ u32 rsvd : 16; /**< reserved */
+#endif
+ } bs;
+ u32 value; /**< context value */
+ } dw1;
+ u8 queue_ctx[CTX_BUF_LEN]; /**< queue context */
+};
+
+/**
+ * @brief struct nic_mig_rq_stop
+ * @details stop rq info for nic migration
+ */
+struct nic_mig_rq_stop {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 11; /**< reserved */
+ u32 rq_num : 8; /**< receive queue number */
+ u32 func_id : 13; /**< function id */
+#else
+ u32 func_id : 13; /**< function id */
+ u32 rq_num : 8; /**< receive queue number */
+ u32 rsvd : 11; /**< reserved */
+#endif
+ } bs;
+ u32 value; /**< context value */
+ } dw;
+ u32 is_empty; /**< is empty */
+};
+
+/**
+ * @brief struct nic_mig_rq_empty_type
+ * @details rq 排空类型 for nic migration
+ */
+enum nic_mig_rq_empty_type {
+ NIC_MIG_RQ_CHK_INIT, /**< rq init check type*/
+ NIC_MIG_RQ_CHK_EMPTY, /**< rq empty check type*/
+ NIC_MIG_RQ_CHECK_ERR, /**< rq error check type*/
+};
+
+/**
+ * @brief struct nic_mig_cmdq_stop
+ * @details stop cmdq info for nic migration
+ */
+struct nic_mig_cmdq_stop {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 10; /**< reserved */
+ u32 cmdq_num : 8; /**< cmdq number */
+ u32 is_stop : 1; /**< is stop */
+ u32 func_id : 13; /**< function id */
+#else
+ u32 func_id : 13; /**< function id */
+ u32 is_stop : 1; /**< is stop */
+ u32 cmdq_num : 8; /**< cmdq number */
+ u32 rsvd : 10; /**< reserved */
+#endif
+ } bs;
+ u32 value; /**< context value */
+ } dw;
+};
+
+#define BAT_ARR_LEN 0x100 /**< bat array length */
+
+/**
+ * @brief struct nic_mig_update_bat
+ * @details update bat table info for nic migration
+ */
+struct nic_mig_update_bat {
+ u32 opcode; /**< opcode */
+ u32 func_id; /**< function id */
+ u32 size; /**< size */
+ u8 data[BAT_ARR_LEN]; /**< data */
+};
+
+/**
+ * @brief struct nic_mig_compensate_intr
+ * @details compensate interrupt info for nic migration
+ */
+struct nic_mig_compensate_intr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd1 : 10; /**< reserved */
+ u32 intr_num : 9; /**< interrupt number */
+ u32 func_id : 13; /**< function id */
+#else
+ u32 func_id : 13; /**< function id */
+ u32 intr_num : 9; /**< interrupt number */
+ u32 rsvd1 : 10; /**< reserved */
+#endif
+ } bs;
+ u32 value; /**< context value */
+ } dw;
+};
+
+#define MIG_FAST_MSG_BHEAP_SIZE 64
+struct mig_nic_fast_msg_bheap {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 8;
+ u32 opcode : 8;
+ u32 func_id : 16;
+#else
+ u32 func_id : 16;
+ u32 opcode : 8;
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+ u8 bheap[MIG_FAST_MSG_BHEAP_SIZE];
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd_defs.h
new file mode 100644
index 000000000..6287687cd
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd_defs.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd_defs.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC cmdq struct defines between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_DEFS_H
+#define NIC_NPU_CMD_DEFS_H
+
+#if defined(__LINUX__) || defined(__VMWARE__)
+#include <linux/types.h>
+#endif
+
+#include "nic_cfg_comm.h"
+
+/**
+ * @brief struct nic_cmdq_header
+ * @details nic cmdq header info
+ */
+struct nic_cmdq_header {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ /* 0x0:SQ, 0x1:RQ */
+ u16 queue_type; /**< queue type */
+ /* queue number in buffer follow this header */
+ u16 queue_num; /**< queue number */
+#else
+ u16 queue_num; /**< queue number */
+ u16 queue_type; /**< queue type */
+#endif
+ } cmdq_ctx_dw0;
+
+ u32 ctx_dw0; /**< context word 0 */
+ };
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u16 rsvd; /**< reserved */
+ u16 start_qid; /**< start queue id */
+#else
+ u16 start_qid; /**< start queue id */
+ u16 rsvd; /**< reserved */
+#endif
+};
+
+/**
+ * @brief struct nic_cmdq_context_modify_s
+ * @details nic cmdq context modify info
+ */
+struct nic_cmdq_context_modify_s {
+ struct nic_cmdq_header hdr; /**< cmdq header */
+ u8 data[2016]; /**< cmdq context data */
+};
+
+struct cmdq_space_dw0_s {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u16 queue_type; /**< queue type */
+ u16 queue_num; /**< queue number */
+#else
+ u16 queue_num; /**< queue number */
+ u16 queue_type; /**< queue type */
+#endif
+};
+
+/**
+ * @brief struct nic_cmdq_clean_q_space
+ * @details nic cmdq queue space info
+ */
+struct nic_cmdq_clean_q_space {
+ /* queue_type = 0, TSO
+ queue_type = 1, LRO */
+ union {
+ struct cmdq_space_dw0_s cmdq_space_dw0;
+ u32 space_dw0; /**< space word 0 */
+ };
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u16 rsvd; /**< reserved */
+ u16 start_qid; /**< start queue id */
+#else
+ u16 start_qid; /**< start queue id */
+ u16 rsvd; /**< reserved */
+#endif
+
+ u32 rsvd1; /**< reserved */
+};
+
+/**
+ * @brief truct nic_cmdq_flush_rq_task
+ * @details nic cmdq rq 排空任务信息
+ */
+struct nic_cmdq_flush_rq_task {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u16 q_id; /**< queue id */
+ u16 glb_rq_id; /**< global rq id */
+#else
+ u16 glb_rq_id; /**< global rq id */
+ u16 q_id; /**< queue id */
+#endif
+ } bs;
+
+ u32 value; /**< value */
+ } dw0;
+};
+
+/**
+ * @brief union nic_cmdq_arm
+ * @details nic cmdq arm info
+ */
+union nic_cmdq_arm {
+ struct cmdq_arm_dw0_s {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u16 qpn; /**< queue pair number */
+ u16 pi; /**< produce index */
+#else
+ u16 pi; /**< produce index */
+ u16 qpn; /**< queue pair number */
+#endif
+ } dw0;
+
+ u32 arm_dw0; /**< arm word 0 */
+};
+
+/**
+ * @brief truct nic_rss_indirect_tbl
+ * @details nic rss indirect table
+ */
+struct nic_rss_indirect_tbl {
+ u32 user_data[2];
+ u32 rsvd[2]; // Make sure that 16B beyond entry[]
+ u16 entry[NIC_RSS_INDIR_SIZE]; /**< rss indirect table entry */
+};
+
+/**
+ * @brief struct nic_rss_glb_qid_indirect_tbl
+ * @details nic rss glb qid indirect table
+ */
+struct nic_rss_glb_qid_indirect_tbl {
+ u32 group_index; /**< group index */
+ u32 offset; /**< offset */
+ u32 size; /**< size */
+ u32 rsvd; /* Make sure that 16B beyond entry[] */
+ u16 entry[NIC_RSS_INDIR_SIZE]; /**< rss indirect table entry */
+};
+
+/**
+ * @brief struct nic_rss_context_tbl
+ * @details nic vlan context info
+ */
+struct nic_rss_context_tbl {
+ u32 rsvd[4]; /**< reserved */
+ u32 ctx; /**< rss context */
+};
+
+/**
+ * @brief struct nic_vlan_ctx
+ * @details nic vlan context info
+ */
+struct nic_vlan_ctx {
+ u32 func_id; /**< function id */
+ u32 qid; /* if qid = 0xFFFF, config current function all queue */
+ u32 vlan_id; /**< vlan id */
+ u32 vlan_mode; /**< vlan mode */
+ u32 vlan_sel; /**< vlan select */
+};
+
+/**
+ * @brief struct nic_cmdq_vport_stats
+ * @details nic cmdq vport stats info
+ */
+struct nic_cmdq_vport_stats {
+ u64 tx_uc_pkts_vport;
+ u64 tx_uc_bytes_vport;
+ u64 tx_mc_pkts_vport;
+ u64 tx_mc_bytes_vport;
+ u64 tx_bc_pkts_vport;
+ u64 tx_bc_bytes_vport;
+
+ u64 rx_uc_pkts_vport;
+ u64 rx_uc_bytes_vport;
+ u64 rx_mc_pkts_vport;
+ u64 rx_mc_bytes_vport;
+ u64 rx_bc_pkts_vport;
+ u64 rx_bc_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+
+ u64 rsvd[8]; /* 预留8个counter */
+};
+
+#endif /* NIC_CMDQ_INTF_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_wqe_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_wqe_defs.h
new file mode 100644
index 000000000..6dc8c8d46
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_wqe_defs.h
@@ -0,0 +1,333 @@
+#ifndef NIC_NPU_WQE_DEFINE_H
+#define NIC_NPU_WQE_DEFINE_H
+
+#include "typedef.h"
+
+/**
+ * @brief 内部/外部IP类型
+ * @details 定义一个枚举类型,用于表示内部/外部IP类型
+ */
+typedef enum {
+ /*
+ * 00 - non ip packet or packet type is not defined by software
+ * 01 - ipv6 packet
+ * 10 - ipv4 packet with no ip checksum offload
+ * 11 - ipv4 packet with ip checksum offload
+ */
+ NON_IP_TYPE = 0,
+ TYPE_IPV6,
+ TYPE_IPV4,
+ TYPE_IPV4_CS_OFF
+} qsf_ip_type_e;
+
+/**
+ * @brief 定义隧道类型枚举,用于表示不同的隧道类型
+ * @details 此枚举用于表示不同的隧道类型,包括无隧道、UDP隧道(无CS)、UDP隧道(有CS)和GRE隧道。
+ */
+typedef enum {
+ /*
+ * 0 - no udp / gre tunneling / no tunnel
+ * 1 - udp tunneling header with no cs
+ * 2 - udp tunneling header with cs
+ * 3 - gre tunneling header
+ */
+ L4_TUNNEL_NO_TUNNEL = 0,
+ L4_TUNNEL_UDP_NO_CS,
+ L4_TUNNEL_UDP_CS,
+ L4_TUNNEL_GRE
+} qsf_tunnel_type_e;
+
+/**
+ * @brief 定义一个枚举类型,用于表示不同的第四层协议类型
+ * @details 这个枚举类型包含了四种不同的第四层协议类型,分别是未知/碎片化的数据包、传输控制协议、流控制传输协议和用户数据报协议。
+ */
+typedef enum {
+ /*
+ * 00b - unknown / fragmented packet
+ * 01b - tcp
+ * 10b - sctp
+ * 11b - udp
+ */
+
+ L4_TYPE_UNKNOWN = 0,
+ L4_TYPE_TCP,
+ L4_TYPE_SCTP,
+ L4_TYPE_UDP
+} qsf_l4_offload_type_e;
+
+/**
+ * @struct tag_l2nic_rx_compact_cqe
+ * @brief 定义了一个接收完成队列条目(Completion Queue Entry, CQE)的结构体,
+ * 该结构体用于描述接收到的数据包的各种属性。
+ * @details 这个结构体用于表示接收到的数据包的完成状态,
+ * 它包含了关于数据包的各种标志和错误信息。
+ */
+typedef struct tag_l2nic_rx_compact_cqe {
+ /**
+ * @union dw0
+ * @brief 该联合体用于存储接收到的数据包的各种属性。
+ */
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rx_done : 1; /**< 接收完成标志 */
+ u32 cqe_type : 1; /**< CQE类型 */
+ u32 ts_flag : 1; /**< 时间戳标志 */
+ u32 vlan_offload : 1; /**< VLAN硬解析标志 */
+ u32 pkt_fmt : 3; /**< 数据包格式 */
+ u32 ip_type : 1; /**< IP类型 */
+ u32 cqe_len : 1; /**< CQE长度 */
+ u32 pkt_mc : 2; /**< 数据包多播标志 */
+ u32 checksum_err : 2; /**< 校验和错误标志 */
+ u32 pkt_type : 3; /**< 数据包类型 */
+ u32 pkt_len : 16; /**< 数据包长度 */
+#else
+ u32 pkt_len : 16; /**< 数据包长度 */
+ u32 pkt_type : 3; /**< 数据包类型 */
+ u32 checksum_err : 2; /**< 校验和错误标志 */
+ u32 pkt_mc : 2; /**< 数据包多播标志 */
+ u32 cqe_len : 1; /**< CQE长度 */
+ u32 ip_type : 1; /**< IP类型 */
+ u32 pkt_fmt : 3; /**< 数据包格式 */
+ u32 vlan_offload : 1; /**< VLAN硬解析标志 */
+ u32 ts_flag : 1; /**< 时间戳标志 */
+ u32 cqe_type : 1; /**< CQE类型 */
+ u32 rx_done : 1; /**< 接收完成标志 */
+#endif
+ } bs;
+ u32 value; /**< 存储所有字段的值 */
+ } dw0;
+
+ /**
+ * @union dw1
+ * @brief 该联合体用于存储接收到的数据包的RSS哈希值。
+ */
+ union {
+ struct {
+ u32 rss_hash_value; /**< RSS哈希值 */
+ } bs;
+ u32 value; /**< 存储所有字段的值 */
+ } dw1;
+
+ /**
+ * @union dw2
+ * @brief 该联合体用于存储接收到的数据包的各种属性。
+ */
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 lro_num : 8; /**< LRO(Large Receive Offload)数量 */
+ u32 vlan_tag : 16; /**< VLAN标签 */
+ u32 rsvd2 : 2; /**< 保留字段 */
+ u32 pfe_tx_pkt_en : 1; /**< PFE(Physical Function Engine)传输数据包使能 */
+ u32 port_id : 2; /**< 端口ID */
+ u32 flow_mark_vld : 1; /**< 流量标记有效标志 */
+ u32 src_function_id_h : 2; /**< 源函数ID的高8位 */
+#else
+ u32 src_function_id_h : 2; /**< 源函数ID的高8位 */
+ u32 flow_mark_vld : 1; /**< 流量标记有效标志 */
+ u32 port_id : 2; /**< 端口ID */
+ u32 pfe_tx_pkt_en : 1; /**< PFE(Physical Function Engine)传输数据包使能 */
+ u32 rsvd2 : 2; /**< 保留字段 */
+ u32 vlan_tag : 16; /**< VLAN标签 */
+ u32 lro_num : 8; /**< LRO(Large Receive Offload)数量 */
+#endif
+ } bs;
+ u32 value; /**< 存储所有字段的值 */
+ } dw2;
+
+ /**
+ * @union dw3
+ * @brief 该联合体用于存储接收到的数据包的各种属性。
+ */
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 src_function_id_l : 8; /**< 源函数ID的低8位 */
+ u32 flow_mark : 24; /**< 流量标记 */
+#else
+ u32 flow_mark : 24; /**< 流量标记 */
+ u32 src_function_id_l : 8; /**< 源函数ID的低8位 */
+#endif
+ } bs;
+ u32 value; /**< 存储所有字段的值 */
+ } dw3;
+} l2nic_rx_compact_cqe_s;
+
+/**
+ * @struct l2nic_rx_cqe_s.
+ * @brief L2nic_rx_cqe_s data structure.
+ * @details 这个结构体用于表示接收到的数据包的完成状态,
+ * 它包含了关于数据包的各种标志和错误信息。
+ */
+typedef struct tag_l2nic_rx_cqe {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rx_done : 1; /**< 表示数据包已经完全接收 */
+ u32 bp_en : 1; /**< 表示缓冲池已经启用 */
+ u32 decry_pkt : 1; /**< 表示需要解密数据包 */
+ u32 flush : 1; /**< 表示需要刷新数据包 */
+ u32 spec_flags : 3; /**< 特殊标志位 */
+ u32 rsvd0 : 1; /**< 保留字段 */
+ u32 lro_num : 8; /**< 大接收离散连接数 */
+ u32 checksum_err : 16; /**< 校验和错误信息 */
+#else
+ u32 checksum_err : 16; /**< 校验和错误信息 */
+ u32 lro_num : 8; /**< 大接收离散连接数 */
+ u32 rsvd0 : 1; /**< 保留字段 */
+ u32 spec_flags : 3; /**< 特殊标志位 */
+ u32 flush : 1; /**< 表示需要刷新数据包 */
+ u32 decry_pkt : 1; /**< 表示需要解密数据包 */
+ u32 bp_en : 1; /**< 表示缓冲池已经启用 */
+ u32 rx_done : 1; /**< 表示数据包已经完全接收 */
+#endif
+ } bs;
+ u32 value; /**< 结构体的值 */
+ } dw0;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 length : 16; /**< 包长 */
+ u32 vlan : 16; /**< vlan号 */
+#else
+ u32 vlan : 16; /**< vlan号 */
+ u32 length : 16; /**< 包长 */
+#endif
+ } bs;
+ u32 value; /**< 结构体的值 */
+ } dw1;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rss_type : 8; /**< rss类型 */
+ u32 rsvd0 : 2; /**< 保留字段 */
+ u32 vlan_offload_en : 1; /**< vlan卸载使能位 */
+ u32 umbcast : 2; /**< umb播 */
+ u32 rsvd1 : 7; /**< 保留字段 */
+ u32 pkt_types : 12; /**< 报文类型 */
+#else
+ u32 pkt_types : 12; /**< 报文类型 */
+ u32 rsvd1 : 7; /**< 保留字段 */
+ u32 umbcast : 2; /**< umb播 */
+ u32 vlan_offload_en : 1; /**< vlan卸载使能位 */
+ u32 rsvd0 : 2; /**< 保留字段 */
+ u32 rss_type : 8; /**< rss类型 */
+#endif
+ } bs;
+ u32 value; /**< 结构体的值 */
+ } dw2;
+
+ union {
+ struct {
+ u32 rss_hash_value; /**< rss哈希值 */
+ } bs;
+ u32 value; /**< 结构体的值 */
+ } dw3;
+
+ /**< dw4~dw7 field for nic/ovs multipexing */
+ union {
+ struct { /**< for nic */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 if_1588 : 1; /**< 定义一个32位无符号整数,用于表示是否支持1588协议 */
+ u32 if_tx_ts : 1; /**< 定义一个32位无符号整数,用于表示是否支持发送时间戳 */
+ u32 if_rx_ts : 1; /**< 定义一个32位无符号整数,用于表示是否支持接收时间戳 */
+ u32 rsvd : 1; /**< 定义一个32位无符号整数,用于保留 */
+ u32 msg_1588_type : 4; /**< 定义一个32位无符号整数,用于表示1588协议的类型 */
+ u32 msg_1588_offset : 8; /**< 定义一个32位无符号整数,用于表示1588协议的偏移量 */
+ u32 tx_ts_seq : 16; /**< 定义一个32位无符号整数,用于表示发送时间戳的序列号 */
+#else
+ u32 tx_ts_seq : 16; /**< 定义一个32位无符号整数,用于表示发送时间戳的序列号 */
+ u32 msg_1588_offset : 8; /**< 定义一个32位无符号整数,用于表示1588协议的偏移量 */
+ u32 msg_1588_type : 4; /**< 定义一个32位无符号整数,用于表示1588协议的类型 */
+ u32 rsvd : 1; /**< 定义一个32位无符号整数,用于保留 */
+ u32 if_rx_ts : 1; /**< 定义一个32位无符号整数,用于表示是否支持接收时间戳 */
+ u32 if_tx_ts : 1; /**< 定义一个32位无符号整数,用于表示是否支持发送时间戳 */
+ u32 if_1588 : 1; /**< 定义一个32位无符号整数,用于表示是否支持1588协议 */
+#endif
+ } bs;
+
+ struct { /**< for ovs */
+ u32 reserved; /**< 保留字段 */
+ } ovs_bs;
+
+ struct {
+ u32 xid; /**< x id for crypt*/
+ } crypt_bs;
+
+ u32 value; /**< 结构体的值 */
+ } dw4;
+
+ union {
+ struct { /**< for nic */
+ u32 msg_1588_ts;
+ } bs;
+
+ struct { /**< for ovs */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 mac_type : 2; /**< for ovs. mac_type */
+ u32 l3_type : 3; /**< for ovs. l3_type */
+ u32 l4_type : 3; /**< for ovs. l4_type */
+ u32 rsvd0 : 2; /**< 保留字段 */
+ u32 traffic_type : 6; /**< for ovs. traffic type: 0-default l2nic pkt, 1-fallback traffic, 2-miss upcall
+ traffic, 2-command */
+ u32 traffic_from : 16; /**< for ovs. traffic from: vf_id, only support traffic_type=0(default l2nic) or 2(miss
+ upcall) */
+#else
+ u32 traffic_from : 16; /**< for ovs. traffic from: vf_id, only support traffic_type=0(default l2nic) or 2(miss
+ upcall) */
+ u32 traffic_type : 6; /**< for ovs. traffic type: 0-default l2nic pkt, 1-fallback traffic, 2-miss upcall
+ traffic, 2-command */
+ u32 rsvd0 : 2; /**< 保留字段 */
+ u32 l4_type : 3; /**< for ovs. l4_type */
+ u32 l3_type : 3; /**< for ovs. l3_type */
+ u32 mac_type : 2; /**< for ovs. mac_type */
+#endif
+ } ovs_bs;
+
+ struct { /**< for crypt */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 16; /**< 保留字段 */
+ u32 decrypt_status : 8; /**< 解密状态 */
+ u32 esp_next_head : 8; /**< 下个头部 */
+#else
+ u32 esp_next_head : 8; /**< 下个头部 */
+ u32 decrypt_status : 8; /**< 解密状态 */
+ u32 rsvd : 16; /**< 保留字段 */
+#endif
+ } crypt_bs; /**< 结构体的值 */
+
+ u32 value;
+ } dw5;
+
+ union {
+ struct { /**< for nic */
+ u32 lro_ts; /**< 未使用 */
+ } bs;
+
+ struct { /**< for ovs */
+ u32 reserved; /**< 保留字段 */
+ } ovs_bs;
+
+ u32 value; /**< 结构体的值 */
+ } dw6;
+
+ union {
+ struct { /**< for nic */
+ u32 first_len : 13; /**< Datalen of the first or middle pkt size. */
+ u32 last_len : 13; /**< Data len of the last pkt size. */
+ u32 pkt_num : 5; /**< the number of packet. */
+ u32 super_cqe_en : 1; /**< only this bit = 1, other fileds in this DW is valid. */
+ } bs;
+
+ struct { /**< for ovs */
+ u32 localtag; /**< local tag */
+ } ovs_bs;
+
+ u32 value; /**< 结构体的值 */
+ } dw7;
+} l2nic_rx_cqe_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/adm_dict.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/adm_dict.h
new file mode 100644
index 000000000..4f1240d0e
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/adm_dict.h
@@ -0,0 +1,78 @@
+/*********************************************************************************
+* @copyright Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+* @file adm_dict.h
+* @brief 管理命令地址解耦相关字典定义
+* @author l30012907
+* @date 2023-07-17
+**********************************************************************************/
+
+#ifndef ADM_DICT_H
+#define ADM_DICT_H
+
+#include "typedef.h"
+
+enum {
+ DICT_ELEMENT_U8 = 1,
+ DICT_ELEMENT_U16 = 2,
+ DICT_ELEMENT_U32 = 4,
+ DICT_ELEMENT_U64 = 8,
+};
+
+#define MAX_REG_DICT_NAME_LEN 48
+#define MAX_DICT_FILE_NAME_LEN 40
+#define MAX_REG_FEATURE_NAME_LEN 8
+#define MAX_REG_SUB_FEATURE_NAME_LEN 8
+#define MAX_SM_TBL_NAME_LEN 40
+
+#define COUNTER_MPU_DICT_NAME "counter_mpu.bin"
+#define COUNTER_IPSUTX_DICT_NAME "counter_ipsutx.bin"
+#define COUNTER_IPSURX_DICT_NAME "counter_ipsurx.bin"
+#define COUNTER_NPU_DICT_NAME "counter_dict.bin"
+#define SML_TBL_DEFINE_DICT_NAME "sml_table_define_dict.bin"
+#define SML_TABLE_STRUCT_DICT_NAME "sml_table_struct_dict.bin"
+
+// 通用字典头
+typedef struct {
+ char file_name[MAX_DICT_FILE_NAME_LEN]; // 字典文件名
+ u8 version; // 字典自身的版本信息,与固件大包版本不同
+ u8 rsvd;
+ u16 item_size; // 单个字典元素大小
+ u32 item_num; // 字典元素数量
+ u32 rsvd1[3];
+} dict_info_s;
+
+// 寄存器字典描述
+typedef struct {
+ char name[MAX_REG_DICT_NAME_LEN]; // 寄存器或内存的显示名称
+ char feature[MAX_REG_FEATURE_NAME_LEN]; // 所属的特性
+ char sub_feature[MAX_REG_SUB_FEATURE_NAME_LEN]; // 所属的子特性
+ u8 node_id; // 业务隶属的模块ID
+ u8 type; // u16\u32\u64
+ u8 bit_start; // 单独bit描述的起始位置
+ u8 bit_end; // 单独bit描述的结束位置
+ u32 addr; // 模块内偏移地址
+ u32 rsvd[4];
+} reg_dict_s;
+
+typedef struct {
+ dict_info_s head;
+ reg_dict_s dict[];
+} reg_dict_file_s;
+
+typedef struct {
+ char name[MAX_SM_TBL_NAME_LEN]; // table表名字,40字节
+ u8 rsvd1;
+ u8 node_id; // table 所在的物理节点
+ u8 inst_id; // table 所在的实例号
+ u8 entry_size; // 单个表项大小
+ u8 rsvd[20];
+} sml_table_dict_s;
+
+/* 导出符号给工具DT,检查基本格式 */
+#ifdef TOOL_DT_MCRO
+extern void *counter_mpu_dict_ptr;
+extern void *counter_ipsutx_dict_ptr;
+extern void *counter_ipsurx_dict_ptr;
+#endif
+
+#endif // ADM_DICT_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/counter_dict.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/counter_dict.h
new file mode 100644
index 000000000..391542c32
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/counter_dict.h
@@ -0,0 +1,31 @@
+/*********************************************************************************
+* @copyright Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
+* @brief counter字典的定义, 用于描述counter名字和counter id的对应关系
+* @date 2023-07-10
+**********************************************************************************/
+#ifndef COUNTER_DICT_H
+#define COUNTER_DICT_H
+
+#include "base_type.h"
+
+#define MAX_COUNTER_NAME_LEN 80
+#define MAX_COUNTER_DESC_LEN 80
+#define MAX_FEATURE_NAME_LEN 8
+#define MAX_SUB_FEATURE_NAME_LEN 8
+
+typedef struct {
+ const char name[MAX_COUNTER_NAME_LEN]; // counter 的名字
+ const char desc[MAX_COUNTER_DESC_LEN]; // counter 的描述
+ const char feature[MAX_FEATURE_NAME_LEN]; // counter 所属的特性
+ const char sub_feature[MAX_SUB_FEATURE_NAME_LEN]; // counter 所属的子特性
+ u8 level; // counter 的级别,包括KEY, ERR, WARN, INFO, DBG
+ u8 type; // counter 的类型, 包括CTR_32, CTR_64, CTR_PAIR等
+ u8 unit; // counter 的单个大小,例如CTR_32就是32 bits,即4 bytes
+ u8 step; // counter 的索引步进单位,即一个counter占多个个ID
+ u8 node_id; // counter 所在的物理节点
+ u8 inst_id; // counter 所在的实例号
+ u32 base_id; // counter 在实例内的相对起始ID
+ u32 num; // counter 的数量
+} ctr_dict_s;
+
+#endif /* COUNTER_DICT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/dfx_cap_pkt_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/dfx_cap_pkt_cfg.h
new file mode 100644
index 000000000..68b8e11c0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/dfx_cap_pkt_cfg.h
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ Description : capture packet config
+*******************************************************************************/
+#ifndef SML_TABLE_CAP_PKT_CFG_H
+#define SML_TABLE_CAP_PKT_CFG_H
+
+#include "typedef.h"
+
+/**
+ * Struct name: sml_glb_tbl_cap_pkt_cfg_s
+ * Structure type of the @brief microcode capture packet information
+ * Data structure of the index 4 table in the Description: global configuration table
+ */
+typedef struct tag_sml_glb_tbl_cap_pkt_cfg {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cap_en : 1;
+ u32 function_id : 1;
+ u32 sip : 1;
+ u32 dip : 1;
+ u32 seid : 1;
+ u32 deid : 1;
+ u32 sport : 1;
+ u32 dport : 1;
+ u32 vni : 1;
+ u32 vlan : 1;
+ u32 len : 1;
+ u32 port_id : 1;
+ u32 upi : 1;
+ u32 sjetty : 1;
+ u32 opcode : 1;
+ u32 dst_qpn : 1;
+ u32 txrx : 1; // UB:mask不配置时txrx抓包; RoCE:mask不配置时默认只抓tx
+ u32 mac : 1;
+ u32 next_ext_hdr : 1; // 对外呈现为协议规定的bth_rsvd7, 当前实现为next_ext_hdr
+ u32 rsvd : 13;
+#else
+ u32 rsvd : 13;
+ u32 next_ext_hdr : 1;
+ u32 mac : 1;
+ u32 txrx : 1;
+ u32 dst_qpn : 1;
+ u32 opcode : 1;
+ u32 sjetty : 1;
+ u32 upi : 1;
+ u32 port_id : 1;
+ u32 len : 1;
+ u32 vlan : 1;
+ u32 vni : 1;
+ u32 dport : 1;
+ u32 sport : 1;
+ u32 deid : 1;
+ u32 seid : 1;
+ u32 dip : 1;
+ u32 sip : 1;
+ u32 function_id : 1;
+ u32 cap_en : 1;
+#endif
+ } mask;
+
+ union {
+ struct {
+ u32 sip_seid0; // ip ip层,eid tp层
+ u32 sip_seid1; // ip ip层,eid tp层
+ u32 sip_seid2; // ip ip层,eid tp层
+ u32 sip_seid3; // ip ip层,eid tp层
+ };
+ struct {
+ u8 mac[6]; // 仅1872使用
+ u8 rsv3[10];
+ };
+ u32 sip_seid[4];
+ };
+
+ union {
+ struct {
+ u32 dip_deid0;
+ u32 dip_deid1;
+ u32 dip_deid2;
+ u32 dip_deid3;
+ };
+ u32 dip_deid[4];
+ };
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 function_id : 12;
+ u32 vlan : 12;
+ u32 len : 8;
+#else
+ u32 len : 8; // 抓包长度
+ u32 vlan : 12; // 链路层
+ u32 function_id : 12; // vf id
+#endif
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 sport : 16;
+ u32 dport : 16;
+#else
+ u32 dport : 16; // tcp/udp层
+ u32 sport : 16;
+#endif
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 port_id : 3;
+ u32 ip_type : 1; // 0 ipv4 1 ipv6
+ u32 report_host_id : 3;
+ u32 report_function_id : 5; // PF
+ u32 report_ep : 3;
+ u32 report_cos : 3;
+ u32 txrx : 2; // 0 rx抓包 1 tx抓包 2 txrx全抓
+ u32 rsv : 12;
+#else
+ u32 rsv : 12;
+ u32 txrx : 2;
+ u32 report_cos : 3;
+ u32 report_ep : 3;
+ u32 report_function_id : 5; // PF
+ u32 report_host_id : 3;
+ u32 ip_type : 1; // 0 ipv4 1 ipv6
+ u32 port_id : 3; // 物理网口
+#endif
+
+ u32 upi_vni; // tp层upi或vxlan,ub不支持vxlan
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 sjetty_id : 20;
+ u32 opcode : 8;
+ u32 rsv2 : 4;
+#else
+ u32 rsv2 : 4;
+ u32 opcode : 8;
+ u32 sjetty_id : 20; // ta层本端jetty/jfs id
+#endif
+
+ u32 dst_qpn;
+
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 next_ext_hdr : 7;
+ u32 rsv4 : 25;
+#else
+ u32 rsv4 : 25;
+ u32 next_ext_hdr : 7;
+#endif
+} sml_glb_tbl_cap_pkt_cfg_s;
+
+#endif /* SML_TABLE_CAP_PKT_CFG_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hmm_context.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hmm_context.h
new file mode 100644
index 000000000..893f0c2b5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hmm_context.h
@@ -0,0 +1,230 @@
+/******************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+ ******************************************************************************
+ File Name : hmm_context.h
+ Version : Initial Draft
+ Description : common command queue interface
+ Function List :
+ History :
+ Modification: Created file
+
+******************************************************************************/
+
+#ifndef HMM_CONTEXT_H
+#define HMM_CONTEXT_H
+
+/* **************** Macro Definition ****************** */
+#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
+
+/* **************** Data Structure Definition ****************** */
+/* * MPT Format start */
+typedef struct roce_mpt_context {
+ /* DW0 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 access_bind : 1; /* Whether mr can be bound to mw */
+ u32 remote_access_en : 1; /* Indicates whether the FRMR can specify remote rights. */
+ u32 fast_reg_en : 1; /* Indicates whether the FRMR operation is supported. */
+ u32 invalid_en : 1; /* Indicates whether to support the INVALID operation. */
+ u32 remote_invalid_en : 1; /* Indicates whether to support the remote INVALID operation. */
+ u32 r_w : 1; /* Mr or mw */
+ u32 pa : 1; /* Flag bit of DMA_MR */
+ u32 rkey : 1;
+ u32 dif_mode : 1;
+ u32 bqp : 1; /* 1: Bound to qp */
+ u32 bpd : 1; /* 1: Bound to pd */
+ u32 access_ra : 1; /* The value 1 indicates that the remote Atomic permission is supported. */
+ u32 access_rw : 1; /* 1: The remote write permission is supported. */
+ u32 access_rr : 1; /* 1: Indicates that the remote read permission is supported. */
+ u32 access_lw : 1; /* The value 1 indicates that the local write permission is supported. */
+ u32 access_lr : 1; /* 1: Indicates that the local read permission is supported. */
+ u32 zbva : 1; /* The value 1 indicates that ZBVA is supported, that is, iova = 0. */
+ u32 signature : 4;
+ u32 mtt_page_size : 4; /* Page_size of mtt */
+ u32 mtt_layer_num : 3; /* Mtt level */
+ u32 buf_page_size : 4; /* Page_size of the buffer */
+#else
+ u32 buf_page_size : 4; /* Page_size of the buffer */
+ u32 mtt_layer_num : 3; /* Number of mtt levels */
+ u32 mtt_page_size : 4; /* Page_size of mtt */
+ u32 signature : 4;
+ u32 zbva : 1; /* The value 1 indicates that ZBVA is supported, that is, iova = 0. */
+ u32 access_lr : 1; /* 1: Indicates that the local read permission is supported. */
+ u32 access_lw : 1; /* The value 1 indicates that the local write permission is supported. */
+ u32 access_rr : 1; /* 1: Indicates that the remote read permission is supported. */
+ u32 access_rw : 1; /* 1: The remote write permission is supported. */
+ u32 access_ra : 1; /* The value 1 indicates that the remote Atomic permission is supported. */
+ u32 bpd : 1; /* 1: Bound to pd */
+ u32 bqp : 1; /* 1: Bound to qp */
+ u32 dif_mode : 1;
+ u32 rkey : 1;
+ u32 pa : 1; /* Flag bit of DMA_MR */
+ u32 r_w : 1; /* Mr or mw. The value 1 indicates MR, and the value 0 indicates MW. */
+ u32 remote_invalid_en : 1; /* Indicates whether to support the remote INVALID operation. */
+ u32 invalid_en : 1; /* Indicates whether to support the INVALID operation. */
+ u32 fast_reg_en : 1; /* Indicates whether the FRMR operation is supported. */
+ u32 remote_access_en : 1; /* Indicates whether the FRMR can specify the remote authority. */
+ u32 access_bind : 1; /* Whether mr can be bound to mw */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 qpn : 20; /* Qp bound to mw */
+ u32 ep : 3;
+ u32 sector_size : 1; /* 0:512B, 1:4KB */
+ u32 dma_attr_idx : 6; /* Dma attribute index */
+ u32 so_ro : 2; /* Dma order-preserving flag */
+#else
+ u32 so_ro : 2; /* Dma sequence preserving flag */
+ u32 dma_attr_idx : 6; /* Dma attribute index */
+ u32 sector_size : 1; /* 0:512B, 1:4KB */
+ u32 ep : 3;
+ u32 qpn : 20; /* Qp bound to mw */
+#endif
+ } bs;
+
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 rsvd : 22;
+ u32 prp_list_en : 1; /* nvme prp list mode */
+ u32 sector_size : 1; /* 0:512B, 1:4KB */
+ u32 dma_attr_idx : 6; /* Dma attribute index */
+ u32 so_ro : 2; /* Dma order-preserving flag */
+#else
+ u32 so_ro : 2; /* Dma sequence preserving flag */
+ u32 dma_attr_idx : 6; /* Dma attribute index */
+ u32 sector_size : 1; /* 0:512B, 1:4KB */
+ u32 prp_list_en : 1; /* nvme prp list mode */
+ u32 rsvd : 22;
+#endif
+ } dpu;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 pdn : 18; /* Pd bound to mr or mw */
+ u32 block_size : 6; /* 2^(page_size+12) + 8*block_size */
+ u32 cos : 3;
+ u32 indirect_mr : 1;
+ u32 status : 4; /* Mpt status. Valid values are VALID, FREE, and INVALID. */
+#else
+ u32 status : 4; /* Mpt status. Valid values are VALID, FREE, and INVALID. */
+ u32 indirect_mr : 1; /* indirect mr flag */
+ u32 cos : 3;
+ u32 block_size : 6; /* 2^(page_size+12) + 8*block_size */
+ u32 pdn : 18; /* Pd bound to mr or mw */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 fbo : 22;
+ u32 page_mode : 1;
+ u32 sgl_mode : 1; /* If set, indicates this MPT is double SGL type. */
+ u32 mkey : 8; /* The index is not included. */
+#else
+ u32 mkey : 8; /* The index is not included. */
+ u32 sgl_mode : 1; /* If set, indicates this MPT is double SGL type. */
+ u32 page_mode : 1;
+ u32 fbo : 22;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4~5 */
+ union {
+ u64 iova; /* Start address of mr or mw */
+ struct {
+ u32 iova_hi; /* Upper 32 bits of the start address of mr or mw */
+ u32 iova_lo; /* Lower 32 bits of the start address of mr or mw */
+ } dw4;
+ };
+
+ /* DW6~7 */
+ union {
+ u64 length; /* Length of mr or mw */
+ struct {
+ u32 length_hi; /* Length of mr or mw */
+ u32 length_lo; /* Length of mr or mw */
+ } dw6;
+ };
+
+ /* DW8~9 */
+ union {
+ u64 mtt_base_addr; /* Mtt base address (pa)hi:bit[63:32], lo:bit[31:03], gpa_sign[02:00] */
+ struct {
+ u32 mtt_base_addr_hi; /* Mtt base address (pa) upper 32 bits */
+ u32 mtt_base_addr_lo; /* Mtt base address (pa) lower 32 bits */
+ } dw8;
+ };
+
+ /* DW10 */
+ union {
+ u32 mr_mkey; /* This parameter is valid for MW. */
+ u32 mw_cnt; /* This parameter is valid when the MR is used. */
+ };
+
+ /* DW11 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 david_en : 1;
+ u32 rsvd : 1;
+ u32 fe_valid_num : 2;
+ u32 fe_id : 12;
+ u32 fe_offset : 8;
+ u32 rsvd1 : 8;
+#else
+ u32 rsvd1 : 8;
+ u32 fe_offset : 8;
+ u32 fe_id : 12;
+ u32 fe_valid_num : 2;
+ u32 rsvd : 1;
+ u32 david_en : 1;
+#endif
+ } dw11;
+ u32 mtt_sz; /* This parameter is valid when FRMR. */
+ };
+
+ /* DW12~DW13 */
+ u32 rsvd[2];
+
+ /* DW14~15 */
+ union {
+ u64 mw_vaddr; /* Mtt base address (pa)hi:bit[63:32], lo:bit[31:03], gpa_sign[02:00] */
+ struct {
+ u32 mw_vaddr_hi; /* Mtt base address (pa) upper 32 bits */
+ u32 mw_vaddr_lo; /* Mtt base address (pa) lower 32 bits */
+ } dw14;
+ struct {
+ u32 mw_vaddr_hi; /* Mtt base address (pa) upper 32 bits */
+ u32 mw_vaddr_lo; /* Mtt base address (pa) lower 32 bits */
+ } dw15;
+ };
+} roce_mpt_context_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce5_gid_type.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce5_gid_type.h
new file mode 100644
index 000000000..69bc6bee0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce5_gid_type.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+ * Description: RDMA common context format.
+ * Create: 2026-04-27
+ */
+
+#ifndef ROCE5_GID_TYPE_H
+#define ROCE5_GID_TYPE_H
+
+/**
+ * @brief enum roce5_gid_type - RoCE GID type definitions
+ * @details 定义RoCE GID类型枚举,与stp定义一致
+ */
+enum roce5_gid_type {
+ ROCE_IPv4_ROCEv2_GID = 0,
+ ROCE_IPv6_ROCEv2_GID = 1,
+ ROCE_ROCEv1_GID = 2,
+ ROCE_INV_GID
+};
+
+#endif /* ROCE5_GID_TYPE_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_cqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_cqe_format.h
new file mode 100644
index 000000000..41d8df16f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_cqe_format.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA XQE format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_CQE_FORMAT_H
+#define ROCE_CQE_FORMAT_H
+
+/**
+ * @brief struct roce_cqe - RoCE Completion Queue Entry format
+ * @details 定义RoCE CQE(完成队列元素)的数据结构,用于描述SQ/RQ操作完成信息
+ */
+typedef struct roce_cqe {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 owner : 1; /**< Owner bit. During initialization, 0 indicates all hardware, and 1 indicates all software.
+ This bit is modified when the hardware writes the CQE.
+ The meaning of each queue owner bit is reversed. */
+ u32 size : 2; /**< For roce, this field is reserved. */
+ u32 dif_en : 1; /**< For roce, this field is reserved. */
+ u32 wq_id : 4; /**< For roce, this field is reserved. */
+ u32 error_code : 4; /**< For roce, this field is reserved. */
+ u32 qpn : 20; /**< Local QPN, which is used in all cases. The driver finds the software QPC based on the QPN. */
+#else
+ u32 qpn : 20; /**< Local QPN, which is used in all cases. The driver finds the software QPC based on the QPN. */
+ u32 error_code : 4; /**< For roce, this field is reserved. */
+ u32 wq_id : 4; /**< For roce, this field is reserved. */
+ u32 dif_en : 1; /**< For roce, this field is reserved. */
+ u32 size : 2; /**< For roce, this field is reserved. */
+ u32 owner : 1; /**< Owner bit. During initialization, 0 indicates all hardware, and 1 indicates all software.
+ This bit is modified when the hardware writes the CQE.
+ The meaning of each queue owner bit is reversed. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 op_type : 5; /**< The same as what is for SQ WQE. For details, see the enumeration roce_cqe_opcode */
+ u32 s_r : 1; /**< Indicates SQ CQE or RQ CQE. 1-Send Completion; 0-Receive Completion */
+ u32 inline_r : 1; /**< Indicates whether RQ inline; SQ ignores this bit */
+ u32 flush_op : 1;
+ u32 fake : 1; /**< Indicates whether the CQE is a fake one. When fake, optype & syndronme should be 0 */
+ u32 inline_c : 1; /**< Indicates whether CQE inline; Currently only valid in read rsp SQ CQE */
+ u32 rsvd : 2;
+ u32 wqebb_cnt : 20; /**< The WQEBB index and SQ/RQ/SRQ are valid. */
+#else
+ u32 wqebb_cnt : 20; /**< The WQEBB index and SQ/RQ/SRQ are valid. */
+ u32 rsvd : 2;
+ u32 inline_c : 1; /**< Indicates whether CQE inline; Currently only valid in read rsp SQ CQE */
+ u32 fake : 1; /**< Indicates whether the CQE is a fake one. When fake, optype & syndronme should be 0 */
+ u32 flush_op : 1;
+ u32 inline_r : 1; /**< Indicates whether RQ inline; SQ ignores this bit */
+ u32 s_r : 1; /**< Indicates SQ CQE or RQ CQE. 1-Send Completion; 0-Receive Completion */
+ u32 op_type : 5; /**< The same as what is for SQ WQE. For details, see the enumeration roce_cqe_opcode */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ u32 byte_cnt; /**< Indicates the number of transmitted bytes. This field is valid for the RDMA read and receive
+ operations. For the recv of RDMA write imm, the value is 0. */
+
+ /* DW3 */
+ u32 imm_invalid_rkey; /**< The receiving is complete and valid. */
+
+ /* DW4 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vlan_id : 12;
+ u32 rsvd : 1;
+ u32 vlan_pri : 3;
+ u32 smac_h : 16;
+#else
+ u32 smac_h : 16;
+ u32 vlan_pri : 3;
+ u32 rsvd : 1;
+ u32 vlan_id : 12;
+#endif
+ } bs; /**< for ud only */
+ u32 value;
+ } dw4;
+
+ /* DW5 */
+ union {
+ u32 smac_l;
+ u32 wqe_num;
+ };
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vlan_pre : 2; /**< The for ud only:UD receive end is valid. The 00-packet does not contain a VLAN ID. The
+ 01-packet contains a VLAN ID. */
+ u32 fl : 1; /**< This field is valid only for UD. Force loopback */
+ u32 stp : 2;
+ u32 rsvd : 3;
+ u32 srqn_rqpn : 24; /**< The XRC at the receive end is valid. When the XRCSRQ at the receive end is received,
+ the ;UD at the remote end refers to the QPN at the remote end. */
+#else
+ u32 srqn_rqpn : 24; /**< The XRC at the receive end is valid. When the ;UD at XRCSRQ is received, the at the
+ remote end is the QPN at the remote end. */
+ u32 rsvd : 3;
+ u32 stp : 2;
+ u32 fl : 1; /**< This field is valid only for UD. Force loopback */
+ u32 vlan_pre : 2; /**< The for ud only:UD receive end is valid. The 00-packet does not contain a VLAN ID. The
+ 01-packet contains a VLAN ID. */
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ /* DW7 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 wqe_cnt : 16; /**< WQE index, valid SQ */
+ u32 rsvd : 8;
+ u32 syndrome : 8; /**< 0 indicates that the operation is complete. This parameter is valid when Op_type is set
+ to ROCE_OPCODE_ERR. For details about the definition, see the enumeration
+ roce_cqe_syndrome. */
+#else
+ u32 syndrome : 8; /**< 0 indicates that the operation is complete. This field is valid when Op_type is set to
+ ROCE_OPCODE_ERR. For details, see the enumeration roce_cqe_syndrome. */
+ u32 rsvd : 8;
+ u32 wqe_cnt : 16; /**< WQE index, valid SQ */
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+
+ union {
+ u32 inline_data0;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd0 : 12;
+ u32 global_qpn : 20; /**< 偏移需要联动1815E的HBU配置,当前固定只支持一个qpn_mode */
+#else
+ u32 global_qpn : 20;
+ u32 rsvd0 : 12;
+#endif
+ } bs;
+ } dw8;
+ u32 inline_data1;
+
+ u32 common_rsvd[4];
+ u32 ulp_rsvd[2];
+} roce_cqe_s;
+
+#endif /* ROCE_CQE_FORMAT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_ext_data_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_ext_data_defs.h
new file mode 100644
index 000000000..668bab279
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_ext_data_defs.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq extended attributes.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_NPU_CMD_EXT_DATA_DEFS_H
+#define ROCE_NPU_CMD_EXT_DATA_DEFS_H
+
+#pragma pack(4)
+
+/**
+ * @brief struct roce_uld_feature_s - ULD feature negotiation data
+ * @details 暴露给上层业务的属性协商数据结构
+ */
+typedef struct {
+ u64 roce_uld_kernel_ext_ability;
+ u64 roce_uld_user_ext_ability;
+} roce_uld_feature_s;
+
+#pragma pack()
+
+#endif /* ROCE_NPU_CMD_EXT_DATA_DEFS_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_type_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_type_defs.h
new file mode 100644
index 000000000..117ab6e40
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_npu_cmd_type_defs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq command format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_NPU_CMD_TYPE_DEFS_H
+#define ROCE_NPU_CMD_TYPE_DEFS_H
+
+enum CMD_TYPE_BITMASK_E {
+ CMD_TYPE_BITMASK_EXT = 0,
+ CMD_TYPE_BITMASK_RSVD0,
+ CMD_TYPE_BITMASK_JBOF, /**< 不活跃接口 */
+ CMD_TYPE_BITMASK_PLUGIN_RET, /**< 不活跃接口 */
+ CMD_TYPE_BITMASK_VBS, /**< 不活跃接口 */
+ CMD_TYPE_BITMASK_DSW, /**< 不活跃接口 */
+ CMD_TYPE_BITMASK_NOFAA, /**< 不活跃接口 */
+ CMD_TYPE_BITMASK_SHADOW,
+ CMD_TYPE_BITMASK_VROCE, /**< 不活跃接口 */
+ CMD_TYPE_BITMASK_RSVD1 = 9,
+ CMD_TYPE_BITMASK_COMM,
+ CMD_TYPE_BITMASK_GID,
+ CMD_TYPE_BITMASK_MR,
+ CMD_TYPE_BITMASK_SRQ,
+ CMD_TYPE_BITMASK_CQ,
+ CMD_TYPE_BITMASK_QP = 15
+};
+
+#define VERBS_CMD_TYPE_QP_BITMASK (1u << CMD_TYPE_BITMASK_QP)
+#define VERBS_CMD_TYPE_CQ_BITMASK (1u << CMD_TYPE_BITMASK_CQ)
+#define VERBS_CMD_TYPE_SRQ_BITMASK (1u << CMD_TYPE_BITMASK_SRQ)
+#define VERBS_CMD_TYPE_MR_BITMASK (1u << CMD_TYPE_BITMASK_MR)
+#define VERBS_CMD_TYPE_GID_BITMASK (1u << CMD_TYPE_BITMASK_GID)
+#define VERBS_CMD_TYPE_COMM_BITMASK (1u << CMD_TYPE_BITMASK_COMM)
+#define VERBS_CMD_TYPE_VROCE_BITMASK (1u << CMD_TYPE_BITMASK_VROCE)
+#define VERBS_CMD_TYPE_SHADOW_BITMASK (1u << CMD_TYPE_BITMASK_SHADOW)
+#define VERBS_CMD_TYPE_NOFAA_BITMASK (1u << CMD_TYPE_BITMASK_NOFAA)
+#define VERBS_CMD_TYPE_DSW_BITMASK (1u << CMD_TYPE_BITMASK_DSW)
+#define VERBS_CMD_TYPE_VBS_BITMASK (1u << CMD_TYPE_BITMASK_VBS)
+#define VERBS_CMD_TYPE_JBOF_BITMASK (1u << CMD_TYPE_BITMASK_JBOF)
+#define VERBS_CMD_TYPE_EXT_BITMASK (1u << CMD_TYPE_BITMASK_EXT)
+
+#pragma pack(4)
+typedef struct tag_roce_verbs_cmd_header {
+ 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 */
+
+ u32 opt;
+
+ union {
+ u32 value;
+
+ struct {
+ u32 rsvd : 16;
+ u32 shadow_vfid : 16;
+ } bs;
+ } dw3;
+} roce_verbs_cmd_header_s;
+
+#pragma pack()
+
+#endif /* ROCE_NPU_CMD_TYPE_DEFS_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_opt_types.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_opt_types.h
new file mode 100644
index 000000000..99ae383fe
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_opt_types.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+ * Description: RDMA wqe opt types.
+ * Create: 2021-04-28
+ */
+
+#ifndef ROCE_WQE_OPT_TYPES_H
+#define ROCE_WQE_OPT_TYPES_H
+
+#define ROCE_TX_SEND 0
+#define ROCE_TX_SEND_INVALIDATE 1
+#define ROCE_TX_SEND_IMMEDIATE 2
+#define ROCE_TX_OPTYPE_RSVD3 3
+#define ROCE_TX_WRITE 4
+#define ROCE_TX_WRITE_IMMEDIATE 5
+#define ROCE_TX_OPTYPE_RSVD6 6
+#define ROCE_TX_OPTYPE_RSVD7 7
+#define ROCE_TX_READ 8
+#define ROCE_TX_OPTYPE_RSVD9 9
+#define ROCE_TX_OPTYPE_RSVD10 10
+#define ROCE_TX_EXT_ATOMIC_COMPARE_SWAP 11
+#define ROCE_TX_ATOMIC_COMPARE_SWAP 12
+#define ROCE_TX_ATOMIC_FETCH_ADD 13
+#define ROCE_TX_ATOMIC_MASKED_COMPARE_SWAP 14
+#define ROCE_TX_ATOMIC_MASKED_FETCH_ADD 15
+#define ROCE_FAST_REG_PMR 16
+#define ROCE_LOCAL_INVALIDATE 17
+#define ROCE_BIND_MW_TYPE1_TYPE2 18
+#define ROCE_REG_SIG_MR 19
+#define ROCE_LOCAL_EXT 20
+#define ROCE_TX_OPTYPE_RSVD15 21
+#define ROCE_RESIZE_TYPE 22
+#define ROCE_DAVID_FLUSH 23 /**< david 排空opcode */
+#define ROCE_TX_OPTYPE_RSVD18 24
+#define ROCE_TX_OPTYPE_RSVD19 25
+#define ROCE_TX_OPTYPE_RSVD1A 26
+#define ROCE_TX_OPTYPE_RSVD1B 27
+#define ROCE_TX_OPTYPE_RSVD1C 28
+#define ROCE_TX_OPTYPE_RSVD1D 29
+#define ROCE_ERR_TYPE 30
+#define ROCE_TX_OPTYPE_RSVD1F 31
+
+#endif /* ROCE_WQE_OPT_TYPES_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_ulp_task.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_ulp_task.h
new file mode 100644
index 000000000..8db3caea6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/rdma/roce_wqe_ulp_task.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA wqe structure format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_WQE_ULP_TASK_H
+#define ROCE_WQE_ULP_TASK_H
+
+/**
+ * @brief union roce5_wqe_tsk_com_seg - WQE task common segment
+ * @details 定义WQE任务通用段格式,包含操作类型、标志位等信息
+ */
+typedef union roce5_wqe_tsk_com_seg {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 se : 1;
+ u32 f : 1;
+ u32 c : 1;
+ u32 op_type : 5;
+ u32 so : 1;
+ u32 rsvd : 3;
+ u32 dif_en : 1;
+ u32 rsvd0 : 1;
+ u32 xrc_srqn : 18;
+#else
+ u32 xrc_srqn : 18; /**< The XRC is valid, and the remote SRQN is specified. */
+ u32 rsvd0 : 1;
+ u32 dif_en : 1;
+ u32 rsvd : 3;
+ u32 so : 1; /**< Strong order-preserving flag, valid only for Local invalidate\Type 2 Bind MW and FRPMR (consider
+ the implementation at the bottom layer) */
+ u32 op_type : 5; /**< Operation type of the SQ WQE.
+ 8'h00-Send
+ 8'h01-Send with Invalidate
+ 8'h02-Send with Immediate Data
+ 8'h03-rsvd
+ 8'h04-RDMA Write
+ 8'h05-RDMA Write with Immediate Data
+ 8'h06-RDMA WRITE CMD64
+ 8'h07-rsvd
+ 8'h08-RDMA READ
+ 8'h09-ATOMIC WRITE
+ 8'h0a-FLUSH
+ 8'h0b-rsvd
+ 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 operation(extended for further local operation)
+ other-Reserved */
+ u32 c : 1; /**< Indicates whether the SQ generates the CQE, which is required by the microcode. */
+ u32 f : 1; /**< Indicates whether the SQ requires order-preserving. */
+ u32 se : 1; /**< Indicates whether the packet carries the SE flag. */
+#endif
+ } bs;
+
+ u32 value;
+} roce_wqe_tsk_com_seg_u;
+
+/**
+ * @brief union roce_wqe_tsk_misc_seg - WQE task misc segment
+ * @details 定义WQE任务杂项段格式
+ */
+typedef union roce_wqe_tsk_misc_seg {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 pi : 16; /**< 完整的没有掩码队列深度的pi, fast direct wqe场景有效 */
+ u32 cmd_len : 8;
+ u32 last_ext_len : 8;
+#else
+ u32 last_ext_len : 8;
+ u32 cmd_len : 8;
+ u32 pi : 16;
+#endif
+ } bs;
+
+ u32 value;
+} roce_wqe_tsk_misc_seg_u;
+
+/**
+ * @brief struct roce_wqe_ulp_rdma_tsk_seg - ULP RDMA task segment
+ * @details 定义ULP RDMA任务段格式,用于ULP扩展的RDMA操作
+ */
+typedef struct roce_wqe_ulp_rdma_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 data_len; /**< Length of the data sent by the SQ WQE */
+
+ /* DW2 */
+ u32 immdata_invkey;
+
+ /* DW3 */
+ roce_wqe_tsk_misc_seg_u dw3;
+
+ /* DW4~5 */
+ union {
+ u64 va;
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+#ifndef PLATFORM_MODE_SNP_MACC /**< 宏指令不支持匿名结构体 */
+ } dw4;
+ };
+#else
+ } macc_bs;
+ } dw4;
+#endif /* PLATFORM_MODE_SNP_MACC */
+
+ /* DW6 */
+ u32 rkey;
+
+ /* DW7 */
+ u32 ulp_value;
+} roce_wqe_ulp_rdma_tsk_seg_s;
+
+#endif /* ROCE_WQE_ULP_TASK_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_base_view_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_base_view_defs.h
new file mode 100644
index 000000000..616361ede
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_base_view_defs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
+ * Description: UBCNET BASE VIEW表项结构体定义
+ * Create: 2025-11-13
+ * Notes:
+ * History:
+ */
+
+#ifndef UBCNET_BASE_VIEW_DEFS_H
+#define UBCNET_BASE_VIEW_DEFS_H
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_heartbeat_view_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_heartbeat_view_defs.h
new file mode 100644
index 000000000..b0dece1c0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_heartbeat_view_defs.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2027. All rights reserved.
+ * Description: UBCNET heartbeat VIEW表项结构体定义
+ * Create: 2025-12-3
+ * Notes:
+ * History:
+ */
+
+#ifndef UBCNET_HEARTBEAT_VIEW_DEFS_H
+#define UBCNET_HEARTBEAT_VIEW_DEFS_H
+
+#include "base_type.h"
+
+typedef enum {
+ UBCNET_HB_FE_DT_HOST_NIC = 0,
+ UBCNET_HB_FE_DT_HOST_VIRTIO = 1,
+ UBCNET_HB_FE_DT_HOST_NVME = 2,
+ UBCNET_HB_FE_DT_DAVID = 3,
+} ubcnet_hbfe_dt_e;
+
+typedef enum {
+ UBCNET_PATH_HB_DISABLE = 0,
+ UBCNET_PATH_HB_ENABLE = 1,
+} ubcnet_path_hb_en_e;
+
+typedef enum {
+ UBCNET_PATH_STATE_IDLE = 0,
+ UBCNET_PATH_STATE_ACTIVE = 1,
+ UBCNET_PATH_STATE_DEAD = 2,
+ UBCNET_PATH_STATE_RECOVERY = 3,
+ UBCNET_PATH_STATE_ILLEGAL = 4, /* 非法state标识 */
+} ubcnet_path_state_e;
+
+/* ubcnet_hb_path_id 按C00版本产品化规格严格定义如下,未来可能涉及扩展
+rhost_type仅支持0~1, 0-host,1-david
+port_id仅支持0~5
+rhost_id支持0~63
+*/
+#define IS_UBCNET_HB_PATH_ID_VALID(rhost_type, port_id, rhost_id) \
+ (((rhost_type) <= 1) && ((port_id) <= 5) && ((rhost_id) <= 63))
+#define UBCNET_HB_PATH_ID_DEFINE(rhost_type, port_id, rhost_id) \
+ (((port_id) << 7) | ((rhost_type) << 6) | (rhost_id))
+/* ubcnet heartbeat buf minimum size.
+DPU will use this size to send DMA READ */
+#define UBCNET_HB_BUF_SIZE_MIN 16
+
+typedef struct {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 path_hb_en : 1; /**< path heartbeat enable flag. @see ubcnet_path_hb_en_e */
+ u32 path_hb_recovery_en : 1; /**< path heartbeat recovery enable flag. @see ubcnet_path_hb_en_e */
+ u32 hb_fe : 12; /**< path heartbeat fe glb_func_id. */
+ u32 hb_fe_dt : 2; /**< path heartbeat fe device_type. @see ubcnet_hbfe_dt_e */
+ u32 hb_fe_valid : 1; /**< path heartbeat fe valid flag. 0 hw dpath inalid, 1 hw dpath is valid */
+ u32 hb_fe_rb : 1; /**< path heartbeat fe roudbit */
+ u32 rsvd1 : 14;
+#else
+ u32 rsvd1 : 14;
+ u32 hb_fe_rb : 1;
+ u32 hb_fe_valid : 1;
+ u32 hb_fe_dt : 2;
+ u32 hb_fe : 12;
+ u32 path_hb_recovery_en : 1;
+ u32 path_hb_en : 1;
+#endif
+ } dw0;
+
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 hb_buf_size : 16; /**< path heartbeat buffer size, min size @see UBCNET_HB_BUF_SIZE_MIN */
+ u32 hb_buf_valid : 1; /**< path heartbeat buffer valid flag. 0 invalid, 1 valid. */
+ u32 rsvd1 : 15;
+#else
+ u32 rsvd1 : 15;
+ u32 hb_buf_valid : 1;
+ u32 hb_buf_size : 16;
+#endif
+ } dw1;
+
+ u32 hb_buf_addr_h; /**< path heartbeat buffer address */
+ u32 hb_buf_addr_l;
+} sml_ubcnet_path_hbfe_info_s;
+
+/* MPU start 心跳timer,通过定义usrdata来控制微码单线程完成的心跳路径覆盖范围. */
+#define UBCNET_HB_TMRMSG_PORT_ID(thread_idx, port_shift) \
+ ((thread_idx) >> (port_shift))
+#define UBCNET_HB_TMRMSG_THREAD_RHOST_NUM(rhost_num_order) \
+ (1 << (rhost_num_order))
+#define UBCNET_HB_TMRMSG_THREAD_START_RHOSTID(thread_idx, inner_idx_mask, \
+ rhost_num_order) \
+ (((thread_idx) & (inner_idx_mask)) << (rhost_num_order))
+typedef union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u64 unuseful_bits : 36; /**< tmrmsg userdatra only bit[28:0]is valid */
+ u64 rsvd1 : 12;
+ u64 rhost_max_num : 7; /**< max rhost num per pport */
+ u64 thread_rhost_num_order : 3; /**< heartbeat rhost num per thread, used as @UBCNET_HB_TMRMSG_THREAD_RHOST_NUM */
+ u64 thread_port_shift : 3; /**< get port_id from thread_idx, used as @UBCNET_HB_TMRMSG_PORT_ID */
+ u64 thread_inner_idx_mask : 3; /**< get port inner group id from thread_idx, used as @UBCNET_HB_TMRMSG_THREAD_START_RHOSTID */
+#else
+ u64 thread_inner_idx_mask : 3;
+ u64 thread_port_shift : 3;
+ u64 thread_rhost_num_order : 3;
+ u64 rhost_max_num : 7;
+ u64 rsvd1 : 12;
+ u64 unuseful_bits : 36;
+#endif
+ } bs;
+ u64 value;
+} ubcnet_hb_tmr_msg_usrdata_s;
+
+typedef union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u64 unuseful_bits : 36; /**< tmrmsg userdatra only bit[28:0]is valid */
+ u64 rsvd1 : 10;
+ u64 host_recovery_en : 1;
+ u64 david_recovery_en : 1;
+ u64 rhost_max_num : 7; /**< max rhost num per pport */
+ u64 thread_rhost_num_order : 3; /**< heartbeat rhost num per thread, used as @UBCNET_HB_TMRMSG_THREAD_RHOST_NUM */
+ u64 thread_port_shift : 3; /**< get port_id from thread_idx, used as @UBCNET_HB_TMRMSG_PORT_ID */
+ u64 thread_inner_idx_mask : 3; /**< get port inner group id from thread_idx, used as @UBCNET_HB_TMRMSG_THREAD_START_RHOSTID */
+#else
+ u64 thread_inner_idx_mask : 3;
+ u64 thread_port_shift : 3;
+ u64 thread_rhost_num_order : 3;
+ u64 rhost_max_num : 7;
+ u64 david_recovery_en : 1;
+ u64 host_recovery_en : 1;
+ u64 rsvd1 : 10;
+ u64 unuseful_bits : 36;
+#endif
+ } bs;
+ u64 value;
+} ubcnet_hb_recovery_tmr_msg_usrdata_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mami_extend.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mami_extend.h
new file mode 100644
index 000000000..e9478dabd
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mami_extend.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: UBCNET MAMI提供ULP的扩展接口
+ * Create: 2025/11/25
+ */
+
+#ifndef UBCNET_MAMI_EXTEND_H
+#define UBCNET_MAMI_EXTEND_H
+
+#include "base_type.h"
+#include "ccp_algo_format.h"
+#include "sml_base_table_def.h"
+#include "ubcnet_mpu_cmd_defs.h"
+
+#define MAMI_INFO_BUFFER_MAX_LEN 20
+#define MAMI_RSP_BUFFER_MAX_LEN 128
+#define GLB_UBCNET_RHOST_MAX_CTRL_UE_NUM 8
+
+typedef enum {
+ UBCNET_MAMI_SET = 0,
+ UBCNET_MAMI_GET,
+ UBCNET_MAMI_DEL,
+ UBCNET_MAMI_OP_NUM,
+} ubcnet_mami_op_e;
+
+typedef enum {
+ /* 自定义MAMI命令 */
+ MAMI_CMD_VL_INFO = 0x0,
+ MAMI_CMD_REMOTE_PORT_CNA = 0x1,
+ MAMI_CMD_HBM_PERMISSION = 0x2,
+ MAMI_CMD_HBM_UPI = 0x3,
+ MAMI_CMD_HBM_LB = 0x4,
+ MAMI_CMD_PATH_STATE = 0x5,
+ MAMI_CMD_HEART_PERIOD = 0x6,
+ MAMI_CMD_PATH_HEART_EN = 0x7,
+ MAMI_CMD_DAVID_HB_BUF = 0x8,
+ MAMI_CMD_HEARTFE_INFO = 0x9,
+ MAMI_CMD_DPU_OQ_MAX_SPEED = 0xa,
+ MAMI_CMD_HB_RECOVERY_CTRL = 0xb,
+
+ /* 标准MAMI命令 */
+ MAMI_CMD_TPL_SCC = 0x10,
+ MAMI_CMD_TPL_CCC = 0x11,
+ MAMI_CMD_NUM,
+} ubcnet_mami_cmd_e;
+
+typedef enum {
+ CC_DISABLE = 0x0,
+ DCQCN_NO_CONGESTION = 0x1,
+ DCQCN_CONGESTION = 0x2,
+ LDCP = 0x3,
+} ubcnet_cog_alg_sel_e;
+
+typedef enum {
+ VL_FLOW_TYPE_CDMA_D = 0,
+ VL_FLOW_TYPE_MMIO = 1,
+ VL_FLOW_TYPE_BUS_MESSAGE = 2,
+ VL_FLOW_TYPE_CDMA_C = 3,
+ VL_FLOW_TYPE_MAX,
+} vl_flow_type_e;
+
+typedef enum {
+ VL_TYPE_REQ = 0x0,
+ VL_TYPE_RSP = 0x1,
+ VL_TYPE_MAX,
+} vl_type_e;
+
+/**
+ * @brief MAMI command structure
+ *
+ * Defines the command format for management interface between MPU and UBCNET.
+ * Supports various operations (SET/GET/DEL) through a unified interface.
+ *
+ */
+typedef struct {
+ u32 version; /**< Protocol version for compatibility */
+ ubcnet_mami_cmd_e cmd; /**< MAMI command type, @see ubcnet_mami_cmd_e */
+ u32 cmd_info[MAMI_INFO_BUFFER_MAX_LEN]; /**< Command parameter buffer */
+ u32 mami_cmd_size; /**< Actual command data size */
+ u32 mami_rsp_size; /**< Actual response data size */
+ u32 rsv[2];
+} ubcnet_mpu_mami_cmd_s;
+
+typedef struct {
+ u32 eid; /**< ubs instance id, indicates the remote unique node, 20bit */
+ u32 remote_host_type; /**< see @ubcnet_remote_host_type_e */
+ u32 remote_port_id; /**< 1825 ubc port id 0-5 */
+ u32 cna; /** 16bit */
+} ubcnet_mpu_mami_port_cna_s;
+
+typedef struct {
+ u32 eid;
+} ubcnet_mpu_mami_port_cna_get_req_s;
+
+typedef struct {
+ struct {
+ u32 rhost_id : 6;
+ u32 rhost_type : 2;
+ u32 upi : 16;
+ u32 lb : 8;
+ } dw0;
+
+ struct {
+ u32 sl : 4;
+ u32 active_port : 6;
+ u32 rsv1 : 22;
+ } dw1;
+
+ u16 port_cna[GLB_MAX_UBC_PORT_NUM];
+} ubcnet_mpu_mami_get_david_port_cna_rsp_s;
+
+typedef struct {
+ u32 rhost_id : 6;
+ u32 rhost_type : 2;
+ u32 active_port : 6;
+ u32 rsv1 : 18;
+ u16 port_cna[GLB_MAX_UBC_PORT_NUM];
+} ubcnet_mpu_mami_get_host_port_cna_rsp_s;
+
+typedef struct {
+ u32 eid;
+ u32 tafe_id;
+} ubcnet_mpu_mami_hbm_permission_s;
+
+typedef struct {
+ u32 eid;
+ u32 upi;
+} ubcnet_mpu_mami_hbm_upi_s;
+
+typedef struct {
+ u32 eid;
+ u32 lb;
+} ubcnet_mpu_mami_hbm_lb_s;
+
+typedef struct {
+ u32 tp_st : 3;
+ u32 scc_token : 19;
+ u32 cng_alg_sel : 3;
+ u32 tmpt_id : 6;
+ u32 scc_reg_on : 1;
+ u32 scc_data[8];
+ u32 rsvl[7];
+} ubcnet_mpu_mami_ccc_ctx_s;
+
+typedef struct {
+ u32 planeId;
+ u16 ueId;
+ u16 rsv; /* 4字节对齐 */
+} ubcnet_mpu_mami_ub_entity_s;
+
+typedef struct {
+ ubcnet_mpu_mami_ub_entity_s fe;
+ u32 dcna;
+ u32 vl;
+ u8 rsv[4];
+ ubcnet_mpu_mami_ccc_ctx_s ccc_ctx;
+} ubcnet_mpu_mami_ccc_s;
+
+typedef struct {
+ u32 tmpt_id;
+ u32 plane_id;
+} ubcnet_mpu_mami_scc_req_s;
+
+typedef struct {
+ ccp_dcqcn_ubcnet_para_s dcqcn_para;
+ u8 rsv[4];
+} ubcnet_mpu_mami_scc_rsp_s;
+
+typedef struct {
+ ubcnet_mpu_mami_scc_req_s scc_req;
+ ccp_dcqcn_ubcnet_para_s dcqcn_para;
+ u8 rsv[4];
+} ubcnet_mpu_mami_scc_s;
+
+typedef struct tag_vl_pair {
+ u32 req_vl : 4;
+ u32 rsp_vl : 4;
+ u32 valid : 1;
+ u32 rsvd : 23;
+} vl_pair_s;
+
+typedef struct {
+ u32 remote_host_type;
+ u32 ubc_port_id;
+ vl_pair_s vl_pair[VL_FLOW_TYPE_MAX];
+} ubcnet_mpu_mami_vl_info_s;
+
+typedef struct {
+ ubcnet_mpu_mami_vl_info_s
+ vl_info[GLB_MAX_UBC_PORT_NUM * REMOTE_HOST_TYPE_NUM];
+} ubcnet_mpu_mami_vl_info_rsp_s;
+
+typedef struct {
+ u32 rhost_type; /**< see @ubcnet_remote_host_type_e */
+ u32 port_id; /**< 1825 ubc port id 0-5 */
+ u32 eid; /**< ubs instance id, indicates the remote unique node */
+} ubcnet_mpu_mami_path_info_s;
+
+typedef struct {
+ u32 rhost_type; /**< see @ubcnet_remote_host_type_e */
+ u32 hb_period; /**< TODO: MIN/MAX to be determined */
+} ubcnet_mpu_mami_heart_period_s;
+
+typedef struct {
+ ubcnet_mpu_mami_path_info_s
+ path_info; /**< see @ubcnet_mpu_mami_path_info_s */
+ u32 path_hb_en; /**< 0:disable 1:enable */
+ u32 path_hb_recovery_en; /**< 0:disable 1:enable */
+} ubcnet_mpu_mami_path_heart_en_s;
+
+typedef struct {
+ u32 heart_buf_size;
+ u32 heart_buf_tid;
+ u64 heart_buf_addr;
+} ubcnet_mpu_mami_hb_buf_s;
+
+typedef struct {
+ u8 path_hb_en; /**< 0:disable 1:enable */
+ u8 path_hb_recovery_en;
+ u16 rsvd;
+ u32 hb_fe; /**< global func_id */
+ ubcnet_mpu_mami_hb_buf_s hb_info; /**< see @ubcnet_mpu_mami_hb_buf_s */
+} ubcnet_mpu_mami_heartfe_info_s;
+
+/* ********************************** oq 限速结构体 ********************************** */
+/**
+ * @brief MAMI Set command oq speed struct
+ *
+ */
+typedef struct ubcnet_mpu_cmd_oq_max_speed {
+ u32 dcna; /**< Hi1825视角,对端port_cna */
+ u32 vl; /**< 0-15 */
+ u32 rate; /**< 单位:MB/s */
+} ubcnet_mpu_mami_oq_max_speed_s;
+
+/**
+ * @brief MAMI Get command oq speed req struct
+ *
+ */
+typedef struct ubcnet_mpu_mami_get_oq_max_speed_req {
+ u32 dcna; /**< Hi1825视角,对端port_cna */
+ u32 vl; /**< 0-15 */
+} ubcnet_mpu_mami_get_oq_max_speed_req_s;
+
+typedef struct {
+ struct mgmt_msg_head msg_head;
+ ubcnet_mpu_mami_cmd_s mami_cmd;
+ ubcnet_mami_op_e op_type;
+ u32 rsp_info[MAMI_RSP_BUFFER_MAX_LEN];
+} ubcnet_mpu_cmd_mami_table_op_s;
+
+typedef struct {
+ u32 eid; /* 对应远端节点的bus instance eid,远端节点的唯一标识 */
+} ubcnet_mpu_mami_hbm_permission_req;
+
+typedef struct {
+ u32 actual_num;
+ u32 ctrl_ue_list
+ [GLB_UBCNET_RHOST_MAX_CTRL_UE_NUM]; /* UBCNET_RHOST_MAX_CTRL_UE_NUM = 8 */
+} ubcnet_mpu_mami_hbm_permission_rsp;
+
+typedef struct {
+ u8 recovery_threshold; /* 心跳恢复的阈值,目前默认10次 */
+ u8 rsvd;
+ u16 hb_recovery_period; /* 恢复探测超时时间. 单位:S */
+} ubcnet_mpu_mami_hb_recovery;
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd.h
new file mode 100644
index 000000000..9743ecc60
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: UBC commands msg between Driver and MPU.
+ * Author: None
+ * Create: 2024/12/17
+ */
+
+#ifndef UBCNET_MPU_CMD_H
+#define UBCNET_MPU_CMD_H
+
+/**
+ * @brief UBCNET DRV to MPU Commands
+ * dft cmd above 128
+ */
+typedef enum ubcnet_mpu_cmd_type {
+ UBCNET_MPU_CMD_ADD_OB_TBL = 0, /**< MPU UBC set OB TBL entry
+ @see struct ubcnet_d2h_ob_entry_s */
+ UBCNET_MPU_CMD_RHOST_NODE_INFO_OP =
+ 1, /**< MPU UBCNET RHOST_NODE_INFO TABLE OP
+ @see ubcnet_mpu_cmd_rhost_node_info_op_s */
+ UBCNET_MPU_CMD_GET_DYNAMIC_FE = 2, /**< MPU UBC get dynamic fe ob entry
+ @see ubcnet_mpu_cmd_template_fe_tenant_s */
+ UBCNET_MPU_CMD_RDMA_TID_FE_OP = 3, /**< MPU UBCNET TID_FE OP
+ @see ubcnet_mpu_cmd_tid_fe_op_s */
+ UBCNET_MPU_CMD_RPORT_INFO_TABLE_OP =
+ 4, /**< MPU UBCNET PORT_NODE_INFO TABLE OP
+ @see ubcnet_mpu_cmd_rport_info_table_op_s */
+ UBCNET_MPU_CMD_VOQ_PATH_TABLE_OP = 5, /**< MPU UBCNET VOQ_PATH_TABLE OP
+ @see ubcnet_mpu_cmd_voq_path_tbl_op_s */
+ UBCNET_MPU_CMD_VL_INFO_TABLE_OP = 6, /**< MPU UBCNET VL_INFO_TABLE OP
+ @see ubcnet_mpu_cmd_vl_info_tbl_op_s */
+ UBCNET_MPU_CMD_CC_STATISTICS = 7, /**< MPU UBCNET get cc status
+ @see ubcnet_mpu_cmd_cc_statistics_s */
+ UBCNET_MPU_CMD_MAMI_TBL_OP = 8, /**< MPU UBCNET MAMI TBL OP
+ @see ubcnet_mpu_cmd_mami_table_op_s */
+ UBCNET_MPU_CMD_PERF_STATISTICS = 9, /**< MPU UBCNET PERF STATISTICS OP
+ @ see ubcnet_mpu_cmd_perf_statistics_s */
+ UBCNET_MPU_CMD_GET_D2N_PATH_STATE =
+ 10, /**< MPU UBCNET D2N_PATH_STATE OP
+ @ see ubcnet_cmd_get_d2n_path_state_s */
+ UBCNET_MPU_CMD_HBM_PERMISSION_INFO_OP =
+ 11, /**< MPU UBCNET HBM PERMISSION OP
+ @ see ubcnet_mpu_cmd_hbm_permission_info_op_s */
+ UBCNET_MPU_CMD_PATH_STATE_INFO_OP = 12, /**< MPU UBCNET PATH STATE OP
+ @ see ubcnet_mpu_cmd_path_state_info_op_s */
+ UBCNET_MPU_CMD_CC_ENABLE = 13, /**< MPU UBCNET CC enable/disable
+ @see ubcnet_mpu_cmd_cc_e */
+ UBCNET_MPU_CMD_GET_H2H_FIB = 128, /**< MPU UBC get H2H FIB entry
+ @see ubcnet_h2h_fib_entry_s */
+ UBCNET_MPU_CMD_GET_H2H_NIB = 129, /**< MPU UBC get H2H NIB entry
+ @see struct ubcnet_h2h_nib_entry_s */
+} ubcnet_mpu_cmd_type_e;
+
+#endif /* UBCNET_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd_defs.h
new file mode 100644
index 000000000..990352a74
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_mpu_cmd_defs.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: UBC commands msg between Driver and MPU.
+ * Author: None
+ * Create: 2024/12/17
+ */
+
+#ifndef UBCNET_MPU_CMD_DEFS_H
+#define UBCNET_MPU_CMD_DEFS_H
+
+#include "base_type.h"
+#include "mpu_cmd_base_defs.h"
+#include "ubcnet_rdma_view_defs.h"
+
+#define UBCNET_H2H_SML_TBL_BUF_MAX (768)
+#define MAX_UBCNET_VL_NUM 16
+#define MAX_ROUTE_NUM 32 /* 8 david multi 4 port */
+
+/**
+ * @brief UBCNET H2H SML table arguments, used by struct ubcnet_h2h_cmd_sml_tbl
+ *
+ */
+typedef union ubcnet_h2h_sml_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ u32 pad; /* netlink msg switch for align 16B padding */
+ } tbl_arg;
+
+ u32 args[4];
+} ubcnet_h2h_sml_tbl_args_u;
+
+/**
+ * @brief UBCNET H2H get Route FIB/Neigh NIB command struct defination
+ * @see UBCNET_MPU_CMD_GET_H2H_FIB
+ * @see UBCNET_MPU_CMD_GET_H2H_NIB
+ *
+ */
+typedef struct ubcnet_h2h_cmd_sml_tbl {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u16 func_id; /**< Function ID */
+ u16 pad;
+ u32 tbl_type; /**< SML table type, unused */
+ ubcnet_h2h_sml_tbl_args_u args; /**< SML table arguments */
+ u8 tbl_buf[UBCNET_H2H_SML_TBL_BUF_MAX]; /**< SML table data buffer */
+} ubcnet_h2h_cmd_sml_tbl_s;
+
+typedef struct ubcnet_h2h_fib_entry {
+ u32 daddr[4];
+
+ u32 nexthop_addr[4];
+
+ u8 outintf_idx;
+ u8 flag;
+ u8 nl_type;
+ u8 rsvd0;
+
+ u8 outintf_mac[6];
+ u8 rsvd[10];
+} ubcnet_h2h_fib_entry_s;
+
+typedef struct ubcnet_h2h_nib_entry {
+ u32 nexthop_addr[4];
+
+ u8 outintf_idx;
+ u8 ip_type;
+ u8 rsvd0[2];
+
+ u8 neigh_mac[6];
+ u16 rsvd1;
+} ubcnet_h2h_nib_entry_s;
+
+/**
+ * @brief UBCNET D2H set OB_LOOKUP_TBL command struct defination
+ * @see UBCNET_MPU_CMD_ADD_OB_TBL
+ *
+ */
+
+typedef struct ubcnet_d2h_ob_entry {
+ u32 func_id : 16;
+ u32 rsvd : 16;
+ u32 tid1 : 20;
+ u32 rsvd1 : 12;
+ u32 tid0 : 20;
+ u32 rsvd2 : 12;
+ u32 upi : 16;
+ u32 dcna : 16;
+ u32 deid : 20;
+ u32 rsvd3 : 12;
+ u32 seid : 20;
+ u32 lb : 8;
+ u32 ee : 2;
+ u32 rsvd4 : 2;
+} ubcnet_d2h_ob_entry_s;
+
+typedef struct ubcnet_d2h_cmd_ob_tbl {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ ubcnet_d2h_ob_entry_s ob_entry;
+} ubcnet_d2h_cmd_ob_tbl_s;
+
+typedef enum {
+ RHOST_NODE_INFO_TBL = 0,
+ RPORT_NODE_INFO_TBL = 1,
+ UBCNET_PATH_STATE_TBL = 2,
+ TID_FE_MAP_TBL = 3,
+ VOQ_PATH_TBL = 4,
+ VL_INFO_TBL = 5,
+ OB_TBL = 6,
+ HBM_PERMISSION_TBL = 7,
+ /* 后续表项在这里添加 */
+ UBCNET_TABLE_NUM
+} ubcnet_table_e;
+
+typedef enum {
+ UBCNET_TBL_ADD = 0,
+ UBCNET_TBL_GET,
+ UBCNET_TBL_DEL,
+#ifdef MPU_DFX_VERSION
+ UBCNET_TBL_UPDATE,
+#endif
+ UBCNET_TBL_OP_NUM,
+} ubcnet_table_op_e;
+
+typedef enum {
+ RHOST_NODE_FIELD_UPI = 1,
+ RHOST_NODE_FIELD_LB,
+ RHOST_NODE_FIELD_CNA,
+ RHOST_NODE_FIELD_CTRL_FE,
+} ubcnet_rhost_node_field_e;
+
+typedef enum {
+ RTT = 0,
+ PPS,
+ BPS,
+} ubcnet_perf_op_e;
+
+typedef enum {
+ PERF_PORT = 0,
+ PERF_VL,
+} ubcnet_perf_type_e;
+
+/* ********************************** 远端port节点信息表,sml hash表4+8 ********************************** */
+typedef struct {
+ u32 remote_host_type : 2; /**< 1825内部定的远端host类型,0-1650 1-david 2-1815e */
+ u32 remote_host_id : 7; /**< 1825内部定义id,即模板表创建时hash引擎的返回值 */
+ u32 ubc_port_id : 3; /**< dpu侧和这个remote_ubc_port对应的port_id。 */
+ u32 eid : 20; /**< 远端节点的EID,1650和david都是bus instance eid */
+} ubcnet_rport_node_info_s;
+
+typedef struct ubcnet_mpu_cmd_rport_info_table_op {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 op_type; /**< @see ubcnet_table_op_e */
+ u32 table_id; /**< @see ubcnet_table_e */
+ u32 remote_cna;
+ ubcnet_rport_node_info_s entry;
+} ubcnet_mpu_cmd_rport_info_table_op_s;
+
+/* ********************************** voq信息表,sml hash表8+4 ********************************** */
+/* TODO:这里表项key/item的长度按照8+4的方式暂时写死,后续考虑归一所有表项的所有操作时整改 */
+#define VOQ_PATH_TBL_KEY_LEN (sizeof(u64))
+#define VOQ_PATH_TBL_ITEM_LEN (sizeof(u32))
+typedef struct ubcnet_mpu_cmd_voq_path_tbl_op {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 op_type; /**< @see ubcnet_table_op_e */
+ u32 table_id; /**< @see ubcnet_table_e */
+ u8 key[VOQ_PATH_TBL_KEY_LEN];
+ u8 item[VOQ_PATH_TBL_ITEM_LEN]; /* 实际就是sml表项item的结构体,工具下发时,按照结构体填充,内部使用时,强转成结构体使用 */
+} ubcnet_mpu_cmd_voq_path_tbl_op_s;
+
+/* ********************************** vl信息表,sml lt表,4B item ********************************** */
+#define VL_INFO_TBL_ENTRY_SIZE (4 * sizeof(u32))
+typedef struct ubcnet_mpu_cmd_vl_info_tbl_op {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 op_type; /**< @see ubcnet_table_op_e */
+ u32 table_id; /**< @see ubcnet_table_e */
+ u32 vl : 4; /**< index为vl */
+ u32 remote_host_type : 2;
+ u32 rsv : 26;
+ u8 entry[VL_INFO_TBL_ENTRY_SIZE];
+} ubcnet_mpu_cmd_vl_info_tbl_op_s;
+
+/* ********************************** cc 拥塞状态结构体 ********************************** */
+typedef struct ubcnet_mpu_cmd_cc_statistics {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 cnp_drop;
+} ubcnet_mpu_cmd_cc_statistics_s;
+
+/* ********************************* rhost_node_info mpu********************************* */
+typedef struct ubcnet_mpu_cmd_rhost_node_info_op {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 op_type; /**< @see ubcnet_table_op_e */
+ u32 table_id; /**< @see ubcnet_table_e */
+ u32 field; /**< @see ubcnet_rhost_node_field_e */
+ u32 deid : 20;
+ u32 port_id : 3;
+ u32 rsvd1 : 9;
+ sml_rhost_node_info_tbl_item_s entry;
+} ubcnet_mpu_cmd_rhost_node_info_op_s;
+
+/* ********************************** dynamic fe mpu ********************************** */
+
+typedef struct ubcnet_mpu_cmd_dynamic_fe_get {
+ struct mgmt_msg_head msg_head;
+ u32 fe_id : 12;
+ u32 rsvd0 : 20;
+ ubcnet_d2h_ob_entry_s fe_entry;
+} ubcnet_mpu_cmd_dynamic_fe_get_s;
+
+/* ********************************** tid fe mpu ********************************** */
+typedef struct ubcnet_mpu_cmd_tid_fe_op {
+ struct mgmt_msg_head msg_head;
+ u32 op_type; /**< @see ubcnet_table_op_e */
+ u32 table_id; /**< @see ubcnet_table_e */
+ u32 deid : 20;
+ u32 rsvd1 : 12;
+ u32 ctrl_fe : 12;
+ u32 rsvd2 : 20;
+ u32 tokenid : 20;
+ u32 rsvd0 : 12;
+
+ sml_tid_fe_tbl_8_20_item_s entry;
+} ubcnet_mpu_cmd_tid_fe_op_s;
+
+typedef struct ubcnet_cmd_perf_statistics {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 op_type : 2; /**< @see ubcnet_perf_type_e */
+ u32 port_id : 3;
+ u32 vl : 4;
+ u32 rsvd : 23;
+ u32 timestamp;
+ u64 rx_pkts;
+ u64 rx_bytes;
+ u64 tx_pkts;
+ u64 tx_bytes;
+} ubcnet_cmd_perf_statistics_s;
+
+/**
+ * @brief 单条路径在活信息
+ *
+ */
+typedef struct ubcnet_route_info {
+ u32 scna : 16; /**< 源cna */
+ u32 dcna : 16; /**< 目的cna */
+ u32 path_state : 2; /**< @see ubcnet_path_state_e */
+ u32 rsvd : 30;
+} ubcnet_route_info_s;
+
+/**
+ * @brief 所有d2n路径在活信息
+ *
+ */
+typedef struct ubcnet_route_info_all {
+ ubcnet_route_info_s route_info[MAX_ROUTE_NUM]; /**< All route info */
+ u32 route_num; /**< Valid route number */
+} ubcnet_route_info_all_s;
+
+/**
+ * @brief 所有d2n路径在活信息,对外结构
+ *
+ */
+typedef struct ubcnet_cmd_get_d2n_path_state {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ ubcnet_route_info_all_s route_info_all;
+} ubcnet_cmd_get_d2n_path_state_s;
+
+/**
+ * @brief ubc 拥塞使能对外结构体
+ *
+ */
+typedef struct ubcnet_mpu_cmd_cc_enable {
+ struct mgmt_msg_head msg_head; /**< Common information head */
+ u32 cc_enable; /**< 0: disable, 1: enable */
+} ubcnet_mpu_cmd_cc_enable_s;
+
+#endif /* UBCNET_MPU_CMD_DEFS_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd.h
new file mode 100644
index 000000000..c70eb15bf
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: UBC commands msg between Driver and NPU.
+ * Author: None
+ * Create: 2024/12/17
+ * 设计文档: https://libing.huawei.com/visionit/#/idpView?vid=2055768548&Id=3a0b37fb-e42…
+ * 章节5.13:H2H网络转发功能实现
+ */
+
+#ifndef UBCNET_NPU_CMD_H
+#define UBCNET_NPU_CMD_H
+
+/**
+ * @brief enum ubcnet_npu_cmd_type - UBCNET DRV to NPU Commands
+ * DFT cmd above 128
+ */
+typedef enum ubcnet_npu_cmd_type {
+ UBCNET_NPU_CMD_PERF_RTT = 0,
+ UBCNET_NPU_CMD_FCNP = 1,
+
+ UBCNET_NPU_CMD_SET_H2H_FIB =
+ 128, /**< UBC H2H set NIB msg 64B @see ubcnet_cmd_set_h2h_fib_s */
+ UBCNET_NPU_CMD_SET_H2H_NIB =
+ 129, /**< UBC H2H set NIB msg 48B @see ubcnet_cmd_set_h2h_nib_s */
+ UBCNET_NPU_CMD_MAX = 255
+} ubcnet_npu_cmd_type_e;
+
+/**
+ * @brief enum ubcnet_npu_cmd_fib_opid - UBCNET DRV to NPU FIB OPIDs
+ *
+ */
+typedef enum ubcnet_npu_cmd_fib_opid {
+ UBCNET_NPU_CMD_FIB_INSERT = 0,
+ UBCNET_NPU_CMD_FIB_DELETE,
+ UBCNET_NPU_CMD_FIB_UPDATE
+} ubcnet_npu_cmd_fib_opid_e;
+
+/**
+ * @brief enum ubcnet_npu_cmd_nib_opid - UBCNET DRV to NPU NIB OPIDs
+ *
+ */
+typedef enum ubcnet_npu_cmd_nib_opid {
+ UBCNET_NPU_CMD_NIB_INSERT = 0,
+ UBCNET_NPU_CMD_NIB_DELETE,
+ UBCNET_NPU_CMD_NIB_UPDATE
+} ubcnet_npu_cmd_nib_opid_e;
+
+#endif /* UBCNET_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd_defs.h
new file mode 100644
index 000000000..1f2aab19e
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_npu_cmd_defs.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: UBC commands msg between Driver and NPU.
+ * Author: None
+ * Create: 2024/12/17
+ */
+
+#ifndef UBCNET_NPU_CMD_DEFS_H
+#define UBCNET_NPU_CMD_DEFS_H
+#include "base_type.h"
+
+/**
+ * @brief ubc_cmd_hdr_s
+ * @details cmdq cmd header
+ */
+typedef struct ubc_cmd_hdr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 major_version : 8;
+ u32 minor_version : 8;
+ u32 cmd_type : 8;
+ u32 cmd_subtype : 8;
+#else
+ u32 cmd_subtype : 8;
+ u32 cmd_type : 8;
+ u32 minor_version : 8;
+ u32 major_version : 8;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cmd_len : 16;
+ u32 rsvd : 16;
+#else
+ u32 rsvd : 16;
+ u32 cmd_len : 16;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ u32 rsvd0;
+ u32 rsvd1;
+} ubc_cmd_hdr_s;
+
+/**
+ * @brief ubcnet_cmd_set_h2h_fib_s - UBC H2H set FIB msg defination 64B
+ * @see UBCNET_NPU_CMD_SET_H2H_FIB
+ *
+ */
+typedef struct ubcnet_cmd_set_h2h_fib {
+ ubc_cmd_hdr_s cmdhdr;
+
+ u32 daddr[4]; /* cna/ipv4 in daddr[0] */
+
+ u32 nexthop_addr[4];
+
+ u8 outintf_idx;
+ u8 flag;
+ u8 nl_type;
+ u8 rsvd0;
+
+ u8 outintf_mac[6];
+ u32 rsvd1;
+ u16 rsvd2;
+} ubcnet_cmd_set_h2h_fib_s;
+
+/**
+ * @brief ubcnet_cmd_set_h2h_nib_s - UBC H2H set NIB msg defination 48B
+ * @see UBCNET_NPU_CMD_SET_H2H_NIB
+ *
+ */
+typedef struct ubcnet_cmd_set_h2h_nib {
+ ubc_cmd_hdr_s cmdhdr;
+
+ u32 nexthop_addr[4];
+
+ u8 outintf_idx;
+ u8 ip_type;
+ u16 rsvd0;
+
+ u8 neigh_mac[6];
+ u16 rsvd1;
+ u32 rsvd2;
+} ubcnet_cmd_set_h2h_nib_s;
+
+/**
+ * @brief ubcnet_cmd_fcnp_s
+ * @see UBCNET_NPU_CMD_FCNP
+ *
+ */
+typedef struct ubcnet_cmd_fcnp {
+ ubc_cmd_hdr_s cmdhdr;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vl : 4;
+ u32 rt : 2;
+ u32 ubc_port_id : 3;
+ u32 src_cos : 4;
+ u32 rsvd : 19;
+#else
+ u32 rsvd : 19;
+ u32 src_cos : 4;
+ u32 ubc_port_id : 3;
+ u32 rt : 2;
+ u32 vl : 4;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 scna : 16;
+ u32 dcna : 16;
+#else
+ u32 dcna : 16;
+ u32 scna : 16;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cci : 16;
+ u32 lbf : 8;
+ u32 sl : 4;
+ u32 mgmt : 1;
+ u32 ecn : 2;
+ u32 loc : 1;
+#else
+ u32 loc : 1;
+ u32 ecn : 2;
+ u32 mgmt : 1;
+ u32 sl : 4;
+ u32 lbf : 8;
+ u32 cci : 16;
+#endif
+ };
+ u32 dw2_value;
+ };
+} ubcnet_cmd_fcnp_s;
+
+/**
+ * @brief ubcnet_cmd_perf_rtt_s
+ * @see UBCNET_NPU_CMD_PERF_RTT
+ *
+ */
+typedef struct ubcnet_cmd_perf_rtt {
+ ubc_cmd_hdr_s cmdhdr;
+
+ u32 rhost_type;
+ u32 rhost_id;
+ u32 ubc_port_id;
+} ubcnet_cmd_perf_rtt_s;
+
+/**
+ * @brief ubcnet_cmd_perf_rtt_rsp_s
+ * @see UBCNET_NPU_CMD_PERF_RTT
+ *
+ */
+typedef struct ubcnet_cmd_perf_rtt_rsp {
+ u32 interval_time;
+} ubcnet_cmd_perf_rtt_rsp_s;
+#endif /* UBCNET_NPU_CMD_DEFS_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_extend.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_extend.h
new file mode 100644
index 000000000..f19800f79
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_extend.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: UBCNET RDMA模块提供ULP的扩展接口
+ * Create: 2025/11/25
+ */
+
+#ifndef UBCNET_RDMA_EXTEND_H
+#define UBCNET_RDMA_EXTEND_H
+
+#include "base_type.h"
+#include "err_code.h"
+
+#ifdef HI1825V100
+/**
+ * @brief UBC_net提供给ULP的添加/修改tid-fe表对外接口
+ * @param deid 1825视角,远端节点的eid
+ * @param tokenid 协议定义的tokenid
+ * @param ctrl_fe ctrlfe的func_id
+ * @details UBC_net提供给ULP的添加tid-fe表对外接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,ERR_FAILED-1执行失败
+ */
+u32 mpu_ubcnet_internal_add_tid_fe(u32 deid, u32 tokenid, u32 ctrl_fe);
+
+/**
+ * @brief UBC_net提供给ULP的删除tid-fe表对外接口
+ * @param deid 1825视角,远端节点的eid
+ * @param tokenid 协议定义的tokenid
+ * @param ctrl_fe ctrlfe的func_id
+ * @details UBC_net提供给ULP的删除tid-fe表对外接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,ERR_FAILED-1执行失败
+ */
+u32 mpu_ubcnet_internal_del_tid_fe(u32 deid, u32 tokenid, u32 ctrl_fe);
+
+/**
+ * @brief UBC_net提供给ULP的ctrl fe发生flr对外接口
+ * @param ctrl_fe ctrlfe的func_id
+ * @details UBC_net提供给ULP的ctrl fe发生flr对外接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,ERR_FAILED-1执行失败
+ */
+u32 mpu_ubcnet_release_ctrlfe(u16 ctrl_fe);
+
+/**
+ * @brief UBC_net提供给ULP的查询ctrl fe拥有的所有eid list对外接口
+ * @param ctrl_fe ctrlfe的func_id
+ * @param eid_list 保存eid list的数组指针
+ * @param max_count 数组指针最大长度
+ * @param found_count 实际查询到的eid list长度
+ * @details UBC_net提供给ULP的查询ctrl fe拥有的所有eid list对外接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,ERR_FAILED-1执行失败
+ */
+u32 mpu_ubcnet_find_all_eid_by_ctrl_fe(u32 ctrl_fe, u32 *eid_list,
+ u32 max_count, u32 *found_count);
+
+/**
+ * @brief UBC_net提供给ULP的添加David权限扩展接口
+ * @param ctrl_fe ctrlfe的func_id
+ * @details UBC_net提供给ULP的添加David权限扩展接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,其它-非0执行失败
+ */
+u32 mpu_ubcnet_extend_add_david_permit(u32 ctrl_fe);
+
+/**
+ * @brief UBC_net提供给ULP的删除David权限扩展接口
+ * @param ctrl_fe ctrlfe的func_id
+ * @details UBC_net提供给ULP的删除David权限扩展接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,其它-非0执行失败
+ */
+u32 mpu_ubcnet_extend_del_david_permit(u32 ctrl_fe);
+
+/**
+ * @brief UBC_net提供给ULP的NDA场景下添加/修改tid-fe表对外接口
+ * @param deid 1825视角,远端节点的eid
+ * @param tokenid 协议定义的tokenid
+ * @param ctrl_fe ctrlfe的func_id
+ * @param buf_out 实际映射的表项内容
+ * @details UBC_net提供给ULP的添加tid-fe表对外接口
+ * @attention 只支持1825
+ * @return ERR_OK-0执行成功,ERR_FAILED-1执行失败
+ */
+u32 mpu_ubcnet_internal_add_tid_fe_nda(u32 deid, u32 tokenid, u32 ctrl_fe,
+ u32 *buf_out);
+#endif
+#endif /* UBCNET_MPU_EXTEND_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_view_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_view_defs.h
new file mode 100644
index 000000000..2d2df6b8f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/ubc_net/ubcnet_rdma_view_defs.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
+ * Description: UBCNET RDMA VIEW表项结构体定义
+ * Create: 2025-11-13
+ * Notes:
+ * History:
+ */
+
+#ifndef UBCNET_RDMA_VIEW_DEFS_H
+#define UBCNET_RDMA_VIEW_DEFS_H
+
+#include "base_type.h"
+
+#define UBCNET_DATA_UE_MAX_PORT_NUM (4)
+#define GLB_MAX_UBC_PORT_NUM 6
+
+/*---------------静态表(模板fe)结构体------------------*/
+typedef struct {
+ u32 eid;
+ u32 rsvd;
+} sml_rhost_node_info_tbl_key_s;
+
+typedef struct {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 18;
+ u32 rhost_type : 2;
+ u32 rhost_id : 6; /* 当前david在当前pod统一编号 */
+ u32 port_bitmap : 6; /* 1825有效ubc port口 位图 */
+#else
+ u32 port_bitmap : 6;
+ u32 rhost_id : 6;
+ u32 rhost_type : 2;
+ u32 rsvd : 18;
+#endif
+ } dw0;
+
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 4;
+ u32 sl : 4; /* 详见ob数据结构 */
+ u32 lb : 8; /* 详见ob数据结构 */
+ u32 upi : 16; /* 详见ob数据结构 */
+#else
+ u32 upi : 16;
+ u32 lb : 8;
+ u32 sl : 4;
+ u32 rsvd : 4;
+#endif
+ } dw1;
+
+ u16 port_cna[GLB_MAX_UBC_PORT_NUM];
+} sml_rhost_node_info_tbl_item_s;
+
+/*--------------tid_fe表结构体------------------*/
+typedef struct ubcnet_port_info {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u16 rsvd : 1;
+ u16 ubc_port_idx : 3; /* 记录有效UBC Port id */
+ u16 data_fe_idx : 12; /* 记录有效UBC Port对应Data FE索引信息 */
+#else
+ u16 data_fe_idx : 12; /* 记录有效UBC Port对应Data FE索引信息 */
+ u16 ubc_port_idx : 3; /* 记录有效UBC Port id */
+ u16 rsvd : 1;
+#endif
+} ubcnet_port_info_s;
+
+typedef struct npu_ctrl_ue_info {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u16 rsvd : 4;
+ u16 npu_ctrl_fe_idx : 12; /* 记录有效UBC Port对应npu ctrl FE索引信息 */
+#else
+ u16 npu_ctrl_fe_idx : 12; /* 记录有效UBC Port对应npu ctrl FE索引信息 */
+ u16 rsvd : 4;
+#endif
+} npu_ctrl_ue_info_s;
+
+typedef struct {
+ u32 tid;
+ u32 eid;
+} sml_tid_fe_tbl_8_20_key_s;
+
+typedef struct {
+ ubcnet_port_info_s
+ ubc_ports_info[UBCNET_DATA_UE_MAX_PORT_NUM]; /* dw0-dw1 */
+
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 refcnt : 16;
+ u32 david_id : 6;
+ u32 data_fe_info_valid : 1;
+ u32 npu_ctrl_info_valid : 1;
+ u32 active_port_num : 4;
+ u32 rsvd5 : 2;
+ u32 at_flag : 1;
+ u32 rsvd4 : 1;
+#else
+ u32 rsvd4 : 1;
+ u32 at_flag : 1; /* 用于记录使用TID0还是使用TID1 */
+ u32 rsvd5 : 2;
+ u32 active_port_num : 4; /* 当前有效的UBC Port平面个数 */
+ u32 npu_ctrl_info_valid : 1; /* 是否映射npu ctrl fe */
+ u32 data_fe_info_valid : 1; /* 是否映射npu data fe */
+ u32 david_id : 6; /* 静态表中的david id,表示当前David在PoD内统一编号,用于对不同david做OQ限速 */
+ u32 refcnt : 16; /* 表示有多少个MR关联同一个David上的TID */
+#endif
+ } dw2;
+
+ npu_ctrl_ue_info_s npu_ctrl_info[UBCNET_DATA_UE_MAX_PORT_NUM];
+} sml_tid_fe_tbl_8_20_item_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_buddy.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_buddy.c
new file mode 100644
index 000000000..18025c7f0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_buddy.c
@@ -0,0 +1,186 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2023. All rights reserved.
+ File Name : hmm_buddy.c
+ Version : Initial Draft
+ Description : realize the management of buddy
+***************************************************************************** */
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/errno.h>
+#include "hmm_buddy.h"
+
+u32 hmm_buddy_alloc(struct hmm_buddy *buddy, u32 order)
+{
+ u32 first_index = 0;
+ u32 cur_order = 0;
+ u32 cur_bit_num = 0;
+
+ if (buddy == NULL) {
+ pr_err("%s: Buddy is null\n", __FUNCTION__);
+ return HMM_INVALID_INDEX;
+ }
+ if (order > buddy->max_order) {
+ pr_err("%s: Order(%u) is bigger than max order(%u)\n",
+ __FUNCTION__, order, buddy->max_order);
+ return HMM_INVALID_INDEX;
+ }
+ spin_lock(&buddy->lock);
+
+ for (cur_order = order; cur_order <= buddy->max_order; ++cur_order) {
+ if (buddy->num_free[cur_order] != 0) {
+ cur_bit_num = 1U << (buddy->max_order - cur_order);
+ first_index =
+ (u32)find_first_bit(buddy->bits[cur_order],
+ (unsigned long)cur_bit_num);
+ if (first_index < cur_bit_num) {
+ goto found;
+ }
+ }
+ }
+ spin_unlock(&buddy->lock);
+ pr_err("%s: Get a invalid index\n", __FUNCTION__);
+ return HMM_INVALID_INDEX;
+
+found:
+ clear_bit((int)first_index, buddy->bits[cur_order]);
+ --buddy->num_free[cur_order];
+
+ while (cur_order > order) {
+ --cur_order;
+ first_index <<= 1;
+ set_bit(first_index ^ 1, buddy->bits[cur_order]);
+ ++buddy->num_free[cur_order];
+ }
+ first_index <<= order;
+ spin_unlock(&buddy->lock);
+ return first_index;
+}
+
+void hmm_buddy_free(struct hmm_buddy *buddy, u32 first_index, u32 order)
+{
+ u32 tmp_first_index = first_index;
+ u32 tmp_order = order;
+
+ if (buddy == NULL) {
+ pr_err("%s: Buddy is null\n", __FUNCTION__);
+ return;
+ }
+
+ if (tmp_order > buddy->max_order) {
+ pr_err("%s: Order(%u) is bigger than max order(%u)\n",
+ __FUNCTION__, tmp_order, buddy->max_order);
+ return;
+ }
+
+ tmp_first_index >>= tmp_order;
+ spin_lock(&buddy->lock);
+ while (test_bit((int)(tmp_first_index ^ 1), buddy->bits[tmp_order]) !=
+ 0) {
+ clear_bit((int)(tmp_first_index ^ 1), buddy->bits[tmp_order]);
+ --buddy->num_free[tmp_order];
+ tmp_first_index >>= 1;
+ ++tmp_order;
+ }
+ set_bit(tmp_first_index, buddy->bits[tmp_order]);
+ ++buddy->num_free[tmp_order];
+ spin_unlock(&buddy->lock);
+ return;
+}
+
+static void hmm_buddy_alloc_bitmap_fail(struct hmm_buddy *buddy, u32 i)
+{
+ u32 j = 0;
+
+ for (j = 0; j < i; j++) {
+ if (is_vmalloc_addr(buddy->bits[j])) {
+ vfree(buddy->bits[j]);
+ } else {
+ kfree(buddy->bits[j]);
+ }
+ buddy->bits[j] = NULL;
+ }
+ kfree(buddy->bits);
+ buddy->bits = NULL;
+ return;
+}
+
+int hmm_buddy_init(struct hmm_buddy *buddy, u32 max_order)
+{
+ u32 i = 0;
+ u32 bit_num = 0;
+
+ if (buddy == NULL) {
+ pr_err("%s: Buddy is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ buddy->max_order = max_order;
+ spin_lock_init(&buddy->lock);
+ buddy->num_free =
+ (unsigned int *)kcalloc((unsigned long)(buddy->max_order + 1UL),
+ sizeof(int), GFP_KERNEL);
+ if (buddy->num_free == NULL) {
+ pr_err("%s: Alloc memory for buddy->num_free failed, ret(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return -ENOMEM;
+ }
+ buddy->bits = (unsigned long **)kcalloc(
+ (unsigned long)(buddy->max_order + 1UL), sizeof(long *),
+ GFP_KERNEL);
+ if (buddy->bits == NULL) {
+ pr_err("%s: Alloc memory for buddy->bits failed, ret(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ goto alloc_bits_fail;
+ }
+
+ for (i = 0; i <= buddy->max_order; i++) {
+ bit_num = (u32)BITS_TO_LONGS(1UL << (buddy->max_order - i));
+ buddy->bits[i] = (unsigned long *)kcalloc(
+ (unsigned long)bit_num, sizeof(long),
+ GFP_KERNEL | __GFP_NOWARN);
+ if (buddy->bits[i] == NULL) {
+ pr_err("%s: Kcalloc memory for buddy->bits[%u] failed, ret(%d)\n",
+ __FUNCTION__, i, -ENOMEM);
+ buddy->bits[i] = (unsigned long *)vzalloc(
+ (unsigned long)bit_num * sizeof(long));
+ if (buddy->bits[i] == NULL) {
+ pr_err("%s: Vzalloc memory for buddy->bits[%d] failed, ret(%d)\n",
+ __FUNCTION__, i, -ENOMEM);
+ goto alloc_bitmap_fail;
+ }
+ }
+ }
+ set_bit(0, buddy->bits[buddy->max_order]);
+ buddy->num_free[buddy->max_order] = 1;
+ return 0;
+
+alloc_bitmap_fail:
+ hmm_buddy_alloc_bitmap_fail(buddy, i);
+alloc_bits_fail:
+ kfree(buddy->num_free);
+ buddy->num_free = NULL;
+ return -ENOMEM;
+}
+
+void hmm_buddy_cleanup(struct hmm_buddy *buddy)
+{
+ u32 i;
+
+ if (buddy == NULL) {
+ pr_err("%s: Buddy is null\n", __FUNCTION__);
+ return;
+ }
+ for (i = 0; i <= buddy->max_order; i++) {
+ if (is_vmalloc_addr(buddy->bits[i])) {
+ vfree(buddy->bits[i]);
+ } else {
+ kfree(buddy->bits[i]);
+ }
+ buddy->bits[i] = NULL;
+ }
+ kfree(buddy->bits);
+ buddy->bits = NULL;
+ kfree(buddy->num_free);
+ buddy->num_free = NULL;
+ return;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_common.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_common.c
new file mode 100644
index 000000000..d28fee22f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_common.c
@@ -0,0 +1,798 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ File Name : hmm_comp.c
+ Version : Initial Draft
+ Last Modified :
+ Description : implement the management of PDID, XRCD, MPT, MTT, RDMARC,
+ GID and GUID
+***************************************************************************** */
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "hinic5_rdma.h"
+#include "hinic5_id_tbl.h"
+#include "roce_npu_cmd_mr_defs.h"
+#include "roce_npu_cmd_defs.h"
+#include "securec.h"
+#include "cfm_cmd.h"
+#include "hmm_cmd_defs.h"
+#include "hmm_common.h"
+
+enum hmm_device_type hmm_get_device_type(struct hinic5_lld_dev *lld_dev)
+{
+ struct device *dev = NULL;
+ struct pci_dev *pdev = NULL;
+
+ if (lld_dev == NULL) {
+ return HMM_DEV_TYPE_UNKNOWN;
+ }
+
+ if (lld_dev->dev_type == HINIC5_DEVICE_T_UB) {
+ return HMM_DEV_TYPE_HI1825_V100;
+ }
+
+ dev = lld_dev->dev;
+ pdev = container_of(dev, struct pci_dev, dev);
+
+ if ((pdev->device == HINIC5_DEV_ID_25V1_PF) ||
+ (pdev->device == HINIC5_DEV_ID_25V1_VF)) {
+ return HMM_DEV_TYPE_HI1825_V100;
+ }
+
+ switch (pdev->subsystem_device) {
+ case HI_1825_V100_SUB_DEV_ID_2X100:
+ case HI_1825_V100_SUB_DEV_ID_COMPUTE_2X200:
+ return HMM_DEV_TYPE_HI1825_V100;
+ default:
+ pr_err("[HMM] Unknown Subsystem id(%u).",
+ pdev->subsystem_device);
+ return HMM_DEV_TYPE_UNKNOWN;
+ }
+}
+
+struct hmm_comp_priv *get_hmm_comp_priv(void *hwdev, u32 service_type)
+{
+ return (struct hmm_comp_priv *)hinic5_get_service_adapter(
+ hwdev, (enum hinic5_service_type)service_type);
+}
+
+void uni_hmm_mpt_to_big_endian(hmm_verbs_mr_attr_s *mr_attr)
+{
+ u32 i;
+
+ mr_attr->dw0.value = cpu_to_be32(mr_attr->dw0.value);
+ mr_attr->dw1.value = cpu_to_be32(mr_attr->dw1.value);
+ mr_attr->dw2.value = cpu_to_be32(mr_attr->dw2.value);
+ mr_attr->dw3.value = cpu_to_be32(mr_attr->dw3.value);
+ mr_attr->iova = cpu_to_be64(mr_attr->iova);
+ mr_attr->length = cpu_to_be64(mr_attr->length);
+ mr_attr->mtt_base_addr = cpu_to_be64(mr_attr->mtt_base_addr);
+ mr_attr->mtt_sz = cpu_to_be32(mr_attr->mtt_sz);
+ for (i = 0; i < sizeof(mr_attr->userdata) / sizeof(u32); i++) {
+ mr_attr->userdata[i] = cpu_to_be32(mr_attr->userdata[i]);
+ }
+}
+
+void uni_hmm_set_mr_access(hmm_verbs_mr_attr_s *mr_attr,
+ const struct hmm_rdma *mr)
+{
+ mr_attr->dw0.bs.access_lr = 1; /* Local access enabled by default */
+
+ if ((RDMA_IB_ACCESS_LOCAL_WRITE & mr->access) != 0) {
+ mr_attr->dw0.bs.access_lw = 1;
+ }
+ if ((RDMA_IB_ACCESS_REMOTE_READ & mr->access) != 0) {
+ mr_attr->dw0.bs.access_rr = 1;
+ }
+ if ((RDMA_IB_ACCESS_REMOTE_WRITE & mr->access) != 0) {
+ mr_attr->dw0.bs.access_rw = 1;
+ }
+ if ((RDMA_IB_ACCESS_REMOTE_ATOMIC & mr->access) != 0) {
+ mr_attr->dw0.bs.access_ra = 1;
+ }
+ if ((RDMA_IB_ACCESS_MW_BIND & mr->access) != 0) {
+ mr_attr->dw0.bs.access_bind = 1;
+ }
+}
+
+void uni_hmm_set_mptc_type_below_phy_mr(hmm_verbs_mr_attr_s *mr_attr,
+ struct hmm_rdma *mr)
+{
+ switch (mr->type) {
+ case HMM_RDMA_DMA_MR:
+ mr_attr->dw0.bs.pa = 1;
+ mr_attr->mtt_base_addr = 0;
+ mr_attr->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_USER_MR:
+ mr_attr->mtt_base_addr = mr->mtt.mtt_paddr;
+ mr_attr->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_FRMR:
+ mr_attr->mtt_base_addr = mr->mtt.mtt_paddr;
+ mr_attr->dw0.bs.fast_reg_en = 1;
+ mr_attr->dw0.bs.remote_access_en = 1;
+ mr_attr->dw2.bs.status = MPT_STATUS_FREE;
+ mr_attr->mtt_sz =
+ (mr->mtt.mtt_layers > 0) ?
+ 1U << mr->mtt.mtt_seg[mr->mtt.mtt_layers - 1]
+ ->order :
+ 0;
+ break;
+
+ case HMM_RDMA_FMR:
+ mr_attr->mtt_base_addr = mr->mtt.mtt_paddr;
+ mr_attr->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+ default:
+ pr_err("%s: unsupport mr type(%d)\n", __FUNCTION__, mr->type);
+ break;
+ }
+}
+
+void uni_hmm_set_mptc_type_above_phy_mr(hmm_verbs_mr_attr_s *mr_attr,
+ struct hmm_rdma *mr)
+{
+ switch (mr->type) {
+ case HMM_RDMA_PHYS_MR:
+ mr_attr->mtt_base_addr = mr->mtt.mtt_paddr;
+ mr_attr->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_RSVD_LKEY:
+ mr_attr->dw0.bs.rkey = 1;
+ mr_attr->dw0.bs.bpd = 0;
+ mr_attr->dw0.bs.invalid_en = 0;
+ mr_attr->dw0.bs.remote_invalid_en = 0;
+ mr_attr->dw0.bs.pa = 1;
+ mr_attr->mtt_base_addr = 0;
+ mr_attr->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_SIG_MR:
+ mr_attr->mtt_base_addr = mr->mtt.mtt_paddr;
+ mr_attr->dw2.bs.status = MPT_STATUS_FREE;
+ break;
+
+ case HMM_RDMA_INDIRECT_MR:
+ mr_attr->mtt_base_addr = 0;
+ mr_attr->dw2.bs.status = MPT_STATUS_FREE;
+ break;
+ default:
+ pr_err("%s: unsupport mr type(%d)\n", __FUNCTION__, mr->type);
+ break;
+ }
+}
+
+void uni_hmm_set_mptc_according_to_type(hmm_verbs_mr_attr_s *mr_attr,
+ struct hmm_rdma *mr)
+{
+ if (mr->type < HMM_RDMA_PHYS_MR) {
+ uni_hmm_set_mptc_type_below_phy_mr(mr_attr, mr);
+ } else {
+ uni_hmm_set_mptc_type_above_phy_mr(mr_attr, mr);
+ }
+}
+
+static void uni_hmm_set_mr_cmd_buf(hmm_verbs_mr_attr_s *mr_attr,
+ struct hmm_rdma *mr)
+{
+ uni_hmm_set_mr_access(mr_attr, mr);
+
+ mr_attr->dw0.bs.invalid_en = 1;
+ mr_attr->dw0.bs.remote_invalid_en = 1;
+ mr_attr->dw0.bs.r_w = MPT_MR;
+ mr_attr->dw0.bs.bpd = 1;
+
+ mr_attr->dw2.bs.pdn = mr->pdn & 0x3ffff;
+
+ if (mr->type != HMM_RDMA_INDIRECT_MR) {
+ mr_attr->dw0.bs.mtt_page_size =
+ (mr->mtt.mtt_page_shift > PAGE_SHIFT_4K) ?
+ (mr->mtt.mtt_page_shift - PAGE_SHIFT_4K) :
+ 0;
+ mr_attr->dw0.bs.mtt_layer_num = mr->mtt.mtt_layers;
+ mr_attr->dw0.bs.buf_page_size =
+ (mr->mtt.buf_page_shift > PAGE_SHIFT_4K) ?
+ (mr->mtt.buf_page_shift - PAGE_SHIFT_4K) :
+ 0;
+
+ mr_attr->dw1.bs.dma_attr_idx = MPT_DMA_ATTR_IDX;
+ mr_attr->dw1.bs.so_ro = 0;
+
+ mr_attr->dw2.bs.block_size =
+ (mr->block_size / BLOCK_SIZE_DEVIDE_SECTOR) & 0x3f;
+ if (mr->block_size > 0) {
+ mr_attr->dw3.bs.page_mode = 1;
+ }
+
+ mr_attr->iova = mr->iova;
+ mr_attr->length = mr->size;
+ mr_attr->dw3.bs.fbo = 0;
+ if ((mr->access & RDMA_IB_ACCESS_ZERO_BASED) != 0) {
+ mr_attr->dw0.bs.zbva = 1;
+ mr_attr->dw3.bs.fbo =
+ mr->iova & ((1U << mr->mtt.buf_page_shift) - 1);
+ mr_attr->iova = 0;
+ }
+ } else {
+ mr_attr->dw2.bs.indirect_mr = 1;
+ }
+
+ mr_attr->dw3.bs.mkey = mr->key & 0xFF;
+
+ uni_hmm_set_mptc_according_to_type(mr_attr, mr);
+}
+
+static void uni_hmm_set_mw_cmd_buf(hmm_verbs_mr_attr_s *mr_attr,
+ struct hmm_rdma *hmmrdma)
+{
+ /* fill mpt_entry */
+ mr_attr->dw0.bs.bpd = 1;
+ mr_attr->dw0.bs.r_w = MPT_MW;
+ mr_attr->dw0.bs.access_lr = 1;
+ mr_attr->dw0.bs.access_lw = 1;
+
+ mr_attr->dw1.bs.dma_attr_idx = MPT_DMA_ATTR_IDX;
+ mr_attr->dw1.bs.so_ro = RDMA_MPT_SO_RO;
+
+ mr_attr->dw2.bs.pdn = hmmrdma->pdn;
+ mr_attr->dw2.bs.status = MPT_STATUS_VALID;
+
+ mr_attr->dw3.bs.mkey = hmmrdma->key & 0xFF;
+
+ /* only type2 mw binds with QP and suppoort invalid operation, init value is FREE */
+ if (hmmrdma->type == HMM_RDMA_MW_TYPE_2) {
+ mr_attr->dw0.bs.invalid_en = 1;
+ mr_attr->dw0.bs.remote_invalid_en = 1;
+ mr_attr->dw0.bs.bqp = 1;
+
+ mr_attr->dw2.bs.status = MPT_STATUS_FREE;
+ }
+}
+
+int uni_hmm_set_cmd_buf(hmm_verbs_mr_attr_s *mr_attr, struct hmm_rdma *hmmrdma)
+{
+ if (HMM_RDMA_MR_START <= hmmrdma->type &&
+ hmmrdma->type < HMM_RDMA_MR_END) {
+ uni_hmm_set_mr_cmd_buf(mr_attr, hmmrdma);
+ } else if (HMM_RDMA_MW_START <= hmmrdma->type &&
+ hmmrdma->type < HMM_RDMA_MW_END) {
+ uni_hmm_set_mw_cmd_buf(mr_attr, hmmrdma);
+ } else {
+ pr_err("%s: Invalid rdma type(%d)\n", __FUNCTION__,
+ hmmrdma->type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int hmm_set_mr_attr_user_data(hmm_verbs_mr_attr_s *mr_attr,
+ struct hmm_rdma *hmmrdma)
+{
+ u32 cpy_len = HMM_USER_DATA_LENGTH * sizeof(u32);
+ memcpy_s(&mr_attr->userdata, cpy_len, &hmmrdma->user_data, cpy_len);
+
+ uni_hmm_mpt_to_big_endian(mr_attr);
+ return 0;
+}
+
+int hmm_enable_mpt(struct hinic5_lld_dev *lld_dev, void *hwdev,
+ cqm_cmd_buf_s *cqm_cmd_inbuf, u16 channel)
+{
+ u8 mod;
+ u8 cmd;
+ int ret;
+ enum hmm_device_type device_type = hmm_get_device_type(lld_dev);
+
+ if (device_type == HMM_DEV_TYPE_HI1825_V100) {
+ mod = HINIC5_MOD_CFM;
+ cmd = CFM_NPU_CMD_HMM_OPS;
+ } else {
+ mod = HINIC5_MOD_ROCE;
+ cmd = RDMA_CMD_SW2HW_MPT;
+ }
+ ret = cqm5_send_cmd_box(hwdev, mod, cmd, cqm_cmd_inbuf, NULL, NULL,
+ CMD_TIME_OUT_A, channel);
+ if (ret != 0) {
+ if (hinic5_get_heartbeat_status(hwdev) != PCIE_LINK_DOWN) {
+ pr_err("%s: Send cmd rdma_roce_cmd_sw2hw_mpt failed, cmd:0x%x, mod:0x%x,ret(%d)\n",
+ __FUNCTION__, cmd, mod, ret);
+ if ((ret == (-ETIMEDOUT)) || (ret == (-EPERM))) {
+ return -CMDQ_TIMEOUT;
+ }
+ return -CMDQ_ERR;
+ }
+ pr_err("%s: Card not present, return err\n", __FUNCTION__);
+ return -CMDQ_ERR;
+ }
+
+ return 0;
+}
+
+int uni_hmm_rdma_enable_mpt(struct hinic5_lld_dev *lld_dev, void *hwdev,
+ struct hmm_rdma *mr, u16 channel)
+{
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ hmm_verbs_mr_attr_s *mr_attr = NULL;
+ hmm_uni_cmd_mpt_sw2hw_s *mpt_sw2hw_inbuf = NULL;
+ int ret = 0;
+ errno_t rc;
+
+ cqm_cmd_inbuf = cqm5_cmd_alloc(hwdev);
+ if (cqm_cmd_inbuf == NULL) {
+ pr_err("%s: Alloc cmd_buf failed, err(%d)\n", __FUNCTION__,
+ -ENOMEM);
+ return -ENOMEM;
+ }
+
+ cqm_cmd_inbuf->size = (u16)sizeof(hmm_uni_cmd_mpt_sw2hw_s);
+ mpt_sw2hw_inbuf = (hmm_uni_cmd_mpt_sw2hw_s *)cqm_cmd_inbuf->buf;
+ rc = memset_s(mpt_sw2hw_inbuf, sizeof(*mpt_sw2hw_inbuf), 0,
+ sizeof(*mpt_sw2hw_inbuf));
+ if (rc != EOK) {
+ pr_err("%s: memset error\n", __FUNCTION__);
+ }
+ mpt_sw2hw_inbuf->com.dw0.bs.cmd_bitmask =
+ (u16)cpu_to_be16(VERBS_CMD_TYPE_MR_BITMASK);
+ mpt_sw2hw_inbuf->com.index = cpu_to_be32(mr->mpt.mpt_index);
+ mpt_sw2hw_inbuf->com.dw0.bs.sub_cmd = RDMA_CMD_SW2HW_MPT;
+ mr_attr = &mpt_sw2hw_inbuf->mr_attr;
+
+ ret = uni_hmm_set_cmd_buf(mr_attr, mr);
+ if (ret != 0) {
+ pr_err("%s: Failed to fulfill command buffer, ret(%d), index(0x%x).\n",
+ __FUNCTION__, ret, mr->mpt.mpt_index);
+ goto out;
+ }
+
+ ret = hmm_set_mr_attr_user_data(mr_attr, mr);
+ if (ret != 0) {
+ pr_err("%s: Failed to fulfill userdata, ret(%d), index(0x%x).\n",
+ __FUNCTION__, ret, mr->mpt.mpt_index);
+ goto out;
+ }
+
+ ret = hmm_enable_mpt(lld_dev, hwdev, cqm_cmd_inbuf, channel);
+ if (ret != 0) {
+ pr_err("%s: Enable mr's mpt failed, ret(%d) index(0x%x)\n",
+ __FUNCTION__, ret, mr->mpt.mpt_index);
+ goto out;
+ }
+ mr->enabled = RDMA_MPT_EN_HW;
+out:
+ cqm5_cmd_free(hwdev, cqm_cmd_inbuf);
+ return ret;
+}
+
+void uni_assemble_mpt_hw2sw(hmm_uni_cmd_mpt_hw2sw_s **mpt_hw2sw_inbuf,
+ struct hmm_comp_priv *comp_priv,
+ cqm_cmd_buf_s *cqm_cmd_inbuf)
+{
+ *mpt_hw2sw_inbuf = (hmm_uni_cmd_mpt_hw2sw_s *)cqm_cmd_inbuf->buf;
+
+ if (memset_s(*mpt_hw2sw_inbuf, sizeof(hmm_uni_cmd_mpt_hw2sw_s), 0,
+ sizeof(hmm_uni_cmd_mpt_hw2sw_s)) != EOK) {
+ pr_err("[HMM] %s: memory set error, err(%d)\n", __FUNCTION__,
+ -ENOMEM);
+ }
+
+ (*mpt_hw2sw_inbuf)->dmtt_cache.mtt_flags = 0; /* 默认按VF踢除cache */
+ (*mpt_hw2sw_inbuf)->dmtt_cache.mtt_num = 0;
+ (*mpt_hw2sw_inbuf)->dmtt_cache.mtt_cache_line_start =
+ cpu_to_be32(comp_priv->dev_cap.dmtt_cl_start);
+ (*mpt_hw2sw_inbuf)->dmtt_cache.mtt_cache_line_end =
+ cpu_to_be32(comp_priv->dev_cap.dmtt_cl_end);
+ (*mpt_hw2sw_inbuf)->dmtt_cache.mtt_cache_line_size =
+ cpu_to_be32(comp_priv->dev_cap.dmtt_cl_sz);
+ return;
+}
+
+void assemble_mpt_hw2sw(struct rdma_mpt_hw2sw_inbuf **mpt_hw2sw_inbuf,
+ struct hmm_comp_priv *comp_priv,
+ cqm_cmd_buf_s *cqm_cmd_inbuf)
+{
+ *mpt_hw2sw_inbuf = (struct rdma_mpt_hw2sw_inbuf *)cqm_cmd_inbuf->buf;
+
+ if (memset_s(*mpt_hw2sw_inbuf, sizeof(struct rdma_mpt_hw2sw_inbuf), 0,
+ sizeof(struct rdma_mpt_hw2sw_inbuf)) != EOK) {
+ pr_err("[HMM] %s: memory set error, err(%d)\n", __FUNCTION__,
+ -ENOMEM);
+ }
+
+ (*mpt_hw2sw_inbuf)->dmtt_flags = 0; /* 默认按VF踢除cache */
+ (*mpt_hw2sw_inbuf)->dmtt_num = 0;
+ (*mpt_hw2sw_inbuf)->dmtt_cache_line_start =
+ cpu_to_be32(comp_priv->dev_cap.dmtt_cl_start);
+ (*mpt_hw2sw_inbuf)->dmtt_cache_line_end =
+ cpu_to_be32(comp_priv->dev_cap.dmtt_cl_end);
+ (*mpt_hw2sw_inbuf)->dmtt_cache_line_size =
+ cpu_to_be32(comp_priv->dev_cap.dmtt_cl_sz);
+ return;
+}
+
+void hmm_disable_mpt_config_cqm_cmd_old(cqm_cmd_buf_s *cqm_cmd_inbuf,
+ struct hmm_comp_priv *comp_priv,
+ struct mpt *mpt)
+{
+ struct rdma_mpt_hw2sw_inbuf *mpt_hw2sw_inbuf = NULL;
+
+ cqm_cmd_inbuf->size = (u16)sizeof(struct rdma_mpt_hw2sw_inbuf);
+ assemble_mpt_hw2sw(&mpt_hw2sw_inbuf, comp_priv, cqm_cmd_inbuf);
+ mpt_hw2sw_inbuf->com.index = cpu_to_be32(mpt->mpt_index);
+ mpt_hw2sw_inbuf->com.dw0.bs.cmd_bitmask =
+ (u16)cpu_to_be16(VERBS_CMD_TYPE_MR_BITMASK);
+}
+
+void hmm_disable_mpt_config_cqm_cmd(cqm_cmd_buf_s *cqm_cmd_inbuf,
+ struct hmm_comp_priv *comp_priv,
+ struct mpt *mpt)
+{
+ hmm_uni_cmd_mpt_hw2sw_s *mpt_hw2sw_inbuf = NULL;
+
+ cqm_cmd_inbuf->size = (u16)sizeof(hmm_uni_cmd_mpt_hw2sw_s);
+ uni_assemble_mpt_hw2sw(&mpt_hw2sw_inbuf, comp_priv, cqm_cmd_inbuf);
+ mpt_hw2sw_inbuf->com.index = cpu_to_be32(mpt->mpt_index);
+ mpt_hw2sw_inbuf->com.dw0.bs.cmd_bitmask =
+ (u16)cpu_to_be16(VERBS_CMD_TYPE_MR_BITMASK);
+ mpt_hw2sw_inbuf->com.dw0.bs.sub_cmd = RDMA_CMD_HW2SW_MPT;
+}
+
+int hmm_disable_mpt(struct hinic5_lld_dev *lld_dev,
+ struct hmm_comp_priv *comp_priv, struct mpt *mpt,
+ u16 channel)
+{
+ u8 mod;
+ u8 cmd;
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ enum hmm_device_type device_type = hmm_get_device_type(lld_dev);
+
+ cqm_cmd_inbuf = cqm5_cmd_alloc(comp_priv->hwdev);
+ if (cqm_cmd_inbuf == NULL) {
+ pr_err("%s: alloc cmd_buf failed, err(%d)\n", __FUNCTION__,
+ -ENOMEM);
+ return -ENOMEM;
+ }
+
+ if ((device_type == HMM_DEV_TYPE_HI1823_V200) ||
+ (device_type == HMM_DEV_TYPE_HI1825_V100)) {
+ hmm_disable_mpt_config_cqm_cmd(cqm_cmd_inbuf, comp_priv, mpt);
+ } else if (device_type == HMM_DEV_TYPE_HI1823_V100) {
+ hmm_disable_mpt_config_cqm_cmd_old(cqm_cmd_inbuf, comp_priv,
+ mpt);
+ } else {
+ pr_err("[HMM] Unknown device type(%u).", device_type);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (device_type == HMM_DEV_TYPE_HI1825_V100) {
+ mod = HINIC5_MOD_CFM;
+ cmd = CFM_NPU_CMD_HMM_OPS;
+ } else {
+ mod = HINIC5_MOD_ROCE;
+ cmd = RDMA_CMD_HW2SW_MPT;
+ }
+
+ ret = cqm5_send_cmd_box(comp_priv->hwdev, mod, cmd, cqm_cmd_inbuf, NULL,
+ NULL, CMD_TIME_OUT_A, channel);
+ if (ret != 0) {
+ if (hinic5_get_heartbeat_status(comp_priv->hwdev) !=
+ PCIE_LINK_DOWN) {
+ pr_err("%s: Send cmd rdma_roce_cmd_hw2sw_mpt failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ if ((ret == (-ETIMEDOUT)) || (ret == (-EPERM))) {
+ ret = -CMDQ_TIMEOUT;
+ goto out;
+ }
+ ret = -CMDQ_ERR;
+ goto out;
+ }
+ pr_err("%s: Card not present, return ok\n", __FUNCTION__);
+ ret = 0;
+ }
+
+out:
+ cqm5_cmd_free(comp_priv->hwdev, cqm_cmd_inbuf);
+ return ret;
+}
+
+static void hmm_set_mptc_type_below_phy_mr(struct roce_mpt_context *mpt_ctx,
+ struct hmm_rdma *mr)
+{
+ switch (mr->type) {
+ case HMM_RDMA_DMA_MR:
+ mpt_ctx->dw0.bs.pa = 1;
+ mpt_ctx->mtt_base_addr = 0;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_USER_MR:
+ mpt_ctx->mtt_base_addr = mr->mtt.mtt_paddr;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_FRMR:
+ mpt_ctx->mtt_base_addr = mr->mtt.mtt_paddr;
+ mpt_ctx->dw0.bs.fast_reg_en = 1;
+ mpt_ctx->dw0.bs.remote_access_en = 1;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_FREE;
+ mpt_ctx->mtt_sz =
+ (mr->mtt.mtt_layers > 0) ?
+ 1U << mr->mtt.mtt_seg[mr->mtt.mtt_layers - 1]
+ ->order :
+ 0;
+ break;
+
+ case HMM_RDMA_FMR:
+ mpt_ctx->mtt_base_addr = mr->mtt.mtt_paddr;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+ default:
+ pr_err("%s: unsupport mr type(%d)\n", __FUNCTION__, mr->type);
+ break;
+ }
+}
+
+static void hmm_set_mptc_type_above_phy_mr(struct roce_mpt_context *mpt_ctx,
+ struct hmm_rdma *mr)
+{
+ switch (mr->type) {
+ case HMM_RDMA_PHYS_MR:
+ mpt_ctx->mtt_base_addr = mr->mtt.mtt_paddr;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_RSVD_LKEY:
+ mpt_ctx->dw0.bs.rkey = 1;
+ mpt_ctx->dw0.bs.bpd = 0;
+ mpt_ctx->dw0.bs.invalid_en = 0;
+ mpt_ctx->dw0.bs.remote_invalid_en = 0;
+ mpt_ctx->dw0.bs.pa = 1;
+ mpt_ctx->mtt_base_addr = 0;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_VALID;
+ break;
+
+ case HMM_RDMA_SIG_MR:
+ mpt_ctx->mtt_base_addr = mr->mtt.mtt_paddr;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_FREE;
+ break;
+
+ case HMM_RDMA_INDIRECT_MR:
+ mpt_ctx->dw2.bs.status = MPT_STATUS_FREE;
+ break;
+ default:
+ pr_err("%s: unsupport mr type(%d)\n", __FUNCTION__, mr->type);
+ break;
+ }
+}
+
+static void hmm_set_mr_access(struct roce_mpt_context *mpt_ctx,
+ const struct hmm_rdma *mr)
+{
+ mpt_ctx->dw0.bs.access_lr = 1; /* Local access enabled by default */
+
+ if ((RDMA_IB_ACCESS_LOCAL_WRITE & mr->access) != 0) {
+ mpt_ctx->dw0.bs.access_lw = 1;
+ }
+ if ((RDMA_IB_ACCESS_REMOTE_READ & mr->access) != 0) {
+ mpt_ctx->dw0.bs.access_rr = 1;
+ }
+ if ((RDMA_IB_ACCESS_REMOTE_WRITE & mr->access) != 0) {
+ mpt_ctx->dw0.bs.access_rw = 1;
+ }
+ if ((RDMA_IB_ACCESS_REMOTE_ATOMIC & mr->access) != 0) {
+ mpt_ctx->dw0.bs.access_ra = 1;
+ }
+ if ((RDMA_IB_ACCESS_MW_BIND & mr->access) != 0) {
+ mpt_ctx->dw0.bs.access_bind = 1;
+ }
+}
+
+static void hmm_set_mptc_according_to_type(struct roce_mpt_context *mpt_ctx,
+ struct hmm_rdma *mr)
+{
+ if (mr->type < HMM_RDMA_PHYS_MR) {
+ hmm_set_mptc_type_below_phy_mr(mpt_ctx, mr);
+ } else {
+ hmm_set_mptc_type_above_phy_mr(mpt_ctx, mr);
+ }
+}
+
+static void hmm_mpt_to_big_endian(struct roce_mpt_context *mpt_ctx)
+{
+ mpt_ctx->dw0.value = cpu_to_be32(mpt_ctx->dw0.value);
+ mpt_ctx->dw1.value = cpu_to_be32(mpt_ctx->dw1.value);
+ mpt_ctx->dw2.value = cpu_to_be32(mpt_ctx->dw2.value);
+ mpt_ctx->dw3.value = cpu_to_be32(mpt_ctx->dw3.value);
+ mpt_ctx->iova = cpu_to_be64(mpt_ctx->iova);
+ mpt_ctx->length = cpu_to_be64(mpt_ctx->length);
+ mpt_ctx->mtt_base_addr = cpu_to_be64(mpt_ctx->mtt_base_addr);
+ mpt_ctx->mtt_sz = cpu_to_be32(mpt_ctx->mtt_sz);
+}
+
+static void hmm_set_mr_cmd_buf(struct roce_mpt_context *mpt_ctx,
+ struct hmm_rdma *mr)
+{
+ hmm_set_mr_access(mpt_ctx, mr);
+
+ mpt_ctx->dw0.bs.invalid_en = 1;
+ mpt_ctx->dw0.bs.remote_invalid_en = 1;
+ mpt_ctx->dw0.bs.r_w = MPT_MR;
+ mpt_ctx->dw0.bs.bpd = 1;
+ mpt_ctx->dw2.bs.pdn = mr->pdn & 0x3ffff;
+
+ if (mr->type != HMM_RDMA_INDIRECT_MR) {
+ mpt_ctx->dw0.bs.mtt_page_size =
+ (mr->mtt.mtt_page_shift > PAGE_SHIFT_4K) ?
+ (mr->mtt.mtt_page_shift - PAGE_SHIFT_4K) :
+ 0;
+ mpt_ctx->dw0.bs.mtt_layer_num = mr->mtt.mtt_layers;
+ mpt_ctx->dw0.bs.buf_page_size =
+ (mr->mtt.buf_page_shift > PAGE_SHIFT_4K) ?
+ (mr->mtt.buf_page_shift - PAGE_SHIFT_4K) :
+ 0;
+ mpt_ctx->dw1.bs.dma_attr_idx = MPT_DMA_ATTR_IDX;
+ mpt_ctx->dw1.bs.so_ro = 0;
+ mpt_ctx->dw2.bs.block_size =
+ (mr->block_size / BLOCK_SIZE_DEVIDE_SECTOR) & 0x3f;
+ if (mr->block_size > 0) {
+ mpt_ctx->dw3.bs.page_mode = 1;
+ }
+
+ mpt_ctx->iova = mr->iova;
+ mpt_ctx->length = mr->size;
+ mpt_ctx->dw3.bs.fbo = 0;
+ if ((mr->access & RDMA_IB_ACCESS_ZERO_BASED) != 0) {
+ mpt_ctx->dw0.bs.zbva = 1;
+ mpt_ctx->dw3.bs.fbo = mr->iova & PAGE_MASK;
+ mpt_ctx->iova = 0;
+ }
+ } else {
+ mpt_ctx->dw2.bs.indirect_mr = 1;
+ }
+
+ mpt_ctx->dw3.bs.mkey = mr->key & 0xFF;
+
+ hmm_set_mptc_according_to_type(mpt_ctx, mr);
+}
+
+static void hmm_set_mw_cmd_buf(struct roce_mpt_context *mpt_ctx,
+ struct hmm_rdma *hmmrdma)
+{
+ /* fill mpt_entry */
+ mpt_ctx->dw0.bs.bpd = 1;
+ mpt_ctx->dw0.bs.r_w = MPT_MW;
+ mpt_ctx->dw0.bs.access_lr = 1;
+ mpt_ctx->dw0.bs.access_lw = 1;
+
+ mpt_ctx->dw1.bs.dma_attr_idx = MPT_DMA_ATTR_IDX;
+ mpt_ctx->dw1.bs.so_ro = RDMA_MPT_SO_RO;
+
+ mpt_ctx->dw2.bs.pdn = hmmrdma->pdn;
+ mpt_ctx->dw2.bs.status = MPT_STATUS_VALID;
+
+ mpt_ctx->dw3.bs.mkey = hmmrdma->key & 0xFF;
+
+ /* only type2 mw binds with QP and suppoort invalid operation, init value is FREE */
+ if (hmmrdma->type == HMM_RDMA_MW_TYPE_2) {
+ mpt_ctx->dw0.bs.invalid_en = 1;
+ mpt_ctx->dw0.bs.remote_invalid_en = 1;
+ mpt_ctx->dw0.bs.bqp = 1;
+
+ mpt_ctx->dw2.bs.status = MPT_STATUS_FREE;
+ }
+}
+
+int hmm_set_cmd_buf(struct roce_mpt_context *mpt_ctx, struct hmm_rdma *hmmrdma)
+{
+ if (hmmrdma->type < HMM_RDMA_MR_END) {
+ hmm_set_mr_cmd_buf(mpt_ctx, hmmrdma);
+ } else if (hmmrdma->type < HMM_RDMA_MW_END) {
+ hmm_set_mw_cmd_buf(mpt_ctx, hmmrdma);
+ } else {
+ pr_err("%s: Invalid rdma type(%d)\n", __FUNCTION__,
+ hmmrdma->type);
+ return -EINVAL;
+ }
+
+ hmm_mpt_to_big_endian(mpt_ctx);
+
+ return 0;
+}
+
+int hmm_rdma_enable_mpt(struct hinic5_lld_dev *lld_dev, void *hwdev,
+ struct hmm_rdma *mr, u16 channel)
+{
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ struct rdma_mpt_entry *mpt_entry = NULL;
+ struct rdma_mpt_sw2hw_inbuf *mpt_sw2hw_inbuf = NULL;
+ int ret = 0;
+ errno_t rc;
+
+ if ((lld_dev == NULL) || (hwdev == NULL) || (mr == NULL)) {
+ pr_err("%s: Parameters are NULL, dev(%d), hwdev(%d), mr(%d)\n",
+ __FUNCTION__, !!lld_dev, !!hwdev, !!mr);
+ return -EINVAL;
+ }
+
+ if ((hmm_get_device_type(lld_dev) == HMM_DEV_TYPE_HI1823_V200) ||
+ (hmm_get_device_type(lld_dev) == HMM_DEV_TYPE_HI1825_V100)) {
+ return uni_hmm_rdma_enable_mpt(lld_dev, hwdev, mr, channel);
+ }
+
+ cqm_cmd_inbuf = cqm5_cmd_alloc(hwdev);
+ if (cqm_cmd_inbuf == NULL) {
+ pr_err("%s: Alloc cmd_buf failed, err(%d)\n", __FUNCTION__,
+ -ENOMEM);
+ return -ENOMEM;
+ }
+
+ cqm_cmd_inbuf->size = (u16)sizeof(struct rdma_mpt_sw2hw_inbuf);
+ mpt_sw2hw_inbuf = (struct rdma_mpt_sw2hw_inbuf *)cqm_cmd_inbuf->buf;
+ rc = memset_s(mpt_sw2hw_inbuf, sizeof(*mpt_sw2hw_inbuf), 0,
+ sizeof(*mpt_sw2hw_inbuf));
+ if (rc != EOK) {
+ pr_err("%s: memset error\n", __FUNCTION__);
+ }
+ mpt_sw2hw_inbuf->com.dw0.bs.cmd_bitmask =
+ (u16)cpu_to_be16(VERBS_CMD_TYPE_MR_BITMASK);
+ mpt_sw2hw_inbuf->com.dw0.bs.sub_cmd = RDMA_CMD_SW2HW_MPT;
+ mpt_sw2hw_inbuf->com.index = cpu_to_be32(mr->mpt.mpt_index);
+ mpt_entry = &mpt_sw2hw_inbuf->mpt_entry;
+
+ ret = hmm_set_cmd_buf(&mpt_entry->roce_mpt_ctx, mr);
+ if (ret != 0) {
+ pr_err("%s: Failed to fulfill command buffer, ret(%d), index(0x%x).\n",
+ __FUNCTION__, ret, mr->mpt.mpt_index);
+ goto out;
+ }
+
+ ret = hmm_enable_mpt(lld_dev, hwdev, cqm_cmd_inbuf, channel);
+ if (ret != 0) {
+ pr_err("%s: Enable mr's mpt failed, ret(%d) index(0x%x)\n",
+ __FUNCTION__, ret, mr->mpt.mpt_index);
+ goto out;
+ }
+ mr->enabled = RDMA_MPT_EN_HW;
+out:
+ cqm5_cmd_free(hwdev, cqm_cmd_inbuf);
+ return ret;
+}
+
+int hmm_rdma_disable_mpt(struct hinic5_lld_dev *lld_dev, void *hwdev,
+ struct hmm_rdma *mr, u32 service_type, u16 channel)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ int ret = 0;
+
+ if ((lld_dev == NULL) || (hwdev == NULL) || (mr == NULL)) {
+ pr_err("%s: invalid param: dev:%d, hwdev:%d, mr:%d\n",
+ __FUNCTION__, !!lld_dev, !!hwdev, !!mr);
+ return -EINVAL;
+ }
+
+ comp_priv = get_hmm_comp_priv(hwdev, service_type);
+ if (comp_priv == NULL) {
+ pr_err("%s: Comp_priv is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (mr->enabled == RDMA_MPT_EN_HW) {
+ ret = hmm_disable_mpt(lld_dev, comp_priv, &mr->mpt, channel);
+ if (ret != 0) {
+ pr_err("%s: Disable mr's mpt failed, ret(%d) index(0x%x)\n",
+ __FUNCTION__, ret, mr->mpt.mpt_index);
+ return ret;
+ }
+
+ mr->enabled = RDMA_MPT_EN_SW;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em.c
new file mode 100644
index 000000000..871209296
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em.c
@@ -0,0 +1,395 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ Description : management of entry
+ ***************************************************************************** */
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+#include "hmm_em_inner.h"
+#ifdef LLT_TEST
+#include "llt_roce_stub.h"
+#endif
+
+#include "securec.h"
+
+static void hmm_em_chunk_free(struct device *dev, struct hmm_em_chunk *em_chunk)
+{
+ struct hmm_em_buf *cur_buf = NULL;
+ struct hmm_em_buf *next_buf = NULL;
+
+ cur_buf = &em_chunk->em_buf_list;
+ next_buf = cur_buf->next_buf;
+
+ while (next_buf != NULL) {
+ cur_buf = next_buf;
+ next_buf = cur_buf->next_buf;
+
+ if ((cur_buf->buf != NULL) && (cur_buf->length > 0)) {
+ if (memset_s(cur_buf->buf, cur_buf->length, 0,
+ cur_buf->length) != EOK) {
+ dev_err(dev,
+ "[HMM] %s: memory set error, err(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ }
+ dma_free_coherent(dev, (unsigned long)cur_buf->length,
+ cur_buf->buf, cur_buf->dma_addr);
+ cur_buf->buf = NULL;
+ cur_buf->length = 0;
+ }
+
+ kfree(cur_buf);
+ cur_buf = NULL;
+ }
+
+ kfree(em_chunk);
+}
+
+static int hmm_em_chunk_alloc_npages(struct device *dev,
+ struct hmm_em_chunk *em_chunk,
+ int min_order)
+{
+ int cur_order = 0;
+ int npages = 0;
+ unsigned int chunk_size = HMM_EM_CHUNK_SIZE;
+ struct hmm_em_buf *cur_buf = &em_chunk->em_buf_list;
+ struct hmm_em_buf *next_buf = NULL;
+
+ cur_buf->next_buf = NULL;
+ cur_buf->length = 0;
+ cur_order = get_order(chunk_size); //lint !e834 !e587
+ npages = (int)(1U << (unsigned int)cur_order);
+ while (npages > 0) {
+ if (next_buf == NULL) {
+ next_buf = (struct hmm_em_buf *)kzalloc(
+ sizeof(struct hmm_em_buf), GFP_KERNEL);
+ if (next_buf == NULL) {
+ dev_err(dev,
+ "[HMM] %s: Alloc memory for em_buf failed, err(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return (-ENOMEM);
+ }
+
+ next_buf->length = 0;
+ next_buf->next_buf = NULL;
+ }
+ cur_buf->next_buf = next_buf;
+
+ next_buf->buf = dma_alloc_coherent(
+ dev,
+ (size_t)HMM_EM_PAGE_SIZE << (unsigned int)cur_order,
+ &next_buf->dma_addr, GFP_KERNEL);
+ if (next_buf->buf == NULL) {
+ cur_order--;
+ if (cur_order < min_order) {
+ dev_err(dev,
+ "[HMM] %s:em_chunk alloc dma buf failed, err(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return (-ENOMEM);
+ } else {
+ dev_err(dev,
+ "[HMM, WARN] %s: em_chunk alloc %d o dma failed. can't alloc small mem.\n",
+ __FUNCTION__, cur_order);
+ continue;
+ }
+ }
+
+ next_buf->length = (u32)HMM_EM_PAGE_SIZE
+ << (unsigned int)cur_order;
+ em_chunk->buf_num++;
+ npages -= (int)(1U << (unsigned int)cur_order);
+
+ cur_buf = next_buf;
+ next_buf = NULL;
+ }
+
+ return 0;
+}
+
+static struct hmm_em_chunk *hmm_em_chunk_alloc(struct device *dev,
+ int min_order)
+{
+ struct hmm_em_chunk *em_chunk = NULL;
+ int ret;
+
+ em_chunk = (struct hmm_em_chunk *)kzalloc(sizeof(struct hmm_em_chunk),
+ GFP_KERNEL);
+ if (em_chunk == NULL) {
+ dev_err(dev,
+ "[HMM] %s: Alloc memory for em_chunk failed, err(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return (struct hmm_em_chunk *)ERR_PTR((long)-ENOMEM);
+ }
+
+ em_chunk->buf_num = 0;
+ ret = hmm_em_chunk_alloc_npages(dev, em_chunk, min_order);
+ if (ret != 0) {
+ hmm_em_chunk_free(dev, em_chunk);
+ return (struct hmm_em_chunk *)ERR_PTR((long)ret);
+ }
+
+ em_chunk->refcount = 0;
+
+ return em_chunk;
+}
+
+static void hmm_em_table_put(struct device *dev, struct hmm_em_table *em_table,
+ u32 obj)
+{
+ u32 i = 0;
+
+ if (obj >= em_table->obj_num) {
+ dev_err(dev, "[HMM] %s: Obj over range, obj(0x%x), max(0x%x)\n",
+ __FUNCTION__, obj, em_table->obj_num - 1);
+ return;
+ }
+
+ i = obj / (HMM_EM_CHUNK_SIZE / em_table->obj_size);
+
+ mutex_lock(&em_table->mutex);
+
+ if ((em_table->em_chunk[i] == NULL) ||
+ (IS_ERR(em_table->em_chunk[i]))) {
+ dev_err(dev,
+ "[HMM] %s: Em_table->em_chunk[%u] not alloced, obj(0x%x)\n",
+ __FUNCTION__, i, obj);
+ mutex_unlock(&em_table->mutex);
+ return;
+ }
+
+ if (em_table->em_chunk[i]->refcount == 1) {
+ em_table->em_chunk[i]->refcount = 0;
+ hmm_em_chunk_free(dev, em_table->em_chunk[i]);
+ em_table->em_chunk[i] = NULL;
+ } else {
+ --em_table->em_chunk[i]->refcount;
+ }
+
+ mutex_unlock(&em_table->mutex);
+}
+
+static int hmm_em_table_get(struct device *dev, struct hmm_em_table *em_table,
+ u32 obj)
+{
+ int ret = 0;
+ u32 i;
+
+ if (obj >= em_table->obj_num) {
+ dev_err(dev, "[HMM] %s: Obj over range, obj(0x%x), max(0x%x)\n",
+ __FUNCTION__, obj, em_table->obj_num - 1);
+ return -EINVAL;
+ }
+
+ i = obj / (HMM_EM_CHUNK_SIZE / em_table->obj_size);
+
+ mutex_lock(&em_table->mutex);
+
+ if (!IS_ERR_OR_NULL(em_table->em_chunk[i])) {
+ ++em_table->em_chunk[i]->refcount;
+ goto out;
+ }
+
+ em_table->em_chunk[i] = hmm_em_chunk_alloc(dev, em_table->min_order);
+ if (IS_ERR(em_table->em_chunk[i])) {
+ ret = (int)PTR_ERR(em_table->em_chunk[i]);
+ dev_err(dev, "[HMM] %s: Alloc em_chunk failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ goto out;
+ }
+
+ ++em_table->em_chunk[i]->refcount;
+
+out:
+ mutex_unlock(&em_table->mutex);
+
+ return ret;
+}
+
+void *hmm_em_table_find(struct hmm_em_table *em_table, u32 obj,
+ dma_addr_t *dma_handle)
+{
+ void *vaddr = NULL;
+ struct hmm_em_chunk *em_chunk = NULL;
+ struct hmm_em_buf *cur_buf = NULL;
+ struct hmm_em_buf *next_buf = NULL;
+ u64 table_offset;
+ u32 offset;
+
+ if (em_table == NULL) {
+ pr_err("%s: Em_table is null, err(%d)\n", __FUNCTION__,
+ -EINVAL);
+ return NULL;
+ }
+
+ if (obj >= em_table->obj_num) {
+ pr_err("%s: Obj over range, obj(0x%x), max(0x%x)\n",
+ __FUNCTION__, obj, em_table->obj_num - 1);
+ return NULL;
+ }
+
+ mutex_lock(&em_table->mutex);
+
+ table_offset = (u64)obj * em_table->obj_size;
+ em_chunk = em_table->em_chunk[table_offset / HMM_EM_CHUNK_SIZE];
+ offset = table_offset % HMM_EM_CHUNK_SIZE;
+
+ if (em_chunk == NULL || IS_ERR(em_chunk)) {
+ pr_err("%s: Em_chunk has not been alloced, err(%d)\n",
+ __FUNCTION__, -EINVAL);
+ goto err_out;
+ }
+
+ cur_buf = &em_chunk->em_buf_list;
+ next_buf = cur_buf->next_buf;
+
+ while (next_buf != NULL) {
+ cur_buf = next_buf;
+ if (offset < cur_buf->length) {
+ if (dma_handle != NULL) {
+ *dma_handle = cur_buf->dma_addr + offset;
+ }
+
+ vaddr = (void *)((char *)(cur_buf->buf) + offset);
+ mutex_unlock(&em_table->mutex);
+ return vaddr;
+ }
+
+ offset -= cur_buf->length;
+ next_buf = cur_buf->next_buf;
+ }
+
+err_out:
+ mutex_unlock(&em_table->mutex);
+
+ return NULL;
+}
+
+void hmm_em_table_put_range(struct device *dev, struct hmm_em_table *em_table,
+ u32 start, u32 end)
+{
+ int i = 0;
+ int inc = 0;
+
+ if ((dev == NULL) || (em_table == NULL)) {
+ pr_err("[HMM] %s: dev or em_table is null, err(%d)\n",
+ __FUNCTION__, -EINVAL);
+ return;
+ }
+
+ inc = (int)(HMM_EM_CHUNK_SIZE / em_table->obj_size);
+ for (i = (int)start; i <= (int)end; i += inc) {
+ hmm_em_table_put(dev, em_table, (u32)i);
+ }
+
+ return;
+}
+
+int hmm_em_table_get_range(struct device *dev, struct hmm_em_table *em_table,
+ u32 start, u32 end)
+{
+ int ret = 0;
+ int i = 0;
+ int inc = 0;
+
+ if ((dev == NULL) || (em_table == NULL)) {
+ pr_err("[HMM] %s: dev or em_table is null, err(%d)\n",
+ __FUNCTION__, -EINVAL);
+ return -EINVAL;
+ }
+
+ inc = (int)(HMM_EM_CHUNK_SIZE / em_table->obj_size);
+
+ for (i = (int)start; i <= (int)end; i += inc) {
+ ret = hmm_em_table_get(dev, em_table, (u32)i);
+ if (ret != 0) {
+ dev_err(dev,
+ "[HMM] %s: Get entry failed, start(%u), end(%u), i(%d), ret(%d)\n",
+ __FUNCTION__, start, end, i, ret);
+ goto err_out;
+ }
+ }
+
+ return 0;
+
+err_out:
+ while (i > (int)start) {
+ i -= inc;
+ hmm_em_table_put(dev, em_table, (u32)i);
+ }
+
+ return ret;
+}
+
+int hmm_em_init_table(struct device *dev, struct hmm_em_table *em_table,
+ u32 obj_size, u32 nobj, u32 reserved_bot, int min_order)
+{
+ u32 obj_per_chunk = 0;
+ u32 chunk_num = 0;
+
+ if ((dev == NULL) || (em_table == NULL)) {
+ pr_err("[HMM] %s: dev or em_table is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (nobj == 0) {
+ dev_err(dev, "[HMM] %s: Nobj is invalid\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ /*lint -e587 */
+ if (nobj != HMM_EM_ROUNDUP_POW_OF_TWO(nobj)) {
+ dev_err(dev, "[HMM] %s: Obj isn't pow of two, nobj(0x%x)\n",
+ __FUNCTION__, nobj);
+ return -EINVAL;
+ }
+
+ if (obj_size != HMM_EM_ROUNDUP_POW_OF_TWO(obj_size)) {
+ dev_err(dev,
+ "[HMM] %s: Obj_size isn't pow of two, obj_size(0x%x)\n",
+ __FUNCTION__, obj_size);
+ return -EINVAL;
+ }
+ /*lint +e587 */
+
+ obj_per_chunk = HMM_EM_CHUNK_SIZE / obj_size;
+ chunk_num = (nobj + obj_per_chunk - 1) / obj_per_chunk;
+
+ em_table->em_chunk = (struct hmm_em_chunk **)kcalloc(
+ (size_t)chunk_num, sizeof(struct hmm_em_chunk *), GFP_KERNEL);
+ if (em_table->em_chunk == NULL) {
+ dev_err(dev, "[HMM] %s: Em_table->em_chunk create failed\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ em_table->chunk_num = chunk_num;
+ em_table->obj_num = nobj;
+ em_table->obj_size = obj_size;
+ em_table->min_order = min_order;
+
+ mutex_init(&em_table->mutex);
+
+ return 0;
+}
+
+void hmm_em_cleanup_table(struct device *dev, struct hmm_em_table *em_table)
+{
+ u32 i = 0;
+
+ if ((dev == NULL) || (em_table == NULL)) {
+ pr_err("[HMM] %s: dev or em_table is null\n", __FUNCTION__);
+ return;
+ }
+
+ for (i = 0; i < em_table->chunk_num; i++) {
+ if (!IS_ERR_OR_NULL(em_table->em_chunk[i])) {
+ hmm_em_chunk_free(dev, em_table->em_chunk[i]);
+ em_table->em_chunk[i] = NULL;
+ }
+ }
+
+ kfree(em_table->em_chunk);
+ em_table->em_chunk = NULL;
+
+ return;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em_inner.h
new file mode 100644
index 000000000..185c80298
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_em_inner.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ * Description : structure and interface about management of entry
+ */
+
+#ifndef HMM_EM_H
+#define HMM_EM_H
+
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include "hmm_common.h"
+
+#define HMM_EM_CHUNK_SIZE \
+ (1 << 21) /**< 定义一个宏常量值为2的21次方,即1048576 */
+#define HMM_EM_PAGE_SIZE PAGE_SIZE /**< 表示HMM_EM页面的大小,通常为4096字节 */
+
+#define HMM_EM_ROUNDUP_POW_OF_TWO roundup_pow_of_two
+
+/**
+ * @brief 在HMM EM表中查找对象
+ * @param em_table HMM EM表
+ * @param obj 要查找的对象
+ * @param dma_handle DMA句柄
+ *
+ * @return void* 如果找到,返回对象的指针,否则返回NULL
+ */
+void *hmm_em_table_find(struct hmm_em_table *em_table, u32 obj,
+ dma_addr_t *dma_handle);
+/**
+ * @brief 将一个范围内的HMM表项添加到设备中
+ * @param dev 设备的指针
+ * @param em_table HMM表的指针
+ * @param start 范围的起始地址
+ * @param end 范围的结束地址
+ *
+ * @details 这个函数将一个范围内的HMM表项添加到设备中。
+ * 参数dev是设备的指针,em_table是HMM表的指针,start和end分别是范围的起始和结束地址。
+ *
+ * @return 无
+ */
+void hmm_em_table_put_range(struct device *dev, struct hmm_em_table *em_table,
+ u32 start, u32 end);
+/**
+ * @brief 获取HMM EM表的范围
+ * @param dev 设备的指针
+ * @param em_table HMM EM表
+ * @param start 起始地址
+ * @param end 结束地址
+ *
+ * @return 返回获取到的范围
+ */
+int hmm_em_table_get_range(struct device *dev, struct hmm_em_table *em_table,
+ u32 start, u32 end);
+/**
+ * @brief 初始化HMM表
+ * @param dev 设备的指针
+ * @param em_table HMM表
+ * @param obj_size 对象大小
+ * @param nobj 对象数量
+ * @param reserved_bot 保留底部
+ * @param min_order 最小顺序
+ *
+ * @return 返回0表示成功,否则返回错误代码
+ */
+int hmm_em_init_table(struct device *dev, struct hmm_em_table *em_table,
+ u32 obj_size, u32 nobj, u32 reserved_bot, int min_order);
+/**
+ * @brief 清理HMM EM表
+ * @param dev 设备的指针
+ * @param em_table HMM EM表
+ *
+ * @return void
+ */
+void hmm_em_cleanup_table(struct device *dev, struct hmm_em_table *em_table);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_init.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_init.c
new file mode 100644
index 000000000..4eb8ed6c5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_init.c
@@ -0,0 +1,157 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ File Name : hmm_comp_init.c
+ Version : Initial Draft
+ Last Modified :
+ Description : implement the management of MPT, MTT
+***************************************************************************** */
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include "hinic5_hw.h"
+#include "hinic5_crm.h"
+
+#include "hmm_common.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_hmm.h"
+
+u32 g_mtt_page_size = 0U;
+module_param(g_mtt_page_size, uint, S_IRUGO);
+MODULE_PARM_DESC(g_mtt_page_size, "0:4K,1:64K,2:2M,default:4K");
+
+static int hmm_init_table(void *hwdev, struct hmm_comp_priv *comp_priv,
+ u32 srv_type)
+{
+ int ret;
+
+ ret = hmm_mtt_init(comp_priv);
+ if (ret != 0) {
+ pr_err("%s: Initialize mtt's table failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ return ret;
+ }
+
+ ret = hinic5_register_service_adapter(
+ (void *)hwdev, (void *)comp_priv,
+ (enum hinic5_service_type)srv_type);
+ if (ret != 0) {
+ pr_err("%s: put hmm_comp_res failed, ret(%d)\n", __FUNCTION__,
+ ret);
+ goto err_init;
+ }
+ pr_info("%s: Hmm init resource successful\n", __FUNCTION__);
+ return 0;
+
+err_init:
+ hmm_mtt_cleanup(comp_priv);
+ return ret;
+}
+
+void hmm_cleanup_resource(void *hwdev, u32 service_type)
+{
+ struct rdma_service_cap rdma_cap;
+ struct hmm_comp_priv *comp_priv = NULL;
+
+ if (hwdev == NULL) {
+ pr_err("%s: Hwdev is null\n", __FUNCTION__);
+ return;
+ }
+
+ if (!hinic5_is_rdma_en(hwdev, &rdma_cap)) {
+ pr_err("%s: rdma is not enabled.\n", __FUNCTION__);
+ return;
+ }
+
+ comp_priv = get_hmm_comp_priv(hwdev, service_type);
+ if (comp_priv == NULL) {
+ pr_err("%s: Comp_priv is null\n", __FUNCTION__);
+ return;
+ }
+
+ hmm_mtt_cleanup(comp_priv);
+
+ kfree(comp_priv);
+
+ hinic5_unregister_service_adapter(
+ (void *)hwdev, (enum hinic5_service_type)service_type);
+
+ pr_info("%s: hmm cleanup resource successful", __FUNCTION__);
+
+ return;
+}
+
+static void hmm_init_comp_priv(void *hwdev, struct rdma_service_cap *rdma_cap,
+ struct hmm_comp_priv *comp_priv)
+{
+ comp_priv->hwdev = hwdev;
+ comp_priv->dev =
+ (struct device *)(((struct hinic5_hwdev *)hwdev)->dev_hdl);
+ comp_priv->dev_cap.log_mtt = rdma_cap->log_mtt;
+ comp_priv->dev_cap.log_mtt_seg = rdma_cap->log_mtt_seg;
+ comp_priv->dev_cap.mtt_entry_sz = rdma_cap->mtt_entry_sz;
+ comp_priv->dev_cap.mpt_entry_sz = rdma_cap->mpt_entry_sz;
+ comp_priv->dev_cap.num_mtts = rdma_cap->num_mtts;
+
+ comp_priv->dev_cap.dmtt_cl_start =
+ rdma_cap->dev_rdma_cap.roce_own_cap.dmtt_cl_start;
+ comp_priv->dev_cap.dmtt_cl_end =
+ rdma_cap->dev_rdma_cap.roce_own_cap.dmtt_cl_end;
+ comp_priv->dev_cap.dmtt_cl_sz =
+ rdma_cap->dev_rdma_cap.roce_own_cap.dmtt_cl_sz;
+
+ switch (g_mtt_page_size) {
+ case MTT_PAGE_SIZE_4K:
+ comp_priv->mtt_page_size = PAGE_SIZE_4K; /* page size is 4K */
+ comp_priv->mtt_page_shift =
+ PAGE_SHIFT_4K; /* page size is 1 left shift 12 */
+ break;
+ case MTT_PAGE_SIZE_64K:
+ comp_priv->mtt_page_size = PAGE_SIZE_64K; /* page size is 64K */
+ comp_priv->mtt_page_shift =
+ PAGE_SHIFT_64K; /* page size is 1 left shift 16 */
+ break;
+ case MTT_PAGE_SIZE_2M:
+ comp_priv->mtt_page_size = PAGE_SIZE_2M; /* page size is 2M */
+ comp_priv->mtt_page_shift =
+ PAGE_SHIFT_2M; /* page size is 1 left shift 21 */
+ break;
+ default:
+ comp_priv->mtt_page_size = PAGE_SIZE_4K; /* page size is 4K */
+ comp_priv->mtt_page_shift =
+ PAGE_SHIFT_4K; /* page size is 1 left shift 12 */
+ break;
+ }
+}
+
+int hmm_init_resource(void *hwdev, u32 service_type)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ struct rdma_service_cap rdma_cap;
+ int ret;
+
+ if (hwdev == NULL) {
+ pr_err("%s: Hwdev is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (!hinic5_is_rdma_en(hwdev, &rdma_cap)) {
+ pr_info("%s: rdma is not enabled.\n", __FUNCTION__);
+ return 0;
+ }
+
+ comp_priv = (struct hmm_comp_priv *)kzalloc(
+ sizeof(struct hmm_comp_priv), GFP_KERNEL);
+ if (comp_priv == NULL) {
+ pr_err("%s: Alloc memory for comp_priv failed, ret(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return -ENOMEM;
+ }
+ hmm_init_comp_priv(hwdev, &rdma_cap, comp_priv);
+
+ ret = hmm_init_table(hwdev, comp_priv, service_type);
+ if (ret != 0) {
+ pr_err("%s: hmm init table failed, ret(%d)\n", __FUNCTION__,
+ ret);
+ kfree(comp_priv);
+ }
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mpt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mpt.c
new file mode 100644
index 000000000..d616e833b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mpt.c
@@ -0,0 +1,60 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ File Name : hmm_comp_res.c
+ Version : Initial Draft
+ Description : implement the management of MPT, MTT
+***************************************************************************** */
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "hmm_common.h"
+
+int hmm_mpt_alloc_templated(void *hwdev, struct mpt *mpt, u32 service_type,
+ u32 xid)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ u32 mpt_entry_size = 0;
+
+ if ((hwdev == NULL) || (mpt == NULL)) {
+ pr_err("%s: Hwdev or mpt is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ comp_priv = get_hmm_comp_priv(hwdev, service_type);
+ if (comp_priv == NULL) {
+ pr_err("%s: Comp_priv is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ mpt_entry_size = comp_priv->dev_cap.mpt_entry_sz;
+
+ mpt->mpt_object = (void *)cqm5_object_qpc_mpt_create(
+ hwdev, service_type, CQM_OBJECT_MPT, mpt_entry_size, mpt, xid,
+ 0, 0);
+ if (mpt->mpt_object == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Alloc mpt_object failed, err(%d)\n", __FUNCTION__,
+ -ENOMEM);
+ return -ENOMEM;
+ }
+
+ mpt->mpt_index = ((cqm_qpc_mpt_s *)mpt->mpt_object)->xid;
+ mpt->vaddr = (void *)((cqm_qpc_mpt_s *)mpt->mpt_object)->vaddr;
+
+ return 0;
+}
+
+void hmm_mpt_free(void *hwdev, struct mpt *mpt)
+{
+ if ((hwdev == NULL) || (mpt == NULL)) {
+ pr_err("%s: Hwdev or mpt is null\n", __FUNCTION__);
+ return;
+ }
+
+ cqm5_object_delete(&((cqm_qpc_mpt_s *)mpt->mpt_object)->object);
+ mpt->vaddr = NULL;
+ mpt->mpt_object = NULL;
+
+ return;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mr.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mr.c
new file mode 100644
index 000000000..6f0f6a75c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mr.c
@@ -0,0 +1,397 @@
+/* *****************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ Description : implement the verbs of momory region
+***************************************************************************** */
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/semaphore.h>
+
+#include "hinic5_crm.h"
+#include "hinic5_hwdev.h"
+#include "hmm_umem_inner.h"
+#include "hmm_common.h"
+#include "hinic5_hmm.h"
+
+#ifdef LLT_TEST
+#include "llt_roce_stub.h"
+#endif
+
+/**
+* @brief tpt资源分配
+* @param hwdev 硬件设备指针
+* @param mpt mpt结构体指针
+* @param mtt mtt结构体指针
+* @param npages 页数
+* @param page_shift 页大小
+* @param service_type 服务类型
+*
+* @return 返回0表示成功,其他值表示失败
+*/
+int hmm_alloc_tpt(struct hinic5_hwdev *hwdev, struct mpt *mpt, struct mtt *mtt,
+ u32 npages, u32 page_shift, u32 service_type)
+{
+ int ret;
+
+ ret = hmm_mpt_alloc(hwdev, mpt, service_type);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to alloc mpt, ret(%d), func_id(%d)\n",
+ __func__, __LINE__, ret, hinic5_global_func_id(hwdev));
+ return ret;
+ }
+
+ /* npages = 0 or 1, means not need mtt */
+ ret = hmm_mtt_alloc(hwdev, npages, page_shift, mtt, service_type);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to alloc mtt, ret(%d), func_id(%d)\n",
+ __func__, __LINE__, ret, hinic5_global_func_id(hwdev));
+ goto err_alloc_mtt;
+ }
+ return 0;
+
+err_alloc_mtt:
+ hmm_mpt_free(hwdev, mpt);
+
+ return ret;
+}
+
+/**
+* @brief tpt资源释放
+* @param hwdev 硬件设备指针
+* @param mpt mpt结构体指针
+* @param mtt mtt结构体指针
+* @param service_type 服务类型
+*
+* @return 返回0表示成功,其他值表示失败
+*/
+void hmm_free_tpt(void *hwdev, struct mpt *mpt, struct mtt *mtt,
+ u32 service_type)
+{
+ hmm_mtt_free(hwdev, mtt, service_type);
+ hmm_mpt_free(hwdev, mpt);
+}
+
+static int hmm_umem_write_mtt_check(const void *hwdev, const struct mtt *mtt,
+ const struct hmm_umem *umem)
+{
+ if ((hwdev == NULL) || (mtt == NULL) || (umem == NULL)) {
+ pr_err("[HMM, ERR] %s(%d): hwdev or mtt or umem is null\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int hmm_umem_write_mtt_update(struct hinic5_hwdev *hwdev,
+ struct mtt *mtt, struct hmm_umem *umem,
+ u64 *page_list, u32 service_type)
+{
+ int ret = 0;
+ int i = 0;
+ u32 j = 0;
+ u32 pages_in_chunk = 0; /* umem_chunk中单个内存块的页个数 */
+ u32 npages = 0; /* 已经记录的页个数 */
+ u32 start_index = 0; /* 要写入mtt的页 */
+ struct scatterlist *sg = NULL;
+ u64 page_size = 0;
+
+ page_size = BIT((unsigned int)umem->page_shift);
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) {
+ /* cal page num in truck */
+ pages_in_chunk = sg_dma_len(sg) >> mtt->buf_page_shift;
+ for (j = 0; j < pages_in_chunk; ++j) {
+ page_list[npages] =
+ sg_dma_address(sg) + (page_size * j);
+ npages++;
+
+ /* one page can hold (PAGE_SIZE / sizeof(u64)) addrs */
+ if (npages == (PAGE_SIZE / sizeof(u64))) {
+ ret = hmm_mtt_write(hwdev, mtt, start_index,
+ npages, page_list,
+ service_type);
+ start_index += npages;
+ npages = 0;
+ }
+ if ((npages == 0) && (ret != 0)) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to write mtt, func_id(%d)\n",
+ __func__, __LINE__,
+ hinic5_global_func_id(hwdev));
+ goto out;
+ }
+ }
+ }
+
+ if (npages != 0) {
+ ret = hmm_mtt_write(hwdev, mtt, start_index, npages, page_list,
+ service_type);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to write mtt, ret(%d), start_index(%d), func_id(%d)\n",
+ __func__, __LINE__, ret, start_index,
+ hinic5_global_func_id(hwdev));
+ goto out;
+ }
+ }
+
+out:
+ kfree(page_list);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : hmm_umem_write_mtt
+ Description : write mtt for umem(get from memory alloced by user)
+ Input : struct hinic5_hwdev *hwdev
+ struct mtt *mtt
+ struct hmm_umem *umem
+ Output : None
+**************************************************************************** */
+int hmm_umem_write_mtt(struct hinic5_hwdev *hwdev, struct mtt *mtt,
+ struct hmm_umem *umem, u32 service_type)
+{
+ int ret;
+ u64 *page_list = NULL; /* 要写入mtt的page_list */
+
+ ret = hmm_umem_write_mtt_check(hwdev, mtt, umem);
+ if (ret != 0) {
+ return ret;
+ }
+ page_list = (u64 *)kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (page_list == NULL) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to alloc memory for page list, func_id(%d)\n",
+ __func__, __LINE__, hinic5_global_func_id(hwdev));
+ return -ENOMEM;
+ }
+ ret = hmm_umem_write_mtt_update(hwdev, mtt, umem, page_list,
+ service_type);
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : get_key_from_index
+ Description : mr key的计算算法,通过index移位计算得到
+ Input : u32 mpt_index
+ Output : None
+**************************************************************************** */
+static u32 get_key_from_index(u32 mpt_index)
+{
+ return (mpt_index >> MR_KEY_RIGHT_SHIFT_OFS) |
+ (mpt_index << MR_KEY_LEFT_SHIFT_OFS);
+}
+
+/* ****************************************************************************
+ Prototype : hmm_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
+**************************************************************************** */
+static void hmm_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 = access;
+ mr->key = get_key_from_index(
+ mr->mpt.mpt_index); /* 由mpt index转换为key */
+ mr->type = mr_type;
+}
+
+/**
+ * @brief 更新用户内存注册表
+ * @param hwdev 硬件设备的指针,可能是用于执行硬件操作的接口
+ * @param mr 内存注册表的指针,用于存储内存的相关信息
+ * @param pdn 页目录号,用于标识内存的页
+ * @param length 内存的长度,即内存的大小
+ * @param virt_addr 虚拟地址,用于标识内存的位置
+ * @param access 访问权限,用于标识内存的访问方式
+ * @param service_type 服务类型,可能是用于标识内存的使用场景
+ * @param channel 通道号,可能是用于标识内存的使用通道
+ *
+ * @details 这个函数主要用于高性能计算或者网络通信的场景,例如在一些需要大量内存操作的场景,或者在需要对内存进行精细管理的场景
+ *
+ * @return 返回0表示成功,否则返回错误码
+ */
+int hmm_reg_user_mr_update(struct hinic5_hwdev *hwdev, struct hmm_mr *mr,
+ u32 pdn, u64 length, u64 virt_addr, int access,
+ u32 service_type, u16 channel)
+{
+ int ret = 0;
+ u32 npages = 0;
+ u32 page_shift = 0;
+
+ mr->rdmamr.mtt.mtt_type = MTT_DMTT_TYPE;
+ npages = (u32)hmm_umem_page_count(mr->umem);
+ page_shift = (u32)(mr->umem->page_shift);
+ ret = hmm_alloc_tpt(hwdev, &mr->rdmamr.mpt, &mr->rdmamr.mtt, npages,
+ page_shift, service_type);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to alloc mpt and mtt, func_id(%d)\n",
+ __func__, __LINE__, hinic5_global_func_id(hwdev));
+ return ret;
+ }
+ mr->rdmamr.enabled = RDMA_MPT_EN_SW;
+
+ hmm_set_rdma_mr(&mr->rdmamr, RDMA_USER_MR, pdn, virt_addr, length,
+ (u32)access);
+
+ ret = hmm_umem_write_mtt(hwdev, &mr->rdmamr.mtt, mr->umem,
+ service_type);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to write mtt, func_id(%d)\n",
+ __func__, __LINE__, hinic5_global_func_id(hwdev));
+ goto err_write_mtt;
+ }
+
+ ret = hmm_rdma_enable_mpt(hwdev->adapter_hdl, hwdev, &mr->rdmamr,
+ channel);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to enable mpt of user mr, func_id(%d)\n",
+ __func__, __LINE__, hinic5_global_func_id(hwdev));
+ goto err_write_mtt;
+ }
+ return 0;
+
+err_write_mtt:
+ hmm_free_tpt(hwdev, &mr->rdmamr.mpt, &mr->rdmamr.mtt, service_type);
+ mr->rdmamr.enabled = HMM_MPT_DISABLED;
+ return ret;
+}
+
+/**
+ * @brief 注销HMM MR更新
+ * @param hwdev 硬件设备信息
+ * @param mr RDMA内存区域
+ * @param service_type 服务类型
+ * @param channel 通道号
+ *
+ * @details 在RDMA环境中管理MR的注销和更新。当一个MR不再需要时,可以通过这个函数将其注销,并更新相关的状态
+ *
+ * @return 返回0表示成功,否则返回错误码
+ */
+int hmm_dereg_mr_update(struct hinic5_hwdev *hwdev, struct hmm_rdma *mr,
+ u32 service_type, u16 channel)
+{
+ int ret = 0;
+ ret = hmm_rdma_disable_mpt(hwdev->adapter_hdl, hwdev, mr, service_type,
+ channel);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to disable mpt of mr, ret(%d)\n",
+ __func__, __LINE__, ret);
+ return ret;
+ }
+
+ hmm_free_tpt(hwdev, &mr->mpt, &mr->mtt, service_type);
+ mr->enabled = HMM_MPT_DISABLED;
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : hmm_reg_user_mr
+ Description : register MR for user
+ Input : void *hw_dev
+ u64 start
+ u64 length
+ u64 virt_addr
+ int hmm_acess
+ Output : None
+**************************************************************************** */
+struct hmm_mr *hmm_reg_user_mr(void *hw_dev, u64 start, u32 pd, u64 length,
+ u64 virt_addr, int hmm_acess, u32 service_type,
+ u16 channel)
+{
+ int ret = 0;
+ struct hmm_mr *mr = NULL;
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)hw_dev;
+
+ if (hwdev == NULL) {
+ pr_err("[HMM, ERR] %s(%d): hwdev is null\n", __func__,
+ __LINE__);
+ goto err_out;
+ }
+
+ mr = (struct hmm_mr *)kzalloc(sizeof(*mr), GFP_KERNEL);
+ if (mr == NULL) {
+ ret = -ENOMEM;
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to alloc memory for mr, func_id(%d)\n",
+ __func__, __LINE__, hinic5_global_func_id(hwdev));
+ goto err_out;
+ }
+
+ mr->hwdev = hwdev;
+ mr->rdmamr.iova = virt_addr;
+ mr->umem = hmm_umem_get(hw_dev, start, (size_t)length, hmm_acess, 0);
+ if (IS_ERR(mr->umem)) {
+ ret = (int)PTR_ERR(mr->umem);
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to get ib umem, func_id(%d)\n",
+ __func__, __LINE__, hinic5_global_func_id(hwdev));
+ goto err_free;
+ }
+
+ rcu_read_lock();
+ mr->umem->tgid = get_task_pid(current->group_leader, PIDTYPE_PID);
+ rcu_read_unlock();
+ ret = hmm_reg_user_mr_update(hwdev, mr, pd, length, virt_addr,
+ hmm_acess, service_type, channel);
+ if (ret != 0) {
+ goto err_get_umem;
+ }
+ return mr;
+
+err_get_umem:
+ hmm_umem_release(mr->umem);
+
+err_free:
+ kfree(mr);
+
+err_out:
+ return (struct hmm_mr *)ERR_PTR((long)ret);
+}
+
+/* ****************************************************************************
+ Prototype : hmm_dereg_mr
+ Description : dereg DMA_MR, user_MR or FRMR
+ Input : struct hmm_mr *mr
+ Output : None
+
+**************************************************************************** */
+int hmm_dereg_mr(struct hmm_mr *mr, u32 service_type, u16 channel)
+{
+ int ret = 0;
+ struct hinic5_hwdev *hwdev = NULL;
+
+ if (mr == NULL) {
+ pr_err("[HMM, ERR] %s(%d): Ibmr is null\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ hwdev = (struct hinic5_hwdev *)mr->hwdev;
+ ret = hmm_dereg_mr_update(hwdev, &mr->rdmamr, service_type, channel);
+ if (ret != 0) {
+ dev_err(hwdev->dev_hdl,
+ "[HMM, ERR] %s(%d): Failed to de-reg mr update, ret(%d), func_id(%d)\n",
+ __func__, __LINE__, ret, hinic5_global_func_id(hwdev));
+ return ret;
+ }
+
+ if (mr->umem) {
+ hmm_umem_release(mr->umem);
+ }
+ kfree(mr);
+ return ret;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mtt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mtt.c
new file mode 100644
index 000000000..b310e05ce
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_mtt.c
@@ -0,0 +1,586 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+
+ Description : implement the management of MPT, MTT
+***************************************************************************** */
+
+#include <linux/netdevice.h>
+#include "hmm_common.h"
+#include "hmm_em_inner.h"
+
+static int hmm_set_mtt_layer(const struct hmm_comp_priv *comp_priv,
+ struct mtt *mtt, u32 npages)
+{
+ u32 one_layer_flag = 0;
+ u64 two_layer_flag = 0;
+ u64 three_layer_flag = 0;
+
+ one_layer_flag = comp_priv->mtt_page_size / PA_SIZE;
+ two_layer_flag = ((u64)one_layer_flag) * ((u64)one_layer_flag);
+ three_layer_flag = (u64)one_layer_flag * two_layer_flag;
+
+ if (npages <= 1) {
+ mtt->mtt_layers = MTT_ZERO_LAYER;
+ } else if (npages <= one_layer_flag) {
+ mtt->mtt_layers = MTT_ONE_LAYER;
+ } else if (npages <= two_layer_flag) {
+ mtt->mtt_layers = MTT_TWO_LAYER;
+ } else if ((u64)npages <= three_layer_flag) {
+ mtt->mtt_layers = MTT_THREE_LAYER;
+ } else {
+ dev_err(comp_priv->dev,
+ "%s: Npages(0x%x) over range, ret(%d)\n", __FUNCTION__,
+ npages, -EINVAL);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#ifdef SIGN_MTT_EN
+
+static u16 hmm_gen_cmtt_sign(u64 mtt_base_gpa)
+{
+ u16 sign0 = (mtt_base_gpa >> CMTT_SIGN_SHIFT0) & CMTT_SIGN_MASK;
+ u16 sign1 = (mtt_base_gpa >> CMTT_SIGN_SHIFT1) & CMTT_SIGN_MASK;
+ u16 sign2 = (mtt_base_gpa >> CMTT_SIGN_SHIFT2) & CMTT_SIGN_MASK;
+ u16 cmtt_sign = ~(sign0 ^ sign1 ^ sign2);
+
+ cmtt_sign &= CMTT_SIGN_MASK;
+ return cmtt_sign;
+}
+
+static u16 hmm_gen_dmtt_sign(u64 mtt_base_gpa)
+{
+ u16 sign0 =
+ ((u16)(mtt_base_gpa >> DMTT_SIGN_SHIFT0) << DMTT_ADD_SHIFT0) &
+ DMTT_SIGN_MASK;
+ u16 sign1 = (mtt_base_gpa >> DMTT_SIGN_SHIFT1) & DMTT_SIGN_MASK;
+ u16 sign2 = (mtt_base_gpa >> DMTT_SIGN_SHIFT2) & DMTT_SIGN_MASK;
+ u16 sign3 = (mtt_base_gpa >> DMTT_SIGN_SHIFT3) & DMTT_SIGN_MASK;
+ u16 dmtt_sign = ~(sign0 ^ sign1 ^ sign2 ^ sign3);
+
+ dmtt_sign &= DMTT_SIGN_MASK;
+ return dmtt_sign;
+}
+
+u64 hmm_gen_mtt_sign(u64 mtt_base_gpa, enum mtt_data_type_e type)
+{
+ if (type == MTT_CMTT_TYPE) {
+ return hmm_gen_cmtt_sign(mtt_base_gpa);
+ }
+ return (u64)hmm_gen_dmtt_sign(mtt_base_gpa) << 1;
+}
+
+#endif
+
+static int hmm_find_mtt_page_list(struct hmm_comp_priv *comp_priv,
+ struct mtt_seg *mtt_seg, u32 npages,
+ u64 *page_list)
+{
+ void *vaddr = NULL;
+ u32 i = 0;
+ u32 mtt_index = 0;
+ u32 mtts_per_page = 0;
+
+ mtts_per_page = comp_priv->mtt_page_size / PA_SIZE;
+ if ((mtt_seg->offset % mtts_per_page) != 0) {
+ dev_err(comp_priv->dev,
+ "%s: First mtt isn't in the head of page, ret(%d)\n",
+ __FUNCTION__, -EINVAL);
+ return -EINVAL;
+ }
+
+ mtt_index = mtt_seg->offset;
+ for (i = 0; i < npages; i++) {
+ vaddr = hmm_em_table_find(&comp_priv->mtt_em_table, mtt_index,
+ &page_list[i]);
+ if (vaddr == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Can't find va and pa of mtt entry, ret(%d)\n",
+ __FUNCTION__, -EINVAL);
+ return -EINVAL;
+ }
+
+ mtt_index += comp_priv->mtt_page_size / PA_SIZE;
+ }
+
+ return 0;
+}
+
+static int hmm_write_mtt_chunk(struct hmm_comp_priv *comp_priv, struct mtt *mtt,
+ u32 mtt_level_index, u32 start_index, u32 npages,
+ const u64 *page_list)
+{
+ u32 i = 0;
+ u16 sign_val = 0;
+ __be64 *mtts = NULL;
+
+ mtts = (__be64 *)hmm_em_table_find(
+ &comp_priv->mtt_em_table,
+ mtt->mtt_seg[mtt_level_index]->offset + start_index, NULL);
+ if (mtts == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Can't find va and pa of mtt entry, ret(%d)\n",
+ __FUNCTION__, -EINVAL);
+ return -EINVAL;
+ }
+#ifdef SIGN_MTT_EN
+ sign_val =
+ (u16)(hmm_gen_mtt_sign(mtt->mtt_paddr, mtt->mtt_type) & 0xffff);
+#endif
+ for (i = 0; i < npages; i++) {
+ mtts[i] = cpu_to_be64(page_list[i] | MTT_PA_VALID |
+ (sign_val << 1));
+ }
+
+ return 0;
+}
+
+static int hmm_write_mtt_seg(struct hmm_comp_priv *comp_priv, struct mtt *mtt,
+ u32 mtt_level_index, u32 start_index, u32 npages,
+ u64 *page_list)
+{
+ int ret = 0;
+ u32 chunk = 0;
+ u32 mtts_per_page = 0;
+ u32 max_mtts_first_page = 0;
+ u32 tmp_npages = npages;
+ u32 tmp_start_index = start_index;
+ u64 *tmp_page_list = page_list;
+
+ /* caculate how may mtts fit in the first page */
+ mtts_per_page = comp_priv->mtt_page_size / PA_SIZE;
+ max_mtts_first_page =
+ mtts_per_page -
+ ((mtt->mtt_seg[mtt_level_index]->offset + tmp_start_index) %
+ mtts_per_page);
+
+ chunk = (tmp_npages < max_mtts_first_page) ? tmp_npages :
+ max_mtts_first_page;
+
+ while ((int)tmp_npages > 0) {
+ ret = hmm_write_mtt_chunk(comp_priv, mtt, mtt_level_index,
+ tmp_start_index, chunk,
+ tmp_page_list);
+ if (ret != 0) {
+ dev_err(comp_priv->dev,
+ "%s: Write mtt chunk failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ return ret;
+ }
+
+ tmp_npages -= chunk;
+ tmp_start_index += chunk;
+ tmp_page_list += chunk;
+
+ chunk = (tmp_npages < mtts_per_page) ? tmp_npages :
+ mtts_per_page;
+ }
+
+ return 0;
+}
+
+static int hmm_alloc_mtt_seg(struct hmm_comp_priv *comp_priv,
+ struct mtt_seg *mtt_seg)
+{
+ int ret = 0;
+ u32 seg_offset = 0;
+ u32 seg_order = 0;
+ u32 log_mtts_per_seg = 0;
+
+ log_mtts_per_seg = comp_priv->dev_cap.log_mtt_seg;
+
+ seg_order = (mtt_seg->order > log_mtts_per_seg) ?
+ (mtt_seg->order - log_mtts_per_seg) :
+ 0;
+ mtt_seg->order = seg_order + log_mtts_per_seg;
+
+ seg_offset = hmm_buddy_alloc(&comp_priv->mtt_buddy, seg_order);
+ if (seg_offset == HMM_INVALID_INDEX) {
+ dev_err(comp_priv->dev, "%s: Alloc mtt index failed\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ mtt_seg->offset = seg_offset << log_mtts_per_seg;
+
+ ret = hmm_em_table_get_range(
+ comp_priv->dev, &comp_priv->mtt_em_table, mtt_seg->offset,
+ mtt_seg->offset + (u32)(1U << mtt_seg->order) - 1);
+ if (ret != 0) {
+ dev_err(comp_priv->dev, "%s: Alloc mtt entry failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ goto err_get_entry;
+ }
+
+ mtt_seg->vaddr = hmm_em_table_find(&comp_priv->mtt_em_table,
+ mtt_seg->offset, &mtt_seg->paddr);
+ if (mtt_seg->vaddr == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Can't find start address of mtt_seg\n",
+ __FUNCTION__);
+ goto err_find_entry;
+ }
+
+ return 0;
+
+err_find_entry:
+ hmm_em_table_put_range(
+ comp_priv->dev, &comp_priv->mtt_em_table, mtt_seg->offset,
+ mtt_seg->offset + (u32)(1U << mtt_seg->order) - 1);
+
+err_get_entry:
+ hmm_buddy_free(&comp_priv->mtt_buddy, seg_offset, seg_order);
+
+ return -ENOMEM;
+}
+
+static void hmm_free_mtt_seg(struct hmm_comp_priv *comp_priv,
+ struct mtt_seg *mtt_seg)
+{
+ u32 seg_offset = 0;
+ u32 seg_order = 0;
+ int log_mtts_per_seg = 0;
+
+ hmm_em_table_put_range(comp_priv->dev, &comp_priv->mtt_em_table,
+ mtt_seg->offset,
+ mtt_seg->offset + (1U << mtt_seg->order) - 1);
+
+ log_mtts_per_seg = (int)comp_priv->dev_cap.log_mtt_seg;
+ seg_order = mtt_seg->order - (u32)log_mtts_per_seg;
+ seg_offset = mtt_seg->offset >> (unsigned int)log_mtts_per_seg;
+
+ hmm_buddy_free(&comp_priv->mtt_buddy, seg_offset, seg_order);
+}
+
+static int hmm_init_mtt_seg(struct hmm_comp_priv *comp_priv, struct mtt *mtt,
+ u32 npages)
+{
+ u32 i;
+ int ret;
+
+ if ((comp_priv == NULL) || (mtt == NULL)) {
+ pr_err("%s: Comp_priv or mtt is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (npages >= comp_priv->dev_cap.num_mtts) {
+ dev_err(comp_priv->dev,
+ "%s: Npages(0x%x) over range, ret(%d)\n", __FUNCTION__,
+ npages, -EINVAL);
+ return -EINVAL;
+ }
+
+ ret = hmm_set_mtt_layer(comp_priv, mtt, npages);
+ if (ret != 0) {
+ return ret;
+ }
+
+ mtt->mtt_seg = (struct mtt_seg **)kzalloc(
+ mtt->mtt_layers * sizeof(struct mtt_seg *), GFP_KERNEL);
+ if (mtt->mtt_seg == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Alloc memory for mtt->mtt_seg failed, ret(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < mtt->mtt_layers; i++) {
+ mtt->mtt_seg[i] = (struct mtt_seg *)kzalloc(
+ sizeof(struct mtt_seg), GFP_KERNEL);
+ if (mtt->mtt_seg[i] == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Alloc memory for mtt->mtt_seg[i] failed, ret(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ goto err_out;
+ }
+ }
+
+ return 0;
+
+err_out:
+ for (i = 0; i < mtt->mtt_layers; i++) {
+ if (mtt->mtt_seg[i]) {
+ kfree(mtt->mtt_seg[i]);
+ mtt->mtt_seg[i] = NULL;
+ }
+ }
+
+ kfree(mtt->mtt_seg);
+ mtt->mtt_seg = NULL;
+
+ return -ENOMEM;
+}
+
+static int hmm_mtt_alloc_prepare(void *hwdev, u32 npages, struct mtt *mtt,
+ struct hmm_comp_priv **comp_priv,
+ u32 service_type)
+{
+ int ret = 0;
+
+ if ((hwdev == NULL) || (mtt == NULL)) {
+ pr_err("%s: Hwdev or mtt is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ *comp_priv = get_hmm_comp_priv(hwdev, service_type);
+ if (*comp_priv == NULL) {
+ pr_err("%s: Comp_priv is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ ret = hmm_init_mtt_seg(*comp_priv, mtt, npages);
+ if (ret != 0) {
+ dev_err((*comp_priv)->dev,
+ "%s: Initialize mtt_seg failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int hmm_enable_mtt_related(struct hmm_comp_priv *comp_priv,
+ struct mtt *mtt, u32 low_layer_index)
+{
+ u64 *page_list = NULL;
+ struct mtt_seg *low_mtt_seg = NULL;
+ u32 npages = 0;
+ int ret = 0;
+
+ low_mtt_seg = mtt->mtt_seg[low_layer_index];
+ npages = (u32)((1UL << low_mtt_seg->order) /
+ (comp_priv->mtt_page_size / PA_SIZE));
+ page_list = (u64 *)kzalloc(npages * PA_SIZE, GFP_KERNEL);
+ if (page_list == NULL) {
+ dev_err(comp_priv->dev,
+ "%s: Alloc memory for page_list failed, ret(%d)\n",
+ __FUNCTION__, -ENOMEM);
+ return -ENOMEM;
+ }
+
+ ret = hmm_find_mtt_page_list(comp_priv, low_mtt_seg, npages, page_list);
+ if (ret != 0) {
+ dev_err(comp_priv->dev,
+ "%s: Can't find page_list of mtt_seg, ret(%d)\n",
+ __FUNCTION__, ret);
+ goto out;
+ }
+
+ ret = hmm_write_mtt_seg(comp_priv, mtt, low_layer_index + 1, 0, npages,
+ page_list);
+ if (ret != 0) {
+ dev_err(comp_priv->dev, "%s: Write mtt_seg failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ goto out;
+ }
+
+out:
+ kfree(page_list);
+
+ return ret;
+}
+
+static void hmm_cleanup_mtt_seg(struct mtt *mtt)
+{
+ u32 i = 0;
+
+ for (i = 0; i < mtt->mtt_layers; i++) {
+ if (mtt->mtt_seg[i]) {
+ kfree(mtt->mtt_seg[i]);
+ mtt->mtt_seg[i] = NULL;
+ }
+ }
+
+ kfree(mtt->mtt_seg);
+ mtt->mtt_seg = NULL;
+}
+
+int hmm_mtt_alloc(void *hwdev, u32 npages, u32 page_shift, struct mtt *mtt,
+ u32 service_type)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ int ret = 0;
+ u32 i = 0;
+ u32 cur_layer = 0;
+ u32 order = 0;
+ u32 tmp_npages = npages;
+
+ ret = hmm_mtt_alloc_prepare(hwdev, npages, mtt, &comp_priv,
+ service_type);
+ if (ret != 0) {
+ return ret;
+ }
+
+ for (cur_layer = 1; cur_layer <= mtt->mtt_layers; cur_layer++) {
+ tmp_npages = (tmp_npages < HMM_MTT_NUM_PER_CACHELINE) ?
+ HMM_MTT_NUM_PER_CACHELINE :
+ tmp_npages;
+ for (i = 1; i < tmp_npages; i <<= 1) {
+ order++;
+ }
+
+ mtt->mtt_seg[cur_layer - 1]->order = order;
+ ret = hmm_alloc_mtt_seg(comp_priv, mtt->mtt_seg[cur_layer - 1]);
+ if (ret != 0) {
+ dev_err(comp_priv->dev,
+ "%s: Alloc mtt_seg failed, npages(%u), ret(%d)\n",
+ __FUNCTION__, tmp_npages, ret);
+ goto err_out;
+ }
+
+ tmp_npages = (u32)(1U << mtt->mtt_seg[cur_layer - 1]->order) /
+ (comp_priv->mtt_page_size / PA_SIZE);
+ order = 0;
+ }
+ if (mtt->mtt_layers > 0) {
+ mtt->mtt_vaddr =
+ (__be64 *)mtt->mtt_seg[mtt->mtt_layers - 1]->vaddr;
+ mtt->mtt_paddr = mtt->mtt_seg[mtt->mtt_layers - 1]->paddr;
+ }
+ for (i = 1; i < mtt->mtt_layers; i++) {
+ ret = hmm_enable_mtt_related(comp_priv, mtt, i - 1);
+ if (ret != 0) {
+ dev_err(comp_priv->dev,
+ "%s: Cant't get multi mtt_seg related, i(%u), ret(%d)\n",
+ __FUNCTION__, i, ret);
+ goto err_out;
+ }
+ }
+ mtt->buf_page_shift = page_shift;
+ mtt->mtt_page_shift = comp_priv->mtt_page_shift;
+ return 0;
+err_out:
+ for (i = cur_layer - 1; i > 0; i--) {
+ hmm_free_mtt_seg(comp_priv, mtt->mtt_seg[i - 1]);
+ }
+ hmm_cleanup_mtt_seg(mtt);
+ return -ENOMEM;
+}
+
+void hmm_mtt_free(void *hwdev, struct mtt *mtt, u32 service_type)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ u32 i = 0;
+
+ if ((hwdev == NULL) || (mtt == NULL)) {
+ pr_err("%s: Hwdev or mtt is null\n", __FUNCTION__);
+ return;
+ }
+
+ comp_priv = get_hmm_comp_priv(hwdev, service_type);
+ if (comp_priv == NULL) {
+ pr_err("%s: Comp_priv is null\n", __FUNCTION__);
+ return;
+ }
+
+ if (mtt->mtt_layers == 0) {
+ return;
+ }
+
+ for (i = 0; i < mtt->mtt_layers; i++) {
+ hmm_free_mtt_seg(comp_priv, mtt->mtt_seg[i]);
+ }
+
+ hmm_cleanup_mtt_seg(mtt);
+}
+
+int hmm_mtt_write(void *hwdev, struct mtt *mtt, u32 start_index, u32 npages,
+ u64 *page_list, u32 service_type)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ int ret = 0;
+
+ if ((hwdev == NULL) || (mtt == NULL) || page_list == NULL) {
+ pr_err("%s: Hwdev or mtt or page_list is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ comp_priv = get_hmm_comp_priv(hwdev, service_type);
+ if (comp_priv == NULL) {
+ pr_err("%s: Comp_priv is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (mtt->mtt_layers == 0) {
+ mtt->mtt_paddr = page_list[0];
+ return 0;
+ }
+
+ ret = hmm_write_mtt_seg(comp_priv, mtt, 0, start_index, npages,
+ page_list);
+ if (ret != 0) {
+ dev_err(comp_priv->dev, "%s: Write mtt seg failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int hmm_mtt_init(struct hmm_comp_priv *comp_priv)
+{
+ int ret = 0;
+ u32 i = 0;
+ u32 max_order = 0;
+ u32 mtt_num = 0;
+ u32 mtt_size = 0;
+ u32 log_mtts_per_seg = 0;
+
+ if (comp_priv == NULL || comp_priv->dev == NULL) {
+ pr_err("%s: comp_priv(%d) or comp_priv->dev is null\n",
+ __FUNCTION__, !!comp_priv);
+ return -EINVAL;
+ }
+
+ mtt_num = comp_priv->dev_cap.num_mtts;
+ log_mtts_per_seg = comp_priv->dev_cap.log_mtt_seg;
+ mtt_size = comp_priv->dev_cap.mtt_entry_sz;
+
+ for (i = 1; i < mtt_num; i <<= 1) {
+ max_order++;
+ }
+
+ max_order = (max_order > log_mtts_per_seg) ?
+ (max_order - log_mtts_per_seg) :
+ 0;
+
+ ret = hmm_buddy_init(&comp_priv->mtt_buddy, max_order);
+ if (ret != 0) {
+ dev_err(comp_priv->dev,
+ "%s: Initialize mtt's buddy failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ return ret;
+ }
+
+ ret = hmm_em_init_table(
+ comp_priv->dev, &comp_priv->mtt_em_table, mtt_size, mtt_num, 0,
+ (int)(comp_priv->mtt_page_shift - PAGE_SHIFT_4K));
+ if (ret != 0) {
+ dev_err(comp_priv->dev,
+ "%s: Initialize mtt's em_table failed, ret(%d)\n",
+ __FUNCTION__, ret);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ hmm_buddy_cleanup(&comp_priv->mtt_buddy);
+
+ return ret;
+}
+
+void hmm_mtt_cleanup(struct hmm_comp_priv *comp_priv)
+{
+ if (comp_priv == NULL || comp_priv->dev == NULL) {
+ pr_err("%s: comp_priv or comp_priv->dev is null\n",
+ __FUNCTION__);
+ return;
+ }
+
+ hmm_em_cleanup_table(comp_priv->dev, &comp_priv->mtt_em_table);
+
+ hmm_buddy_cleanup(&comp_priv->mtt_buddy);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem.c
new file mode 100644
index 000000000..4f9b4a7f9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem.c
@@ -0,0 +1,404 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ Description : get the dma sglist from virtal memory address
+***************************************************************************** */
+
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/signal.h>
+#include <linux/sched/mm.h>
+#include <linux/sched/signal.h>
+#include <linux/hugetlb.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include "hinic5_rdma.h"
+#include "hinic5_hwdev.h"
+#include "hmm_umem_inner.h"
+
+struct hmm_resource_bundle {
+ struct hmm_umem *hmem;
+ struct page **page_list;
+ struct vm_area_struct **vma_list;
+ int need_release;
+ unsigned long locked_pages;
+ unsigned long current_base;
+ unsigned long npages;
+};
+
+static void hmm_umemsg_release(struct device *device, struct hmm_umem *hmm_umem,
+ int dirty)
+{
+ struct scatterlist *sg = NULL;
+ struct page *page = NULL;
+ int i = 0;
+
+ if (hmm_umem->nmap > 0)
+ dma_unmap_sg(device, hmm_umem->sg_head.sgl, hmm_umem->npages,
+ DMA_BIDIRECTIONAL);
+
+ for_each_sg(hmm_umem->sg_head.sgl, sg, hmm_umem->npages, i) {
+ page = sg_page(sg);
+ if (!PageDirty(page) && hmm_umem->writable && dirty)
+ set_page_dirty_lock(page);
+ put_page(page);
+ }
+
+ sg_free_table(&hmm_umem->sg_head);
+ return;
+}
+
+static int hmm_umem_get_check(struct device *device, unsigned long addr,
+ size_t size, int access)
+{
+ /*
+ * If the combination of the addr and size requested for this memory
+ * region causes an integer overflow, return error.
+ */
+ if (((addr + size) < addr) || PAGE_ALIGN(addr + size) < (addr + size)) {
+ return -EINVAL;
+ }
+
+ if (can_do_mlock() == 0) {
+ return -EPERM;
+ }
+
+ if ((access & HMM_UMEM_ACCESS_ON_DEMAND) != 0) {
+ dev_err(device, "[HMM, ERR] %s(%d): don't support odp \n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hmm_alloc_and_init_hmm_res(struct hmm_resource_bundle *hmm_res,
+ struct device *device, unsigned long addr,
+ size_t size, int access)
+{
+ int ret;
+
+ ret = hmm_umem_get_check(device, addr, size, access);
+ if (ret != 0) {
+ return ret;
+ }
+
+ hmm_res->hmem = kzalloc(sizeof(struct hmm_umem), GFP_KERNEL);
+ if (hmm_res->hmem == NULL) {
+ return -ENOMEM;
+ }
+
+ hmm_res->page_list = (struct page **)__get_free_page(GFP_KERNEL);
+ if (hmm_res->page_list == NULL) {
+ kfree(hmm_res->hmem);
+ return -ENOMEM;
+ }
+ /* We assume the memory is from hugetlb until proved otherwise */
+ hmm_res->hmem->hugetlb = 1;
+
+ /*
+ * if we can't alloc the vma_list, it's not so bad;
+ * just assume the memory is not hugetlb memory
+ */
+ hmm_res->vma_list =
+ (struct vm_area_struct **)__get_free_page(GFP_KERNEL);
+ if (hmm_res->vma_list == NULL) {
+ hmm_res->hmem->hugetlb = 0;
+ }
+
+ hmm_res->hmem->device = device;
+ hmm_res->hmem->length = size;
+ hmm_res->hmem->address = addr;
+ hmm_res->hmem->page_shift = PAGE_SHIFT;
+ /*
+ * We ask for writable memory if any of the following
+ * access flags are set. "Local write" and "remote write"
+ * obviously require write access. "Remote atomic" can do
+ * things like fetch and add, which will modify memory, and
+ * "MW bind" can change permissions by binding a window.
+ */
+ hmm_res->hmem->writable =
+ !!(access &
+ (HMM_UMEM_ACCESS_LOCAL_WRITE | HMM_UMEM_ACCESS_REMOTE_WRITE |
+ HMM_UMEM_ACCESS_REMOTE_ATOMIC | HMM_UMEM_ACCESS_MW_BIND));
+ hmm_res->hmem->odp_data = NULL;
+ hmm_res->npages = hmm_umem_num_pages(hmm_res->hmem);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
+ down_write(¤t->mm->mmap_sem);
+#else
+ mmap_write_lock(current->mm);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
+ hmm_res->locked_pages = hmm_res->npages + current->mm->pinned_vm;
+#else
+ hmm_res->locked_pages =
+ hmm_res->npages + atomic64_read(¤t->mm->pinned_vm);
+#endif
+ hmm_res->current_base = addr & PAGE_MASK;
+ return 0;
+}
+
+static struct hmm_umem *
+hmm_umem_get_final_report(struct hmm_resource_bundle *hmm_res,
+ struct device *device, int ret)
+{
+ if (ret < 0) {
+ if (hmm_res->need_release != 0) {
+ hmm_umemsg_release(device, hmm_res->hmem, 0);
+ }
+ kfree(hmm_res->hmem);
+ } else {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
+ current->mm->pinned_vm = hmm_res->locked_pages;
+#else
+ atomic64_set(¤t->mm->pinned_vm, hmm_res->locked_pages);
+#endif
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
+ up_write(¤t->mm->mmap_sem);
+#else
+ mmap_write_unlock(current->mm);
+#endif
+ if (hmm_res->vma_list != NULL) {
+ free_page((unsigned long)(uintptr_t)hmm_res->vma_list);
+ }
+ free_page((unsigned long)(uintptr_t)hmm_res->page_list);
+ return (ret < 0) ? ERR_PTR(ret) : hmm_res->hmem;
+}
+
+static int hmm_check_hmm_res_status(struct hmm_resource_bundle *hmm_res)
+{
+ unsigned long lock_limit;
+
+ lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+ if ((hmm_res->locked_pages > lock_limit) && !capable(CAP_IPC_LOCK)) {
+ return -EINVAL;
+ }
+ if (hmm_res->npages == 0 || hmm_res->npages > UINT_MAX) {
+ return -EINVAL;
+ }
+ if (sg_alloc_table(&hmm_res->hmem->sg_head,
+ (unsigned int)hmm_res->npages, GFP_KERNEL) != 0) {
+ return -ENOMEM;
+ }
+
+ hmm_res->need_release = 1;
+ return 0;
+}
+
+#ifdef HAVE_GET_USER_PAGES_8_PARAMS
+static inline int hmm_get_user_pages(struct hmm_resource_bundle *hmm_res)
+{
+ return get_user_pages(current, current->mm, hmm_res->current_base,
+ min_t(unsigned long, hmm_res->npages,
+ PAGE_SIZE / sizeof(struct page *)),
+ 1, !hmm_res->hmem->writable, hmm_res->page_list,
+ hmm_res->vma_list);
+}
+#else
+#if defined(HAVE_GET_USER_PAGES_LONGTERM) && \
+ LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+#define GET_USER_PAGES_FUN get_user_pages_longterm
+#else
+#define GET_USER_PAGES_FUN get_user_pages
+#endif
+
+static inline int hmm_get_user_pages(struct hmm_resource_bundle *hmm_res)
+{
+#ifdef HAVE_GET_USER_PAGES_GUP_FLAGS
+ unsigned int gup_flags = FOLL_WRITE;
+
+ if (hmm_res->hmem->writable == 0) {
+ gup_flags |= FOLL_FORCE;
+ }
+ return GET_USER_PAGES_FUN(hmm_res->current_base,
+ min_t(unsigned long, hmm_res->npages,
+ PAGE_SIZE / sizeof(struct page *)),
+ gup_flags, hmm_res->page_list,
+ hmm_res->vma_list);
+#else
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
+ return GET_USER_PAGES_FUN(hmm_res->current_base,
+ min_t(unsigned long, hmm_res->npages,
+ PAGE_SIZE / sizeof(struct page *)),
+ 1, hmm_res->page_list);
+#else
+ return GET_USER_PAGES_FUN(hmm_res->current_base,
+ min_t(unsigned long, hmm_res->npages,
+ PAGE_SIZE / sizeof(struct page *)),
+ 1, hmm_res->page_list, hmm_res->vma_list);
+#endif
+
+#endif
+}
+#endif
+
+static int hmm_handle_hmm_res(struct hmm_resource_bundle *hmm_res)
+{
+ int i = 0;
+ struct scatterlist *sg = NULL;
+ struct scatterlist *sg_list_start = NULL;
+ int ret;
+
+ sg_list_start = hmm_res->hmem->sg_head.sgl;
+ while (hmm_res->npages != 0) {
+ ret = hmm_get_user_pages(hmm_res);
+ if (ret < 0) {
+ return ret;
+ }
+ hmm_res->hmem->npages += ret;
+ hmm_res->current_base += ret * PAGE_SIZE;
+ hmm_res->npages = (unsigned long)(hmm_res->npages - ret);
+
+ for_each_sg(sg_list_start, sg, ret, i) {
+ if (hmm_res->vma_list != NULL &&
+ !is_vm_hugetlb_page(hmm_res->vma_list[i])) {
+ hmm_res->hmem->hugetlb = 0;
+ }
+ sg_set_page(sg, hmm_res->page_list[i], PAGE_SIZE, 0);
+ }
+
+ /* preparing for next loop */
+ sg_list_start = sg;
+ }
+
+ return 0;
+}
+
+/**
+ * hmm_umem_get - Pin and DMA map userspace memory.
+ *
+ * If access flags indicate ODP memory, avoid pinning. Instead, stores
+ * the mm for future page fault handling in conjunction with MMU notifiers.
+ *
+ * @context: userspace context to pin memory for
+ * @addr: userspace virtual address to start at
+ * @size: length of region to pin
+ * @access: RDMA_IB_ACCESS_xxx flags for memory being pinned
+ * @dmasync: flush in-flight DMA when the memory region is written
+ */
+struct hmm_umem *hmm_umem_get(void *hwdev, unsigned long addr, size_t size,
+ int access, int dmasync)
+{
+ int ret;
+ struct hmm_resource_bundle hmm_res = { 0 };
+ struct device *device = NULL;
+#ifdef HAVE_STRUCT_DMA_ATTRS
+ DEFINE_DMA_ATTRS(dma_attrs);
+#else
+ unsigned long dma_attrs = 0;
+#endif
+
+ if (hwdev == NULL) {
+ return ERR_PTR(-EINVAL);
+ }
+ device = ((struct hinic5_hwdev *)hwdev)->dev_hdl;
+ ret = hmm_alloc_and_init_hmm_res(&hmm_res, device, addr, size, access);
+ if (ret != 0) {
+ return ERR_PTR(ret);
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)
+ if (dmasync) {
+#ifdef HAVE_STRUCT_DMA_ATTRS
+ dma_set_attr(DMA_ATTR_WRITE_BARRIER, &dma_attrs);
+#else
+ dma_attrs |= DMA_ATTR_WRITE_BARRIER;
+#endif
+ }
+#endif
+
+ ret = hmm_check_hmm_res_status(&hmm_res);
+ if (ret != 0) {
+ goto out;
+ }
+ ret = hmm_handle_hmm_res(&hmm_res);
+ if (ret != 0) {
+ goto out;
+ }
+
+#ifdef HAVE_STRUCT_DMA_ATTRS
+ hmm_res.hmem->nmap = dma_map_sg_attrs(device, hmm_res.hmem->sg_head.sgl,
+ hmm_res.hmem->npages,
+ DMA_BIDIRECTIONAL, &dma_attrs);
+#else
+ hmm_res.hmem->nmap = dma_map_sg_attrs(device, hmm_res.hmem->sg_head.sgl,
+ hmm_res.hmem->npages,
+ DMA_BIDIRECTIONAL, dma_attrs);
+#endif
+ if (hmm_res.hmem->nmap <= 0) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = 0;
+
+out:
+ return hmm_umem_get_final_report(&hmm_res, device, ret);
+}
+
+/**
+ * hmm_umem_release - release memory pinned with ib_umem_get
+ * @hmem: umem struct to release
+ */
+void hmm_umem_release(struct hmm_umem *hmem)
+{
+ struct mm_struct *mm = NULL;
+ struct task_struct *task = NULL;
+ unsigned long diff;
+
+ if (hmem->odp_data) {
+ pr_err("[HMM, ERR] %s(%d): Don't support odp \n", __func__,
+ __LINE__);
+ return;
+ }
+
+ hmm_umemsg_release(hmem->device, hmem, 1);
+ task = get_pid_task(hmem->tgid, PIDTYPE_PID);
+ if (task == NULL) {
+ goto out;
+ }
+ mm = get_task_mm(task);
+ put_task_struct(task);
+ if (mm == NULL) {
+ goto out;
+ }
+
+ diff = hmm_umem_num_pages(hmem);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
+ down_write(&mm->mmap_sem);
+#else
+ mmap_write_lock(mm);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
+ mm->pinned_vm -= diff;
+#else
+ atomic64_sub(diff, &mm->pinned_vm);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
+ up_write(&mm->mmap_sem);
+#else
+ mmap_write_unlock(mm);
+#endif
+ mmput(mm);
+out:
+ kfree(hmem);
+}
+
+u32 hmm_umem_page_count(struct hmm_umem *hmem)
+{
+ u32 i;
+ u32 n;
+ struct scatterlist *sg = NULL;
+
+ if (hmem->odp_data) {
+ return (u32)(hmm_umem_num_pages(hmem));
+ }
+
+ n = 0;
+ for_each_sg(hmem->sg_head.sgl, sg, hmem->nmap, i)
+ n += sg_dma_len(sg) >> ((u32)hmem->page_shift);
+
+ return n;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem_inner.h
new file mode 100644
index 000000000..ec7e88e95
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/hmm/hmm_umem_inner.h
@@ -0,0 +1,98 @@
+/* ***************************************************************************
+ Copyright (c) Huawei Technologies Co., Ltd. 2018-2021. All rights reserved.
+ Description : structure and interface about umem
+***************************************************************************** */
+
+#ifndef HMM_UMEM_H
+#define HMM_UMEM_H
+
+#include <linux/list.h>
+#include <linux/scatterlist.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+#include <linux/mmu_notifier.h>
+#include <linux/kernel.h>
+#include "hmm_common.h"
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_umem.h>
+
+/**
+ * @brief struct rb_root_cached_struct
+ * @details 用于缓存红黑树的根节点和最左边的节点
+ */
+struct rb_root_cached_struct {
+ struct rb_node *rb_root; /**< 红黑树的根节点 */
+ struct rb_node *rb_leftmost; /**< 红黑树中最左边的节点 */
+};
+
+enum hmm_umem_access {
+ HMM_UMEM_ACCESS_LOCAL_WRITE = 1,
+ HMM_UMEM_ACCESS_REMOTE_WRITE = (1 << 1),
+ HMM_UMEM_ACCESS_REMOTE_READ = (1 << 2),
+ HMM_UMEM_ACCESS_REMOTE_ATOMIC = (1 << 3),
+ HMM_UMEM_ACCESS_MW_BIND = (1 << 4),
+ HMM_UMEM_ACCESS_ZERO_BASED = (1 << 5),
+ HMM_UMEM_ACCESS_ON_DEMAND = (1 << 6),
+};
+
+/* Returns the offset of the umem start relative to the first page. */
+/**
+ * @brief 计算umem的偏移量
+ * @param umem 要计算的umem结构体指针
+ *
+ * @return 返回umem的偏移量
+ */
+static inline int hmm_umem_offset(const struct hmm_umem *umem)
+{
+ return umem->address & ~PAGE_MASK;
+}
+
+/* Returns the first page of an ODP umem. */
+/**
+ * @brief 计算用户内存的起始地址
+ * @param umem 用户内存结构体指针
+ *
+ * @return 用户内存的起始地址
+ */
+static inline unsigned long hmm_umem_start(struct hmm_umem *umem)
+{
+ return umem->address - hmm_umem_offset(umem);
+}
+
+/* Returns the address of the page after the last one of an ODP umem. */
+/**
+ * @brief 计算用户内存区域的结束地址
+ * @param umem 用户内存区域的指针
+ *
+ * @return 返回计算后的用户内存区域的结束地址
+ */
+static inline unsigned long hmm_umem_end(const struct hmm_umem *umem)
+{
+ return ALIGN(umem->address + umem->length,
+ BIT((unsigned int)umem->page_shift));
+}
+
+/**
+ * @brief 计算用户内存中的页面数量
+ * @param umem 用户内存结构体指针
+ *
+ * @return 页面数量
+ */
+static inline size_t hmm_umem_num_pages(struct hmm_umem *umem)
+{
+ return (size_t)(((unsigned long)(hmm_umem_end(umem) -
+ hmm_umem_start(umem))) >>
+ (unsigned long)umem->page_shift);
+}
+
+/**
+ * @brief 获取HMM用户内存的页面数量
+ * @param hmem 指向HMM用户内存的指针
+ *
+ * @return 返回页面数量
+ */
+u32 hmm_umem_page_count(struct hmm_umem *hmem);
+
+#endif /* HMM_UMEM_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.c
new file mode 100644
index 000000000..1adb16cf9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ *
+ * File Name : rdma_bitmap.c
+ * Version : v2.0
+ * Created : 2021/3/10
+ * Last Modified : 2021/12/23
+ * Description : The the management of RoCE bitmap.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": [RDMA]" fmt
+
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/bitmap.h>
+
+#include "rdma_bitmap.h"
+
+u32 rdma_bitmap_alloc(struct rdma_bitmap *bitmap)
+{
+ u32 index = 0;
+
+ if (bitmap == NULL) {
+ pr_err("Bitmap is null");
+ return RDMA_INVALID_INDEX;
+ }
+
+ spin_lock(&bitmap->lock);
+
+ index = (u32)find_next_zero_bit(bitmap->table,
+ (unsigned long)bitmap->max_num,
+ (unsigned long)bitmap->last);
+ if (index >= bitmap->max_num) {
+ bitmap->top =
+ (bitmap->top + bitmap->max_num + bitmap->reserved_top) &
+ bitmap->mask;
+ index = (u32)find_first_zero_bit(
+ bitmap->table, (unsigned long)bitmap->max_num);
+ }
+
+ if (index < bitmap->max_num) {
+ set_bit(index, bitmap->table);
+ bitmap->last = index + 1;
+ if (bitmap->last == bitmap->max_num) {
+ bitmap->last = 0;
+ }
+
+ index |= bitmap->top;
+ --bitmap->avail;
+ } else {
+ pr_err("Get a invalid index");
+ spin_unlock(&bitmap->lock);
+ return RDMA_INVALID_INDEX;
+ }
+
+ spin_unlock(&bitmap->lock);
+
+ return index;
+}
+
+void rdma_bitmap_free(struct rdma_bitmap *bitmap, u32 index)
+{
+ u32 index_tmp = index;
+ if (bitmap == NULL) {
+ pr_err("Bitmap is null");
+ return;
+ }
+
+ if (index_tmp >= bitmap->max_num) {
+ pr_err("Index(%d) is bigger or equal than max(%d)", index_tmp,
+ bitmap->max_num);
+ return;
+ }
+
+ index_tmp &= bitmap->max_num + bitmap->reserved_top - 1;
+
+ spin_lock(&bitmap->lock);
+
+ bitmap->last = min(bitmap->last, index_tmp);
+ bitmap->top = (bitmap->top + bitmap->max_num + bitmap->reserved_top) &
+ bitmap->mask;
+
+ bitmap_clear(bitmap->table, (int)index_tmp, 1);
+ ++bitmap->avail;
+ spin_unlock(&bitmap->lock);
+}
+
+int rdma_bitmap_init(struct rdma_bitmap *bitmap, u32 num, u32 mask,
+ u32 reserved_bot, u32 reserved_top)
+{
+ if (bitmap == NULL) {
+ pr_err("Bitmap is null");
+ return -EINVAL;
+ }
+
+ if (num & (num - 1)) {
+ pr_err("Num(%d) isn't pow of two, err(%d)", num, -EINVAL);
+ return -EINVAL;
+ }
+
+ if (num <= (reserved_bot + reserved_top)) {
+ pr_err("Reserved num is bigger than total num, err(%d)",
+ -EINVAL);
+ return -EINVAL;
+ }
+
+ bitmap->last = 0;
+ bitmap->top = 0;
+ bitmap->max_num = num - reserved_top;
+ bitmap->mask = mask;
+ bitmap->reserved_top = reserved_top;
+ bitmap->avail = (num - reserved_top) - reserved_bot;
+
+ spin_lock_init(&bitmap->lock);
+
+ bitmap->table = (unsigned long *)kzalloc(
+ BITS_TO_LONGS(bitmap->max_num) * sizeof(long), GFP_KERNEL);
+ if (bitmap->table == NULL) {
+ bitmap->table = (unsigned long *)vzalloc((
+ size_t)(BITS_TO_LONGS(bitmap->max_num) * sizeof(long)));
+ if (bitmap->table == NULL) {
+ pr_err("Failed to vzalloc bitmap->table, ret(%d)",
+ -ENOMEM);
+ return -ENOMEM;
+ }
+ }
+
+ bitmap_set(bitmap->table, 0, (int)reserved_bot);
+
+ return 0;
+}
+
+void rdma_bitmap_cleanup(struct rdma_bitmap *bitmap)
+{
+ if (bitmap == NULL) {
+ pr_err("Bitmap is null");
+ return;
+ }
+
+ if (is_vmalloc_addr(bitmap->table)) {
+ vfree(bitmap->table);
+ } else {
+ kfree(bitmap->table);
+ }
+
+ bitmap->table = NULL;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.h
new file mode 100644
index 000000000..8047b8af2
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/rdma/rdma_bitmap.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ *
+ * File Name : rdma_bitmap.h
+ * Version : v2.0
+ * Created : 2021/3/10
+ * Last Modified : 2021/12/23
+ * Description : define RoCE bitmap related macro and structure
+ */
+
+#ifndef RDMA_BITMAP_H
+#define RDMA_BITMAP_H
+
+#include <linux/spinlock.h>
+
+#ifndef RDMA_INVALID_INDEX
+#define RDMA_INVALID_INDEX 0xFFFFFFFF
+#endif
+
+struct rdma_bitmap {
+ u32 last; /* bottom of available id */
+ u32 top; /* top value of non zone of id */
+ u32 max_num; /* max id num */
+ u32 reserved_top; /* unavailable top num */
+ u32 mask; /* mask of id */
+ u32 avail; /* num of available id */
+ spinlock_t lock; /* spinlock of bitmap */
+ unsigned long *table; /* memory of bitmap */
+};
+
+u32 rdma_bitmap_alloc(struct rdma_bitmap *bitmap);
+
+void rdma_bitmap_free(struct rdma_bitmap *bitmap, u32 index);
+
+int rdma_bitmap_init(struct rdma_bitmap *bitmap, u32 num, u32 mask,
+ u32 reserved_bot, u32 reserved_top);
+
+void rdma_bitmap_cleanup(struct rdma_bitmap *bitmap);
+
+#endif // __RDMA_BITMAP_H__
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_lld_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_lld_common.h
new file mode 100644
index 000000000..f5859b628
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_lld_common.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2026 Huawei Technologies Co., Ltd */
+
+#ifndef HINIC5_LLD_COMMON_H
+#define HINIC5_LLD_COMMON_H
+
+#include <linux/pci.h>
+
+#include "hinic5_lld.h"
+
+/**
+ * @brief hinic5_get_lld_dev_by_dev - get lld device by dev
+ * @param device: 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 返回lld设备
+ */
+struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev(struct device *dev);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram.h
new file mode 100644
index 000000000..9e2385bd4
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2022 Huawei Technologies Co., Ltd */
+
+#ifndef HINIC5_VRAM
+#define 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;
+
+ hiudk_dev_flush_infos flush_infos[CMD_MAX_MAX_PF_NUM];
+} hiudk_async_ctrl;
+
+int wait5_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_vram_init(void);
+void hisdk5_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/vram_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/vram_common.h
new file mode 100644
index 000000000..c5dd00daa
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/vram_common.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+ * Description: Header File, vram common
+ * Create: 2023/7/19
+ */
+#ifndef VRAM_COMMON_H
+#define VRAM_COMMON_H
+
+#if !defined(__UEFI__) && !defined(__WIN__)
+#include <linux/notifier.h>
+#include <linux/numa.h>
+#endif
+
+#define VRAM_BLOCK_SIZE_2M 0x200000UL
+#define KEXEC_SIGN "hinic-in-kexec"
+// now vram_name max len is 14, when add other vram, attention this value
+#define VRAM_NAME_SIZE 15
+#define VRAM_NAME_MAX_LEN 16
+
+#define VRAM_CQM_GLB_FUNC_BASE "F"
+#define VRAM_CQM_FAKE_MEM_BASE "FK"
+#define VRAM_CQM_CLA_BASE "C"
+#define VRAM_CQM_CLA_TYPE_BASE "T"
+#define VRAM_CQM_CLA_SMF_BASE "M"
+#define VRAM_CQM_CLA_COORD_X "X"
+#define VRAM_CQM_CLA_COORD_Y "Y"
+#define VRAM_CQM_CLA_COORD_Z "Z"
+#define VRAM_CQM_BITMAP_BASE "B"
+
+#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
+#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_FUNC_BASE "NIC_F"
+
+#define VRAM_NIC_MQM "NM"
+
+#define VRAM_VBS_IOCB "IOCB"
+#define VRAM_VBS_RXQS_CQE "RCQE"
+#define VRAM_VBS_NAME_BASE "VBS_"
+#define VRAM_VBS_VOLQ_MTT "VOLQMTT"
+#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
+#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
+#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
+#define VRAM_VROCE_UUID "VROCE_UUID"
+#define VRAM_VROCE_VID "VROCE_VID"
+#define VRAM_VROCE_BASE "VROCE_BASE"
+#define VRAM_VROCE_DSCP "VROCE_DSCP"
+#define VRAM_VROCE_QOS "VROCE_QOS"
+#define VRAM_VROCE_DEV "VROCE_DEV"
+#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
+#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define MPU_OS_HOTREPLACE_FLAG 0x1
+
+#define USE_VRAM 1
+#define NO_USE_VRAM 0
+
+#define OS_HOT_REPLACE_DOING 1
+#define OS_HOT_REPLACE_DONE 0
+
+#define VRAM_NUMA_NODE_NUM 2
+
+/* 从运行时所在的CPU申请 */
+#define VRAM_AFFINITY_NUMA 0xfe
+
+/* 不指定NUMA, 从空闲NUMA申请 */
+#define 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 hi5_vram_kalloc(name, size) 0
+#define vram5_get_kexec_flag() 0
+#define hi5_vram_get_gfp_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 *(*vram_kalloc_t)(char *name, u64 size);
+typedef void __iomem *(*vpmem_kalloc_node_t)(char *name, u64 size, u8 numa);
+typedef void (*vram_kfree_t)(void __iomem *vaddr, char *name, u64 size);
+typedef gfp_t (*vram_get_gfp_vram_t)(void);
+
+/**
+ * @brief init vram related symbols
+ **/
+void lookup5_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 vram memory
+ * @param name name of vram memory
+ * @param size size of vram memory
+ **/
+void __iomem *hi5_vram_kalloc(char *name, u64 size);
+/**
+ * @brief get gfp of vram for dma
+ * @return
+ * - gfp_t from sdi_nanoos
+ **/
+gfp_t hi5_vram_get_gfp_vram(void);
+/**
+ * @brief set kexec status
+ * @param status 1 : doing kexec, 0 : done kexec
+ * @return
+ * - Zero if successful. Non-zero otherwise.
+ **/
+int hi5_set_kexec_status(int status);
+/**
+ * @brief get kexec status
+ * @return
+ * - Zero if successful. Non-zero otherwise.
+ **/
+int hi5_get_kexec_status(void);
+/**
+ * @brief set use-vram flag
+ * @param flag: true : use vram, false : don't use vram
+ **/
+void set5_use_vram_flag(bool flag);
+/**
+ * @brief get kexec flag
+ * @return
+ * - 0: done kexec
+ * - 1: doing kexec
+ **/
+int vram5_get_kexec_flag(void);
+
+#endif
+
+#endif /* VRAM_COMMON_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.c
new file mode 100644
index 000000000..34858736b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#include "ossl_knl.h"
+#include "hinic5_cqm.h"
+#include "cqm_npu_cmd.h"
+#include "cqm_cmdq.h"
+#include "cqm_main.h"
+#include "cqm_npu_cmd_defs.h"
+#include "cqm_182x_cmdq_ops.h"
+
+static s32 prepare_cmd_buf_bat_update(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_bat_update_param *param,
+ u8 *cmd)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct cqm_182x_bat_update_cmd *cmd_data = buf_in->buf;
+ u8 *bat = NULL;
+ int ret;
+
+ cmd_data->offset = param->bat_offset / 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;
+ ret = memcpy_s(cmd_data->data, CQM_BAT_MAX_SIZE, bat,
+ param->update_size);
+ if (ret != 0) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "memcpy_s failed, size %u, err %d\n",
+ param->update_size, ret);
+ return CQM_FAIL;
+ }
+
+ cqm_swab32((u8 *)cmd_data,
+ sizeof(struct cqm_182x_bat_update_cmd) >> CQM_DW_SHIFT);
+ *cmd = (u8)CQM_CMD_T_BAT_UPDATE;
+
+ return CQM_SUCCESS;
+}
+
+static void prepare_cmd_buf_cla_update(cqm_cla_update_cmd_s *cmd_info,
+ struct tag_cqm_cmd_buf *buf_in, u8 *cmd)
+{
+ struct 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;
+
+ cqm_swab32((u8 *)cmd_data,
+ (sizeof(struct cqm_182x_cla_update_cmd) >> CQM_DW_SHIFT));
+ *cmd = (u8)CQM_CMD_T_CLA_UPDATE;
+}
+
+static void prepare_cmd_cache_invalidate(cqm_cla_cache_invalid_cmd_s *cmd_info,
+ struct tag_cqm_cmd_buf *buf_in,
+ u8 *cmd)
+{
+ struct 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;
+
+ cqm_swab32((u8 *)cmd_data,
+ /* shift 2 bits by right to get length of dw(4B) */
+ (sizeof(struct cqm_182x_cla_cache_invalid_cmd) >>
+ CQM_DW_SHIFT));
+ *cmd = (u8)CQM_CMD_T_CLA_CACHE_INVALID;
+}
+
+struct cqm_cmdq_ops *cqm_cmdq_get_182x_ops(void)
+{
+ static struct 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/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.h
new file mode 100644
index 000000000..a4a9f6d18
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef _CQM_182X_CMDQ_PRIVATE_H_
+#define _CQM_182X_CMDQ_PRIVATE_H_
+
+#include "ossl_knl.h"
+#include "cqm_npu_cmd_defs.h"
+
+struct cqm_182x_bat_update_cmd {
+ u32 offset; /* byte offset,16Byte aligned */
+ u32 byte_len; /* max size: 256byte */
+ u8 data[CQM_BAT_MAX_SIZE];
+ u32 smf_id;
+ u32 func_id;
+};
+
+struct 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 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/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.c
new file mode 100644
index 000000000..c194347ee
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#include "ossl_knl.h"
+#include "hinic5_cqm.h"
+#include "cqm_cmdq.h"
+#include "cqm_main.h"
+#include "cqm_npu_cmd_defs.h"
+#include "cqm_187x_cmdq_ops.h"
+
+static s32 prepare_cmd_buf_bat_update(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_bat_update_param *param,
+ u8 *cmd)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct cqm_187x_bat_update_cmd *cmd_data = buf_in->buf;
+ u8 *bat = NULL;
+ int ret;
+
+ cmd_data->offset = param->bat_offset / 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;
+ ret = memcpy_s(cmd_data->data, CQM_BAT_MAX_SIZE, bat,
+ param->update_size);
+ if (ret != 0) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "memcpy_s failed, size %u, err %d\n",
+ param->update_size, ret);
+ return CQM_FAIL;
+ }
+
+ cqm_swab32((u8 *)cmd_data,
+ sizeof(struct cqm_187x_bat_update_cmd) >> CQM_DW_SHIFT);
+ *cmd = (u8)CQM_HTN_CMD_T_BAT_UPDATE;
+
+ return CQM_SUCCESS;
+}
+
+static void prepare_cmd_buf_cla_update(cqm_cla_update_cmd_s *cmd_info,
+ struct tag_cqm_cmd_buf *buf_in, u8 *cmd)
+{
+ struct 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;
+
+ cqm_swab32((u8 *)cmd_data,
+ (sizeof(struct cqm_187x_cla_update_cmd) >> CQM_DW_SHIFT));
+ *cmd = (u8)CQM_HTN_CMD_T_CLA_UPDATE;
+}
+
+static void prepare_cmd_cache_invalidate(cqm_cla_cache_invalid_cmd_s *cmd_info,
+ struct tag_cqm_cmd_buf *buf_in,
+ u8 *cmd)
+{
+ struct 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;
+
+ cqm_swab32((u8 *)cmd_data,
+ /* shift 2 bits by right to get length of dw(4B) */
+ (sizeof(struct cqm_187x_cla_cache_invalid_cmd) >> 2));
+ *cmd = (u8)CQM_HTN_CMD_T_CLA_CACHE_INVALID;
+}
+
+struct cqm_cmdq_ops *cqm_cmdq_get_187x_ops(void)
+{
+ static struct 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/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.h
new file mode 100644
index 000000000..5251c0110
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef _CQM_187X_CMDQ_PRIVATE_H_
+#define _CQM_187X_CMDQ_PRIVATE_H_
+
+#include "ossl_knl.h"
+#include "cqm_npu_cmd_defs.h"
+
+struct 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[CQM_BAT_MAX_SIZE];
+};
+
+struct 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 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 */
+};
+
+/* CQM HTN CMD */
+enum cqm_htn_cmd {
+ CQM_HTN_CMD_T_CLA_CACHE_INVALID = 0x20,
+ CQM_HTN_CMD_T_BAT_UPDATE,
+ CQM_HTN_CMD_T_CLA_UPDATE
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.c
new file mode 100644
index 000000000..a3935f129
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.c
@@ -0,0 +1,2745 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "hisdk5_hwif.h"
+#include "hinic5_hw_comm.h"
+#include "hinic5_hw_cfg.h"
+#include "hinic5_vram_api.h"
+#include "hisdk5_typedef.h"
+
+#include "cqm_object.h"
+#include "cqm_bitmap_table.h"
+#include "cqm_cmd.h"
+#include "cqm_object_intern.h"
+#include "cqm_main.h"
+#include "cqm_bat_cla.h"
+
+#include "comm_defs.h"
+#include "cqm_npu_cmd.h"
+#include "cqm_npu_cmd_defs.h"
+#include "cqm_cmdq.h"
+
+#include "vram_common.h"
+
+static unsigned char cqm_ver = 8;
+module_param(cqm_ver, byte, 0444);
+MODULE_PARM_DESC(cqm_ver, "for cqm version control (default=8)");
+
+static bool cqm_cla_hugepage_hint = false;
+module_param(cqm_cla_hugepage_hint, bool, 0444);
+MODULE_PARM_DESC(
+ cqm_cla_hugepage_hint,
+ "Hint for hugepage alloc to improve TLB locality (default false). "
+ "This option only impacts QPC and Timer Spoke Lists.");
+
+#ifdef __CQM_DEBUG__
+bool cqm_verbose = false;
+module_param(cqm_verbose, bool, 0644);
+#endif
+
+static inline u32 get_cacheline_size(u32 entry_type)
+{
+ /* The cacheline of the timer is changed to 512. */
+ if (entry_type == CQM_BAT_ENTRY_T_TIMER && cqm_ver == 0x8)
+ return CQM_CHIP_TIMER_CACHELINE;
+
+ return CQM_CHIP_CACHELINE;
+}
+
+static void cqm_bat_fill_cla_common_gpa(
+ struct tag_cqm_handle *cqm_handle, struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
+{
+ u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
+ struct hinic5_func_attr *func_attr = NULL;
+ struct tag_cqm_bat_entry_vf2pf gpa = { 0 };
+ u32 cla_gpa_h = 0;
+ dma_addr_t pa;
+
+ if (cla_table->cla_lvl == CQM_CLA_LVL_0)
+ pa = cla_table->cla_z_buf.buf_list[0].pa;
+ else if (cla_table->cla_lvl == 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 = CQM_ADDR_HI(pa) & CQM_CHIP_GPA_HIMASK;
+ gpa.acs_spu_en = cqm_get_acs_spu_en(cqm_handle);
+
+ /* In fake mode, fake_vf_en in the GPA address of the BAT
+ * must be set to 1.
+ */
+ if (CQM_IS_FAKE_CHILD_AGENT(cqm_handle)) {
+ gpa.fake_vf_en = 1;
+ func_attr = &cqm_handle->parent_cqm_handle->func_attribute;
+ gpa.pf_id = func_attr->func_global_idx;
+ } else {
+ gpa.fake_vf_en = 0;
+ }
+
+ (void)memcpy_s(&cla_gpa_h, sizeof(u32), &gpa, sizeof(u32));
+ bat_entry_standerd->cla_gpa_h = cla_gpa_h;
+
+ /* GPA is valid when gpa[0] = 1.
+ * CQM_BAT_ENTRY_T_REORDER does not support GPA validity check.
+ */
+ if (cla_table->type == CQM_BAT_ENTRY_T_REORDER)
+ bat_entry_standerd->cla_gpa_l = CQM_ADDR_LW(pa);
+ else
+ bat_entry_standerd->cla_gpa_l = CQM_ADDR_LW(pa) |
+ gpa_check_enable;
+
+ cqm_info(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 cqm_bat_fill_cla_common(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u8 *entry_base_addr)
+{
+ struct tag_cqm_bat_entry_standerd *bat_entry_standerd = NULL;
+ u32 cache_line = get_cacheline_size(cla_table->type);
+
+ if (cla_table->obj_num == 0) {
+ cqm_dbg(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_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 == CQM_OBJECT_512)
+ bat_entry_standerd->entry_size = CQM_BAT_ENTRY_SIZE_512;
+ else
+ bat_entry_standerd->entry_size =
+ CQM_BAT_ENTRY_SIZE_1024;
+ bat_entry_standerd->max_number =
+ cla_table->max_buffer_size / cla_table->obj_size;
+ } else {
+ if (cache_line == CQM_CHIP_CACHELINE) {
+ bat_entry_standerd->entry_size = CQM_BAT_ENTRY_SIZE_256;
+ bat_entry_standerd->max_number =
+ cla_table->max_buffer_size / cache_line;
+ } else {
+ bat_entry_standerd->entry_size = 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 = 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;
+
+ cqm_bat_fill_cla_common_gpa(cqm_handle, cla_table, bat_entry_standerd);
+}
+
+static void cqm_bat_fill_cla_cfg(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u8 **entry_base_addr)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct tag_cqm_bat_entry_cfg *bat_entry_cfg = NULL;
+
+ bat_entry_cfg = (struct tag_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 >> CQM_HASH_NUMBER_UNIT) != 0) {
+ bat_entry_cfg->bucket_num =
+ ((func_cap->hash_number >> 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_cqm_bat_entry_cfg);
+}
+
+static void cqm_bat_fill_cla_other(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u8 **entry_base_addr)
+{
+ cqm_bat_fill_cla_common(cqm_handle, cla_table, *entry_base_addr);
+
+ (*entry_base_addr) += sizeof(struct tag_cqm_bat_entry_standerd);
+}
+
+static void cqm_bat_fill_cla_taskmap(struct tag_cqm_handle *cqm_handle,
+ const struct tag_cqm_cla_table *cla_table,
+ u8 **entry_base_addr)
+{
+ struct tag_cqm_bat_entry_taskmap *bat_entry_taskmap = NULL;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 i;
+
+ if (cqm_handle->func_capability.taskmap_number != 0) {
+ u32 taskmap_buf_num = min(cla_table->cla_z_buf.buf_number,
+ (u32)CQM_BAT_ENTRY_TASKMAP_NUM);
+
+ bat_entry_taskmap =
+ (struct tag_cqm_bat_entry_taskmap *)(*entry_base_addr);
+ for (i = 0; i < taskmap_buf_num; i++) {
+ bat_entry_taskmap->addr[i].gpa_h =
+ (u32)(cla_table->cla_z_buf.buf_list[i].pa >>
+ CQM_CHIP_GPA_HSHIFT);
+ bat_entry_taskmap->addr[i].gpa_l =
+ (u32)(cla_table->cla_z_buf.buf_list[i].pa &
+ CQM_CHIP_GPA_LOMASK);
+ 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_cqm_bat_entry_taskmap);
+}
+
+static void cqm_bat_fill_cla_timer(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u8 **entry_base_addr)
+{
+ /* Only the PPF allocates timer resources. */
+ if (!CQM_IS_PPF(cqm_handle)) {
+ (*entry_base_addr) += CQM_BAT_ENTRY_SIZE;
+ } else {
+ cqm_bat_fill_cla_common(cqm_handle, cla_table,
+ *entry_base_addr);
+
+ (*entry_base_addr) += sizeof(struct tag_cqm_bat_entry_standerd);
+ }
+}
+
+static void cqm_bat_fill_cla_invalid(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u8 **entry_base_addr)
+{
+ (*entry_base_addr) += CQM_BAT_ENTRY_SIZE;
+}
+
+/**
+ * Prototype : cqm_bat_fill_cla
+ * Description : Fill the base address of the CLA table into the BAT table.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+static void cqm_bat_fill_cla(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ u32 entry_type = 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 < CQM_BAT_ENTRY_MAX; i++) {
+ cqm_dbg_on(cqm_verbose, 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 == CQM_BAT_ENTRY_T_CFG) {
+ cqm_bat_fill_cla_cfg(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (entry_type == CQM_BAT_ENTRY_T_TASKMAP) {
+ cqm_bat_fill_cla_taskmap(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (entry_type == CQM_BAT_ENTRY_T_INVALID) {
+ cqm_bat_fill_cla_invalid(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (entry_type == CQM_BAT_ENTRY_T_TIMER) {
+ if (CQM_IS_PPF(cqm_handle) &&
+ CQM_IS_LB_MODE_1_OR_2(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_cqm_bat_entry_standerd);
+ continue;
+ }
+
+ cqm_bat_fill_cla_timer(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (entry_type == CQM_BAT_ENTRY_T_HASH) {
+ if (CQM_IS_LB_MODE_1_OR_2(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_cqm_bat_entry_standerd);
+ continue;
+ }
+
+ cqm_bat_fill_cla_other(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (entry_type == CQM_BAT_ENTRY_T_XID2CID) {
+ if (COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev) &&
+ CQM_IS_LB_MODE_1_OR_2(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_cqm_bat_entry_standerd);
+ continue;
+ }
+
+ cqm_bat_fill_cla_other(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else {
+ cqm_bat_fill_cla_other(cqm_handle, cla_table,
+ &entry_base_addr);
+ }
+
+ /* Check whether entry_base_addr is out-of-bounds array. */
+ if (entry_base_addr >=
+ (bat_table->bat + CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE))
+ break;
+ }
+}
+
+u32 cqm_lb0_get_smf_id(const struct tag_cqm_handle *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 = cqm_handle->func_attribute.func_global_idx & 0x3;
+ /* if smf2 and smf3 are disabled, only select smf0/smf1 */
+ if ((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 = 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 */
+ (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 cqm_funcid2smfid(const struct tag_cqm_handle *cqm_handle)
+{
+ /* When the LB mode is disabled, SMF0 is always returned. */
+ if (CQM_IS_LB_MODE_NORMAL(cqm_handle))
+ return 0;
+ if (CQM_IS_LB_MODE_0(cqm_handle))
+ return cqm_lb0_get_smf_id(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 cqm_update_bat_gpa(struct tag_cqm_handle *cqm_handle, u32 smf_id)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ u32 entry_type = CQM_BAT_ENTRY_T_INVALID;
+ u8 *entry_base_addr = bat_table->bat;
+ u32 i = 0;
+
+ if (!CQM_IS_LB_MODE_1_OR_2(cqm_handle))
+ return;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ entry_type = bat_table->bat_entry_type[i];
+ if (CQM_IS_PPF(cqm_handle) &&
+ entry_type == CQM_BAT_ENTRY_T_TIMER) {
+ cla_table = &bat_table->timer_entry[smf_id];
+ cqm_bat_fill_cla_timer(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (entry_type == CQM_BAT_ENTRY_T_HASH) {
+ cla_table = &bat_table->hash_entry[smf_id];
+ cqm_bat_fill_cla_other(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else if (COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev) &&
+ entry_type == CQM_BAT_ENTRY_T_XID2CID) {
+ cla_table = &bat_table->xid2cid_entry[smf_id];
+ cqm_bat_fill_cla_other(cqm_handle, cla_table,
+ &entry_base_addr);
+ } else {
+ if (entry_type == CQM_BAT_ENTRY_T_TASKMAP)
+ entry_base_addr += sizeof(
+ struct tag_cqm_bat_entry_taskmap);
+ else
+ entry_base_addr += CQM_BAT_ENTRY_SIZE;
+ }
+
+ /* Check whether entry_base_addr is out-of-bounds array. */
+ if (entry_base_addr >=
+ (bat_table->bat + CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE))
+ break;
+ }
+}
+
+static s32 cqm_bat_update_smf_cmd(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_bat_update_param *param)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct cqm_cmdq_ops *ops = cqm_handle->cmdq_ops;
+ u8 cmd;
+ bool illegal_args = true;
+ s32 ret = CQM_FAIL;
+
+ illegal_args =
+ (param->bat_offset % CQM_BAT_ENTRY_SIZE != 0) ||
+ (param->update_size % CQM_BAT_ENTRY_SIZE != 0) ||
+ (param->update_size == 0) ||
+ (param->bat_offset + param->update_size > bat_table->bat_size);
+ if (unlikely(illegal_args)) {
+ cqm_err(handle->dev_hdl,
+ "Bat update: invalid args, bat_offset %u, update_size %u.",
+ param->bat_offset, param->update_size);
+ return CQM_FAIL;
+ }
+
+ 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(cqm_handle, buf_in, param, &cmd);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(prepare_cmd_buf_bat_update));
+ return CQM_FAIL;
+ }
+
+ cqm_dbg_byte_print(handle->dev_hdl, (u32 *)bat_table->bat,
+ sizeof(bat_table->bat));
+
+ ret = cqm5_send_cmd_box((void *)(handle), CQM_MOD_CQM, cmd, buf_in,
+ NULL, NULL, CQM_CMD_TIMEOUT,
+ HINIC5_CHANNEL_DEFAULT);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm5_send_cmd_box));
+ cqm_err(handle->dev_hdl, "%s: send_cmd_box ret=%d\n", __func__,
+ ret);
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_bat_update_smf(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in, u32 smf_id,
+ u32 func_id)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_bat_update_param param = { 0 };
+ struct hinic5_bat_entry_config l3i_config = { 0 };
+ int is_in_kexec;
+ s32 ret = CQM_FAIL;
+
+ is_in_kexec = vram5_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl,
+ "Skip updating the cqm_bat to chip during kexec!");
+ return CQM_SUCCESS;
+ }
+
+ if (bat_table->bat_size > CQM_BAT_MAX_SIZE) {
+ cqm_err(handle->dev_hdl,
+ "bat_size = %u, which is more than %d.",
+ bat_table->bat_size, CQM_BAT_MAX_SIZE);
+ return CQM_FAIL;
+ }
+
+ ret = hinic5_bat_get_l3i_entry_config(handle, &l3i_config);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl,
+ 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 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 = cqm_bat_update_smf_cmd(cqm_handle, buf_in, ¶m);
+ if (ret != 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 = cqm_bat_update_smf_cmd(cqm_handle, buf_in,
+ ¶m);
+ if (ret != CQM_SUCCESS)
+ goto cmd_err;
+ }
+ } else {
+ /* update all bat entries */
+ param.bat_offset = 0;
+ param.update_size = bat_table->bat_size;
+ ret = cqm_bat_update_smf_cmd(cqm_handle, buf_in, ¶m);
+ if (ret != CQM_SUCCESS)
+ goto cmd_err;
+ }
+
+ return CQM_SUCCESS;
+
+cmd_err:
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_update_smf_cmd));
+ return ret;
+}
+
+static s32 cqm_bat_update_all_smf(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in, u32 func_id)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ u32 smf_id = 0;
+ s32 ret = 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;
+
+ cqm_update_bat_gpa(cqm_handle, smf_id);
+ ret = cqm_bat_update_smf(cqm_handle, buf_in, smf_id, func_id);
+ if (ret != 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 cqm_bat_update_lb(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in, u32 func_id)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+ u32 smf_id;
+
+ if (CQM_IS_LB_MODE_NORMAL(cqm_handle)) {
+ smf_id = cqm_funcid2smfid(cqm_handle);
+ return cqm_bat_update_smf(cqm_handle, buf_in, smf_id, func_id);
+ }
+
+ if (CQM_IS_LB_MODE_0(cqm_handle)) {
+ if (CQM_IS_PPF(cqm_handle))
+ return cqm_bat_update_all_smf(cqm_handle, buf_in,
+ func_id);
+ smf_id = cqm_funcid2smfid(cqm_handle);
+ return cqm_bat_update_smf(cqm_handle, buf_in, smf_id, func_id);
+ }
+
+ if (CQM_IS_LB_MODE_1(cqm_handle) || CQM_IS_LB_MODE_2(cqm_handle))
+ return cqm_bat_update_all_smf(cqm_handle, buf_in, func_id);
+
+ cqm_err(hwdev->dev_hdl, "Bat update: unsupported lb mode=%u\n",
+ cqm_handle->func_capability.lb_mode);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_bat_update
+ * Description : Send a command to tile to update the BAT table through cmdq.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+static s32 cqm_bat_update(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ s32 ret = CQM_FAIL;
+ u32 func_id = 0;
+
+ /* The BAT is maintained by the parent function. */
+ if (CQM_IS_FAKE_CHILD(cqm_handle)) {
+ cqm_err(hwdev->dev_hdl,
+ "Bat update: unsupported for fake child\n");
+ return CQM_FAIL;
+ }
+
+ buf_in = cqm5_cmd_alloc((void *)(cqm_handle->ex_handle));
+ if (unlikely((buf_in) == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(buf_in));
+ return 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 (CQM_IS_FAKE_CHILD_AGENT(cqm_handle))
+ func_id = cqm_handle->func_attribute.func_global_idx;
+ else
+ func_id = 0xffff;
+
+ ret = cqm_bat_update_lb(cqm_handle, buf_in, func_id);
+
+ cqm5_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
+ return ret;
+}
+
+static inline u32
+bat_entry_type_init_ft_rdma(struct tag_cqm_bat_table *bat_table)
+{
+ u32 i = 0;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_CFG;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_HASH;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_QPC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_SCQC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_SRQC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_MPT;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_GID;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_LUN;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_TASKMAP;
+ return i;
+}
+
+static inline u32 bat_entry_type_init_ft(struct tag_cqm_bat_table *bat_table)
+{
+ u32 i = 0;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_CFG;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_HASH;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_QPC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_SCQC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_LUN;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_TASKMAP;
+ return i;
+}
+
+static inline u32 bat_entry_type_init_rdma(struct tag_cqm_bat_table *bat_table)
+{
+ u32 i = 0;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_QPC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_SCQC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_SRQC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_MPT;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_GID;
+ return i;
+}
+
+static inline s32
+bat_entry_type_init_pf_parts(struct tag_cqm_bat_table *bat_table,
+ u32 entry_start)
+{
+ u32 i = entry_start;
+
+ if (WARN_ON_ONCE(entry_start + 0x5 >= CQM_BAT_ENTRY_MAX))
+ return CQM_FAIL;
+
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_L3I;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_CHILDC;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_TIMER;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_XID2CID;
+ bat_table->bat_entry_type[i++] = CQM_BAT_ENTRY_T_REORDER;
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_bat_entry_type_init(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_bat_table *bat_table)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ enum func_type func_type = cqm_handle->func_attribute.func_type;
+ bool is_pf = (func_type == CQM_PF) || (func_type == CQM_PPF);
+ bool has_pf_parts = is_pf || capability->vf_bat_expanded;
+ u32 i;
+
+ if (WARN_ON_ONCE(!cqm_func_type_valid(func_type)))
+ return CQM_FAIL;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++)
+ bat_table->bat_entry_type[i] = CQM_BAT_ENTRY_T_INVALID;
+
+ if (capability->ft_enable && capability->rdma_enable) {
+ bat_table->bat_size = has_pf_parts ? CQM_BAT_SIZE_FT_RDMA_PF :
+ CQM_BAT_SIZE_FT_RDMA_VF;
+ i = bat_entry_type_init_ft_rdma(bat_table);
+ } else if (capability->ft_enable) {
+ bat_table->bat_size = has_pf_parts ? CQM_BAT_SIZE_FT_PF :
+ CQM_BAT_SIZE_FT_VF;
+ i = bat_entry_type_init_ft(bat_table);
+ } else if (capability->rdma_enable) {
+ bat_table->bat_size = has_pf_parts ? CQM_BAT_SIZE_RDMA_PF :
+ CQM_BAT_SIZE_RDMA_VF;
+ i = bat_entry_type_init_rdma(bat_table);
+ } else {
+ bat_table->bat_size = has_pf_parts ? CQM_BAT_SIZE_PF :
+ CQM_BAT_SIZE_VF;
+ i = 0;
+ }
+
+ if (has_pf_parts)
+ return bat_entry_type_init_pf_parts(bat_table, i);
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : 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_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+s32 cqm_bat_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+
+ (void)memset_s(bat_table, sizeof(struct tag_cqm_bat_table), 0,
+ sizeof(struct tag_cqm_bat_table));
+
+ return cqm_bat_entry_type_init(cqm_handle, bat_table);
+}
+
+STATIC s32 cqm_cla_reset(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ struct tag_cqm_cla_reset_cmd *cmd_data = NULL;
+ int ret = CQM_SUCCESS;
+
+ buf_in = cqm5_cmd_alloc(handle);
+ if (unlikely(!buf_in)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(buf_in));
+ return CQM_FAIL;
+ }
+
+ cmd_data = buf_in->buf;
+ ret = memset_s(cmd_data, buf_in->size, 0, sizeof(*cmd_data));
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ "Cla reset: memset fail, buf size %u, count %lu, ret %d\n",
+ buf_in->size, sizeof(*cmd_data), ret);
+ goto out;
+ }
+
+ cmd_data->func_id = hinic5_global_func_id(handle);
+ cqm_swab32((u8 *)cmd_data,
+ sizeof(struct tag_cqm_cla_reset_cmd) >> CQM_DW_SHIFT);
+ ret = cqm5_send_cmd_box(handle, CQM_MOD_CQM, CQM_CMD_T_CLA_RESET,
+ buf_in, NULL, NULL, CQM_CMD_TIMEOUT,
+ HINIC5_CHANNEL_DEFAULT);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm5_send_cmd_box));
+ }
+
+out:
+ cqm5_cmd_free(handle, buf_in);
+ return ret;
+}
+
+/**
+ * Prototype : cqm_bat_uninit
+ * Description : Deinitialize the BAT table.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 i;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++)
+ bat_table->bat_entry_type[i] = CQM_BAT_ENTRY_T_INVALID;
+
+ /* The BAT is maintained by the parent function.
+ Reset CLA instead of clear BAT. */
+ if (CQM_IS_FAKE_CHILD(cqm_handle)) {
+ cqm_cla_reset(cqm_handle);
+ return;
+ }
+
+ (void)memset_s(bat_table->bat, CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE,
+ 0, CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE);
+ /* Instruct the chip to update the BAT table. */
+ if (cqm_bat_update(cqm_handle) != CQM_SUCCESS)
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_update));
+}
+
+static u64 cqm_cla_chip_gpa_flags(struct tag_cqm_handle *cqm_handle,
+ u8 gpa_check_enable)
+{
+ struct hinic5_func_attr *func_attr = NULL;
+ u64 fake_en, spu_en, pf_id;
+
+ spu_en = ((u64)cqm_get_acs_spu_en(cqm_handle)) << 0x3F;
+
+ /* fake enable */
+ fake_en = 0;
+ pf_id = 0;
+ if (CQM_IS_FAKE_CHILD_AGENT(cqm_handle)) {
+ fake_en = 1ULL << 0x3E;
+ func_attr = &cqm_handle->parent_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 cqm_cla_map_buf(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *cla_base_buf,
+ const struct tag_cqm_buf *cla_sub_buf,
+ u32 base_offset, u32 sub_offset, u32 num,
+ u8 gpa_check_enable)
+{
+ struct hinic5_hwdev *handle = 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))) {
+ 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 CQM_FAIL;
+ }
+
+ gpa_flags = cqm_cla_chip_gpa_flags(cqm_handle, gpa_check_enable);
+
+ cqm_dbg(handle->dev_hdl,
+ "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 CQM_TIMER_FUNC_BUF_NUM 64
+ cqm_dbg_on(
+ i % CQM_TIMER_FUNC_BUF_NUM == 0, handle->dev_hdl,
+ "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) &
+ CQM_CHIP_GPA_MASK) |
+ gpa_flags);
+ cqm_swab64((u8 *)base, 1);
+
+ index_base_offset++;
+ index_sub_offset++;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *cla_base_buf,
+ struct tag_cqm_buf *cla_sub_buf,
+ u8 gpa_check_enable)
+{
+ struct hinic5_hwdev *handle = 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 = cqm_buf_alloc(cqm_handle, cla_base_buf, false);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
+ return ret;
+ }
+ }
+
+ /* Apply for space for sub_buf */
+ if (!cla_sub_buf->buf_list) {
+ ret = cqm_buf_alloc(cqm_handle, cla_sub_buf, false);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
+ cqm_buf_free(cla_base_buf, cqm_handle->dev);
+ return ret;
+ }
+ }
+
+ gpa_flags = cqm_cla_chip_gpa_flags(cqm_handle, gpa_check_enable);
+ cqm_dbg(handle->dev_hdl, "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) &
+ CQM_CHIP_GPA_MASK) |
+ gpa_flags);
+
+ 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 CQM_SUCCESS;
+}
+
+static void cqm_apply_new_buf(struct tag_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 cqm_cla_secure_mem_buf_alloc(struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_buf *buf)
+{
+ /* Applying for the buffer list descriptor space */
+ buf->buf_list =
+ vmalloc(buf->buf_number * sizeof(struct tag_cqm_buf_list));
+ if (unlikely(buf->buf_list == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(secure_mem_buf_alloc));
+ return CQM_FAIL;
+ }
+ (void)memset_s(buf->buf_list,
+ buf->buf_number * sizeof(struct tag_cqm_buf_list), 0,
+ buf->buf_number * sizeof(struct tag_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 = CQM_SECURE_BUFFER_EN;
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_cla_xyz_lvl0(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 trunk_size)
+{
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ s32 ret;
+
+ cla_table->cla_lvl = 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 (cqm_cla_use_secure_mem(cla_table))
+ return cqm_cla_secure_mem_buf_alloc(cla_table, cla_z_buf);
+
+ ret = cqm_buf_alloc(cqm_handle, cla_z_buf, false);
+ if (unlikely(ret != CQM_SUCCESS))
+ cqm_warn(cqm_handle->dev,
+ "lvl_0_z_buf alloc fail. buf size 0x%x, ret %d.\n",
+ trunk_size, ret);
+ return ret;
+}
+
+static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 trunk_size)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ u32 shift = 0, z_buf_num;
+ u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
+ u32 cache_line = get_cacheline_size(cla_table->type);
+ s32 ret;
+
+ if (cla_table->type == CQM_BAT_ENTRY_T_REORDER)
+ gpa_check_enable = 0;
+
+ cla_table->cla_lvl = CQM_CLA_LVL_1;
+
+ shift = 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 = 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 */
+ cqm_apply_new_buf(cla_y_buf, trunk_size, 1, cla_table->trunk_order);
+ ret = cqm_buf_alloc(cqm_handle, cla_y_buf, false);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(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;
+ 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 = cqm_cla_fill_buf(cqm_handle, cla_y_buf, cla_z_buf,
+ gpa_check_enable);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_fill_buf));
+ /* cla_y_buf freed by cqm_cla_fill_buf() */
+ return ret;
+ }
+ } else { /* Only the buffer list space is initialized. The buffer space
+ * is dynamically allocated in services.
+ */
+ ret = cqm_buf_list_alloc(cla_z_buf);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
+ cqm_buf_free(cla_y_buf, cqm_handle->dev);
+ return ret;
+ }
+ }
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_cla_xyz_lvl2_param_init(struct tag_cqm_cla_table *cla_table,
+ u32 trunk_size)
+{
+ u32 shift = 0;
+ u32 cache_line = get_cacheline_size(cla_table->type);
+
+ cla_table->cla_lvl = CQM_CLA_LVL_2;
+
+ shift = cqm_shift(trunk_size / cla_table->obj_size);
+ cla_table->z = ((shift != 0) ? (shift - 1) : (shift));
+ shift = 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 = cqm_shift(trunk_size / cache_line);
+ cla_table->cacheline_z = ((shift != 0) ? (shift - 1) : (shift));
+ shift = 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 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u32 trunk_size)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_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_vram = get5_use_vram_flag();
+ ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(handle->dev_hdl, 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 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
+ struct hinic5_hwdev *handle)
+{
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ const int use_vram = get5_use_vram_flag();
+ int ret;
+
+ cla_x_buf->buf_info.use_vram = use_vram;
+ ret = snprintf_s(cla_x_buf->buf_info.buf_vram_name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ if (ret < 0) {
+ cqm_err(handle->dev_hdl,
+ "cqm cla x vram name snprintf_s failed, cla_table->name:%s",
+ cla_table->name);
+ return CQM_FAIL;
+ }
+
+ cla_y_buf->buf_info.use_vram = use_vram;
+ ret = snprintf_s(cla_y_buf->buf_info.buf_vram_name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ if (ret < 0) {
+ cqm_err(handle->dev_hdl,
+ "cqm cla y vram name snprintf_s failed");
+ return CQM_FAIL;
+ }
+
+ cla_z_buf->buf_info.use_vram = use_vram;
+ ret = snprintf_s(cla_z_buf->buf_info.buf_vram_name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
+ if (ret < 0) {
+ cqm_err(handle->dev_hdl,
+ "cqm cla z vram name snprintf_s failed");
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 trunk_size)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ s32 ret = CQM_FAIL;
+ u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
+
+ cqm_cla_xyz_lvl2_param_init(cla_table, trunk_size);
+
+ ret = cqm_cla_xyz_lvl2_xyz_apply(cqm_handle, cla_table, trunk_size);
+ if (ret != CQM_SUCCESS)
+ return ret;
+
+ if (cla_table->type == 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 = cqm_cla_fill_buf(cqm_handle, cla_y_buf, cla_z_buf,
+ gpa_check_enable);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_fill_buf));
+ cqm_buf_free(cla_x_buf, 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)cqm_cla_fill_buf(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 = cqm_buf_list_alloc(cla_z_buf);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
+ cqm_buf_free(cla_x_buf, cqm_handle->dev);
+ return ret;
+ }
+
+ ret = cqm_buf_list_alloc(cla_y_buf);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
+ cqm_buf_free(cla_z_buf, cqm_handle->dev);
+ cqm_buf_free(cla_x_buf, cqm_handle->dev);
+ return ret;
+ }
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_cla_xyz_lvl2_timer_xyz_apply(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u32 trunk_size)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_func_capability *cap = &cqm_handle->func_capability;
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ u32 timer_func_num, timer_number, actual_buffer_size;
+ s32 ret;
+
+ ret = cqm_cla_xyz_lvl2_xyz_apply(cqm_handle, cla_table, trunk_size);
+ if (ret != CQM_SUCCESS)
+ return ret;
+
+ /* Apply for space for CLA_Y_BUF */
+ if (unlikely(cqm_buf_alloc(cqm_handle, cla_y_buf, false) !=
+ CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
+ cqm_buf_free(cla_x_buf, cqm_handle->dev);
+ return CQM_FAIL;
+ }
+
+ /* Ref: cqm_capability_init_timer() */
+ timer_func_num = cap->timer_pf_num + cap->timer_vf_num_actual;
+ timer_number = CQM_TIMER_ALIGN_SCALE_NUM * timer_func_num;
+ /* Ref: cqm_bat_entry_init_timer() */
+ actual_buffer_size = timer_number * cap->timer_basic_size;
+
+ /* Ref: 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(cqm_buf_alloc(cqm_handle, cla_z_buf, false) !=
+ CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
+ cqm_buf_free(cla_y_buf, cqm_handle->dev);
+ cqm_buf_free(cla_x_buf, cqm_handle->dev);
+ return CQM_FAIL;
+ }
+
+ 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 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 cqm_cla_xyz_lvl2_timer(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u32 trunk_size)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ u8 gpa_check_enable = 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 cqm_cla_xyz_lvl2(cqm_handle, cla_table, trunk_size);
+
+ func_cap->timer_vf_deploy_with_segs = true;
+
+ cqm_cla_xyz_lvl2_param_init(cla_table, trunk_size);
+
+ if (cqm_cla_xyz_lvl2_timer_xyz_apply(cqm_handle, cla_table,
+ trunk_size) != CQM_SUCCESS)
+ return CQM_FAIL;
+
+ func_timer_size =
+ 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 (cqm_cla_map_buf(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) == 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 (cqm_cla_map_buf(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) == 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)cqm_cla_fill_buf(cqm_handle, cla_x_buf, cla_y_buf,
+ gpa_check_enable);
+
+ return CQM_SUCCESS;
+
+mapping_buf_fail:
+ 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);
+ cqm_buf_free(cla_z_buf, cqm_handle->dev);
+ cqm_buf_free(cla_y_buf, cqm_handle->dev);
+ cqm_buf_free(cla_x_buf, cqm_handle->dev);
+ return CQM_FAIL;
+}
+
+static inline int min_order_for_cla_obj(struct tag_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 CQM_CLA_LVL_0;
+ if (max_size <= buf_size * buf_addr_cap)
+ return CQM_CLA_LVL_1;
+ if (max_size <= buf_size * buf_addr_cap * buf_addr_cap)
+ return CQM_CLA_LVL_2;
+ return CQM_CLA_LVL_UNSUPPORT;
+}
+
+static s32 cqm_cla_xyz_alloc(struct tag_cqm_handle *cqm_handle,
+ struct tag_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 == CQM_CLA_LVL_0) {
+ ret = cqm_cla_xyz_lvl0(cqm_handle, cla_table, buf_size);
+ if (unlikely(ret != CQM_SUCCESS))
+ cqm_warn(cqm_handle->dev,
+ CQM_FUNCTION_FAIL(cqm_cla_xyz_lvl0));
+ return ret;
+ }
+
+ /* Level-1 CLA
+ * Allocates CLA_Y_BUF and CLA_Z_BUF during initialization.
+ */
+ if (cla_lvl == CQM_CLA_LVL_1) {
+ ret = cqm_cla_xyz_lvl1(cqm_handle, cla_table, buf_size);
+ if (unlikely(ret != CQM_SUCCESS))
+ cqm_warn(cqm_handle->dev,
+ CQM_FUNCTION_FAIL(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 == CQM_CLA_LVL_2) {
+ if (cla_table->type == CQM_BAT_ENTRY_T_TIMER) {
+ ret = cqm_cla_xyz_lvl2_timer(cqm_handle, cla_table,
+ buf_size);
+ if (unlikely(ret != CQM_SUCCESS))
+ cqm_warn(cqm_handle->dev,
+ CQM_FUNCTION_FAIL(
+ cqm_cla_xyz_lvl2_timer));
+ return ret;
+ } else {
+ ret = cqm_cla_xyz_lvl2(cqm_handle, cla_table, buf_size);
+ if (unlikely(ret != CQM_SUCCESS))
+ cqm_warn(cqm_handle->dev,
+ CQM_FUNCTION_FAIL(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.
+ */
+ cqm_err(cqm_handle->dev,
+ "Cla alloc: cla max_buffer_size 0x%x exceeds support range\n",
+ cla_table->max_buffer_size);
+ return CQM_FAIL;
+}
+
+/**
+ * Try hugepages for CLA tables, fallback to 4K pages.
+ * Fallback is limited to alloc_pages() failures during CLA buffers init.
+ */
+static s32 cqm_cla_xyz_hugepage(struct tag_cqm_handle *cqm_handle,
+ struct tag_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;
+
+ cqm_dbg(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 = cqm_cla_xyz_alloc(cqm_handle, cla_table, (u32)order);
+ if (ret == CQM_BUF_ALLOC_BUDDY_PAGES_FAIL) {
+ cqm_warn(cqm_handle->dev,
+ "Cla alloc: insufficient pages (order %d).\n",
+ order);
+ continue;
+ }
+
+ if (unlikely(ret != CQM_SUCCESS))
+ cqm_err(cqm_handle->dev,
+ CQM_FUNCTION_FAIL(cqm_cla_xyz_alloc));
+ return ret;
+ }
+
+ return CQM_FAIL;
+}
+
+static s32 cqm_cla_xyz_check(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ /* Check whether obj_size is 2^n-aligned. An error is reported when
+ * obj_size is 0 or 1.
+ */
+ if (!cqm_check_align(cla_table->obj_size)) {
+ 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 CQM_FAIL;
+ }
+
+ if (min_order_for_cla_obj(cla_table) > MAX_ORDER) {
+ cqm_err(cqm_handle->dev,
+ "Cla alloc: cla_type %u, obj_size 0x%x is too big\n",
+ cla_table->type, cla_table->obj_size);
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_cla_xyz
+ * Description : Calculate the number of levels of CLA tables and allocate
+ * space for each level of CLA table.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * struct tag_cqm_cla_table *cla_table
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+STATIC s32 cqm_cla_xyz(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ s32 ret = CQM_FAIL;
+
+ /* The BAT and CLA of the Fake VF are maintained by the parent function. */
+ if (CQM_IS_FAKE_CHILD(cqm_handle)) {
+ 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 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) {
+ cqm_info(
+ handle->dev_hdl,
+ "Cla alloc: cla_type %u, obj_num 0, don't alloc buffer\n",
+ cla_table->type);
+ return CQM_SUCCESS;
+ }
+
+ 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 = cqm_cla_xyz_check(cqm_handle, cla_table);
+ if (ret != CQM_SUCCESS)
+ return ret;
+
+ ret = cqm_cla_xyz_vram_name_init(cla_table, handle);
+ if (ret != CQM_SUCCESS)
+ return ret;
+
+ /* Try hugepages for CLA tables. */
+ if (unlikely(cla_table->hugepage_hint))
+ return cqm_cla_xyz_hugepage(cqm_handle, cla_table);
+
+ /* Build CLA tables with specified page order. */
+ if ((int)cla_table->trunk_order < min_order_for_cla_obj(cla_table)) {
+ 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 CQM_FAIL;
+ }
+ return cqm_cla_xyz_alloc(cqm_handle, cla_table, cla_table->trunk_order);
+}
+
+static void update_entry_cap_for_secure_mem(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ if (!cqm_cla_use_secure_mem(cla_table))
+ 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;
+ 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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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 (cqm_cla_hugepage_hint)
+ cla_table->hugepage_hint = true;
+}
+
+static void init_scqc_entry_cap(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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;
+}
+
+static void init_srqc_entry_cap(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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;
+}
+
+static void init_mpt_entry_cap(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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;
+}
+
+static void init_gid_entry_cap(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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 = 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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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 = CQM_4K_PAGE_ORDER;
+ cla_table->alloc_static = true;
+}
+
+static void init_l3i_entry_cap(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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 = CQM_8K_PAGE_ORDER;
+ cla_table->alloc_static = true;
+
+ if (cqm_cla_hugepage_hint)
+ cla_table->hugepage_hint = true;
+}
+
+static void init_xid2cid_entry_cap(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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 = 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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_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_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_func_capability *capability);
+
+static const init_entry_cap init_entry_cap_funcs[CQM_BAT_ENTRY_T_MAX] = {
+ NULL, /* 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, /* CQM_BAT_ENTRY_T_INVALID */
+};
+
+static void
+cqm_cla_init_entry_capability(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_func_capability *capability)
+{
+ cla_table->max_index_bit = 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](cqm_handle, cla_table,
+ capability);
+ update_entry_cap_for_secure_mem(cqm_handle, cla_table);
+ }
+}
+
+static s32 cqm_cla_init_entry_memory(struct tag_cqm_handle *cqm_handle,
+ u32 entry_idx)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_cla_table *cla_table = &bat_table->entry[entry_idx];
+ struct tag_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 (CQM_IS_LB_MODE_1_OR_2(cqm_handle) &&
+ (entry_type == CQM_BAT_ENTRY_T_TIMER ||
+ entry_type == CQM_BAT_ENTRY_T_HASH ||
+ (entry_type == CQM_BAT_ENTRY_T_XID2CID &&
+ COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev)))) {
+ for (i = 0; i < cqm_handle->func_capability.smf_max_num; i++) {
+ if (cla_table->type == CQM_BAT_ENTRY_T_TIMER)
+ cla_table_tmp = &bat_table->timer_entry[i];
+ else if (entry_type == CQM_BAT_ENTRY_T_HASH)
+ cla_table_tmp = &bat_table->hash_entry[i];
+ else
+ cla_table_tmp = &bat_table->xid2cid_entry[i];
+
+ (void)memcpy_s(cla_table_tmp,
+ sizeof(struct tag_cqm_cla_table),
+ cla_table,
+ sizeof(struct tag_cqm_cla_table));
+
+ ret = snprintf_s(cla_table_tmp->name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%s%01u",
+ cla_table->name, VRAM_CQM_CLA_SMF_BASE,
+ i);
+ if (ret < 0) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "cqm cla timer vram name snprintf_s failed");
+ cqm_cla_uninit(cqm_handle, entry_idx);
+ return CQM_FAIL;
+ }
+
+ if (cqm_cla_xyz(cqm_handle, cla_table_tmp) ==
+ CQM_FAIL) {
+ cqm_cla_uninit(cqm_handle, entry_idx);
+ return CQM_FAIL;
+ }
+ }
+ return CQM_SUCCESS;
+ }
+
+ if (cqm_cla_xyz(cqm_handle, cla_table) == CQM_FAIL) {
+ cqm_cla_uninit(cqm_handle, entry_idx);
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_func_capability *capability)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ s32 ret;
+ u32 i = 0;
+ int err;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ cla_table = &bat_table->entry[i];
+ cla_table->type = bat_table->bat_entry_type[i];
+
+ err = snprintf_s(cla_table->name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%s%s%02u",
+ cqm_handle->name, VRAM_CQM_CLA_BASE,
+ VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
+ if (err < 0) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "cqm cla table vram name snprintf_s failed");
+ return CQM_FAIL;
+ }
+
+ mutex_init(&cla_table->lock);
+
+ cqm_cla_init_entry_capability(cqm_handle, cla_table,
+ capability);
+
+ /* Those entries don't need to alloc memory */
+ if (cla_table->type < CQM_BAT_ENTRY_T_HASH ||
+ cla_table->type > CQM_BAT_ENTRY_T_REORDER) {
+ continue;
+ }
+
+ /* Timer entry is only deployed in PPF */
+ if (cla_table->type == CQM_BAT_ENTRY_T_TIMER &&
+ !CQM_IS_PPF(cqm_handle))
+ continue;
+
+ ret = cqm_cla_init_entry_memory(cqm_handle, i);
+ if (ret != CQM_SUCCESS)
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_cla_init
+ * Description : Initialize the CLA table.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+s32 cqm_cla_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ s32 ret;
+
+ if (unlikely(cqm_try_init_secure_mem(cqm_handle) != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(secure_mem_init));
+ return CQM_FAIL;
+ }
+
+ /* Applying for CLA Entries */
+ if (cqm_cla_init_entry(cqm_handle, capability) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_init_entry));
+ return CQM_FAIL;
+ }
+
+ /* The BAT and CLA of the Fake VF are maintained by the parent function. */
+ if (CQM_IS_FAKE_CHILD(cqm_handle)) {
+ return cqm_cla_reset(cqm_handle);
+ }
+
+ /* After the CLA entry is applied, the address is filled
+ * in the BAT table.
+ */
+ cqm_bat_fill_cla(cqm_handle);
+
+ /* Instruct the chip to update the BAT table. */
+ if (cqm_bat_update(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_update));
+ goto err;
+ }
+
+ cqm_info(handle->dev_hdl,
+ "Timer start: func_type=%d, timer_enable=%u\n",
+ cqm_handle->func_attribute.func_type,
+ cqm_handle->func_capability.timer_enable);
+
+ if (CQM_IS_PPF(cqm_handle) &&
+ cqm_handle->func_capability.timer_enable == CQM_TIMER_ENABLE) {
+ /* Enable the timer after the timer resources are applied for */
+ ret = hinic5_ppf_tmr_start(handle);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ "PPF timer start failed, err %d\n", ret);
+ goto err;
+ }
+ }
+
+ return CQM_SUCCESS;
+
+err:
+ cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX);
+ return CQM_FAIL;
+}
+
+/* Inverse operation of cqm_cla_xyz() */
+static void cqm_cla_table_free_cache_inv(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ s32 *inv_flag)
+{
+ /* The CLA memory are maintained by the parent function. */
+ if (CQM_IS_FAKE_CHILD(cqm_handle))
+ return;
+
+ cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_x_buf, inv_flag);
+ cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_y_buf, inv_flag);
+ cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_z_buf, inv_flag);
+}
+
+STATIC INLINE void cqm_cla_uninit_entry(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ s32 *inv_flag)
+{
+ if (cla_table->type != CQM_BAT_ENTRY_T_INVALID)
+ cqm_cla_table_free_cache_inv(cqm_handle, cla_table, inv_flag);
+ mutex_deinit(&cla_table->lock);
+}
+
+/**
+ * Prototype : cqm_cla_uninit
+ * Description : Deinitialize the CLA table.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+void cqm_cla_uninit(struct tag_cqm_handle *cqm_handle, u32 entry_numb)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_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];
+ cqm_cla_uninit_entry(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 (CQM_IS_LB_MODE_1_OR_2(cqm_handle) && CQM_IS_PPF(cqm_handle)) {
+ for (i = 0; i < cqm_handle->func_capability.smf_max_num; i++) {
+ cla_table = &bat_table->timer_entry[i];
+ cqm_cla_uninit_entry(cqm_handle, cla_table, &inv_flag);
+ }
+ }
+
+ if (CQM_IS_LB_MODE_1_OR_2(cqm_handle)) {
+ for (i = 0; i < cqm_handle->func_capability.smf_max_num; i++) {
+ cla_table = &bat_table->hash_entry[i];
+ cqm_cla_uninit_entry(cqm_handle, cla_table, &inv_flag);
+ }
+ }
+
+ if (CQM_IS_LB_MODE_1_OR_2(cqm_handle) &&
+ COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev)) {
+ for (i = 0; i < cqm_handle->func_capability.smf_max_num; i++) {
+ cla_table = &bat_table->xid2cid_entry[i];
+ cqm_cla_uninit_entry(cqm_handle, cla_table, &inv_flag);
+ }
+ }
+
+ /* 释放安全内存。产品化则由Qemu释放 */
+ cqm_free_secure_mem(cqm_handle);
+}
+
+static s32 cqm_cla_update_cmd(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ cqm_cla_update_cmd_s *cmd_info)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ s32 ret = CQM_FAIL;
+ u8 cmd;
+
+ cqm_handle->cmdq_ops->prepare_cmd_buf_cla_update(cmd_info, buf_in,
+ &cmd);
+ ret = cqm5_send_cmd_box((void *)(cqm_handle->ex_handle), CQM_MOD_CQM,
+ cmd, buf_in, NULL, NULL, CQM_CMD_TIMEOUT,
+ HINIC5_CHANNEL_DEFAULT);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm5_send_cmd_box));
+ cqm_err(handle->dev_hdl,
+ "Cla alloc: cqm_cla_update, cqm5_send_cmd_box_ret=%d\n",
+ ret);
+ cqm_err(handle->dev_hdl,
+ "Cla alloc: 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 CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_cla_cmd_init(cqm_cla_update_cmd_s *cmd,
+ struct tag_cqm_handle *cqm_handle,
+ dma_addr_t parant_pa, dma_addr_t child_pa,
+ u8 cla_update_mode)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u64 spu_en = 0;
+ dma_addr_t pa = 0;
+ u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
+
+ spu_en = ((u64)cqm_get_acs_spu_en(cqm_handle)) << 0x3F;
+
+ pa = (parant_pa | spu_en);
+ cmd->gpa_h = CQM_ADDR_HI(pa);
+ cmd->gpa_l = CQM_ADDR_LW(pa);
+
+ pa = (child_pa | spu_en);
+ cmd->value_h = CQM_ADDR_HI(pa);
+ cmd->value_l = 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 CQM_CLA_RECORD_NEW_GPA:
+ cmd->value_l |= 1;
+ break;
+ /* gpa[0]=0 means this GPA is valid */
+ case CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID:
+ case CQM_CLA_DEL_GPA_WITH_CACHE_INVALID:
+ cmd->value_l &= (~1);
+ break;
+ default:
+ cqm_err(handle->dev_hdl,
+ "Cla alloc: %s, wrong cla_update_mode=%u\n",
+ __func__, cla_update_mode);
+ break;
+ }
+ }
+}
+
+static s32 cqm_cla_update_all_smf(struct tag_cqm_handle *cqm_handle,
+ cqm_cla_update_cmd_s *cmd,
+ struct tag_cqm_cmd_buf *buf_in)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ u32 i = 0;
+ s32 ret = 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 = cqm_cla_update_cmd(cqm_handle, buf_in, cmd);
+ if (ret != CQM_SUCCESS)
+ return ret;
+ }
+ }
+ return ret;
+}
+
+/**
+ * Prototype : cqm_cla_update
+ * Description : Send a command to update the CLA table.
+ * Input : struct tag_cqm_handle *cqm_handle,
+ * struct tag_cqm_buf_list *buf_node_parent parent node of the content to
+ * be updated
+ * struct tag_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 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
+ const struct tag_cqm_buf_list *buf_node_parent,
+ const struct tag_cqm_buf_list *buf_node_child,
+ u32 child_index, u8 cla_update_mode)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ cqm_cla_update_cmd_s cmd;
+ s32 ret = CQM_FAIL;
+
+ buf_in = cqm5_cmd_alloc(cqm_handle->ex_handle);
+ if (unlikely(buf_in == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(buf_in));
+ return CQM_FAIL;
+ }
+
+ /* Fill command format, convert to big endian. */
+ cqm_cla_cmd_init(
+ &cmd, cqm_handle,
+ (buf_node_parent->pa + (child_index * sizeof(dma_addr_t))),
+ buf_node_child->pa, cla_update_mode);
+
+ 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 (CQM_IS_FAKE_CHILD_AGENT(cqm_handle))
+ cmd.func_id = 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 (CQM_IS_LB_MODE_NORMAL(cqm_handle) ||
+ (CQM_IS_LB_MODE_0(cqm_handle) && !CQM_IS_PPF(cqm_handle))) {
+ cmd.smf_id = cqm_funcid2smfid(cqm_handle);
+ ret = cqm_cla_update_cmd(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 (CQM_IS_LB_MODE_1_OR_2(cqm_handle) ||
+ (CQM_IS_LB_MODE_0(cqm_handle) && CQM_IS_PPF(cqm_handle))) {
+ ret = cqm_cla_update_all_smf(cqm_handle, &cmd, buf_in);
+ } else {
+ cqm_err(handle->dev_hdl, "Cla update: unsupported lb mode=%u\n",
+ cqm_handle->func_capability.lb_mode);
+ ret = CQM_FAIL;
+ }
+
+ cqm5_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
+ return ret;
+}
+
+/**
+ * Prototype : cqm_cla_alloc
+ * Description : Trunk page for applying for a CLA.
+ * Input : struct tag_cqm_handle *cqm_handle,
+ * struct tag_cqm_cla_table *cla_table,
+ * struct tag_cqm_buf_list *buf_node_parent parent node of the content to
+ * be updated
+ * struct tag_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 cqm_cla_alloc(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_buf_list *buf_node_parent,
+ struct tag_cqm_buf_list *buf_node_child,
+ u32 child_index)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ s32 ret = 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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(va));
+ return CQM_FAIL;
+ }
+ /* PCI mapping */
+ buf_node_child->pa = dma_map_single(cqm_handle->dev, buf_node_child->va,
+ PAGE_SIZE << cla_table->trunk_order,
+ DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(cqm_handle->dev, buf_node_child->pa) != 0) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(buf_node_child->pa));
+ goto err1;
+ }
+
+ /* Notify the chip of trunk_pa so that the chip fills in cla entry */
+ ret = cqm_cla_update(cqm_handle, buf_node_parent, buf_node_child,
+ child_index, CQM_CLA_RECORD_NEW_GPA);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_update));
+ goto err2;
+ }
+
+ return CQM_SUCCESS;
+
+err2:
+ dma_unmap_single(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 CQM_FAIL;
+}
+
+static void cqm_unmap_and_free_pages(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf_list *buf_node,
+ u32 order)
+{
+ /* Remove PCI mapping from the trunk page */
+ dma_unmap_single(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 : cqm_cla_free_without_cache_invalid
+ * Description : Release trunk page of a CLA
+ * Input : struct tag_cqm_handle *cqm_handle
+ * struct tag_cqm_cla_table *cla_table
+ * struct tag_cqm_buf_list *buf_node
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/5/15
+ * Modification : Created function
+ */
+static void cqm_cla_free_without_cache_invalid(
+ struct tag_cqm_handle *cqm_handle, struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_buf_list *buf_node_parent,
+ struct tag_cqm_buf_list *buf_node_child, u32 child_index)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ if (cqm_cla_update(
+ cqm_handle, buf_node_parent, buf_node_child, child_index,
+ CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_update));
+ return;
+ }
+ /* Remove PCI mapping from the trunk page and Release trunk page */
+ cqm_unmap_and_free_pages(cqm_handle, buf_node_child,
+ cla_table->trunk_order);
+}
+
+STATIC void cqm_cla_free_with_cache_invalid(
+ struct tag_cqm_handle *cqm_handle, struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_buf_list *buf_node_parent,
+ struct tag_cqm_buf_list *buf_node_child, u32 child_index)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 trunk_size;
+
+ if (cqm_cla_update(cqm_handle, buf_node_parent, buf_node_child,
+ child_index,
+ CQM_CLA_DEL_GPA_WITH_CACHE_INVALID) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_update));
+ return;
+ }
+
+ /* invalid cache */
+ trunk_size = (u32)(PAGE_SIZE << cla_table->trunk_order);
+ if (cqm_cla_cache_invalid(cqm_handle, buf_node_child->pa, trunk_size) !=
+ CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_cache_invalid));
+ return;
+ }
+
+ /* Remove PCI mapping from the trunk page and Release trunk page */
+ cqm_unmap_and_free_pages(cqm_handle, buf_node_child,
+ cla_table->trunk_order);
+}
+
+static inline u8 *cqm_cla_do_get_lvl0(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u32 index, u32 count, dma_addr_t *pa)
+{
+ struct tag_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 *cqm_cla_do_get_lvl1(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u32 index, u32 count, dma_addr_t *pa)
+{
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf_list *buf_node_y = NULL;
+ struct tag_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) {
+ 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 (cqm_cla_alloc(cqm_handle, cla_table, buf_node_y, buf_node_z,
+ y_index) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_alloc));
+ cqm_err(handle->dev_hdl,
+ "Cla get: cla_table->type=%u\n",
+ cla_table->type);
+ return NULL;
+ }
+ }
+
+ cqm_dbg_on(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 *cqm_cla_do_get_lvl2(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table,
+ u32 index, u32 count, dma_addr_t *pa)
+{
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf_list *buf_node_x = NULL;
+ struct tag_cqm_buf_list *buf_node_y = NULL;
+ struct tag_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) {
+ 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 (cqm_cla_alloc(cqm_handle, cla_table, buf_node_x, buf_node_y,
+ x_index) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_alloc));
+ return NULL;
+ }
+ }
+
+ /* The z buf node does not exist, applying for pages for z node. */
+ if (!buf_node_z->va) {
+ if (cqm_cla_alloc(cqm_handle, cla_table, buf_node_y, buf_node_z,
+ y_index) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_alloc));
+ if (buf_node_y->refcount == 0)
+ /* To release node Y, cache_invalid is
+ * required.
+ */
+ cqm_cla_free_with_cache_invalid(
+ cqm_handle, cla_table, buf_node_x,
+ buf_node_y, x_index);
+ return NULL;
+ }
+
+ cqm_dbg_on(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++;
+ }
+
+ cqm_dbg_on(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 *cqm_cla_do_get(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 index,
+ u32 count, dma_addr_t *pa)
+{
+ if (cla_table->cla_lvl == CQM_CLA_LVL_0)
+ return cqm_cla_do_get_lvl0(cqm_handle, cla_table, index, count,
+ pa);
+ if (cla_table->cla_lvl == CQM_CLA_LVL_1)
+ return cqm_cla_do_get_lvl1(cqm_handle, cla_table, index, count,
+ pa);
+ if (cla_table->cla_lvl == CQM_CLA_LVL_2)
+ return cqm_cla_do_get_lvl2(cqm_handle, cla_table, index, count,
+ pa);
+ WARN_ON(true);
+ return NULL;
+}
+
+/**
+ * Prototype : 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_cqm_handle *cqm_handle,
+ * struct tag_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 *cqm_cla_get(struct tag_cqm_handle *cqm_handle,
+ struct tag_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 (CQM_IS_FAKE_CHILD(cqm_handle))
+ return NULL;
+
+ if (index >= cla_table->obj_num)
+ return NULL;
+
+ if (dynamic_alloc)
+ mutex_lock(&cla_table->lock);
+
+ ret_addr = cqm_cla_do_get(cqm_handle, cla_table, index, count, pa);
+
+ if (dynamic_alloc)
+ mutex_unlock(&cla_table->lock);
+
+ return ret_addr;
+}
+
+/**
+ * Prototype : 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_cqm_handle *cqm_handle,
+ * struct tag_cqm_cla_table *cla_table,
+ * u32 index,
+ * u32 count
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_cla_put(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 index, u32 count)
+{
+ struct tag_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
+ struct tag_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
+ struct tag_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf_list *buf_node_z = NULL;
+ struct tag_cqm_buf_list *buf_node_y = NULL;
+ struct tag_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 (CQM_IS_FAKE_CHILD(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 == CQM_CLA_LVL_1) {
+ y_index = index >> (cla_table->z + 1);
+
+ if (y_index >= cla_z_buf->buf_number) {
+ 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. */
+ cqm_cla_free_without_cache_invalid(cqm_handle,
+ cla_table,
+ buf_node_y,
+ buf_node_z, y_index);
+ } else if (cla_table->cla_lvl == 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) {
+ 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) {
+ cqm_cla_free_without_cache_invalid(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. */
+ cqm_cla_free_with_cache_invalid(
+ cqm_handle, cla_table, buf_node_x,
+ buf_node_y, x_index);
+ }
+ }
+
+out:
+ mutex_unlock(&cla_table->lock);
+}
+
+/**
+ * Prototype : cqm_cla_table_get
+ * Description : Searches for the CLA table data structure corresponding to a
+ * BAT entry.
+ * Input : struct tag_cqm_bat_table *bat_table,
+ * u32 entry_type
+ * Output : None
+ * Return Value : struct tag_cqm_cla_table *
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
+ u32 entry_type)
+{
+ struct tag_cqm_cla_table *cla_table = NULL;
+ u32 i = 0;
+
+ for (i = 0; i < 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/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.h
new file mode 100644
index 000000000..32726b34d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bat_cla.h
@@ -0,0 +1,256 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_BAT_CLA_H
+#define CQM_BAT_CLA_H
+
+#include <linux/types.h>
+#include <linux/mutex.h>
+
+#include "hinic5_hw_cfg.h"
+#include "hinic5_cqm.h"
+#include "cqm_bitmap_table.h"
+#include "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 CQM_BAT_MAX_CONN_NUM (0x100000 - 63)
+#define 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 CQM_4K_PAGE_ORDER 0
+#define CQM_4K_PAGE_SIZE 4096
+
+#define CQM_8K_PAGE_ORDER 1
+
+#define CQM_BAT_ENTRY_MAX 16
+#define CQM_BAT_ENTRY_SIZE 16
+#define CQM_BAT_STORE_API_SIZE 16
+#define CQM_BAT_MAX (CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE)
+
+#define CQM_BAT_SIZE_FT_RDMA_PF 240
+#define CQM_BAT_SIZE_FT_RDMA_VF 160
+#define CQM_BAT_SIZE_FT_PF 192
+#define CQM_BAT_SIZE_FT_VF 112
+#define CQM_BAT_SIZE_RDMA_PF 160
+#define CQM_BAT_SIZE_RDMA_VF 80
+#define CQM_BAT_SIZE_PF 80
+#define CQM_BAT_SIZE_VF 0
+
+enum cqm_bat_entry_type {
+ CQM_BAT_ENTRY_T_CFG = 0,
+ CQM_BAT_ENTRY_T_HASH = 1,
+ CQM_BAT_ENTRY_T_QPC = 2,
+ CQM_BAT_ENTRY_T_SCQC = 3,
+ CQM_BAT_ENTRY_T_SRQC = 4,
+ CQM_BAT_ENTRY_T_MPT = 5,
+ CQM_BAT_ENTRY_T_GID = 6,
+ CQM_BAT_ENTRY_T_LUN = 7,
+ CQM_BAT_ENTRY_T_TASKMAP = 8,
+ CQM_BAT_ENTRY_T_L3I = 9,
+ CQM_BAT_ENTRY_T_CHILDC = 10,
+ CQM_BAT_ENTRY_T_TIMER = 11,
+ CQM_BAT_ENTRY_T_XID2CID = 12,
+ CQM_BAT_ENTRY_T_REORDER = 13,
+ CQM_BAT_ENTRY_T_INVALID = 14,
+ CQM_BAT_ENTRY_T_MAX = 15,
+};
+
+/* CLA update mode */
+#define CQM_CLA_RECORD_NEW_GPA 0
+#define CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID 1
+#define CQM_CLA_DEL_GPA_WITH_CACHE_INVALID 2
+
+#define CQM_CLA_LVL_0 0
+#define CQM_CLA_LVL_1 1
+#define CQM_CLA_LVL_2 2
+#define CQM_CLA_LVL_UNSUPPORT 3
+
+#define CQM_MAX_INDEX_BIT_DEFAULT 19
+
+#define CQM_CHIP_CACHELINE 256
+#define CQM_CHIP_TIMER_CACHELINE 512
+#define CQM_OBJECT_256 256
+#define CQM_OBJECT_512 512
+#define CQM_OBJECT_1024 1024
+#define CQM_CHIP_GPA_MASK 0x1ffffffffffffff
+#define CQM_CHIP_GPA_HIMASK 0x1ffffff
+#define CQM_CHIP_GPA_LOMASK 0xffffffff
+#define CQM_CHIP_GPA_HSHIFT 32
+
+/* Aligns with 64 buckets and shifts rightward by 6 bits */
+#define CQM_HASH_NUMBER_UNIT 6
+
+struct cqm_secure_mem_info {
+ void *va;
+ dma_addr_t pa;
+ size_t size;
+};
+
+struct tag_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 cqm_cla_xyz(). This value
+ * will be overriden by 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_cqm_buf cla_x_buf;
+ struct tag_cqm_buf cla_y_buf;
+ struct tag_cqm_buf cla_z_buf;
+
+ struct tag_cqm_bitmap bitmap;
+
+ struct tag_cqm_object_table obj_table; /* Mapping table between
+ * indexes and objects
+ */
+ struct cqm_secure_mem_info
+ secure_mem; /* Secure memory with consecutive physical addresses */
+
+ char name[VRAM_NAME_APPLY_LEN];
+};
+
+static inline bool cqm_cla_use_secure_mem(struct tag_cqm_cla_table *cla_table)
+{
+ return !!cla_table->secure_mem.va;
+}
+
+struct tag_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 CQM_BAT_NO_BYPASS_CACHE 0
+#define CQM_BAT_BYPASS_CACHE 1
+
+#define CQM_BAT_ENTRY_SIZE_256 0
+#define CQM_BAT_ENTRY_SIZE_512 1
+#define CQM_BAT_ENTRY_SIZE_1024 2
+
+struct tag_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_cqm_bat_entry_vf2pf {
+ u32 cla_gpa_h : 25;
+ u32 pf_id : 5;
+ u32 fake_vf_en : 1;
+ u32 acs_spu_en : 1;
+};
+
+#define CQM_BAT_ENTRY_TASKMAP_NUM 4
+struct tag_cqm_bat_entry_taskmap_addr {
+ u32 gpa_h;
+ u32 gpa_l;
+};
+
+struct tag_cqm_bat_entry_taskmap {
+ struct tag_cqm_bat_entry_taskmap_addr addr[CQM_BAT_ENTRY_TASKMAP_NUM];
+};
+
+struct tag_cqm_bat_table {
+ u32 bat_entry_type[CQM_BAT_ENTRY_MAX];
+ u8 bat[CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE];
+ struct tag_cqm_cla_table entry[CQM_BAT_ENTRY_MAX];
+ /* Secure memory with consecutive physical addresses */
+ struct cqm_secure_mem_info 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_cqm_cla_table timer_entry[CHIP_SMF_NUM_MAX];
+ struct tag_cqm_cla_table hash_entry[CHIP_SMF_NUM_MAX];
+ struct tag_cqm_cla_table xid2cid_entry[CHIP_SMF_NUM_MAX];
+ u32 bat_size;
+};
+
+static inline struct tag_cqm_cla_table *
+cqm_bat_table_find_entry(struct tag_cqm_bat_table *bat_table, u32 entry_type)
+{
+ u32 i;
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ if (bat_table->bat_entry_type[i] == entry_type)
+ return &bat_table->entry[i];
+ }
+ return NULL;
+}
+
+struct tag_cqm_bat_update_param {
+ u32 smf_id;
+ u32 func_id;
+ u32 bat_offset;
+ u32 update_size;
+};
+
+s32 cqm_bat_init(struct tag_cqm_handle *cqm_handle);
+void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle);
+
+s32 cqm_cla_init(struct tag_cqm_handle *cqm_handle);
+void cqm_cla_uninit(struct tag_cqm_handle *cqm_handle, u32 entry_numb);
+
+u8 *cqm_cla_get(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 index, u32 count,
+ dma_addr_t *pa);
+void cqm_cla_put(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cla_table *cla_table, u32 index, u32 count);
+
+struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
+ u32 entry_type);
+u32 cqm_funcid2smfid(const struct tag_cqm_handle *cqm_handle);
+
+s32 cqm_try_init_secure_mem(struct tag_cqm_handle *cqm_handle);
+void cqm_free_secure_mem(struct tag_cqm_handle *cqm_handle);
+
+#endif /* CQM_BAT_CLA_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.c
new file mode 100644
index 000000000..294ea0511
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.c
@@ -0,0 +1,1807 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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_vram_api.h"
+
+#include "cqm_object.h"
+#include "cqm_bat_cla.h"
+#include "cqm_cmd.h"
+#include "cqm_object_intern.h"
+#include "cqm_main.h"
+#include "vram_common.h"
+#include "cqm_cmdq.h"
+
+#include "comm_defs.h"
+#include "cqm_npu_cmd_defs.h"
+#ifdef __UEFI__
+#include "ossl_knl_uefi.h"
+#endif
+
+#define common_section
+
+#ifndef __WIN__
+struct malloc_memory {
+ bool (*check_alloc_mode)(const struct hinic5_hwdev *handle,
+ const struct tag_cqm_buf *buf);
+ s32 (*malloc_func)(struct hinic5_hwdev *handle,
+ struct tag_cqm_buf *buf);
+};
+
+struct free_memory {
+ bool (*check_alloc_mode)(const struct hinic5_hwdev *handle,
+ const struct tag_cqm_buf *buf);
+ void (*free_func)(struct tag_cqm_buf *buf);
+};
+#endif
+/**
+ * Prototype : 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 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 : 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 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 : 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 cqm_shift(u32 data)
+{
+ u32 data_num = data;
+ s32 shift = -1;
+
+ do {
+ data_num >>= 1;
+ shift++;
+ } while (data_num != 0);
+
+ return (u32)shift;
+}
+
+/**
+ * Prototype : 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 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 : 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 *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 : 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 cqm_kfree_align(void *addr)
+{
+ void *index_addr = NULL;
+
+ /* Release the original memory address. */
+ index_addr = (void *)((char *)addr - sizeof(void *));
+
+ cqm_dbg_pr_on(cqm_verbose,
+ "free aligned address: %p, original address: %p\n", addr,
+ *(void **)index_addr);
+
+ kfree(*(void **)index_addr);
+}
+
+static void cqm_write_lock(rwlock_t *lock, bool bh)
+{
+ if (bh)
+ write_lock_bh(lock);
+ else
+ write_lock(lock);
+}
+
+static void cqm_write_unlock(rwlock_t *lock, bool bh)
+{
+ if (bh)
+ write_unlock_bh(lock);
+ else
+ write_unlock(lock);
+}
+
+static void cqm_read_lock(rwlock_t *lock, bool bh)
+{
+ if (bh)
+ read_lock_bh(lock);
+ else
+ read_lock(lock);
+}
+
+static void cqm_read_unlock(rwlock_t *lock, bool bh)
+{
+ if (bh)
+ read_unlock_bh(lock);
+ else
+ read_unlock(lock);
+}
+
+s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf, bool direct)
+{
+ struct hinic5_hwdev *handle = 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 CQM_SUCCESS;
+ }
+
+ pages = vmalloc(sizeof(struct page *) * buf->page_number);
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
+ return 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) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(buf->direct.va));
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+#ifndef __WIN__
+
+static bool check_use_vram(const struct hinic5_hwdev *handle,
+ const struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram != 0 ? true : false;
+}
+
+static bool check_use_non_vram(const struct hinic5_hwdev *handle,
+ const struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram != 0 ? false : true;
+}
+
+static bool check_for_use_node_alloc(const struct hinic5_hwdev *handle,
+ const struct tag_cqm_buf *buf)
+{
+ if (buf->buf_info.use_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_cqm_buf *buf)
+{
+ if (buf->buf_info.use_vram == 0 && handle->board_info.service_mode != 0)
+ return true;
+
+ return false;
+}
+
+#ifndef __UEFI__
+static u8 cqm_vram_node(struct hinic5_hwdev *handle)
+{
+ if (nr_node_ids > 0) {
+ u16 func_id = hinic5_global_func_id(handle);
+ // nr_node_ids表示可用的NUMA节点最大数量, 不会大于u8最大值
+ return (u8)(func_id % nr_node_ids);
+ }
+ return VRAM_NUMA_NODE0;
+}
+#endif
+
+static s32 cqm_buf_vram_kalloc(struct hinic5_hwdev *handle,
+ struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ u32 i;
+
+ vaddr = hi5_vram_kalloc_node(buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number,
+ cqm_vram_node(handle));
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < buf->buf_number; i++)
+ buf->buf_list[i].va =
+ (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi5_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_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 cqm_buf_free_page_common(struct tag_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 cqm_buf_use_node_alloc_page(struct hinic5_hwdev *handle,
+ struct tag_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) {
+ 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.
+ */
+ (void)memset_s(va, buf->buf_size, 0, buf->buf_size);
+ buf->buf_list[i].va = va;
+ }
+
+ if (i != buf->buf_number) {
+ cqm_buf_free_page_common(buf);
+ return CQM_BUF_ALLOC_BUDDY_PAGES_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_buf_unused_node_alloc_page(struct hinic5_hwdev *handle,
+ struct tag_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) {
+ 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.
+ */
+ (void)memset_s(va, buf->buf_size, 0, buf->buf_size);
+ buf->buf_list[i].va = va;
+ }
+
+ if (i != buf->buf_number) {
+ cqm_buf_free_page_common(buf);
+ return CQM_BUF_ALLOC_BUDDY_PAGES_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static const struct malloc_memory g_malloc_funcs[] = {
+ { check_use_vram, cqm_buf_vram_kalloc },
+ { check_for_use_node_alloc, cqm_buf_use_node_alloc_page },
+ { check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page }
+};
+
+static const struct free_memory g_free_funcs[] = {
+ { check_use_vram, cqm_buf_vram_free },
+ { check_use_non_vram, cqm_buf_free_page_common }
+};
+
+static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf)
+{
+ struct hinic5_hwdev *handle = 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);
+ }
+
+ cqm_err(handle->dev_hdl, "Unknown alloc mode\n");
+
+ return CQM_FAIL;
+}
+
+static void cqm_buf_free_page(struct tag_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 cqm_buf_alloc_map(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct device *dev = 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) {
+ cqm_err(handle->dev_hdl, 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 CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/* Applying for the buffer list descriptor space */
+s32 cqm_buf_list_alloc(struct tag_cqm_buf *buf)
+{
+ size_t size = buf->buf_number * sizeof(struct tag_cqm_buf_list);
+
+ if (WARN_ON_ONCE(buf->buf_list))
+ return CQM_SUCCESS;
+
+ buf->buf_list = vmalloc(size);
+ if (unlikely(!buf->buf_list)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(linux_buf_list));
+ return CQM_FAIL;
+ }
+
+ (void)memset_s(buf->buf_list, size, 0, size);
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_buf_alloc
+ * Description : Apply for buffer space and DMA mapping for the struct tag_cqm_buf
+ * structure.
+ * Input : struct tag_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 cqm_buf_alloc(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf,
+ bool direct)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 i;
+ s32 ret = CQM_FAIL;
+
+ ret = cqm_buf_list_alloc(buf);
+ if (unlikely(ret != CQM_SUCCESS))
+ return ret;
+
+ /* Page for applying for each buffer */
+ ret = cqm_buf_alloc_page(cqm_handle, buf);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(linux_cqm_buf_alloc_page));
+ goto err1;
+ }
+
+ /* PCI mapping of the buffer */
+ ret = cqm_buf_alloc_map(cqm_handle, buf);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(linux_cqm_buf_alloc_map));
+ goto err2;
+ }
+
+ /* direct remapping */
+ ret = cqm_buf_alloc_direct(cqm_handle, buf, direct);
+ if (unlikely(ret != CQM_SUCCESS)) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_buf_alloc_direct));
+ goto err3;
+ }
+
+ return CQM_SUCCESS;
+
+err3:
+ for (i = 0; i < buf->buf_number; i++)
+ dma_unmap_single(cqm_handle->dev, buf->buf_list[i].pa,
+ buf->buf_size, DMA_BIDIRECTIONAL);
+err2:
+ cqm_buf_free_page(buf);
+err1:
+ vfree(buf->buf_list);
+ buf->buf_list = NULL;
+ return ret;
+}
+
+/**
+ * Prototype : cqm_buf_free
+ * Description : Release the buffer space and DMA mapping for the struct tag_cqm_buf
+ * structure.
+ * Input : struct tag_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 cqm_buf_free(struct tag_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 cqm_cla_secure_mem_buf_alloc()
+ if (buf->secure_mem_flag == 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);
+ }
+ cqm_buf_free_page(buf);
+ }
+
+free_buf_list:
+ if (buf->buf_list) {
+ vfree(buf->buf_list);
+ buf->buf_list = NULL;
+ }
+}
+
+#else /* __WIN__ */
+
+static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf)
+{
+ struct hinic5_hwdev *handle = 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 / CQM_HUGE_BUF_SIZE) +
+ ((total_size % CQM_HUGE_BUF_SIZE) ? 1 : 0);
+ if (!buf->huge_buf_number) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(buf->huge_buf_number));
+ return CQM_FAIL;
+ }
+
+ buf->bufs_addr =
+ vmalloc(buf->huge_buf_number * sizeof(struct huge_buf_addr));
+ if (!buf->bufs_addr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(bufs_addr));
+ return CQM_FAIL;
+ }
+ (void)memset_s(buf->bufs_addr,
+ buf->huge_buf_number * sizeof(struct huge_buf_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 -
+ CQM_HUGE_BUF_SIZE * i);
+ else
+ bufs_addr[i].huge_buf_size = 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) {
+ cqm_err(handle->dev_hdl,
+ 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 CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_buf_alloc_map(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct device *dev = 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)) {
+ cqm_err(handle->dev_hdl, 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 CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+s32 cqm_buf_alloc(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf,
+ bool direct)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct huge_buf_addr *bufs_addr = NULL;
+ u32 cnt;
+ u32 i;
+ s32 j = 0;
+
+ if (buf->buf_size > CQM_HUGE_BUF_SIZE) {
+ cqm_err(handle->dev_hdl,
+ "Buffer size(0x%x) is large than huge buffer size(0x%x)\n",
+ buf->buf_size, CQM_HUGE_BUF_SIZE);
+ return CQM_FAIL;
+ }
+
+ /* Applying for the buffer list descriptor space */
+ buf->buf_list =
+ vmalloc(buf->buf_number * sizeof(struct tag_cqm_buf_list));
+ if (unlikely(buf->buf_list == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(win_buf_list));
+ return CQM_FAIL;
+ }
+ (void)memset_s(buf->buf_list,
+ buf->buf_number * sizeof(struct tag_cqm_buf_list), 0,
+ buf->buf_number * sizeof(struct tag_cqm_buf_list));
+
+ /* Page for applying for each buffer */
+ if (cqm_buf_alloc_page(cqm_handle, buf) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(win_cqm_buf_alloc_page));
+ goto err1;
+ }
+
+ /* PCI mapping of the buffer */
+ if (cqm_buf_alloc_map(cqm_handle, buf) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(win_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 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 CQM_FAIL;
+}
+
+void cqm_buf_free(struct tag_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 cqm_cla_cache_invalid_cmd(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ cqm_cla_cache_invalid_cmd_s *cmd_info)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ s32 ret;
+ u8 cmd;
+
+ cqm_handle->cmdq_ops->prepare_cmd_cache_invalidate(cmd_info, buf_in,
+ &cmd);
+
+ /* Send the cmdq command. */
+ ret = cqm5_send_cmd_box((void *)(cqm_handle->ex_handle), CQM_MOD_CQM,
+ cmd, buf_in, NULL, NULL, CQM_CMD_TIMEOUT,
+ HINIC5_CHANNEL_DEFAULT);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm5_send_cmd_box));
+ cqm_err(handle->dev_hdl,
+ "Cla cache invalid: cqm5_send_cmd_box_ret=%d\n", ret);
+ 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 CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_cla_cache_invalid_all_smf(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ cqm_cla_cache_invalid_cmd_s *cmd)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ u32 i;
+ s32 ret = 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 = cqm_cla_cache_invalid_cmd(cqm_handle, buf_in,
+ cmd);
+ if (ret != CQM_SUCCESS)
+ return ret;
+ }
+ }
+ return ret;
+}
+
+s32 cqm_cla_cache_invalid(struct tag_cqm_handle *cqm_handle, dma_addr_t pa,
+ u32 cache_size)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ struct hinic5_func_attr *func_attr = NULL;
+ struct tag_cqm_bat_entry_vf2pf gpa = { 0 };
+ cqm_cla_cache_invalid_cmd_s cmd;
+ u32 cla_gpa_h = 0;
+ s32 ret = CQM_FAIL;
+
+ buf_in = cqm5_cmd_alloc((void *)(cqm_handle->ex_handle));
+ if (unlikely(buf_in == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(buf_in));
+ return CQM_FAIL;
+ }
+
+ gpa.cla_gpa_h = CQM_ADDR_HI(pa) & CQM_CHIP_GPA_HIMASK;
+ gpa.acs_spu_en = cqm_get_acs_spu_en(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 (CQM_IS_FAKE_CHILD_AGENT(cqm_handle)) {
+ cmd.func_id = cqm_handle->func_attribute.func_global_idx;
+ func_attr = &cqm_handle->parent_cqm_handle->func_attribute;
+ gpa.fake_vf_en = 1;
+ gpa.pf_id = func_attr->func_global_idx;
+ } else {
+ cmd.func_id = 0xffff;
+ }
+ (void)memcpy_s(&cla_gpa_h, sizeof(u32), &gpa, sizeof(u32));
+
+ /* Fill command and convert it to big endian */
+ cmd.cache_size = cache_size;
+ cmd.gpa_l = 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 (CQM_IS_LB_MODE_NORMAL(cqm_handle) ||
+ (CQM_IS_LB_MODE_0(cqm_handle) && !CQM_IS_PPF(cqm_handle))) {
+ cmd.smf_id = cqm_funcid2smfid(cqm_handle);
+ ret = cqm_cla_cache_invalid_cmd(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 (CQM_IS_LB_MODE_1_OR_2(cqm_handle) ||
+ (CQM_IS_LB_MODE_0(cqm_handle) && CQM_IS_PPF(cqm_handle))) {
+ ret = cqm_cla_cache_invalid_all_smf(cqm_handle, buf_in, &cmd);
+ } else {
+ cqm_err(handle->dev_hdl,
+ "Cla cache invalid: unsupport lb mode=%u\n",
+ cqm_handle->func_capability.lb_mode);
+ ret = CQM_FAIL;
+ }
+
+ cqm5_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
+ return ret;
+}
+
+static void free_cache_inv(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf, s32 *inv_flag)
+{
+ struct hinic5_hwdev *handle = 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 != CQM_SUCCESS)
+ continue;
+
+ /* In the Pangea environment, if the cmdq times out,
+ * no subsequent message is sent.
+ */
+ *inv_flag = cqm_cla_cache_invalid(cqm_handle,
+ buf->buf_list[i].pa,
+ (u32)(PAGE_SIZE << order));
+ if (*inv_flag != CQM_SUCCESS)
+ cqm_err(handle->dev_hdl,
+ "Buffer free: fail to invalid buf_list pa cache, inv_flag=%d\n",
+ *inv_flag);
+ }
+}
+
+void cqm_buf_free_cache_inv(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf, s32 *inv_flag)
+{
+ if (!COMM_SUPPORT_SMF_CACHE_INVALID(cqm_handle->ex_handle)) {
+ /* Send a command to the chip to kick out the cache. */
+ free_cache_inv(cqm_handle, buf, inv_flag);
+ }
+
+ /* Clear host resources */
+ cqm_buf_free(buf, cqm_handle->dev);
+}
+
+#define bitmap_section
+
+/**
+ * Prototype : cqm_single_bitmap_init
+ * Description : Initialize a bitmap.
+ * Input : struct tag_cqm_bitmap *bitmap
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/9/9
+ * Modification : Created function
+ */
+static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
+{
+ u32 nbytes;
+
+ spin_lock_init(&bitmap->lock);
+
+ nbytes = BITS_TO_LONGS(bitmap->max_num) * sizeof(long);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi5_vram_kalloc(
+ bitmap->bitmap_info.buf_vram_name, nbytes);
+ else
+ bitmap->table = vmalloc(nbytes);
+
+ if (unlikely(bitmap->table == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(bitmap->table));
+ return CQM_FAIL;
+ }
+
+ (void)memset_s(bitmap->table, nbytes, 0, nbytes);
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_bitmap_toe_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_bitmap *bitmap = NULL;
+
+ /* SRQC of TOE services is not managed through the CLA table,
+ * but the bitmap is required to manage SRQid.
+ */
+ if (cqm_handle->service[CQM_SERVICE_T_TOE].valid) {
+ bitmap = &cqm_handle->toe_own_capability.srqc_bitmap;
+ bitmap->max_num =
+ cqm_handle->toe_own_capability.toe_srqc_number;
+ bitmap->reserved_top = 0;
+ bitmap->reserved_back = 0;
+ bitmap->last = 0;
+ if (bitmap->max_num == 0) {
+ cqm_info(
+ handle->dev_hdl,
+ "Bitmap init: toe_srqc_number=0, don't init bitmap\n");
+ return CQM_SUCCESS;
+ }
+
+ if (cqm_single_bitmap_init(bitmap) != CQM_SUCCESS)
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_bitmap_toe_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bitmap *bitmap = NULL;
+
+ if (cqm_handle->service[CQM_SERVICE_T_TOE].valid) {
+ bitmap = &cqm_handle->toe_own_capability.srqc_bitmap;
+ if (bitmap->table) {
+ spin_lock_deinit(&bitmap->lock);
+ vfree(bitmap->table);
+ bitmap->table = NULL;
+ }
+ }
+}
+
+static s32 cqm_bitmap_init_by_type(u32 type, struct tag_cqm_bitmap *bitmap,
+ struct tag_cqm_func_capability *capability)
+{
+ switch (type) {
+ case 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_vram = get5_use_vram_flag();
+ break;
+ case 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 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 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 CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_bitmap_init
+ * Description : Initialize the bitmap.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ s32 ret = CQM_SUCCESS;
+ u32 i;
+ int err;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ cla_table = &bat_table->entry[i];
+ if (cla_table->obj_num == 0) {
+ 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_s(bitmap->bitmap_info.buf_vram_name,
+ VRAM_NAME_MAX_LEN, VRAM_NAME_MAX_LEN - 1,
+ "%s%s%02u", cla_table->name,
+ VRAM_CQM_BITMAP_BASE, cla_table->type);
+ if (err < 0) {
+ cqm_err(handle->dev_hdl,
+ "cqm bitmap vram name snprintf_s failed");
+ return CQM_FAIL;
+ }
+
+ if (cqm_bitmap_init_by_type(cla_table->type, bitmap,
+ capability) == CQM_SUCCESS) {
+ cqm_info(
+ handle->dev_hdl,
+ "Bitmap init: cla_table_type=%u, max_num=0x%x\n",
+ cla_table->type, bitmap->max_num);
+ ret = cqm_single_bitmap_init(bitmap);
+ }
+
+ if (ret != CQM_SUCCESS) {
+ 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 (cqm_bitmap_toe_init(cqm_handle) != CQM_SUCCESS)
+ goto err;
+
+ return CQM_SUCCESS;
+
+err:
+ cqm_bitmap_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+static void cqm_bitmap_table_free(struct tag_cqm_bitmap *bitmap)
+{
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi5_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_vram_name,
+ BITS_TO_LONGS(bitmap->max_num) * sizeof(long));
+ else
+ vfree(bitmap->table);
+ bitmap->table = NULL;
+}
+
+/**
+ * Prototype : cqm_bitmap_uninit
+ * Description : Deinitialize the bitmap.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ u32 i;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ cla_table = &bat_table->entry[i];
+ bitmap = &cla_table->bitmap;
+ if (cla_table->type != CQM_BAT_ENTRY_T_INVALID) {
+ if (bitmap->table) {
+ spin_lock_deinit(&bitmap->lock);
+ cqm_bitmap_table_free(bitmap);
+ }
+ }
+ }
+
+ cqm_bitmap_toe_uninit(cqm_handle);
+}
+
+/**
+ * Prototype : 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 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 cqm_bitmap_find(struct tag_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 = cqm_bitmap_check_range(table, step, max_num,
+ *index, count);
+ else
+ break;
+ } while (last_num != *index);
+}
+
+static u32 cqm_bitmap_find_with_lowbits_forward(struct tag_cqm_bitmap *bitmap,
+ u32 start, u32 end, u32 lowbits,
+ u32 lowbits_mask)
+{
+ ulong *table = bitmap->table;
+ u32 offset = start;
+ u32 index = CQM_INDEX_INVALID;
+
+ while (offset < end) {
+ index = (u32)find_next_zero_bit(table, end, offset);
+ if (index >= end)
+ return CQM_INDEX_INVALID;
+
+ if ((index & lowbits_mask) == lowbits) /* match lowbits */
+ break;
+
+ offset = index + 1;
+ if (offset == end)
+ return 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 cqm_bitmap_find_with_lowbits_reverse(struct tag_cqm_bitmap *bitmap,
+ u32 start, u32 end, u32 lowbits,
+ u32 lowbits_mask)
+{
+ ulong *table = bitmap->table;
+ u32 offset = start;
+ u32 index = CQM_INDEX_INVALID;
+
+ while (offset > end) {
+ index = (u32)find_next_zero_bit_reverse(table, end, offset);
+ if (index <= end)
+ return CQM_INDEX_INVALID;
+
+ if ((index & lowbits_mask) == lowbits) /* match lowbits */
+ break;
+
+ offset = index - 1;
+ if (offset == end)
+ return CQM_INDEX_INVALID;
+ }
+
+ return index;
+}
+
+/* search range is [start, end) or (end, start] */
+static u32 cqm_bitmap_find_with_lowbits_align(struct tag_cqm_bitmap *bitmap,
+ u32 start, u32 end, u32 xid)
+{
+ u32 lowbits_mode = CQM_DYNAMIC_XID_LB_MODE(xid);
+ u32 lowbits_mask = CQM_DYNAMIC_XID_LOW_BIT_MASK(lowbits_mode);
+ u32 lowbits = (CQM_DYNAMIC_XID_LOW_BITS(xid) & lowbits_mask);
+ u32 index;
+
+ if (start <= end)
+ index = cqm_bitmap_find_with_lowbits_forward(
+ bitmap, start, end, lowbits, lowbits_mask);
+ else
+ index = cqm_bitmap_find_with_lowbits_reverse(
+ bitmap, start, end, lowbits, lowbits_mask);
+
+ return index;
+}
+
+/**
+ * Prototype : 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_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 cqm_bitmap_alloc(struct tag_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. */
+ 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;
+ 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 : 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_cqm_bitmap *bitmap,
+ * struct tag_cqm_bitmap_range *bp_range,
+ * struct tag_cqm_handle *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 cqm_bitmap_alloc_lowbits_align(struct tag_cqm_bitmap *bitmap,
+ struct tag_cqm_bitmap_range *bp_range,
+ struct tag_cqm_handle *cqm_handle, u32 xid,
+ bool update_last)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ ulong *table = bitmap->table;
+ u32 search_mode = 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 == CQM_XID_SEARCH_ALL) {
+ last = bitmap->last;
+ /* Search for an idle bit from the last position. */
+ index = 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 == CQM_INDEX_INVALID) {
+ last = bitmap->reserved_top;
+ index = cqm_bitmap_find_with_lowbits_align(
+ bitmap, last, max_num, xid);
+ }
+ } else {
+ if (CQM_BP_RANGE_VALID(bp_range->start, bp_range->end,
+ bitmap->reserved_top, max_num) == 0) {
+ 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 CQM_INDEX_INVALID;
+ }
+ index = 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 != CQM_INDEX_INVALID) {
+ set_bit(index, table);
+
+ if (update_last && search_mode == 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_cqm_bitmap *bitmap, ulong *table,
+ u32 *ret_index, u32 index)
+{
+ spin_lock(&bitmap->lock);
+ if (test_bit((int)index, table)) {
+ *ret_index = CQM_INDEX_INVALID;
+ } else {
+ set_bit(index, table);
+ *ret_index = index;
+ }
+ spin_unlock(&bitmap->lock);
+}
+
+/**
+ * Prototype : cqm_bitmap_alloc_reserved
+ * Description : Reserve bit applied for based on index.
+ * Input : struct tag_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 cqm_bitmap_alloc_reserved(struct tag_cqm_bitmap *bitmap, u32 count,
+ u32 index)
+{
+ u32 ret_index;
+
+ if (index >= bitmap->max_num || count != 1)
+ return CQM_INDEX_INVALID;
+
+ if (index >= bitmap->reserved_top &&
+ (index < bitmap->max_num - bitmap->reserved_back))
+ return CQM_INDEX_INVALID;
+
+ bitmap_set_table(bitmap, bitmap->table, &ret_index, index);
+ return ret_index;
+}
+
+u32 cqm_bitmap_alloc_by_xid(struct tag_cqm_bitmap *bitmap, u32 count, u32 index)
+{
+ u32 ret_index;
+
+ if (index >= bitmap->max_num || count != 1)
+ return CQM_INDEX_INVALID;
+ bitmap_set_table(bitmap, bitmap->table, &ret_index, index);
+ return ret_index;
+}
+
+/**
+ * Prototype : cqm_bitmap_free
+ * Description : Releases a bitmap index.
+ * Input : struct tag_cqm_bitmap *bitmap,
+ * u32 index,
+ * u32 count
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_bitmap_free(struct tag_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 : cqm_single_object_table_init
+ * Description : Initialize a object table.
+ * Input : struct tag_cqm_object_table *obj_table
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/9/9
+ * Modification : Created function
+ */
+static s32 cqm_single_object_table_init(struct tag_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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(table));
+ return CQM_FAIL;
+ }
+ (void)memset_s(obj_table->table, obj_table->max_num * sizeof(void *), 0,
+ obj_table->max_num * sizeof(void *));
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_object_table_init
+ * Description : Initialize the association table between objects and indexes.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_object_table_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *obj_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ s32 ret = CQM_SUCCESS;
+ u32 i;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ cla_table = &bat_table->entry[i];
+ if (cla_table->obj_num == 0) {
+ 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 CQM_BAT_ENTRY_T_QPC:
+ obj_table->max_num = capability->qpc_number;
+ ret = cqm_single_object_table_init(obj_table);
+ break;
+ case CQM_BAT_ENTRY_T_MPT:
+ obj_table->max_num = capability->mpt_number;
+ ret = cqm_single_object_table_init(obj_table);
+ break;
+ case CQM_BAT_ENTRY_T_SCQC:
+ obj_table->max_num = capability->scqc_number;
+ ret = cqm_single_object_table_init(obj_table);
+ break;
+ case CQM_BAT_ENTRY_T_SRQC:
+ obj_table->max_num = capability->srqc_number;
+ ret = cqm_single_object_table_init(obj_table);
+ break;
+ default:
+ break;
+ }
+
+ if (ret != CQM_SUCCESS) {
+ 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 CQM_SUCCESS;
+
+err:
+ cqm_object_table_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_object_table_uninit
+ * Description : Deinitialize the association table between objects and
+ * indexes.
+ * Input : struct tag_cqm_handle *cqm_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_object_table_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_object_table *obj_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ u32 i;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ cla_table = &bat_table->entry[i];
+ obj_table = &cla_table->obj_table;
+ if (cla_table->type != CQM_BAT_ENTRY_T_INVALID) {
+ if (obj_table->table) {
+ rwlock_deinit(&obj_table->lock);
+ vfree(obj_table->table);
+ obj_table->table = NULL;
+ }
+ }
+ }
+}
+
+/**
+ * Prototype : cqm_object_table_insert
+ * Description : Insert an object
+ * Input : struct tag_cqm_handle *cqm_handle
+ * struct tag_cqm_object_table *object_table
+ * u32 index
+ * struct tag_cqm_object *obj
+ * bool bh
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_object_table_insert(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_object_table *object_table,
+ u32 index, struct tag_cqm_object *obj, bool bh)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ if (index >= object_table->max_num) {
+ cqm_err(handle->dev_hdl,
+ "Obj table insert: index 0x%x exceeds max_num 0x%x\n",
+ index, object_table->max_num);
+ return CQM_FAIL;
+ }
+
+ cqm_write_lock(&object_table->lock, bh);
+
+ if (!object_table->table[index]) {
+ object_table->table[index] = obj;
+ cqm_write_unlock(&object_table->lock, bh);
+ return CQM_SUCCESS;
+ }
+
+ cqm_write_unlock(&object_table->lock, bh);
+ cqm_err(handle->dev_hdl,
+ "Obj table insert: object_table->table[0x%x] has been inserted\n",
+ index);
+
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_object_table_remove
+ * Description : Remove an object
+ * Input : struct tag_cqm_handle *cqm_handle
+ * struct tag_cqm_object_table *object_table
+ * u32 index
+ * const struct tag_cqm_object *obj
+ * bool bh
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_object_table_remove(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_object_table *object_table,
+ u32 index, const struct tag_cqm_object *obj,
+ bool bh)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ if (index >= object_table->max_num) {
+ cqm_err(handle->dev_hdl,
+ "Obj table remove: index 0x%x exceeds max_num 0x%x\n",
+ index, object_table->max_num);
+ return;
+ }
+
+ cqm_write_lock(&object_table->lock, bh);
+
+ if (object_table->table[index] && object_table->table[index] == obj)
+ object_table->table[index] = NULL;
+ else
+ cqm_err(handle->dev_hdl,
+ "Obj table remove: object_table->table[0x%x] has been removed\n",
+ index);
+
+ cqm_write_unlock(&object_table->lock, bh);
+}
+
+/**
+ * Prototype : cqm_object_table_get
+ * Description : Remove an object
+ * Input : struct tag_cqm_handle *cqm_handle
+ * struct tag_cqm_object_table *object_table
+ * u32 index
+ * bool bh
+ * Output : None
+ * Return Value : struct tag_cqm_object *obj
+ * 1.Date : 2018/6/20
+ * Modification : Created function
+ */
+struct tag_cqm_object *
+cqm_object_table_get(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_object_table *object_table, u32 index,
+ bool bh)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object *obj = NULL;
+
+ if (index >= object_table->max_num) {
+ cqm_err(handle->dev_hdl,
+ "Obj table get: index 0x%x exceeds max_num 0x%x\n",
+ index, object_table->max_num);
+ return NULL;
+ }
+
+ cqm_read_lock(&object_table->lock, bh);
+
+ obj = object_table->table[index];
+ if (obj)
+ atomic_inc(&obj->refcount);
+
+ cqm_read_unlock(&object_table->lock, bh);
+
+ return obj;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.h
new file mode 100644
index 000000000..38a42ed76
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bitmap_table.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_BITMAP_TABLE_H
+#define CQM_BITMAP_TABLE_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+
+#include "hinic5_vram_api.h"
+#include "cqm_object.h"
+#include "vram_common.h"
+
+/* cqm_buf_alloc() failed due to buddy allocator page exhaustion. */
+#define CQM_BUF_ALLOC_BUDDY_PAGES_FAIL (CQM_CONTINUE + 1)
+
+struct tag_cqm_bitmap_range {
+ u32 start;
+ u32 end;
+};
+
+struct tag_cqm_bitmap {
+ ulong *table;
+ u32 max_num;
+ u32 last;
+ u32 reserved_top; /* reserved index */
+ u32 reserved_back;
+ spinlock_t lock; /* lock for cqm */
+ struct vram_buf_info bitmap_info;
+};
+
+struct tag_cqm_object_table {
+ /* Now is big array. Later will be optimized as a red-black tree. */
+ struct tag_cqm_object **table;
+ u32 max_num;
+ rwlock_t lock;
+};
+
+struct tag_cqm_handle;
+
+s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle);
+void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle);
+u32 cqm_bitmap_alloc(struct tag_cqm_bitmap *bitmap, u32 step, u32 count,
+ bool update_last);
+u32 cqm_bitmap_alloc_lowbits_align(struct tag_cqm_bitmap *bitmap,
+ struct tag_cqm_bitmap_range *bp_range,
+ struct tag_cqm_handle *cqm_handle, u32 xid,
+ bool update_last);
+u32 cqm_bitmap_alloc_reserved(struct tag_cqm_bitmap *bitmap, u32 count,
+ u32 index);
+void cqm_bitmap_free(struct tag_cqm_bitmap *bitmap, u32 index, u32 count);
+s32 cqm_object_table_init(struct tag_cqm_handle *cqm_handle);
+void cqm_object_table_uninit(struct tag_cqm_handle *cqm_handle);
+s32 cqm_object_table_insert(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_object_table *object_table,
+ u32 index, struct tag_cqm_object *obj, bool bh);
+void cqm_object_table_remove(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_object_table *object_table,
+ u32 index, const struct tag_cqm_object *obj,
+ bool bh);
+struct tag_cqm_object *
+cqm_object_table_get(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_object_table *object_table, u32 index,
+ bool bh);
+u32 cqm_bitmap_alloc_by_xid(struct tag_cqm_bitmap *bitmap, u32 count,
+ u32 index);
+void cqm_swab64(u8 *addr, u32 cnt);
+void cqm_swab32(u8 *addr, u32 cnt);
+bool cqm_check_align(u32 data);
+u32 cqm_shift(u32 data);
+s32 cqm_buf_list_alloc(struct tag_cqm_buf *buf);
+s32 cqm_buf_alloc(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf,
+ bool direct);
+s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf, bool direct);
+void cqm_buf_free(struct tag_cqm_buf *buf, struct device *dev);
+void cqm_buf_free_cache_inv(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_buf *buf, s32 *inv_flag);
+s32 cqm_cla_cache_invalid(struct tag_cqm_handle *cqm_handle, dma_addr_t pa,
+ u32 cache_size);
+void *cqm_kmalloc_align(size_t size, gfp_t flags, u16 align_order);
+void cqm_kfree_align(void *addr);
+
+#endif /* CQM_BITMAP_TABLE_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.c
new file mode 100644
index 000000000..36b390017
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.c
@@ -0,0 +1,549 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "hisdk5_typedef.h"
+
+#include "cqm_object.h"
+#include "cqm_bitmap_table.h"
+#include "cqm_bat_cla.h"
+#include "cqm_cmd.h"
+#include "cqm_main.h"
+#include "cqm_bloomfilter.h"
+
+#include "cqm_npu_cmd.h"
+#include "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_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ cqm_bloomfilter_init_cmd_s *cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ s32 ret;
+
+ buf_in = cqm5_cmd_alloc((void *)(cqm_handle->ex_handle));
+ if (unlikely(buf_in == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(buf_in));
+ return CQM_FAIL;
+ }
+
+ /* Fill the command format and convert it to big-endian. */
+ buf_in->size = sizeof(cqm_bloomfilter_init_cmd_s);
+ cmd = (cqm_bloomfilter_init_cmd_s *)(buf_in->buf);
+ cmd->bloom_filter_addr = capability->bloomfilter_addr;
+ cmd->bloom_filter_len = capability->bloomfilter_length;
+
+ cqm_swab32((u8 *)cmd,
+ (sizeof(cqm_bloomfilter_init_cmd_s) >> CQM_DW_SHIFT));
+
+ ret = cqm5_send_cmd_box((void *)(cqm_handle->ex_handle), CQM_MOD_CQM,
+ CQM_CMD_T_BLOOMFILTER_INIT, buf_in, NULL, NULL,
+ CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm5_send_cmd_box));
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "Bloomfilter: %s ret=%d\n", __func__, ret);
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "Bloomfilter: %s: 0x%x 0x%x\n", __func__,
+ cmd->bloom_filter_addr, cmd->bloom_filter_len);
+ cqm5_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
+ return CQM_FAIL;
+ }
+ cqm5_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
+ return CQM_SUCCESS;
+}
+
+static void cqm_func_bloomfilter_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bloomfilter_table *bloomfilter_table =
+ &cqm_handle->bloomfilter_table;
+
+ if (bloomfilter_table->table) {
+ mutex_deinit(&bloomfilter_table->lock);
+ vfree(bloomfilter_table->table);
+ bloomfilter_table->table = NULL;
+ }
+}
+
+static s32 cqm_func_bloomfilter_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_bloomfilter_table *bloomfilter_table = NULL;
+ struct tag_cqm_func_capability *capability = NULL;
+ u32 array_size;
+ s32 ret;
+
+ bloomfilter_table = &cqm_handle->bloomfilter_table;
+ capability = &cqm_handle->func_capability;
+
+ if (capability->bloomfilter_length == 0) {
+ cqm_info(
+ cqm_handle->ex_handle->dev_hdl,
+ "Bloomfilter: bf_length=0, don't need to init bloomfilter\n");
+ return 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
+ << 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 > CQM_BF_BITARRAY_MAX) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ CQM_WRONG_VALUE(array_size));
+ return 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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(table));
+ return CQM_FAIL;
+ }
+
+ (void)memset_s(bloomfilter_table->table,
+ (bloomfilter_table->table_size * sizeof(u32)), 0,
+ (bloomfilter_table->table_size * sizeof(u32)));
+
+ /* The the bloomfilter must be initialized to 0 by ucode,
+ * because the bloomfilter is mem mode
+ */
+ if (cqm_handle->func_capability.bloomfilter_enable != 0) {
+ ret = bloomfilter_init_cmd(cqm_handle);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(cqm_handle->ex_handle->dev_hdl,
+ "Bloomfilter: bloomfilter_init_cmd ret=%d\n",
+ ret);
+ vfree(bloomfilter_table->table);
+ bloomfilter_table->table = NULL;
+ return CQM_FAIL;
+ }
+ }
+
+ mutex_init(&bloomfilter_table->lock);
+
+ cqm_dbg(cqm_handle->dev,
+ "Bloomfilter: table_size=0x%x, array_size=0x%x\n",
+ bloomfilter_table->table_size, array_size);
+ return CQM_SUCCESS;
+}
+
+static void cqm_fake_bloomfilter_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ u32 i, child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return;
+
+ for (i = 0; i < child_func_number; i++) {
+ cqm_func_bloomfilter_uninit(cqm_handle->fake_cqm_handle[i]);
+ }
+}
+
+static s32 cqm_fake_bloomfilter_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_handle *fake_cqm_handle = NULL;
+ u32 i, child_func_number;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return CQM_SUCCESS;
+
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ for (i = 0; i < child_func_number; i++) {
+ fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
+ if (cqm_func_bloomfilter_init(fake_cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_func_bloomfilter_init));
+ goto bloomfilter_init_err;
+ }
+ }
+
+ return CQM_SUCCESS;
+
+bloomfilter_init_err:
+ cqm_fake_bloomfilter_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_bloomfilter_init
+ * Description : initialize the bloomfilter of cqm
+ * Input : void *ex_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2016/7/6
+ * Modification : Created function
+ */
+s32 cqm_bloomfilter_init(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ if (cqm_fake_bloomfilter_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_fake_bloomfilter_init));
+ return CQM_FAIL;
+ }
+
+ if (cqm_func_bloomfilter_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_func_bloomfilter_init));
+ goto bloomfilter_init_err;
+ }
+
+ return CQM_SUCCESS;
+
+bloomfilter_init_err:
+ cqm_fake_bloomfilter_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_bloomfilter_uninit
+ * Description : uninitialize the bloomfilter of cqm
+ * Input : void *ex_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2016/7/6
+ * Modification : Created function
+ */
+void cqm_bloomfilter_uninit(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ cqm_fake_bloomfilter_uninit(cqm_handle);
+ cqm_func_bloomfilter_uninit(cqm_handle);
+}
+
+/**
+ * Prototype : 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 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_cqm_cmd_buf *buf_in = NULL;
+ cqm_bloomfilter_cmd_s *cmd = NULL;
+ s32 ret;
+
+ buf_in = cqm5_cmd_alloc(ex_handle);
+ if (unlikely(buf_in == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(buf_in));
+ return CQM_FAIL;
+ }
+
+ /* Fill the command format and convert it to big-endian. */
+ buf_in->size = sizeof(cqm_bloomfilter_cmd_s);
+ cmd = (cqm_bloomfilter_cmd_s *)(buf_in->buf);
+ (void)memset_s((void *)cmd, sizeof(cqm_bloomfilter_cmd_s), 0,
+ sizeof(cqm_bloomfilter_cmd_s));
+ cmd->func_id = func_id;
+ cmd->k_en = k_flag;
+ cmd->index_h = (u32)(id >> CQM_DW_OFFSET);
+ cmd->index_l = (u32)(id & CQM_DW_MASK);
+
+ cqm_swab32((u8 *)cmd, (sizeof(cqm_bloomfilter_cmd_s) >> CQM_DW_SHIFT));
+
+ ret = cqm5_send_cmd_box(ex_handle, CQM_MOD_CQM, (u8)op, buf_in, NULL,
+ NULL, CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm5_send_cmd_box));
+ cqm_err(handle->dev_hdl,
+ "Bloomfilter: bloomfilter_cmd ret=%d\n", ret);
+ 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) + CQM_DW_INDEX1),
+ *(((u32 *)(void *)cmd) + CQM_DW_INDEX2),
+ *(((u32 *)(void *)cmd) + CQM_DW_INDEX3));
+ cqm5_cmd_free(ex_handle, buf_in);
+ return CQM_FAIL;
+ }
+
+ cqm5_cmd_free(ex_handle, buf_in);
+
+ return CQM_SUCCESS;
+}
+
+STATIC struct tag_cqm_handle *
+cqm_get_func_cqm_handle(struct hinic5_hwdev *ex_handle, u16 func_id)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ u32 child_func_start, child_func_number;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(ex_handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return NULL;
+ }
+
+ /* function id is PF/VF */
+ if (func_id == hinic5_global_func_id(ex_handle))
+ return cqm_handle;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle)) {
+ cqm_err(ex_handle->dev_hdl,
+ CQM_WRONG_VALUE(CQM_FAKE_FUNC_TYPE(cqm_handle)));
+ return NULL;
+ }
+
+ child_func_start = cqm_get_child_func_start(cqm_handle);
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+ /* function id is fake vf */
+ if (func_id >= child_func_start &&
+ (func_id < (child_func_start + child_func_number)))
+ return cqm_handle
+ ->fake_cqm_handle[func_id - (u16)child_func_start];
+
+ return NULL;
+}
+
+/**
+ * Prototype : cqm5_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 cqm5_bloomfilter_inc(void *ex_handle, u16 func_id, u64 id)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_bloomfilter_table *bloomfilter_table = NULL;
+ u32 array_tmp[CQM_BF_SECTION_NUMBER] = { 0 };
+ struct tag_cqm_handle *cqm_handle = NULL;
+ u32 array_index, array_bit, i;
+ u32 k_flag = 0;
+
+ if (!ex_handle)
+ return CQM_FAIL;
+
+ cqm_dbg_on(cqm_verbose, handle->dev_hdl,
+ "Bloomfilter: func_id: %d, inc id=0x%llx\n", func_id, id);
+
+ cqm_handle = cqm_get_func_cqm_handle(ex_handle, func_id);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+
+ if (cqm_handle->func_capability.bloomfilter_enable == 0) {
+ cqm_info(handle->dev_hdl,
+ "Bloomfilter inc: bloomfilter is disable\n");
+ return 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 = &cqm_handle->bloomfilter_table;
+
+ /* The array index identifies a 32-byte entry. */
+ array_index =
+ (u32)CQM_BF_BITARRAY_INDEX(id, bloomfilter_table->array_mask);
+ /* convert the unit of array_index to bit */
+ array_index = array_index << CQM_BF_ENTRY_SIZE_UNIT;
+ cqm_dbg_on(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 < CQM_BF_SECTION_NUMBER; i++) {
+ /* the position of the bit in 64-bit section */
+ array_bit = (id >>
+ (CQM_BF_SECTION_BASE + i * CQM_BF_SECTION_SIZE)) &
+ 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 * 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])++;
+ cqm_dbg_on(
+ 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 &&
+ cqm_bloomfilter_cmd(ex_handle, func_id, CQM_CMD_T_BLOOMFILTER_SET,
+ k_flag, id) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_bloomfilter_cmd_inc));
+ for (i = 0; i < CQM_BF_SECTION_NUMBER; i++) {
+ array_bit = array_tmp[i];
+ (bloomfilter_table->table[array_bit])--;
+ }
+ mutex_unlock(&bloomfilter_table->lock);
+ return CQM_FAIL;
+ }
+
+ mutex_unlock(&bloomfilter_table->lock);
+
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_bloomfilter_inc);
+
+/**
+ * Prototype : cqm5_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 cqm5_bloomfilter_dec(void *ex_handle, u16 func_id, u64 id)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_bloomfilter_table *bloomfilter_table = NULL;
+ u32 array_tmp[CQM_BF_SECTION_NUMBER] = { 0 };
+ u8 decremented[CQM_BF_SECTION_NUMBER] = { 0 };
+ struct tag_cqm_handle *cqm_handle = NULL;
+ u32 array_index, array_bit, i;
+ u32 k_flag = 0;
+
+ if (!ex_handle)
+ return CQM_FAIL;
+
+ cqm_handle = cqm_get_func_cqm_handle(ex_handle, func_id);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+
+ if (cqm_handle->func_capability.bloomfilter_enable == 0) {
+ cqm_info(handle->dev_hdl,
+ "Bloomfilter dec: bloomfilter is disable\n");
+ return CQM_SUCCESS;
+ }
+
+ bloomfilter_table = &cqm_handle->bloomfilter_table;
+
+ /* The array index identifies a 32-byte entry. */
+ array_index =
+ (u32)CQM_BF_BITARRAY_INDEX(id, bloomfilter_table->array_mask);
+ cqm_dbg_on(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 < CQM_BF_SECTION_NUMBER; i++) {
+ /* the position of the bit in 64-bit section */
+ array_bit = (id >>
+ (CQM_BF_SECTION_BASE + i * CQM_BF_SECTION_SIZE)) &
+ 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]--;
+ decremented[i] = 1;
+ cqm_dbg_on(
+ 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 &&
+ cqm_bloomfilter_cmd(ex_handle, func_id, CQM_CMD_T_BLOOMFILTER_CLEAR,
+ k_flag, id) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_bloomfilter_cmd_dec));
+ for (i = 0; i < CQM_BF_SECTION_NUMBER; i++) {
+ if (decremented[i]) {
+ array_bit = array_tmp[i];
+ (bloomfilter_table->table[array_bit])++;
+ }
+ }
+ mutex_unlock(&bloomfilter_table->lock);
+ return CQM_FAIL;
+ }
+
+ mutex_unlock(&bloomfilter_table->lock);
+
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_bloomfilter_dec);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.h
new file mode 100644
index 000000000..48c7ae8f6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_bloomfilter.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_BLOOMFILTER_H
+#define 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 CQM_BF_ENTRY_SIZE 32
+#define CQM_BF_ENTRY_SIZE_UNIT 8
+#define CQM_BF_BITARRAY_MAX BIT(17)
+
+#define CQM_BF_SECTION_NUMBER 4
+#define CQM_BF_SECTION_BASE 8
+#define CQM_BF_SECTION_SIZE 6
+#define CQM_BF_SECTION_MASK 0x3f
+#define CQM_BF_SECTION_BIT_NUMBER 64
+
+#define CQM_BF_ARRAY_INDEX_OFFSET 32
+#define CQM_BF_BITARRAY_INDEX(id, mask) \
+ (((id) >> CQM_BF_ARRAY_INDEX_OFFSET) & (mask))
+
+/* The unit of bloomfilter_length is 64B(512bits). */
+#define CQM_BF_LENGTH_UNIT 9
+
+#define CQM_DW_MASK 0xffffffff
+#define CQM_DW_OFFSET 32
+#define CQM_DW_INDEX0 0
+#define CQM_DW_INDEX1 1
+#define CQM_DW_INDEX2 2
+#define CQM_DW_INDEX3 3
+
+struct tag_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 cqm_bloomfilter_cmd(void *ex_handle, u16 func_id, u32 op, u32 k_flag,
+ u64 id);
+s32 cqm_bloomfilter_init(void *ex_handle);
+void cqm_bloomfilter_uninit(void *ex_handle);
+s32 cqm5_bloomfilter_inc(void *ex_handle, u16 func_id, u64 id);
+s32 cqm5_bloomfilter_dec(void *ex_handle, u16 func_id, u64 id);
+
+#endif /* CQM_BLOOMFILTER_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.c
new file mode 100644
index 000000000..709635a68
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "cqm_bitmap_table.h"
+#include "cqm_bat_cla.h"
+#include "cqm_main.h"
+
+/**
+ * Prototype : cqm5_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_cqm_cmd_buf *
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+struct tag_cqm_cmd_buf *cqm5_cmd_alloc(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_cmd_alloc_cnt);
+
+ return (struct tag_cqm_cmd_buf *)(void *)hinic5_alloc_cmd_buf(
+ ex_handle);
+}
+EXPORT_SYMBOL(cqm5_cmd_alloc);
+
+/**
+ * Prototype : cqm5_cmd_free
+ * Description : Release for a cmd buffer.
+ * Input : void *ex_handle
+ * struct tag_cqm_cmd_buf *cmd_buf
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm5_cmd_free(void *ex_handle, struct tag_cqm_cmd_buf *cmd_buf)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+ if (unlikely(cmd_buf == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cmd_buf));
+ return;
+ }
+ if (unlikely(cmd_buf->buf == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_cmd_free_cnt);
+
+ hinic5_free_cmd_buf(ex_handle,
+ (struct hinic5_cmd_buf *)(void *)cmd_buf);
+}
+EXPORT_SYMBOL(cqm5_cmd_free);
+
+/**
+ * Prototype : cqm5_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_cqm_cmd_buf *buf_in
+ * struct tag_cqm_cmd_buf *buf_out
+ * u64 *out_param
+ * u32 timeout
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm5_send_cmd_box(void *ex_handle, u8 mod, u8 cmd,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_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)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+ if (unlikely(buf_in == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf_in));
+ return CQM_FAIL;
+ }
+ if (unlikely(buf_in->buf == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf));
+ return CQM_FAIL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_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(cqm5_send_cmd_box);
+
+/**
+ * Prototype : cqm5_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_cqm_cmd_buf *buf_in
+ * struct tag_cqm_cmd_buf *buf_out
+ * u64 *out_param
+ * u32 timeout
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2020/4/9
+ * Modification : Created function
+ */
+s32 cqm5_lb_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, u8 cos_id,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_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)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf_in));
+ return CQM_FAIL;
+ }
+ if (unlikely(buf_in->buf == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf_in->buf));
+ return CQM_FAIL;
+ }
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_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(cqm5_lb_send_cmd_box);
+
+/**
+ * Prototype : cqm5_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_cqm_cmd_buf *buf_in
+ * u64 *out_param
+ * u32 timeout
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm5_send_cmd_imm(void *ex_handle, u8 mod, u8 cmd,
+ struct tag_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)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf_in));
+ return CQM_FAIL;
+ }
+ if (unlikely(buf_in->buf == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(buf));
+ return CQM_FAIL;
+ }
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_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(cqm5_send_cmd_imm);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.h
new file mode 100644
index 000000000..21273781d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmd.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_CMD_H
+#define CQM_CMD_H
+
+#include <linux/types.h>
+
+#include "cqm_object.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+#ifndef HI1825V100
+#define CQM_CMD_TIMEOUT 10000 /* ms */
+#else
+#define CQM_CMD_TIMEOUT 1000000 /* ms */
+#endif
+
+struct tag_cqm_cmd_buf *cqm5_cmd_alloc(void *ex_handle);
+void cqm5_cmd_free(void *ex_handle, struct tag_cqm_cmd_buf *cmd_buf);
+s32 cqm5_send_cmd_box(void *ex_handle, u8 mod, u8 cmd,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, u16 channel);
+s32 cqm5_lb_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, u8 cos_id,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, u16 channel);
+s32 cqm5_send_cmd_imm(void *ex_handle, u8 mod, u8 cmd,
+ struct tag_cqm_cmd_buf *buf_in, u64 *out_param,
+ u32 timeout, u16 channel);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* CQM_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq.h
new file mode 100644
index 000000000..5ce4ecded
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_CMDQ_H
+#define CQM_CMDQ_H
+
+#include "ossl_knl.h"
+#include "cqm_npu_cmd_defs.h"
+#include "cqm_main.h"
+
+struct cqm_cmdq_ops {
+ s32 (*prepare_cmd_buf_bat_update)(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_bat_update_param *param,
+ u8 *cmd);
+ void (*prepare_cmd_buf_cla_update)(cqm_cla_update_cmd_s *cmd_info,
+ struct tag_cqm_cmd_buf *buf_in,
+ u8 *cmd);
+ void (*prepare_cmd_cache_invalidate)(
+ cqm_cla_cache_invalid_cmd_s *cmd_info,
+ struct tag_cqm_cmd_buf *buf_in, u8 *cmd);
+};
+
+struct cqm_cmdq_ops *cqm_cmdq_get_182x_ops(void);
+struct cqm_cmdq_ops *cqm_cmdq_get_187x_ops(void);
+
+void cqm_cmdq_adapt_init(struct tag_cqm_handle *cqm_handle);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq_adapt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq_adapt.c
new file mode 100644
index 000000000..4d5675b65
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_cmdq_adapt.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#include "cqm_cmdq.h"
+#include "hinic5_hwdev.h"
+
+void cqm_cmdq_adapt_init(struct tag_cqm_handle *cqm_handle)
+{
+ if (!COMM_SUPPORT_HTN_CMD(cqm_handle->ex_handle)) {
+ cqm_handle->cmdq_ops = cqm_cmdq_get_182x_ops();
+ } else {
+ cqm_handle->cmdq_ops = cqm_cmdq_get_187x_ops();
+ }
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.c
new file mode 100644
index 000000000..d9acdfe48
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.c
@@ -0,0 +1,571 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "cqm_object.h"
+#include "cqm_bitmap_table.h"
+#include "cqm_bat_cla.h"
+#include "cqm_object_intern.h"
+#include "cqm_main.h"
+#include "cqm_db.h"
+
+/**
+ * Prototype : cqm5_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 cqm5_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)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+ if (unlikely(db_addr == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(db_addr));
+ return CQM_FAIL;
+ }
+ if (unlikely(dwqe_addr == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(dwqe_addr));
+ return CQM_FAIL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_db_addr_alloc_cnt);
+
+ return hinic5_alloc_db_addr(ex_handle, db_addr, dwqe_addr);
+}
+
+s32 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 : cqm5_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 cqm5_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)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm5_db_addr_free_cnt);
+
+ hinic5_free_db_addr(ex_handle, db_addr, dwqe_addr);
+}
+
+static void 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 cqm_need_db_init(s32 service)
+{
+ switch (service) {
+ case CQM_SERVICE_T_NIC:
+ case CQM_SERVICE_T_OVS:
+ case CQM_SERVICE_T_IPSEC:
+ case CQM_SERVICE_T_VIRTIO:
+ case CQM_SERVICE_T_PPA:
+ return false;
+ default:
+ return true;
+ }
+}
+
+/**
+ * Prototype : cqm_db_init
+ * Description : Initialize the doorbell of the CQM.
+ * Input : void *ex_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/7/6
+ * Modification : Created function
+ */
+s32 cqm_db_init(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ s32 i;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ /* Allocate hardware doorbells to services. */
+ for (i = 0; i < CQM_SERVICE_T_MAX; i++) {
+ service = &cqm_handle->service[i];
+ if (!cqm_need_db_init(i) || !service->valid)
+ continue;
+
+ if (cqm5_db_addr_alloc(ex_handle, &service->hardware_db_vaddr,
+ &service->dwqe_vaddr) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm5_db_addr_alloc));
+ break;
+ }
+
+ if (cqm_db_phy_addr_alloc(handle, &service->hardware_db_paddr,
+ &service->dwqe_paddr) !=
+ CQM_SUCCESS) {
+ cqm5_db_addr_free(ex_handle, service->hardware_db_vaddr,
+ service->dwqe_vaddr);
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_db_phy_addr_alloc));
+ break;
+ }
+ }
+
+ if (i != CQM_SERVICE_T_MAX) {
+ i--;
+ for (; i >= 0; i--) {
+ service = &cqm_handle->service[i];
+ if (!cqm_need_db_init(i) || !service->valid)
+ continue;
+
+ cqm5_db_addr_free(ex_handle, service->hardware_db_vaddr,
+ service->dwqe_vaddr);
+ cqm_db_phy_addr_free(ex_handle,
+ &service->hardware_db_paddr,
+ &service->dwqe_paddr);
+ }
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_db_uninit
+ * Description : Deinitialize the doorbell of the CQM.
+ * Input : void *ex_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/7/6
+ * Modification : Created function
+ */
+void cqm_db_uninit(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ s32 i;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ /* Release hardware doorbell. */
+ for (i = 0; i < CQM_SERVICE_T_MAX; i++) {
+ service = &cqm_handle->service[i];
+ if (service->valid && cqm_need_db_init(i)) {
+ cqm5_db_addr_free(ex_handle, service->hardware_db_vaddr,
+ service->dwqe_vaddr);
+ cqm_db_phy_addr_free(ex_handle,
+ &service->hardware_db_paddr,
+ &service->dwqe_paddr);
+ }
+ }
+}
+
+/**
+ * Prototype : cqm5_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 *cqm5_get_db_addr(void *ex_handle, u32 service_type)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("service_type is out of bounds\n");
+ return NULL;
+ }
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+ handle = (struct hinic5_hwdev *)ex_handle;
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return NULL;
+ }
+
+ service = &cqm_handle->service[service_type];
+
+ return (void *)service->hardware_db_vaddr;
+}
+EXPORT_SYMBOL(cqm5_get_db_addr);
+
+/**
+ * Prototype : cqm5_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 cqm5_get_hardware_db_addr(void *ex_handle, u64 *addr,
+ enum hinic5_service_type service_type)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+ if (unlikely(addr == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(addr));
+ return 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 CQM_FAIL;
+ }
+
+ handle = (struct hinic5_hwdev *)ex_handle;
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+
+ service = &cqm_handle->service[service_type];
+
+ *addr = service->hardware_db_paddr;
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_get_hardware_db_addr);
+
+/**
+ * Prototype : cqm5_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 cqm5_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count,
+ u64 db)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+#if defined(__UEFI__) && defined(__HIFC__)
+ EFI_STATUS Status;
+ u64 *offset = NULL;
+#endif
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("service_type is out of bounds\n");
+ return CQM_FAIL;
+ }
+ if (!ex_handle)
+ return CQM_FAIL;
+ handle = (struct hinic5_hwdev *)ex_handle;
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (!cqm_handle)
+ return CQM_FAIL;
+
+ service = &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 CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_ring_hardware_db);
+
+/**
+ * Prototype : cqm5_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 cqm5_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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+ void *dbaddr = NULL;
+
+ handle = (struct hinic5_hwdev *)ex_handle;
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ service = &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 CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm5_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 cqm5_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
+ void *direct_wqe)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+ u64 *tmp = (u64 *)direct_wqe;
+ int i;
+
+ if (!ex_handle)
+ return CQM_FAIL;
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("service_type is out of bounds\n");
+ return CQM_FAIL;
+ }
+
+ handle = (struct hinic5_hwdev *)ex_handle;
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (!cqm_handle)
+ return CQM_FAIL;
+
+ service = &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 CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_ring_direct_wqe_db);
+
+s32 cqm5_ring_direct_wqe_db_fc(void *ex_handle, u32 service_type,
+ void *direct_wqe)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+ u64 *tmp = (u64 *)direct_wqe;
+ int i;
+
+ handle = (struct hinic5_hwdev *)ex_handle;
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ service = &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 CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm5_ring_hardware_db_update_pri
+ * Description : Provides the doorbell interface for the 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 cqm5_ring_hardware_db_update_pri(void *ex_handle, u32 service_type,
+ u8 db_count, u64 db)
+{
+ struct tag_cqm_db_common *db_common =
+ (struct tag_cqm_db_common *)(void *)(&db);
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct hinic5_hwdev *handle = NULL;
+
+ handle = (struct hinic5_hwdev *)ex_handle;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ service = &cqm_handle->service[service_type];
+
+ /* the CQM converts the PRI to the CoS */
+ db_common->cos = 0x7 - db_common->cos;
+
+ cqm_swab32((u8 *)db_common, sizeof(u64) >> 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 CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm5_ring_software_db
+ * Description : Ring software db.
+ * Input : struct tag_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 cqm5_ring_software_db(struct tag_cqm_object *object, u64 db_record)
+{
+ struct tag_cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
+ struct tag_cqm_rdma_qinfo *rdma_qinfo = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct hinic5_hwdev *handle = NULL;
+
+ if (unlikely(object == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object));
+ return CQM_FAIL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)object->cqm_handle;
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+ handle = cqm_handle->ex_handle;
+
+ if (object->object_type == CQM_OBJECT_NONRDMA_EMBEDDED_RQ ||
+ object->object_type == CQM_OBJECT_NONRDMA_EMBEDDED_SQ ||
+ object->object_type == CQM_OBJECT_NONRDMA_SRQ) {
+ nonrdma_qinfo = (struct tag_cqm_nonrdma_qinfo *)(void *)object;
+ nonrdma_qinfo->common.q_header_vaddr->doorbell_record =
+ db_record;
+ } else if ((object->object_type == CQM_OBJECT_NONRDMA_EMBEDDED_CQ) ||
+ (object->object_type == CQM_OBJECT_NONRDMA_SCQ)) {
+ nonrdma_qinfo = (struct tag_cqm_nonrdma_qinfo *)(void *)object;
+ nonrdma_qinfo->common.q_header_vaddr->ci_record = db_record;
+ } else if ((object->object_type == CQM_OBJECT_RDMA_QP) ||
+ (object->object_type == CQM_OBJECT_RDMA_SRQ)) {
+ rdma_qinfo = (struct tag_cqm_rdma_qinfo *)(void *)object;
+ rdma_qinfo->common.q_header_vaddr->doorbell_record = db_record;
+ } else if (object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ rdma_qinfo = (struct tag_cqm_rdma_qinfo *)(void *)object;
+ rdma_qinfo->common.q_header_vaddr->ci_record = db_record;
+ } else {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->object_type));
+ }
+
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_ring_software_db);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.h
new file mode 100644
index 000000000..41e2e2c30
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_db.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_DB_H
+#define CQM_DB_H
+
+#include <linux/types.h>
+
+struct tag_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 cqm5_db_addr_alloc(void *ex_handle, void __iomem **db_addr,
+ void __iomem **dwqe_addr);
+s32 cqm_db_phy_addr_alloc(void *ex_handle, u64 *db_paddr, u64 *dwqe_addr);
+
+s32 cqm_db_init(void *ex_handle);
+void cqm_db_uninit(void *ex_handle);
+
+s32 cqm5_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count,
+ u64 db);
+
+#endif /* CQM_DB_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.c
new file mode 100644
index 000000000..f4567a49a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.c
@@ -0,0 +1,2262 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "hisdk5_hwif.h"
+#include "hinic5_hw_cfg.h"
+#include "hinic5_vram_api.h"
+#include "hisdk5_typedef.h"
+
+#include "vram_common.h"
+
+#include "cqm_object.h"
+#include "cqm_bitmap_table.h"
+#include "cqm_bat_cla.h"
+#include "cqm_bloomfilter.h"
+#include "cqm_db.h"
+#include "cqm_cmdq.h"
+#include "cqm_main.h"
+
+static s32 cqm_set_fake_vf_child_timer(struct tag_cqm_handle *cqm_handle,
+ struct tag_cqm_handle *fake_cqm_handle,
+ bool en)
+{
+ struct hinic5_hwdev *handle =
+ (struct hinic5_hwdev *)cqm_handle->ex_handle;
+ u16 func_global_idx;
+ s32 ret;
+
+ if (fake_cqm_handle->func_capability.timer_enable == 0) {
+ return CQM_SUCCESS;
+ }
+
+ func_global_idx = fake_cqm_handle->func_attribute.func_global_idx;
+ ret = hinic5_func_tmr_bitmap_set(cqm_handle->ex_handle, func_global_idx,
+ en);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ "func_id %u Timer %s timer bitmap failed\n",
+ func_global_idx, en ? "enable" : "disable");
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_unset_fake_vf_timer(struct tag_cqm_handle *cqm_handle)
+{
+ u32 i, child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ for (i = 0; i < child_func_number; i++)
+ (void)cqm_set_fake_vf_child_timer(
+ cqm_handle, cqm_handle->fake_cqm_handle[i], false);
+}
+
+static s32 cqm_set_fake_vf_timer(struct tag_cqm_handle *cqm_handle)
+{
+ u32 i, child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ for (i = 0; i < child_func_number; i++) {
+ s32 ret = cqm_set_fake_vf_child_timer(
+ cqm_handle, cqm_handle->fake_cqm_handle[i], true);
+ if (ret != CQM_SUCCESS)
+ goto err;
+ }
+
+ return CQM_SUCCESS;
+
+err:
+ cqm_unset_fake_vf_timer(cqm_handle);
+ return CQM_FAIL;
+}
+
+static s32 cqm_set_timer_enable(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = ex_handle;
+ struct tag_cqm_handle *cqm_handle = handle->cqm_hdl;
+ u16 func_id = hinic5_global_func_id(ex_handle);
+ int is_in_kexec;
+
+ is_in_kexec = vram5_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl,
+ "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
+ /* Enable children */
+ if (CQM_IS_FAKE_PARENT(cqm_handle) &&
+ cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
+ return CQM_FAIL;
+
+ /* Enable self */
+ if (hinic5_func_tmr_bitmap_set(ex_handle, func_id, true) !=
+ CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ "Timer start: enable timer bitmap failed\n");
+ goto err;
+ }
+
+ return CQM_SUCCESS;
+
+err:
+ if (CQM_IS_FAKE_PARENT(cqm_handle))
+ cqm_unset_fake_vf_timer(cqm_handle);
+ return CQM_FAIL;
+}
+
+static void cqm_set_timer_disable(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = ex_handle;
+ struct tag_cqm_handle *cqm_handle = handle->cqm_hdl;
+
+ /* Disable self */
+ if (hinic5_func_tmr_bitmap_set(ex_handle,
+ hinic5_global_func_id(ex_handle),
+ false) != CQM_SUCCESS)
+ cqm_err(handle->dev_hdl,
+ "func_id %u Timer stop: disable timer bitmap failed\n",
+ hinic5_global_func_id(ex_handle));
+
+ /* Disable children */
+ if (CQM_IS_FAKE_PARENT(cqm_handle))
+ cqm_unset_fake_vf_timer(cqm_handle);
+}
+
+static u32 cqm_set_vio_enable(void *ex_handle, bool enable)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ int err;
+
+ if (!ex_handle)
+ return CQM_FAIL;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (!cqm_handle->service[CQM_SERVICE_T_VIRTIO].valid)
+ return CQM_SUCCESS;
+
+ err = hinic5_func_vio_en(ex_handle, enable);
+ if (err != 0) {
+ cqm_err(handle->dev_hdl, "VIO %s failed, err %d\n",
+ (enable ? "enable" : "disable"), err);
+ return CQM_FAIL;
+ }
+
+ cqm_info(handle->dev_hdl, "VIO %s success\n",
+ (enable ? "enable" : "disable"));
+ return CQM_SUCCESS;
+}
+
+static s32 cqm5_initialize_recource(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+
+ /* Initialize memory entries such as BAT, CLA, and bitmap. */
+ if (cqm_mem_init(ex_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_mem_init));
+ return CQM_FAIL;
+ }
+
+ /* Event callback initialization */
+ if (cqm_event_init(ex_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_event_init));
+ goto err1;
+ }
+
+ /* Doorbell initiation */
+ if (cqm_db_init(ex_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_db_init));
+ goto err2;
+ }
+
+ /* Initialize the bloom filter. */
+ if (cqm_bloomfilter_init(ex_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_bloomfilter_init));
+ goto err3;
+ }
+
+ if (cqm_set_timer_enable(ex_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_set_timer_enable));
+ goto err4;
+ }
+
+ if (cqm_set_vio_enable(ex_handle, true) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_set_vio_enable));
+ goto err5;
+ }
+
+ return CQM_SUCCESS;
+
+err5:
+ cqm_set_timer_disable(ex_handle);
+err4:
+ cqm_bloomfilter_uninit(ex_handle);
+err3:
+ cqm_db_uninit(ex_handle);
+err2:
+ cqm_event_uninit(ex_handle);
+err1:
+ cqm_mem_uninit(ex_handle);
+ return CQM_FAIL;
+}
+
+static struct tag_cqm_handle *cqm_handle_create(void)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+
+ cqm_handle = kzalloc(sizeof(*cqm_handle), GFP_KERNEL);
+ if (unlikely(!cqm_handle)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(cqm_handle));
+ return NULL;
+ }
+
+ /* Clear the memory to prevent other systems from
+ * not clearing the memory.
+ */
+ (void)memset_s(cqm_handle, sizeof(struct tag_cqm_handle), 0,
+ sizeof(struct tag_cqm_handle));
+
+ atomic_set(&cqm_handle->handle_state, CQM_HANDLE_STATE_INIT);
+
+ return cqm_handle;
+}
+
+static struct tag_cqm_handle *
+cqm_handle_fork(struct tag_cqm_handle *parent_handle)
+{
+ struct tag_cqm_handle *child_handle = NULL;
+
+ child_handle = kzalloc(sizeof(*child_handle), GFP_KERNEL);
+ if (unlikely(!child_handle)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(child_handle));
+ return NULL;
+ }
+
+ /* Copy the attributes of the parent CQM handle to the child CQM
+ * handle and modify the values of function.
+ */
+ (void)memcpy_s(child_handle, sizeof(struct tag_cqm_handle),
+ parent_handle, sizeof(struct tag_cqm_handle));
+
+ /* Clear state & unlink some references */
+ atomic_set(&child_handle->handle_state, CQM_HANDLE_STATE_INIT);
+ (void)memset_s(child_handle->fake_cqm_handle,
+ sizeof(child_handle->fake_cqm_handle), 0,
+ sizeof(child_handle->fake_cqm_handle));
+
+ return child_handle;
+}
+
+/**
+ * Prototype : cqm5_init
+ * Description : Complete 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.
+ * cqm5_init->cqm_mem_init->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 cqm5_init(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ s32 ret;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+
+ cqm_handle = cqm_handle_create();
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_FUNCTION_FAIL(cqm_handle_create));
+ return CQM_FAIL;
+ }
+
+ cqm_handle->ex_handle = handle;
+ cqm_handle->dev = handle->dev_hdl;
+ handle->cqm_hdl = (void *)cqm_handle;
+
+ /* 187x ops or 182x ops */
+ cqm_cmdq_adapt_init(cqm_handle);
+ /* Clearing Statistics */
+ (void)memset_s(&handle->hw_stats.cqm_stats, sizeof(struct cqm_stats), 0,
+ sizeof(struct cqm_stats));
+
+ /* Reads VF/PF information. */
+ cqm_handle->func_attribute = handle->hwif->attr;
+ cqm_info(handle->dev_hdl,
+ "Func init: function[%u] type %d(0:PF,1:VF,2:PPF)\n",
+ cqm_handle->func_attribute.func_global_idx,
+ cqm_handle->func_attribute.func_type);
+
+ /* Read capability from configuration management module */
+ ret = cqm_capability_init(ex_handle);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_capability_init));
+ goto err1;
+ }
+
+ /* memory doorbell event bloomfilter timer init */
+ if (cqm5_initialize_recource(ex_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm5_initialize_recource));
+ goto err1;
+ }
+
+ atomic_set(&cqm_handle->handle_state, CQM_HANDLE_STATE_READY);
+ return CQM_SUCCESS;
+
+err1:
+ kfree(handle->cqm_hdl);
+ handle->cqm_hdl = NULL;
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm5_uninit
+ * Description : Deinitializes the 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 cqm5_uninit(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ s32 ret;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+
+ atomic_set(&cqm_handle->handle_state, CQM_HANDLE_STATE_REMOVE);
+
+ cqm_set_vio_enable(ex_handle, false);
+
+ cqm_set_timer_disable(ex_handle);
+
+ /* After the TMR timer stops, the system releases resources
+ * after a delay of one or two milliseconds.
+ */
+ if (CQM_IS_PPF(cqm_handle)) {
+ if (cqm_handle->func_capability.timer_enable ==
+ CQM_TIMER_ENABLE) {
+ cqm_info(handle->dev_hdl, "PPF timer stop\n");
+ ret = hinic5_ppf_tmr_stop(handle);
+ if (ret != CQM_SUCCESS)
+ /* The timer fails to be stopped,
+ * and the resource release is not affected.
+ */
+ 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 */
+ cqm_bloomfilter_uninit(ex_handle);
+
+ /* Release hardware doorbell */
+ cqm_db_uninit(ex_handle);
+
+ /* Cancel the callback of the event */
+ cqm_event_uninit(ex_handle);
+
+ /* Release various memory tables and require the service
+ * to release all objects.
+ */
+ cqm_mem_uninit(ex_handle);
+
+ /* Release cqm_handle */
+ handle->cqm_hdl = NULL;
+ kfree(cqm_handle);
+}
+
+static void cqm_test_mode_init(struct tag_cqm_handle *cqm_handle,
+ struct service_cap *service_capability)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ if (service_capability->test_mode == 0)
+ return;
+
+ cqm_info(handle->dev_hdl, "Enter 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 cqm_service_capability_update(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+
+ func_cap->qpc_number = GET_MIN(CQM_MAX_QPC_NUM, func_cap->qpc_number);
+ func_cap->scqc_number =
+ GET_MIN(CQM_MAX_SCQC_NUM, func_cap->scqc_number);
+ func_cap->srqc_number =
+ GET_MIN(CQM_MAX_SRQC_NUM, func_cap->srqc_number);
+ func_cap->childc_number =
+ GET_MIN(CQM_MAX_CHILDC_NUM, func_cap->childc_number);
+}
+
+static void cqm_service_valid_init(struct tag_cqm_handle *cqm_handle,
+ const struct service_cap *service_capability)
+{
+ u32 type = service_capability->chip_svc_type;
+ struct tag_cqm_service *svc = cqm_handle->service;
+
+ svc[CQM_SERVICE_T_NIC].valid = (type & CFG_SERVICE_MASK_NIC) != 0;
+ svc[CQM_SERVICE_T_OVS].valid = (type & CFG_SERVICE_MASK_OVS) != 0;
+ svc[CQM_SERVICE_T_ROCE].valid = (type & CFG_SERVICE_MASK_ROCE) != 0;
+ svc[CQM_SERVICE_T_TOE].valid = (type & CFG_SERVICE_MASK_TOE) != 0;
+ svc[CQM_SERVICE_T_FC].valid = (type & CFG_SERVICE_MASK_FC) != 0;
+ svc[CQM_SERVICE_T_IPSEC].valid = (type & CFG_SERVICE_MASK_IPSEC) != 0;
+ svc[CQM_SERVICE_T_VBS].valid = (type & CFG_SERVICE_MASK_VBS) != 0;
+ svc[CQM_SERVICE_T_VIRTIO].valid = (type & CFG_SERVICE_MASK_VIRTIO) != 0;
+ svc[CQM_SERVICE_T_IOE].valid = false;
+ svc[CQM_SERVICE_T_PPA].valid = (type & CFG_SERVICE_MASK_PPA) != 0;
+ svc[CQM_SERVICE_T_UB].valid = (type & CFG_SERVICE_MASK_UB) != 0;
+ svc[CQM_SERVICE_T_JBOF].valid = (type & CFG_SERVICE_MASK_JBOF) != 0;
+ svc[CQM_SERVICE_T_VROCE].valid = (type & CFG_SERVICE_MASK_VROCE) != 0;
+ svc[CQM_SERVICE_T_DMMU].valid = (type & CFG_SERVICE_MASK_DMMU) != 0;
+ svc[CQM_SERVICE_T_CFM].valid = (type & CFG_SERVICE_MASK_CFM) != 0;
+}
+
+static void cqm_service_capability_init_nic(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ cqm_info(handle->dev_hdl,
+ "Cap init: nic is valid, but nic need not be init by cqm\n");
+}
+
+static void cqm_service_capability_init_ovs(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &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 = cqm_handle->ex_handle;
+
+ cqm_info(handle->dev_hdl, "Cap init: ovs is valid\n");
+ 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 = 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 = CQM_OVS_PAGESIZE_ORDER;
+}
+
+static void 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)
+{
+ cqm_info(handle->dev_hdl, "Cap init: roce is valid\n");
+ 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);
+ 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);
+ 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);
+ 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 cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = 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;
+
+ 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 += CQM_QPC_ROCE_RSVD;
+ func_cap->scq_reserved += CQM_CQ_ROCE_RSVD;
+ func_cap->srq_reserved += CQM_SRQ_ROCE_RSVD;
+ }
+
+ func_cap->xid_alloc_mode = false; /* xid 快速复用 */
+ 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 = CQM_GID_RDMA_NUM;
+
+ func_cap->gid_basic_size = CQM_GID_SIZE_32;
+ func_cap->childc_number += roce_own_cap->max_child_ctx_num;
+ func_cap->childc_basic_size =
+ GET_MAX(CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
+}
+
+static void cqm_service_capability_init_vroce(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = 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 = CQM_HASH_BUCKET_SIZE_64;
+ cqm_info(handle->dev_hdl, "Cap init: vroce is valid\n");
+ 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 cqm_service_capability_init_toe(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_toe_private_capability *toe_own_cap =
+ &cqm_handle->toe_own_capability;
+ struct tag_cqm_func_capability *func_cap = &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 = cqm_handle->ex_handle;
+
+ cqm_info(handle->dev_hdl, "Cap init: toe is valid\n");
+ 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 = 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 = CQM_SRQC_SIZE_64;
+ func_cap->childc_number += dev_toe_cap->max_cctxt;
+ func_cap->childc_basic_size =
+ GET_MAX(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 cqm_service_capability_init_ioe(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ cqm_info(handle->dev_hdl, "Cap init: ioe is valid\n");
+}
+
+static void cqm_service_capability_init_fc(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &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 = cqm_handle->ex_handle;
+
+ cqm_info(handle->dev_hdl, "Cap init: fc is valid\n");
+ 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 = 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 = CQM_LUN_FC_NUM;
+ func_cap->lun_basic_size = CQM_LUN_SIZE_8;
+ func_cap->taskmap_number = 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 = CQM_FC_PAGESIZE_ORDER;
+}
+
+static void cqm_service_capability_init_vbs(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct service_cap *service_capability = (struct service_cap *)pra;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+
+ 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(CQM_VBS_QPC_SIZE, func_cap->qpc_basic_size);
+ func_cap->qpc_alloc_static = true;
+ func_cap->scqc_basic_size = 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(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 = 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 cqm_service_capability_init_jbof(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct service_cap *service_capability = (struct service_cap *)pra;
+ struct jbof_service_cap *jbof_cap = &service_capability->jbof_cap;
+
+ 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(CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
+ func_cap->hash_number += jbof_cap->hash_bucket_num;
+ func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
+}
+
+static void cqm_service_capability_init_ipsec(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &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 = cqm_handle->ex_handle;
+
+ func_cap->childc_number +=
+ (ipsec_srvcap->max_sactxs + ipsec_srvcap->max_spctxs);
+ func_cap->childc_basic_size =
+ GET_MAX(CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
+ func_cap->scqc_number += ipsec_srvcap->max_cqs;
+ func_cap->scqc_basic_size =
+ GET_MAX(CQM_SCQC_SIZE_64, func_cap->scqc_basic_size);
+ func_cap->scqc_alloc_static = true;
+ func_cap->hash_number +=
+ CQM_CRYPT_HASH_BUCKET_NUM(ipsec_srvcap->sa_hash_bucket_num +
+ ipsec_srvcap->sp_hash_bucket_num);
+ func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
+ cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
+ 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);
+ cqm_info(handle->dev_hdl, "scqc_num 0x%x, scqc_bsize %u\n",
+ ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
+ 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
+cqm_service_capability_init_virtio(struct tag_cqm_handle *cqm_handle, void *pra)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct service_cap *svc_cap = (struct service_cap *)pra;
+ u32 vq_num, vq_size, xid2cid_size;
+
+ cqm_info(handle->dev_hdl, "Cap init: virtio is valid\n");
+
+ vq_num = svc_cap->virtio_vq_num != 0 ? svc_cap->virtio_vq_num :
+ CQM_VIRTIO_VQ_NUM_DEFAULT;
+ vq_num += svc_cap->nvme_qp_num;
+ vq_size = vq_num * svc_cap->virtio_vq_size;
+ 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 * CQM_VIRTIO_FC_SIZE;
+ 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 / CQM_CHIP_CACHELINE;
+ func_cap->xid2cid_basic_size = CQM_CHIP_CACHELINE;
+
+ cqm_info(handle->dev_hdl,
+ "Cap init: xid2cid_size 0x%x, xid2cid_number 0x%x\n",
+ xid2cid_size, func_cap->xid2cid_number);
+}
+
+static void cqm_service_capability_init_ppa(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct service_cap *service_capability = (struct service_cap *)pra;
+ struct ppa_service_cap *ppa_cap = &service_capability->ppa_cap;
+
+ cqm_info(handle->dev_hdl, "Cap init: ppa is valid\n");
+ func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
+ func_cap->qpc_alloc_static = true;
+ func_cap->pagesize_reorder = CQM_PPA_PAGESIZE_ORDER;
+ func_cap->qpc_basic_size =
+ GET_MAX(ppa_cap->pctx_sz, func_cap->qpc_basic_size);
+}
+
+static void cqm_service_capability_init_ub(struct tag_cqm_handle *cqm_handle,
+ void *pra)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = 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;
+
+ 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 = 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(CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
+}
+
+struct cqm_srv_cap_init serv_cap_init_list[] = {
+ { CQM_SERVICE_T_NIC, cqm_service_capability_init_nic },
+ { CQM_SERVICE_T_OVS, cqm_service_capability_init_ovs },
+ { CQM_SERVICE_T_ROCE, cqm_service_capability_init_roce },
+ { CQM_SERVICE_T_TOE, cqm_service_capability_init_toe },
+ { CQM_SERVICE_T_IOE, cqm_service_capability_init_ioe },
+ { CQM_SERVICE_T_FC, cqm_service_capability_init_fc },
+ { CQM_SERVICE_T_VBS, cqm_service_capability_init_vbs },
+ { CQM_SERVICE_T_IPSEC, cqm_service_capability_init_ipsec },
+ { CQM_SERVICE_T_VIRTIO, cqm_service_capability_init_virtio },
+ { CQM_SERVICE_T_PPA, cqm_service_capability_init_ppa },
+ { CQM_SERVICE_T_UB, cqm_service_capability_init_ub },
+ { CQM_SERVICE_T_JBOF, cqm_service_capability_init_jbof },
+ { CQM_SERVICE_T_VROCE, cqm_service_capability_init_vroce },
+};
+
+static void cqm_service_capability_init(struct tag_cqm_handle *cqm_handle,
+ struct service_cap *service_capability)
+{
+ u32 list_size = ARRAY_SIZE(serv_cap_init_list);
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 i;
+
+ for (i = 0; i < CQM_SERVICE_T_MAX; i++) {
+ cqm_handle->service[i].valid = false;
+ cqm_handle->service[i].has_register = false;
+ cqm_handle->service[i].buf_order = 0;
+ }
+
+ cqm_service_valid_init(cqm_handle, service_capability);
+
+ cqm_info(handle->dev_hdl, "Cap init: service type %d\n",
+ service_capability->chip_svc_type);
+
+ for (i = 0; i < list_size; i++) {
+ if (cqm_handle->service[serv_cap_init_list[i].service_type]
+ .valid &&
+ serv_cap_init_list[i].serv_cap_proc) {
+ serv_cap_init_list[i].serv_cap_proc(
+ cqm_handle, (void *)service_capability);
+ }
+ }
+}
+
+static u32 get_fake_func_type(struct tag_cqm_fake_cfg *fake_cfg, u16 func_id)
+{
+ if (func_id == fake_cfg->parent_func)
+ return 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 CQM_FAKE_FUNC_CHILD;
+
+ return CQM_FAKE_FUNC_UNUSED;
+}
+
+/* Set func_type in fake_cqm_handle to ppf, pf, or vf. */
+static void cqm_set_func_type(struct tag_cqm_handle *cqm_handle)
+{
+ u32 idx = cqm_handle->func_attribute.func_global_idx;
+
+ if (idx == 0)
+ cqm_handle->func_attribute.func_type = CQM_PPF;
+ else if (idx < CQM_MAX_PF_NUM)
+ cqm_handle->func_attribute.func_type = CQM_PF;
+ else
+ cqm_handle->func_attribute.func_type = CQM_VF;
+}
+
+static int cqm_capability_init_smf(struct hinic5_hwdev *handle,
+ struct service_cap *svc_cap)
+{
+ struct tag_cqm_handle *cqm_handle = handle->cqm_hdl;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+
+ func_cap->lb_mode = svc_cap->lb_mode;
+
+ if (svc_cap->smf_enabled_num == 0) {
+ cqm_err(handle->dev_hdl, "SMF not enabled.\n");
+ return -EINVAL;
+ }
+
+ /* Initializing the LB Mode */
+ if (func_cap->lb_mode == 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;
+
+ 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);
+ return 0;
+}
+
+static void cqm_capability_init_fake_vf(struct hinic5_hwdev *handle,
+ struct service_cap *svc_cap)
+{
+ struct tag_cqm_handle *cqm_handle = handle->cqm_hdl;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct tag_cqm_fake_cfg *cfg = &func_cap->fake_cfg;
+
+ func_cap->fake_func_type = CQM_FAKE_FUNC_UNUSED;
+ (void)memset_s(cfg, sizeof(*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 =
+ 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_bat_expanded = svc_cap->fake_vf_bat_expanded;
+
+ 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));
+ }
+
+ if (cfg->child_func_number > CQM_FAKE_FUNC_MAX) {
+ cfg->child_func_number = CQM_FAKE_FUNC_MAX;
+ cqm_warn(
+ handle->dev_hdl,
+ "child_func_number exceeds max supported, use %d default\n",
+ CQM_FAKE_FUNC_MAX);
+ }
+
+ 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 cqm_capability_init_bloomfilter(struct hinic5_hwdev *handle)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(handle->cqm_hdl);
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
+
+ func_cap->bloomfilter_enable = service_capability->bloomfilter_en;
+ 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 &&
+ !cqm_check_align(func_cap->bloomfilter_length)) {
+ cqm_err(handle->dev_hdl,
+ "Cap init: bloomfilter_length %u is not the power of 2\n",
+ func_cap->bloomfilter_length);
+
+ return CQM_FAIL;
+ }
+ }
+
+ 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 cqm_capability_init_part_cap(struct hinic5_hwdev *handle)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(handle->cqm_hdl);
+ struct tag_cqm_func_capability *func_cap = &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;
+ 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 = 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 = CQM_L3I_SIZE_8;
+
+ func_cap->xid_alloc_mode = true; /* xid alloc do not reuse */
+ func_cap->gpa_check_enable = true;
+}
+
+STATIC int cqm_get_ppf_timer_cfg(struct hinic5_hwdev *handle)
+{
+ struct tag_cqm_handle *cqm_handle = handle->cqm_hdl;
+ struct tag_cqm_func_capability *func_cap = &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;
+
+ err = memcpy_s(func_cap->timer_vf_segs, sizeof(func_cap->timer_vf_segs),
+ svc_cap->timer_vf_segs, sizeof(svc_cap->timer_vf_segs));
+ if (err != 0) {
+ cqm_info(handle->dev_hdl,
+ "Cap init: memcpy segs failed, err %d\n", err);
+ return err;
+ }
+
+ 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;
+
+ 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);
+
+ 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 cqm_capability_init_timer(struct hinic5_hwdev *handle)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(handle->cqm_hdl);
+ struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ u32 total_timer_num = 0;
+ int err;
+
+ /* Initializes the PPF capabilities: include timer, pf, vf. */
+ if (CQM_IS_PPF(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;
+ cqm_info(handle->dev_hdl, "Cap init: total function num 0x%x\n",
+ service_capability->host_total_function);
+ 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 = 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;
+ cqm_info(handle->dev_hdl,
+ "Cap init: timer_enable %u (1: enable; 0: disable)\n",
+ func_cap->timer_enable);
+
+ func_cap->timer_number = CQM_TIMER_ALIGN_SCALE_NUM * total_timer_num;
+ func_cap->timer_basic_size = CQM_TIMER_SIZE_32;
+
+ return 0;
+}
+
+static void print_bat_cap(struct hinic5_hwdev *hwdev, const char *prefix_in,
+ struct tag_cqm_func_capability *cap)
+{
+ const char *prefix = prefix_in ? prefix_in : "";
+
+ cqm_info(hwdev->dev_hdl, "%sCap init: hash number 0x%x\n", prefix,
+ cap->hash_number);
+ 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);
+ 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);
+ 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);
+ cqm_info(hwdev->dev_hdl, "%sCap init: mpt number 0x%x, reserved 0x%x\n",
+ prefix, cap->mpt_number, cap->mpt_reserved);
+ cqm_info(hwdev->dev_hdl,
+ "%sCap init: gid number 0x%x, lun number 0x%x\n", prefix,
+ cap->gid_number, cap->lun_number);
+ cqm_info(hwdev->dev_hdl,
+ "%sCap init: taskmap number 0x%x, l3i number 0x%x\n", prefix,
+ cap->taskmap_number, cap->l3i_number);
+ cqm_info(hwdev->dev_hdl,
+ "%sCap init: childc number 0x%x, basic size 0x%x\n", prefix,
+ cap->childc_number, cap->childc_basic_size);
+ cqm_info(hwdev->dev_hdl, "%sCap init: timer number 0x%x\n", prefix,
+ cap->timer_number);
+ cqm_info(hwdev->dev_hdl,
+ "%sCap init: xid2cid number 0x%x, alloc static %d\n", prefix,
+ cap->xid2cid_number, cap->xid_alloc_mode);
+ cqm_info(hwdev->dev_hdl, "%sCap init: reorder number 0x%x\n", prefix,
+ cap->reorder_number);
+}
+
+static void cqm_capability_init_cap_print(struct hinic5_hwdev *handle)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(handle->cqm_hdl);
+ struct tag_cqm_func_capability *func_cap = &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->vf_bat_expanded = COMM_SUPPORT_VF_BAT_EXPANDED(handle);
+ func_cap->gpa_spu_en = service_capability->func_gpa_spu_en;
+
+ cqm_info(handle->dev_hdl, "Cap init: pagesize_reorder %u\n",
+ func_cap->pagesize_reorder);
+ 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);
+ cqm_info(handle->dev_hdl,
+ "Cap init: ft_enable %d, rdma_enable %d, vf_bat_expanded %d\n",
+ func_cap->ft_enable, func_cap->rdma_enable,
+ func_cap->vf_bat_expanded);
+
+ print_bat_cap(handle, NULL, func_cap);
+}
+
+/**
+ * Prototype : cqm_capability_init
+ * Description : Initializes the function and service capabilities of the 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 cqm_capability_init(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(handle->cqm_hdl);
+ struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ int err = 0;
+
+ err = cqm_capability_init_timer(handle);
+ if (err != 0)
+ goto out;
+
+ err = cqm_capability_init_bloomfilter(handle);
+ if (err != 0)
+ goto out;
+
+ cqm_capability_init_part_cap(handle);
+
+ err = cqm_capability_init_smf(handle, service_capability);
+ if (err != 0)
+ goto out;
+
+ cqm_capability_init_fake_vf(handle, service_capability);
+
+ cqm_service_capability_init(cqm_handle, service_capability);
+
+ cqm_test_mode_init(cqm_handle, service_capability);
+
+ cqm_service_capability_update(cqm_handle);
+
+ cqm_capability_init_cap_print(handle);
+
+ return CQM_SUCCESS;
+
+out:
+ if (CQM_IS_PPF(cqm_handle))
+ func_cap->timer_enable = 0;
+
+ return err;
+}
+
+static void cqm_fake_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ u32 i;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return;
+
+ for (i = 0; i < CQM_FAKE_FUNC_MAX; i++) {
+ kfree(cqm_handle->fake_cqm_handle[i]);
+ cqm_handle->fake_cqm_handle[i] = NULL;
+ }
+}
+
+static void set_fake_cqm_attr(struct hinic5_hwdev *handle,
+ struct tag_cqm_handle *fake_cqm_handle,
+ u32 child_func_start, u32 i)
+{
+ struct hinic5_func_attr *func_attr = &fake_cqm_handle->func_attribute;
+ struct tag_cqm_func_capability *func_cap =
+ &fake_cqm_handle->func_capability;
+ struct tag_cqm_fake_cfg *cfg = &func_cap->fake_cfg;
+
+ func_attr->func_global_idx = (u16)(child_func_start + i);
+ cqm_set_func_type(fake_cqm_handle);
+
+ func_cap->vf_bat_expanded = cfg->fake_vf_bat_expanded;
+
+ func_cap->fake_func_type = 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;
+ }
+
+ cqm_service_capability_update(fake_cqm_handle);
+}
+
+static void print_fake_cqm_attr(struct hinic5_hwdev *hwdev,
+ struct tag_cqm_handle *fake_cqm_handle)
+{
+ cqm_func_capability_s *fake_func_cap =
+ &fake_cqm_handle->func_capability;
+ struct hinic5_func_attr *fake_func_attr =
+ &fake_cqm_handle->func_attribute;
+ const u16 fake_func_id = fake_func_attr->func_global_idx;
+ char prefix[0x20] = { 0 };
+ 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));
+
+ if (sprintf_s(prefix, sizeof(prefix), "[Fake %u] ", fake_func_id) < 0)
+ print_bat_cap(hwdev, "[Fake]", fake_func_cap);
+ else
+ print_bat_cap(hwdev, prefix, fake_func_cap);
+}
+
+/**
+ * Prototype : cqm_fake_init
+ * Description : When the fake VF mode is supported, the CQM handles of
+ * the fake VFs need to be copied.
+ * Input : struct tag_cqm_handle *cqm_handle: Parent CQM handle of the current PF
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2020/4/15
+ * Modification : Created function
+ */
+static s32 cqm_fake_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_handle *fake_cqm_handle = NULL;
+ u32 child_func_start, child_func_number, i;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return CQM_SUCCESS;
+
+ child_func_start = cqm_get_child_func_start(cqm_handle);
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+ if (child_func_number == 0) {
+ cqm_warn(handle->dev_hdl, "no child func, skip fake init\n");
+ return CQM_SUCCESS;
+ }
+
+ for (i = 0; i < child_func_number; i++) {
+ fake_cqm_handle = cqm_handle_fork(cqm_handle);
+ if (!fake_cqm_handle) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_handle_fork));
+ goto err;
+ }
+
+ set_fake_cqm_attr(handle, fake_cqm_handle,
+ (u32)child_func_start, i);
+ print_fake_cqm_attr(handle, fake_cqm_handle);
+
+ fake_cqm_handle->parent_cqm_handle = cqm_handle;
+ cqm_handle->fake_cqm_handle[i] = fake_cqm_handle;
+ }
+
+ return CQM_SUCCESS;
+
+err:
+ cqm_fake_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+static void cqm_fake_mem_uninit(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_handle *fake_cqm_handle = NULL;
+ u32 child_func_number, i;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return;
+
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ for (i = 0; i < child_func_number; i++) {
+ fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
+ atomic_set(&fake_cqm_handle->handle_state,
+ CQM_HANDLE_STATE_REMOVE);
+
+ cqm_object_table_uninit(fake_cqm_handle);
+ cqm_bitmap_uninit(fake_cqm_handle);
+ cqm_cla_uninit(fake_cqm_handle, CQM_BAT_ENTRY_MAX);
+ cqm_bat_uninit(fake_cqm_handle);
+ }
+}
+
+static s32 fake_cqm_handle_mem_init(struct tag_cqm_handle *fake_cqm_handle)
+{
+ struct hinic5_hwdev *handle = fake_cqm_handle->ex_handle;
+
+ if (!CQM_IS_FAKE_CHILD_AGENT(fake_cqm_handle))
+ return CQM_FAIL;
+
+ if (atomic_cmpxchg(&fake_cqm_handle->handle_state,
+ CQM_HANDLE_STATE_INIT,
+ CQM_HANDLE_STATE_READY) != CQM_HANDLE_STATE_INIT) {
+ cqm_warn(handle->dev_hdl, "[Fake %u] mem already inited\n",
+ fake_cqm_handle->func_attribute.func_global_idx);
+ return CQM_FAIL;
+ }
+
+ if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_init));
+ goto err1;
+ }
+
+ if (cqm_cla_init(fake_cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_init));
+ goto err2;
+ }
+
+ if (cqm_bitmap_init(fake_cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bitmap_init));
+ goto err3;
+ }
+
+ if (cqm_object_table_init(fake_cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_table_init));
+ goto err4;
+ }
+
+ cqm_info(handle->dev_hdl, "[Fake %u] mem inited\n",
+ fake_cqm_handle->func_attribute.func_global_idx);
+
+ return CQM_SUCCESS;
+
+err4:
+ cqm_bitmap_uninit(fake_cqm_handle);
+err3:
+ cqm_cla_uninit(fake_cqm_handle, CQM_BAT_ENTRY_MAX);
+err2:
+ cqm_bat_uninit(fake_cqm_handle);
+err1:
+ cqm_fake_mem_uninit(fake_cqm_handle);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_fake_mem_init
+ * Description : Initialize resources of the extended fake function.
+ * Input : struct tag_cqm_handle *cqm_handle: Parent CQM handle of the current PF
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2020/4/15
+ * Modification : Created function
+ */
+static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_handle *fake_cqm_handle = NULL;
+ u32 child_func_number, i;
+ int ret;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return CQM_SUCCESS;
+
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ for (i = 0; i < child_func_number; i++) {
+ fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
+ ret = snprintf_s(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%s%02u",
+ cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ if (ret < 0) {
+ cqm_err(handle->dev_hdl,
+ "fake cqm handle vram name snprintf_s failed");
+ return CQM_FAIL;
+ }
+
+ /* Fake VF lazy init support */
+ if (cqm_is_fake_vf_lazy_init(cqm_handle)) {
+ cqm_info(
+ handle->dev_hdl, "[Fake %u] init delayed\n",
+ fake_cqm_handle->func_attribute.func_global_idx);
+ continue;
+ }
+
+ ret = fake_cqm_handle_mem_init(fake_cqm_handle);
+ if (ret != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(fake_cqm_handle_mem_init));
+ goto err;
+ }
+ }
+
+ return CQM_SUCCESS;
+
+err:
+ cqm_fake_mem_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_mem_init
+ * Description : Initialize 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 cqm_mem_init(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ int ret;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ ret = snprintf_s(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%02u",
+ VRAM_CQM_GLB_FUNC_BASE, hinic5_global_func_id(handle));
+ if (ret < 0) {
+ cqm_err(handle->dev_hdl,
+ "cqm handle vram name snprintf_s failed");
+ return CQM_FAIL;
+ }
+ if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
+ return CQM_FAIL;
+ }
+
+ if (cqm_fake_mem_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_mem_init));
+ goto err1;
+ }
+
+ if (cqm_bat_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_init));
+ goto err2;
+ }
+
+ if (cqm_cla_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_init));
+ goto err3;
+ }
+
+ if (cqm_bitmap_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bitmap_init));
+ goto err4;
+ }
+
+ if (cqm_object_table_init(cqm_handle) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_table_init));
+ goto err5;
+ }
+
+ return CQM_SUCCESS;
+
+err5:
+ cqm_bitmap_uninit(cqm_handle);
+err4:
+ cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX);
+err3:
+ cqm_bat_uninit(cqm_handle);
+err2:
+ cqm_fake_mem_uninit(cqm_handle);
+err1:
+ cqm_fake_uninit(cqm_handle);
+ return CQM_FAIL;
+}
+
+int cqm5_init_fake_vf(void *ex_handle, u32 vf_id)
+{
+ struct hinic5_hwdev *handle = ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_handle *fake_cqm_handle = NULL;
+ u32 child_func_start, child_func_number;
+ int err;
+
+ if (unlikely(!ex_handle)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return -EINVAL;
+ }
+
+ cqm_handle = handle->cqm_hdl;
+ if (unlikely(!cqm_handle)) {
+ cqm_err(handle->dev_hdl, "Stateful not init\n");
+ return -EINVAL;
+ }
+
+ if (unlikely(atomic_read(&cqm_handle->handle_state) !=
+ CQM_HANDLE_STATE_READY)) {
+ cqm_err(handle->dev_hdl, "Stateful not ready\n");
+ return -EAGAIN;
+ }
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle)) {
+ cqm_err(handle->dev_hdl, "Not a Fake VF group parent\n");
+ return -EPERM;
+ }
+
+ child_func_start = cqm_get_child_func_start(cqm_handle);
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+ if (vf_id < child_func_start ||
+ vf_id >= child_func_start + child_func_number) {
+ cqm_err(handle->dev_hdl, "VF %u is not in the Fake VF group\n",
+ vf_id);
+ return -EINVAL;
+ }
+
+ fake_cqm_handle = cqm_handle->fake_cqm_handle[vf_id - child_func_start];
+ err = fake_cqm_handle_mem_init(fake_cqm_handle);
+ if (err != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(fake_cqm_handle_mem_init));
+ return -EFAULT;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(cqm5_init_fake_vf);
+
+void cqm_cla_fake_vf_cache_invalid(struct tag_cqm_handle *cqm_handle,
+ u32 reset_flag)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_handle *fake_cqm_handle = NULL;
+ u32 child_func_number, i;
+ u16 func_global_idx;
+ int err;
+
+ if (!CQM_IS_FAKE_PARENT(cqm_handle))
+ return;
+
+ child_func_number = cqm_get_child_func_number(cqm_handle);
+
+ for (i = 0; i < child_func_number; i++) {
+ fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
+ func_global_idx =
+ fake_cqm_handle->func_attribute.func_global_idx;
+
+ err = hinic5_func_reset(handle, func_global_idx,
+ BIT(reset_flag), HINIC5_CHANNEL_COMM);
+ if (err != 0)
+ cqm_err(handle->dev_hdl,
+ "cqm fake vf cla cache invalid err, func_id 0x%x\n",
+ func_global_idx);
+ }
+}
+
+void cqm_cla_func_cache_invalid(struct tag_cqm_handle *cqm_handle,
+ u32 reset_flag)
+{
+ int err;
+ u16 func_id;
+ struct hinic5_hwdev *handle =
+ (struct hinic5_hwdev *)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)
+ cqm_err(handle->dev_hdl,
+ "cqm cla cache invalid err, func_index = 0x%x\n",
+ func_id);
+}
+
+/**
+ * Prototype : cqm_mem_uninit
+ * Description : Deinitialize 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 cqm_mem_uninit(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+
+ cqm_object_table_uninit(cqm_handle);
+ cqm_bitmap_uninit(cqm_handle);
+
+ if (COMM_SUPPORT_SMF_CACHE_INVALID(handle)) {
+ cqm_cla_fake_vf_cache_invalid(cqm_handle, RES_TYPE_SMF);
+ cqm_cla_func_cache_invalid(cqm_handle, RES_TYPE_SMF);
+ }
+
+ cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX);
+ cqm_bat_uninit(cqm_handle);
+ cqm_fake_mem_uninit(cqm_handle);
+
+ if (COMM_SUPPORT_SMF_CACHE_INVALID(handle)) {
+ cqm_cla_fake_vf_cache_invalid(cqm_handle,
+ RES_TYPE_SMF_CACHE_INVALID);
+ cqm_cla_func_cache_invalid(cqm_handle,
+ RES_TYPE_SMF_CACHE_INVALID);
+ }
+
+ cqm_fake_uninit(cqm_handle);
+}
+
+/**
+ * Prototype : cqm_event_init
+ * Description : Initialize CQM event callback.
+ * Input : void *ex_handle
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/7/6
+ * Modification : Created function
+ */
+s32 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,
+ cqm_scq_callback) != CHIPIF_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ "Event: fail to register scq callback\n");
+ return CQM_FAIL;
+ }
+
+ if (hinic5_ceq_register_cb(ex_handle, ex_handle, HINIC5_NON_L2NIC_ECQ,
+ cqm_ecq_callback) != CHIPIF_SUCCESS) {
+ 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,
+ cqm_nocq_callback) != CHIPIF_SUCCESS) {
+ 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,
+ cqm_aeq_callback) != CHIPIF_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ "Event: fail to register aeq callback\n");
+ goto err3;
+ }
+
+ return 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 CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_event_uninit
+ * Description : Deinitialize CQM event callback.
+ * Input : void *ex_handle
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/7/6
+ * Modification : Created function
+ */
+void 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 : cqm_scq_callback
+ * Description : 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 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct tag_cqm_queue *cqm_queue = NULL;
+ struct tag_cqm_object *obj = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(scq_callback_ex_handle));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_scq_callback_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(scq_callback_cqm_handle));
+ return;
+ }
+
+ cqm_dbg_on(cqm_verbose, handle->dev_hdl, "Event: %s, ceqe_data=0x%x\n",
+ __func__, ceqe_data);
+ obj = cqm5_object_get(ex_handle, CQM_OBJECT_NONRDMA_SCQ,
+ CQM_CQN_FROM_CEQE(ceqe_data), true);
+ if (unlikely(obj == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(scq_callback_obj));
+ return;
+ }
+
+ if (unlikely(obj->service_type >= CQM_SERVICE_T_MAX)) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(obj->service_type));
+ cqm5_object_put(obj);
+ return;
+ }
+
+ service = &cqm_handle->service[obj->service_type];
+ service_template = &service->service_template;
+ if (service_template->shared_cq_ceq_callback) {
+ cqm_queue = (struct tag_cqm_queue *)(void *)obj;
+ service_template->shared_cq_ceq_callback(
+ service_template->service_handle,
+ CQM_CQN_FROM_CEQE(ceqe_data), cqm_queue->priv);
+ } else {
+ cqm_err(handle->dev_hdl, CQM_PTR_NULL(shared_cq_ceq_callback));
+ }
+
+ cqm5_object_put(obj);
+}
+
+/**
+ * Prototype : cqm_ecq_callback
+ * Description : 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 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct tag_cqm_qpc_mpt *qpc = NULL;
+ struct tag_cqm_object *obj = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ecq_callback_ex_handle));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_ecq_callback_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ecq_callback_cqm_handle));
+ return;
+ }
+
+ obj = cqm5_object_get(ex_handle, CQM_OBJECT_SERVICE_CTX,
+ CQM_XID_FROM_CEQE(ceqe_data), true);
+ if (unlikely(obj == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ecq_callback_obj));
+ return;
+ }
+
+ if (unlikely(obj->service_type >= CQM_SERVICE_T_MAX)) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(obj->service_type));
+ cqm5_object_put(obj);
+ return;
+ }
+
+ service = &cqm_handle->service[obj->service_type];
+ service_template = &service->service_template;
+ if (service_template->embedded_cq_ceq_callback) {
+ qpc = (struct tag_cqm_qpc_mpt *)(void *)obj;
+ service_template->embedded_cq_ceq_callback(
+ service_template->service_handle,
+ CQM_XID_FROM_CEQE(ceqe_data), qpc->priv);
+ } else {
+ cqm_err(handle->dev_hdl,
+ CQM_PTR_NULL(embedded_cq_ceq_callback));
+ }
+
+ cqm5_object_put(obj);
+}
+
+/**
+ * Prototype : cqm_nocq_callback
+ * Description : 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 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct tag_cqm_qpc_mpt *qpc = NULL;
+ struct tag_cqm_object *obj = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(nocq_callback_ex_handle));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_nocq_callback_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(nocq_callback_cqm_handle));
+ return;
+ }
+
+ obj = cqm5_object_get(ex_handle, CQM_OBJECT_SERVICE_CTX,
+ CQM_XID_FROM_CEQE(ceqe_data), true);
+ if (unlikely(obj == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(nocq_callback_obj));
+ return;
+ }
+
+ if (unlikely(obj->service_type >= CQM_SERVICE_T_MAX)) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(obj->service_type));
+ cqm5_object_put(obj);
+ return;
+ }
+
+ service = &cqm_handle->service[obj->service_type];
+ service_template = &service->service_template;
+ if (service_template->no_cq_ceq_callback) {
+ qpc = (struct tag_cqm_qpc_mpt *)(void *)obj;
+ service_template->no_cq_ceq_callback(
+ service_template->service_handle,
+ CQM_XID_FROM_CEQE(ceqe_data),
+ CQM_QID_FROM_CEQE(ceqe_data), qpc->priv);
+ } else {
+ cqm_err(handle->dev_hdl, CQM_PTR_NULL(no_cq_ceq_callback));
+ }
+
+ cqm5_object_put(obj);
+}
+
+/* Distributes events to different service modules
+ * based on the event type.
+ */
+static u32 cqm_aeq_event2type(u8 event)
+{
+ if (event < CQM_AEQ_BASE_T_DMMU)
+ return CQM_SERVICE_T_NIC;
+ if (event < CQM_AEQ_BASE_T_ROCE)
+ return CQM_SERVICE_T_DMMU;
+ if (event < CQM_AEQ_BASE_T_FC)
+ return CQM_SERVICE_T_ROCE;
+ if (event < CQM_AEQ_BASE_T_IOE)
+ return CQM_SERVICE_T_FC;
+ if (event < CQM_AEQ_BASE_T_TOE)
+ return CQM_SERVICE_T_IOE;
+ if (event < CQM_AEQ_BASE_T_UB)
+ return CQM_SERVICE_T_TOE;
+ if (event < CQM_AEQ_BASE_T_VBS)
+ return CQM_SERVICE_T_UB;
+ if (event < CQM_AEQ_BASE_T_IPSEC)
+ return CQM_SERVICE_T_VBS;
+ if (event < CQM_AEQ_BASE_T_MAX)
+ return CQM_SERVICE_T_IPSEC;
+ return CQM_SERVICE_T_MAX;
+}
+
+/**
+ * Prototype : cqm_aeq_callback
+ * Description : 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 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ u8 event_level = FAULT_LEVEL_MAX;
+ u32 service_type;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(aeq_callback_ex_handle));
+ return event_level;
+ }
+
+ if (event >= CQM_AEQ_CALLBACK_CNT_MAX) {
+ cqm_err(handle->dev_hdl, "cqm aeq event invalid %u\n", event);
+ return event_level;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_aeq_callback_cnt[event]);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(aeq_callback_cqm_handle));
+ return event_level;
+ }
+
+ /* Distributes events to different service modules
+ * based on the event type.
+ */
+ service_type = cqm_aeq_event2type(event);
+ if (service_type == CQM_SERVICE_T_MAX) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(event));
+ return event_level;
+ }
+
+ service = &cqm_handle->service[service_type];
+ service_template = &service->service_template;
+
+ if (!service_template->aeq_level_callback)
+ 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)
+ 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 : cqm5_service_register
+ * Description : Callback template for the service driver
+ * to register with the 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 cqm5_service_register(
+ void *ex_handle, struct tag_service_register_template *service_template)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+ if (unlikely(service_template == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(service_template));
+ return CQM_FAIL;
+ }
+
+ if (service_template->service_type >= CQM_SERVICE_T_MAX) {
+ cqm_err(handle->dev_hdl,
+ CQM_WRONG_VALUE(service_template->service_type));
+ return CQM_FAIL;
+ }
+ service = &cqm_handle->service[service_template->service_type];
+ if (!service->valid) {
+ cqm_err(handle->dev_hdl,
+ "Service register: service_type %u is invalid\n",
+ service_template->service_type);
+ return CQM_FAIL;
+ }
+
+ if (service->has_register) {
+ cqm_err(handle->dev_hdl,
+ "Service register: service_type %u has registered\n",
+ service_template->service_type);
+ return CQM_FAIL;
+ }
+
+ service->has_register = true;
+ (void)memcpy_s((void *)(&service->service_template),
+ sizeof(struct tag_service_register_template),
+ (void *)service_template,
+ sizeof(struct tag_service_register_template));
+
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_service_register);
+
+/**
+ * Prototype : cqm5_service_unregister
+ * Description : The service driver deregisters the callback function
+ * from the CQM.
+ * Input : void *ex_handle
+ * u32 service_type
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/5
+ * Modification : Created function
+ */
+void cqm5_service_unregister(void *ex_handle, u32 service_type)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
+ return;
+ }
+
+ service = &cqm_handle->service[service_type];
+ if (!service->valid)
+ cqm_err(handle->dev_hdl,
+ "Service unregister: service_type %u is disable\n",
+ service_type);
+
+ service->has_register = false;
+ (void)memset_s(&service->service_template,
+ sizeof(struct tag_service_register_template), 0,
+ sizeof(struct tag_service_register_template));
+}
+EXPORT_SYMBOL(cqm5_service_unregister);
+
+s32 cqm5_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 CQM_FAIL;
+
+ svc_cap = &handle->cfg_mgmt->svc_cap;
+
+ if (fake_vf_num_cfg > svc_cap->fake_vf_num) {
+ cqm_err(handle->dev_hdl,
+ "fake_vf_num_cfg is invlaid, fw fake_vf_num is %u\n",
+ svc_cap->fake_vf_num);
+ return CQM_FAIL;
+ }
+
+ /* fake_vf_num_cfg is valid when func type is CQM_FAKE_FUNC_PARENT */
+ svc_cap->fake_vf_num_cfg = fake_vf_num_cfg;
+ cqm_info(handle->dev_hdl, "fake_vf_num_cfg set to %u\n",
+ fake_vf_num_cfg);
+
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_fake_vf_num_set);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.h
new file mode 100644
index 000000000..a060f1a4b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_main.h
@@ -0,0 +1,520 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_MAIN_H
+#define CQM_MAIN_H
+
+#include "hinic5_crm.h"
+#include "cqm_bloomfilter.h"
+#include "hisdk5_hwif.h"
+#include "cqm_bat_cla.h"
+
+#define GET_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define GET_MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CQM_DW_SHIFT 2
+#define CQM_QW_SHIFT 3
+
+#define CHIPIF_SUCCESS 0
+#define CHIPIF_FAIL (-1)
+
+#define CQM_TIMER_ENABLE 1
+#define CQM_TIMER_DISABLE 0
+
+#define CQM_HANDLE_STATE_INIT 0
+#define CQM_HANDLE_STATE_READY 1
+#define CQM_HANDLE_STATE_REMOVE 2
+
+/* The value must be the same as that of hinic5_service_type in hinic5_crm.h. */
+#define CQM_SERVICE_T_NIC SERVICE_T_NIC
+#define CQM_SERVICE_T_OVS SERVICE_T_OVS
+#define CQM_SERVICE_T_ROCE SERVICE_T_ROCE
+#define CQM_SERVICE_T_TOE SERVICE_T_TOE
+#define CQM_SERVICE_T_IOE SERVICE_T_IOE
+#define CQM_SERVICE_T_FC SERVICE_T_FC
+#define CQM_SERVICE_T_VBS SERVICE_T_VBS
+#define CQM_SERVICE_T_IPSEC SERVICE_T_IPSEC
+#define CQM_SERVICE_T_VIRTIO SERVICE_T_VIRTIO
+#define CQM_SERVICE_T_PPA SERVICE_T_PPA
+#define CQM_SERVICE_T_UB SERVICE_T_UB
+#define CQM_SERVICE_T_JBOF SERVICE_T_JBOF
+#define CQM_SERVICE_T_VROCE SERVICE_T_VROCE
+#define CQM_SERVICE_T_DMMU SERVICE_T_DMMU
+#define CQM_SERVICE_T_CFM SERVICE_T_CFM
+#define CQM_SERVICE_T_MAX SERVICE_T_MAX
+
+struct tag_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_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;
+ bool fake_vf_bat_expanded;
+
+ 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_cqm_func_capability {
+ /* BAT_PTR table(SMLC) */
+ bool ft_enable; /* BAT for flow table enable */
+ bool rdma_enable; /* BAT for rdma enable */
+ bool vf_bat_expanded;
+
+ 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_cqm_fake_cfg fake_cfg;
+
+ /* Note: for 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;
+} cqm_func_capability_s;
+
+#define CQM_PF TYPE_PF
+#define CQM_VF TYPE_VF
+#define CQM_PPF TYPE_PPF
+#define CQM_UNKNOWN TYPE_UNKNOWN
+#define CQM_MAX_PF_NUM 32
+
+static inline bool cqm_func_type_valid(enum func_type t)
+{
+ return t >= CQM_PF && t < CQM_UNKNOWN;
+}
+
+#define CQM_LB_MODE_NORMAL 0xff
+#define CQM_LB_MODE_0 0
+#define CQM_LB_MODE_1 1
+#define CQM_LB_MODE_2 2
+
+#define CQM_FPGA_MODE 0
+#define CQM_EMU_MODE 1
+
+#define CQM_FAKE_FUNC_UNUSED 0U /* The CQM handle does not use Fake VF. */
+#define CQM_FAKE_FUNC_PARENT \
+ 1U /* The CQM handle is responsible for
+ initializing some VF's resouces. */
+#define 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 CQM_FAKE_FUNC_CHILD \
+ 3U /* Some resources of this CQM handle
+ are managed by a Fake VF Parent. */
+
+#define CQM_FAKE_FUNC_MAX 64
+
+#define CQM_QPC_ROCE_PER_DRCT 12
+#define CQM_QPC_ROCE_NORMAL 0
+#define CQM_QPC_ROCE_VBS_MODE 2
+
+struct tag_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_cqm_bitmap srqc_bitmap;
+};
+
+struct cqm_cmdq_ops;
+struct tag_cqm_handle {
+ struct hinic5_hwdev *ex_handle;
+ struct device *dev;
+ struct hinic5_func_attr func_attribute; /* vf/pf attributes */
+ struct tag_cqm_func_capability
+ func_capability; /* function capability set */
+ struct tag_cqm_service
+ service[CQM_SERVICE_T_MAX]; /* Service-related structure */
+ struct tag_cqm_bat_table bat_table;
+ struct tag_cqm_bloomfilter_table bloomfilter_table;
+
+ atomic_t handle_state; /* see CQM_HANDLE_STATE_XXX */
+
+ /* fake-vf-related structure */
+ struct tag_cqm_handle *fake_cqm_handle[CQM_FAKE_FUNC_MAX];
+ struct tag_cqm_handle *parent_cqm_handle;
+
+ struct tag_cqm_toe_private_capability
+ toe_own_capability; /* TOE service-related
+ * capability set
+ */
+
+ char name[VRAM_NAME_MAX_LEN];
+ struct cqm_cmdq_ops *cmdq_ops;
+};
+
+#define CQM_FUNC_TYPE(cqm_handle) ((cqm_handle)->func_attribute.func_type)
+#define CQM_FAKE_FUNC_TYPE(cqm_handle) \
+ ((cqm_handle)->func_capability.fake_func_type)
+
+#define CQM_IS_FAKE_PARENT(cqm_handle) \
+ (CQM_FAKE_FUNC_TYPE(cqm_handle) == CQM_FAKE_FUNC_PARENT)
+#define CQM_IS_FAKE_CHILD(cqm_handle) \
+ (CQM_FAKE_FUNC_TYPE(cqm_handle) == CQM_FAKE_FUNC_CHILD)
+#define CQM_IS_FAKE_CHILD_AGENT(cqm_handle) \
+ (CQM_FAKE_FUNC_TYPE(cqm_handle) == CQM_FAKE_FUNC_CHILD_AGENT)
+
+#define CQM_IS_PPF(cqm_handle) (CQM_FUNC_TYPE(cqm_handle) == CQM_PPF)
+#define CQM_IS_VF(cqm_handle) \
+ (CQM_FUNC_TYPE(cqm_handle) == CQM_VF && \
+ CQM_FAKE_FUNC_TYPE(cqm_handle) == CQM_FAKE_FUNC_UNUSED)
+
+#define CQM_IS_LB_MODE_NORMAL(cqm_handle) \
+ ((cqm_handle)->func_capability.lb_mode == CQM_LB_MODE_NORMAL)
+#define CQM_IS_LB_MODE_0(cqm_handle) \
+ ((cqm_handle)->func_capability.lb_mode == CQM_LB_MODE_0)
+#define CQM_IS_LB_MODE_1(cqm_handle) \
+ ((cqm_handle)->func_capability.lb_mode == CQM_LB_MODE_1)
+#define CQM_IS_LB_MODE_2(cqm_handle) \
+ ((cqm_handle)->func_capability.lb_mode == CQM_LB_MODE_2)
+#define CQM_IS_LB_MODE_1_OR_2(cqm_handle) \
+ (CQM_IS_LB_MODE_1(cqm_handle) || CQM_IS_LB_MODE_2(cqm_handle))
+
+#define CQM_CQN_FROM_CEQE(data) ((data)&0xfffff)
+#define CQM_XID_FROM_CEQE(data) ((data)&0xfffff)
+#define CQM_QID_FROM_CEQE(data) (((data) >> 20) & 0x7)
+#define CQM_TYPE_FROM_CEQE(data) (((data) >> 23) & 0x7)
+
+#define CQM_HASH_BUCKET_SIZE_64 64
+
+#define CQM_MAX_QPC_NUM 0x100000
+#define CQM_MAX_SCQC_NUM 0x100000
+#define CQM_MAX_SRQC_NUM 0x100000
+#define CQM_MAX_CHILDC_NUM 0x100000
+
+#define CQM_QPC_SIZE_256 256
+#define CQM_QPC_SIZE_512 512
+#define CQM_QPC_SIZE_1024 1024
+
+#define CQM_SCQC_SIZE_32 32
+#define CQM_SCQC_SIZE_64 64
+#define CQM_SCQC_SIZE_128 128
+
+#define CQM_SRQC_SIZE_32 32
+#define CQM_SRQC_SIZE_64 64
+#define CQM_SRQC_SIZE_128 128
+
+#define CQM_MPT_SIZE_64 64
+
+#define CQM_GID_SIZE_32 32
+
+#define CQM_LUN_SIZE_8 8
+
+#define CQM_L3I_SIZE_8 8
+
+#define CQM_TIMER_SIZE_32 32
+
+#define CQM_XID2CID_SIZE_8 8
+
+#define CQM_REORDER_SIZE_256 256
+
+#define CQM_CHILDC_SIZE_256 256
+
+#define CQM_XID2CID_VBS_NUM (2 * 1024) /* 2K nvme Q */
+
+#define CQM_VBS_QPC_SIZE 512
+
+#define CQM_VBS_SCQC_SIZE 128
+
+#define CQM_VIRTIO_VQ_NUM_DEFAULT \
+ (16 * 1024) /* Default number of VirtIO VQs.
+ Future models should get this value from the MGMT. */
+#define CQM_VIRTIO_FC_SIZE 256 /* VirtIO Function Context size */
+
+#define CQM_GID_RDMA_NUM 128
+
+#define CQM_LUN_FC_NUM 64
+
+#define CQM_TASKMAP_FC_NUM 4
+
+#define CQM_L3I_COMM_NUM 64
+
+#define CQM_CHILDC_OVS_VBS_NUM (8 * 1024)
+#define CQM_CHILDC_VBS_NUM (2 * 1024)
+
+#define CQM_TIMER_SCALE_NUM (2 * 1024)
+#define CQM_TIMER_ALIGN_WHEEL_NUM 8
+#define CQM_TIMER_ALIGN_SCALE_NUM \
+ (CQM_TIMER_SCALE_NUM * CQM_TIMER_ALIGN_WHEEL_NUM)
+
+#define CQM_QPC_OVS_RSVD (1024 * 1024)
+#define CQM_QPC_ROCE_RSVD 2
+#define CQM_QPC_ROCEAA_SWITCH_QP_NUM 4
+#define CQM_QPC_ROCEAA_RSVD \
+ (4 * 1024 + CQM_QPC_ROCEAA_SWITCH_QP_NUM) /* 4096 Normal QP +
+ * 4 Switch QP
+ */
+#define CQM_CQ_ROCE_RSVD 16
+#define CQM_CQ_UB_RSVD 131072 // 128K
+#define CQM_SRQ_ROCE_RSVD 16
+
+#define CQM_CQ_ROCEAA_RSVD 64
+#define CQM_SRQ_ROCEAA_RSVD 64
+#define CQM_QPC_ROCE_VBS_RSVD_BACK 204800 /* 200K */
+#define CQM_CQ_VBS_VOLQ_RSVD (2 + 2048)
+#define CQM_CQ_ROCE_VBS_RSVD \
+ GET_MAX(CQM_QPC_ROCE_VBS_RSVD_BACK, CQM_CQ_VBS_VOLQ_RSVD)
+
+#define CQM_OVS_MAX_TIMER_FUNC 48
+
+#define CQM_HASH_BUCKET_NUM_UNIT_4_TO_64 4
+#define CQM_CRYPT_HASH_BUCKET_NUM(tbl_num) \
+ ((tbl_num) >> CQM_HASH_BUCKET_NUM_UNIT_4_TO_64)
+
+#define CQM_PPA_PAGESIZE_ORDER 8
+
+#if defined(__WIN__) && defined(__HIFC__)
+#define CQM_FC_PAGESIZE_ORDER 8
+#else
+#define CQM_FC_PAGESIZE_ORDER 0
+#endif
+
+#define CQM_QHEAD_ALIGN_ORDER 6
+
+typedef void (*serv_cap_init_cb)(struct tag_cqm_handle *, void *);
+
+struct cqm_srv_cap_init {
+ u32 service_type;
+ serv_cap_init_cb serv_cap_proc;
+};
+
+/* Only for llt test */
+s32 cqm_capability_init(void *ex_handle);
+/* Can be defined as static */
+s32 cqm_mem_init(void *ex_handle);
+void cqm_mem_uninit(void *ex_handle);
+s32 cqm_event_init(void *ex_handle);
+void cqm_event_uninit(void *ex_handle);
+void cqm_scq_callback(void *ex_handle, u32 ceqe_data);
+void cqm_ecq_callback(void *ex_handle, u32 ceqe_data);
+void cqm_nocq_callback(void *ex_handle, u32 ceqe_data);
+u8 cqm_aeq_callback(void *ex_handle, u8 event, u8 *data);
+
+s32 cqm5_init(void *ex_handle);
+void cqm5_uninit(void *ex_handle);
+s32 cqm5_service_register(
+ void *ex_handle,
+ struct tag_service_register_template *service_template);
+void cqm5_service_unregister(void *ex_handle, u32 service_type);
+
+s32 cqm5_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
+
+#define CQM_LOG_ID 0
+
+#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
+#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
+#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
+#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
+
+#define cqm_err(dev, format, ...) dev_err(dev, "[CQM]" format, ##__VA_ARGS__)
+#define cqm_warn(dev, format, ...) dev_warn(dev, "[CQM]" format, ##__VA_ARGS__)
+#define cqm_notice(dev, format, ...) \
+ dev_notice(dev, "[CQM]" format, ##__VA_ARGS__)
+#define cqm_info(dev, format, ...) dev_info(dev, "[CQM]" format, ##__VA_ARGS__)
+
+#ifdef __CQM_DEBUG__
+extern bool cqm_verbose;
+
+#define cqm_dbg(dev, format, ...) dev_info(dev, "[CQM]" format, ##__VA_ARGS__)
+#define cqm_dbg_on(condition, dev, format, ...) \
+ ({ \
+ if (condition) \
+ cqm_dbg(dev, format, ##__VA_ARGS__); \
+ })
+
+#define cqm_dbg_pr(format, ...) pr_info("[CQM]" format, ##__VA_ARGS__)
+#define cqm_dbg_pr_on(condition, format, ...) \
+ ({ \
+ if (condition) \
+ cqm_dbg_pr(format, ##__VA_ARGS__); \
+ })
+
+static inline void cqm_dbg_byte_print(struct device *dev, u32 *ptr, u32 len)
+{
+ u32 i;
+ for (i = 0; i < (len >> 0x2); i += 0x4)
+ cqm_dbg(dev, "%.8x %.8x %.8x %.8x\n", ptr[i], ptr[i + 0x1],
+ ptr[i + 0x2], ptr[i + 0x3]);
+}
+#else
+#define cqm_dbg(format, ...)
+#define cqm_dbg_on(condition, format, ...)
+#define cqm_dbg_pr(format, ...)
+#define cqm_dbg_pr_on(condition, format, ...)
+#define cqm_dbg_byte_print(dev, ptr, len)
+#endif
+
+#define CQM_PTR_CHECK_ERR(desc) pr_err("[CQM]" desc)
+
+static inline u32 cqm_get_child_func_start(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *func_cap = &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 cqm_get_child_func_number(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ return func_cap->fake_cfg.child_func_number;
+}
+
+static inline bool cqm_is_fake_vf_lazy_init(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *func_cap = &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 cqm_get_acs_spu_en(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *hwdev = cqm_handle->ex_handle;
+
+ if (cqm_handle->func_capability.gpa_spu_en == FUNC_GPA_SPU_DIS)
+ return 0;
+ if (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 /* CQM_MAIN_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.c
new file mode 100644
index 000000000..b2ea12883
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.c
@@ -0,0 +1,1765 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "hisdk5_typedef.h"
+
+#include "cqm_bitmap_table.h"
+#include "cqm_bat_cla.h"
+#include "cqm_object_intern.h"
+#include "cqm_main.h"
+#include "cqm_object.h"
+
+static void inline cqm_object_init(struct tag_cqm_object *object,
+ u32 service_type,
+ enum cqm_object_type object_type,
+ u32 object_size, void *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->cqm_handle = cqm_handle;
+}
+
+static s32 cqm_object_create_check(struct tag_cqm_handle *cqm_handle,
+ u32 service_type)
+{
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+
+ if (unlikely(service_type >= CQM_SERVICE_T_MAX)) {
+ cqm_err(cqm_handle->dev, "invalid service %u\n", service_type);
+ return CQM_FAIL;
+ }
+ if (unlikely(!cqm_handle->service[service_type].has_register)) {
+ cqm_err(cqm_handle->dev, "service %u has not registered\n",
+ service_type);
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm5_object_qpc_mpt_create
+ * Description : create QPC/MPT
+ * Input : void *ex_handle
+ * u32 service_type
+ * enum 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 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 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_cqm_qpc_mpt *
+ * 1.Date : 2016/2/16
+ * Modification : Created function
+ */
+struct tag_cqm_qpc_mpt *
+cqm5_object_qpc_mpt_create(void *ex_handle, u32 service_type,
+ enum 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_qpc_mpt_info *qpc_mpt_info = NULL;
+ struct tag_cqm_bitmap_range bp_range;
+ s32 ret = CQM_FAIL;
+ u32 relative_index;
+ u32 fake_func_id;
+ u32 index_num = index;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_qpc_mpt_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ if (object_type != CQM_OBJECT_SERVICE_CTX &&
+ object_type != CQM_OBJECT_MPT) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return NULL;
+ }
+
+ /* fake vf adaption, switch to corresponding VF. */
+ if (CQM_IS_FAKE_PARENT(cqm_handle) &&
+ !cqm_handle->func_capability.use_fake_parent_cla) {
+ struct tag_cqm_fake_cfg *fake_cfg =
+ &cqm_handle->func_capability.fake_cfg;
+ if (fake_cfg->fake_vf_max_pctx == 0) {
+ cqm_err(handle->dev_hdl,
+ 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 >= cqm_get_child_func_number(cqm_handle)) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(fake_func_id));
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(index));
+ return NULL;
+ }
+
+ index_num = relative_index;
+ cqm_handle = cqm_handle->fake_cqm_handle[fake_func_id];
+ }
+
+ qpc_mpt_info = kzalloc(sizeof(*qpc_mpt_info), GFP_ATOMIC);
+ if (unlikely(qpc_mpt_info == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(qpc_mpt_info));
+ return NULL;
+ }
+
+ cqm_object_init(&qpc_mpt_info->common.object, service_type, object_type,
+ object_size, 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 = cqm_qpc_mpt_create(&qpc_mpt_info->common.object, &bp_range);
+ if (ret == CQM_SUCCESS)
+ return &qpc_mpt_info->common;
+
+ cqm_warn(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_qpc_mpt_create));
+ kfree(qpc_mpt_info);
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_object_qpc_mpt_create);
+
+static struct tag_cqm_queue *
+cqm_create_rqs(struct tag_cqm_nonrdma_qinfo *rq_qinfo,
+ struct tag_cqm_handle *cqm_handle, struct hinic5_hwdev *handle,
+ u32 init_rq_num)
+{
+ u32 i;
+ /* 3. create queue header */
+ rq_qinfo->common.q_header_vaddr = cqm_kmalloc_align(
+ sizeof(struct tag_cqm_queue_header), GFP_KERNEL | __GFP_ZERO,
+ CQM_QHEAD_ALIGN_ORDER);
+ if (!rq_qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
+ return NULL;
+ }
+
+ rq_qinfo->common.q_header_paddr = dma_map_single(
+ cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
+ sizeof(struct tag_cqm_queue_header), DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(cqm_handle->dev,
+ rq_qinfo->common.q_header_paddr) != 0) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(q_header_vaddr));
+ goto err1;
+ }
+
+ /* 4. create rq */
+ for (i = 0; i < init_rq_num; i++) {
+ if (cqm_container_create(&rq_qinfo->common.object, NULL,
+ true) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(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:
+ cqm_container_free(rq_qinfo->common.head_container, NULL,
+ &rq_qinfo->common);
+ dma_unmap_single(cqm_handle->dev, rq_qinfo->common.q_header_paddr,
+ sizeof(struct tag_cqm_queue_header),
+ DMA_BIDIRECTIONAL);
+err1:
+ cqm_kfree_align(rq_qinfo->common.q_header_vaddr);
+ rq_qinfo->common.q_header_vaddr = NULL;
+ return NULL;
+}
+
+/**
+ * Prototype : cqm5_object_recv_queue_create
+ * Description : when srq is used, create rq.
+ * Input : void *ex_handle
+ * u32 service_type
+ * enum cqm_object_type object_type
+ * u32 init_rq_num
+ * u32 container_size
+ * u32 wqe_size
+ * void *object_priv
+ * Output : None
+ * Return Value : struct tag_cqm_queue *
+ * 1.Date : 2016/2/16
+ * Modification : Created function
+ */
+struct tag_cqm_queue *cqm5_object_recv_queue_create(
+ void *ex_handle, u32 service_type, enum 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_nonrdma_qinfo *rq_qinfo = NULL;
+ struct tag_cqm_queue *ret = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_rq_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ if (object_type != CQM_OBJECT_NONRDMA_EMBEDDED_RQ) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return NULL;
+ }
+
+ if (service_type != CQM_SERVICE_T_TOE) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
+ return NULL;
+ }
+
+ /* 1. create rq qinfo */
+ rq_qinfo = kzalloc(sizeof(*rq_qinfo), GFP_KERNEL);
+ if (unlikely(rq_qinfo == NULL)) {
+ CQM_PTR_CHECK_ERR(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 = CQM_QUEUE_TOE_SRQ_LINK_MODE;
+ rq_qinfo->common.priv = object_priv;
+ cqm_object_init(&rq_qinfo->common.object, service_type, object_type,
+ init_rq_num, cqm_handle);
+
+ /* 3. create rq */
+ ret = cqm_create_rqs(rq_qinfo, cqm_handle, handle, init_rq_num);
+ if (ret == NULL)
+ kfree(rq_qinfo);
+
+ return ret;
+}
+EXPORT_SYMBOL(cqm5_object_recv_queue_create);
+
+/**
+ * Prototype : cqm5_object_share_recv_queue_add_container
+ * Description : allocate new container for srq
+ * Input : struct tag_cqm_queue *common
+ * Output : None
+ * Return Value : tail_container address
+ * 1.Date : 2016/2/14
+ * Modification : Created function
+ */
+s32 cqm5_object_share_recv_queue_add_container(struct tag_cqm_queue *common)
+{
+ if (unlikely(common == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(common));
+ return CQM_FAIL;
+ }
+
+ return cqm_container_create(&common->object, NULL, true);
+}
+EXPORT_SYMBOL(cqm5_object_share_recv_queue_add_container);
+
+s32 cqm5_object_srq_add_container_free(struct tag_cqm_queue *common,
+ u8 **container_addr)
+{
+ if (unlikely(common == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(common));
+ return CQM_FAIL;
+ }
+
+ return cqm_container_create(&common->object, container_addr, false);
+}
+EXPORT_SYMBOL(cqm5_object_srq_add_container_free);
+
+static bool cqm_object_share_recv_queue_param_check(
+ struct hinic5_hwdev *handle, u32 service_type,
+ enum cqm_object_type object_type, u32 container_size, u32 wqe_size)
+{
+ /* service_type must be CQM_SERVICE_T_TOE */
+ if (service_type != CQM_SERVICE_T_TOE) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
+ return false;
+ }
+
+ /* container size2^N aligning */
+ if (!cqm_check_align(container_size)) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(container_size));
+ return false;
+ }
+
+ /* external parameter check: object_type must be
+ * CQM_OBJECT_NONRDMA_SRQ
+ */
+ if (object_type != CQM_OBJECT_NONRDMA_SRQ) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return false;
+ }
+
+ /* wqe_size, the divisor, cannot be 0 */
+ if (wqe_size == 0) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_size));
+ return false;
+ }
+
+ if (container_size < wqe_size) {
+ cqm_err(handle->dev_hdl,
+ "container_size(0x%x) is smaller than wqe_size(0x%x)!",
+ container_size, wqe_size);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Prototype : cqm5_object_share_recv_queue_create
+ * Description : create srq
+ * Input : void *ex_handle
+ * u32 service_type
+ * enum cqm_object_type object_type
+ * u32 container_number
+ * u32 container_size
+ * u32 wqe_size
+ * Output : None
+ * Return Value : struct tag_cqm_queue *
+ * 1.Date : 2016/2/1
+ * Modification : Created function
+ */
+struct tag_cqm_queue *cqm5_object_share_recv_queue_create(
+ void *ex_handle, u32 service_type, enum 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_nonrdma_qinfo *srq_qinfo = NULL;
+ struct tag_cqm_service *service = NULL;
+ s32 ret;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_srq_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ if (!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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(srq_qinfo));
+ return NULL;
+ }
+
+ cqm_object_init(&srq_qinfo->common.object, service_type, object_type,
+ container_number, cqm_handle);
+
+ srq_qinfo->common.queue_link_mode = 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 = &cqm_handle->service[service_type];
+ srq_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
+
+ /* 3. create srq and srq ctx */
+ ret = cqm_share_recv_queue_create(&srq_qinfo->common.object);
+ if (ret == CQM_SUCCESS)
+ return &srq_qinfo->common;
+
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_share_recv_queue_create));
+ kfree(srq_qinfo);
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_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 cqm_object_fc_srq_param_check(struct hinic5_hwdev *handle,
+ u32 service_type,
+ enum cqm_object_type object_type,
+ u32 wqe_size)
+{
+ /* service_type must be CQM_SERVICE_T_FC */
+ if (service_type != CQM_SERVICE_T_FC) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
+ return false;
+ }
+
+ /* object_type must be CQM_OBJECT_NONRDMA_SRQ */
+ if (object_type != CQM_OBJECT_NONRDMA_SRQ) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return false;
+ }
+
+ if (wqe_size >= PAGE_SIZE || !cqm_check_align(wqe_size)) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_size));
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Prototype : 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 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_cqm_queue *
+cqm5_object_fc_srq_create(void *ex_handle, u32 service_type,
+ enum 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
+ struct tag_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)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_fc_srq_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ if (!cqm_object_fc_srq_param_check(handle, service_type, object_type,
+ wqe_size))
+ return NULL;
+
+ service = &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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(nonrdma_qinfo));
+ return NULL;
+ }
+
+ cqm_object_init(&nonrdma_qinfo->common.object, service_type,
+ object_type, wqe_sum, cqm_handle);
+
+ /* Initialize the doorbell used by the current queue.
+ * The default doorbell is the hardware doorbell.
+ */
+ nonrdma_qinfo->common.current_q_doorbell = 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 = 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 = cqm_nonrdma_queue_create(&nonrdma_qinfo->common.object);
+ if (ret == CQM_SUCCESS)
+ return &nonrdma_qinfo->common;
+
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fc_queue_create));
+ kfree(nonrdma_qinfo);
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_object_fc_srq_create);
+
+static bool
+cqm_object_nonrdma_queue_param_check(struct hinic5_hwdev *handle,
+ enum 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 cqm_check_align is to check above
+ */
+ if (wqe_size >= PAGE_SIZE || (!cqm_check_align(wqe_size))) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_size));
+ return false;
+ }
+
+ /* nonrdma supports: RQ, SQ, SRQ, CQ, SCQ */
+ if (object_type < CQM_OBJECT_NONRDMA_EMBEDDED_RQ ||
+ object_type > CQM_OBJECT_NONRDMA_SCQ) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Prototype : cqm5_object_nonrdma_queue_create
+ * Description : create nonrdma queue
+ * Input : void *ex_handle
+ * u32 service_type
+ * enum 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_cqm_queue *
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+struct tag_cqm_queue *cqm5_object_nonrdma_queue_create(
+ void *ex_handle, u32 service_type, enum 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
+ struct tag_cqm_service *service = NULL;
+ s32 ret;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_nonrdma_queue_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ if (!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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(nonrdma_qinfo));
+ return NULL;
+ }
+
+ cqm_object_init(&nonrdma_qinfo->common.object, service_type,
+ object_type, wqe_number, cqm_handle);
+
+ /* Initialize the doorbell used by the current queue.
+ * The default value is hardware doorbell
+ */
+ nonrdma_qinfo->common.current_q_doorbell = CQM_HARDWARE_DOORBELL;
+ /* Currently, the link mode is hardcoded and needs to be transferred by
+ * the service side.
+ */
+ nonrdma_qinfo->common.queue_link_mode = CQM_QUEUE_RING_MODE;
+
+ nonrdma_qinfo->common.priv = object_priv;
+
+ /* Initialize internal private members */
+ nonrdma_qinfo->wqe_size = wqe_size;
+ service = &cqm_handle->service[service_type];
+ if (object_type == CQM_OBJECT_NONRDMA_SCQ) {
+ nonrdma_qinfo->q_ctx_size =
+ service->service_template.scq_ctx_size;
+ } else if (object_type == 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 = cqm_nonrdma_queue_create(&nonrdma_qinfo->common.object);
+ if (ret == CQM_SUCCESS)
+ return &nonrdma_qinfo->common;
+
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_nonrdma_queue_create));
+ kfree(nonrdma_qinfo);
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_object_nonrdma_queue_create);
+
+static bool cqm_object_rdma_queue_param_check(struct hinic5_hwdev *handle,
+ u32 service_type,
+ enum cqm_object_type object_type)
+{
+ /* service_type must be CQM_SERVICE_T_ROCE or CQM_SERVICE_T_UB */
+ if (service_type != CQM_SERVICE_T_ROCE &&
+ service_type != CQM_SERVICE_T_UB &&
+ service_type != CQM_SERVICE_T_VBS) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
+ return false;
+ }
+
+ /* rdma supports: QP, SRQ, SCQ */
+ if (object_type > CQM_OBJECT_RDMA_SCQ ||
+ object_type < CQM_OBJECT_RDMA_QP) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Prototype : cqm5_object_rdma_queue_create
+ * Description : create rdma queue
+ * Input : void *ex_handle
+ * u32 service_type
+ * enum 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 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 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_cqm_queue *
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+struct tag_cqm_queue *
+cqm5_object_rdma_queue_create(void *ex_handle, u32 service_type,
+ enum 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_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_rdma_qinfo *rdma_qinfo = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct tag_cqm_bitmap_range bp_range;
+ s32 ret;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_rdma_queue_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ if (!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)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(rdma_qinfo));
+ return NULL;
+ }
+
+ cqm_object_init(&rdma_qinfo->common.object, service_type, object_type,
+ object_size, cqm_handle);
+ rdma_qinfo->common.queue_link_mode = CQM_QUEUE_RDMA_QUEUE_MODE;
+ rdma_qinfo->common.priv = object_priv;
+ rdma_qinfo->common.current_q_room = 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 = CQM_HARDWARE_DOORBELL;
+
+ service = &cqm_handle->service[service_type];
+ if (object_type == CQM_OBJECT_RDMA_SCQ)
+ rdma_qinfo->q_ctx_size = service->service_template.scq_ctx_size;
+ else if (object_type == CQM_OBJECT_RDMA_SRQ)
+ rdma_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
+
+ ret = cqm_rdma_queue_create(&rdma_qinfo->common.object, &bp_range);
+ if (ret == CQM_SUCCESS)
+ return &rdma_qinfo->common;
+
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_rdma_queue_create));
+ kfree(rdma_qinfo);
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_object_rdma_queue_create);
+
+/**
+ * Prototype : cqm5_object_rdma_table_get
+ * Description : create mtt and rdmarc of the rdma service
+ * Input : void *ex_handle
+ * u32 service_type
+ * enum cqm_object_type object_type
+ * u32 index_base: start of index
+ * u32 index_number
+ * Output : None
+ * Return Value : struct tag_cqm_mtt_rdmarc *
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+struct tag_cqm_mtt_rdmarc *
+cqm5_object_rdma_table_get(void *ex_handle, u32 service_type,
+ enum cqm_object_type object_type, u32 index_base,
+ u32 index_number)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_rdma_table *rdma_table = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ s32 ret;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_rdma_table_create_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_object_create_check(cqm_handle, service_type) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_create_check));
+ return NULL;
+ }
+
+ /* service_type must be CQM_SERVICE_T_ROCE or CQM_SERVICE_T_UB */
+ if (service_type != CQM_SERVICE_T_ROCE &&
+ service_type != CQM_SERVICE_T_UB) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
+ return NULL;
+ }
+
+ if (object_type != CQM_OBJECT_MTT && object_type != CQM_OBJECT_RDMARC) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
+ return NULL;
+ }
+
+ rdma_table = kzalloc(sizeof(*rdma_table), GFP_KERNEL);
+ if (unlikely(rdma_table == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(rdma_table));
+ return NULL;
+ }
+
+ cqm_object_init(&rdma_table->common.object, service_type, object_type,
+ (u32)(index_number * sizeof(dma_addr_t)), cqm_handle);
+ rdma_table->common.index_base = index_base;
+ rdma_table->common.index_number = index_number;
+
+ ret = cqm_rdma_table_create(&rdma_table->common.object);
+ if (ret == CQM_SUCCESS)
+ return &rdma_table->common;
+
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_rdma_table_create));
+ kfree(rdma_table);
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_object_rdma_table_get);
+
+static inline void cqm_object_do_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_handle *cqm_handle = object->cqm_handle;
+ const u32 object_type = object->object_type;
+
+ switch (object_type) {
+ case CQM_OBJECT_SERVICE_CTX:
+ case CQM_OBJECT_MPT:
+ cqm_qpc_mpt_delete(object);
+ return;
+ case CQM_OBJECT_NONRDMA_EMBEDDED_RQ:
+ case CQM_OBJECT_NONRDMA_EMBEDDED_SQ:
+ case CQM_OBJECT_NONRDMA_EMBEDDED_CQ:
+ case CQM_OBJECT_NONRDMA_SCQ:
+ cqm_nonrdma_queue_delete(object);
+ return;
+ case CQM_OBJECT_NONRDMA_SRQ:
+ if (object->service_type == CQM_SERVICE_T_TOE)
+ cqm_share_recv_queue_delete(object);
+ else
+ cqm_nonrdma_queue_delete(object);
+ return;
+ case CQM_OBJECT_RDMA_QP:
+ case CQM_OBJECT_RDMA_SRQ:
+ case CQM_OBJECT_RDMA_SCQ:
+ cqm_rdma_queue_delete(object);
+ return;
+ case CQM_OBJECT_MTT:
+ case CQM_OBJECT_RDMARC:
+ cqm_rdma_table_delete(object);
+ return;
+ default:
+ cqm_err(cqm_handle->dev, CQM_WRONG_VALUE(object_type));
+ return;
+ }
+}
+
+/**
+ * Prototype : cqm5_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_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm5_object_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct hinic5_hwdev *handle = NULL;
+
+ if (unlikely(object == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object));
+ return;
+ }
+ if (!object->cqm_handle) {
+ pr_err("[CQM]object del: cqm_handle is null, service type %u, refcount %d\n",
+ object->service_type, (int)object->refcount.counter);
+ kfree(object);
+ return;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)object->cqm_handle;
+
+ if (!cqm_handle->ex_handle) {
+ pr_err("[CQM]object del: ex_handle is null, service type %u, refcount %d\n",
+ object->service_type, (int)object->refcount.counter);
+ kfree(object);
+ return;
+ }
+
+ handle = cqm_handle->ex_handle;
+
+ if (object->service_type >= CQM_SERVICE_T_MAX) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->service_type));
+ kfree(object);
+ return;
+ }
+
+ cqm_object_do_delete(object);
+ kfree(object);
+}
+EXPORT_SYMBOL(cqm5_object_delete);
+
+/**
+ * Prototype : cqm5_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_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 *cqm5_object_offset_addr(struct tag_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 CQM_OBJECT_MTT:
+ case CQM_OBJECT_RDMARC:
+ return cqm_rdma_table_offset_addr(object, offset, paddr);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_object_offset_addr);
+
+/**
+ * Prototype : cqm5_object_get
+ * Description : Obtain an object based on the index.
+ * Input : void *ex_handle
+ * enum 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_cqm_object *cqm5_object_get(void *ex_handle,
+ enum cqm_object_type object_type,
+ u32 index, bool bh)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_bat_table *bat_table = NULL;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_object *object = NULL;
+
+ if (!ex_handle)
+ return NULL;
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (!cqm_handle)
+ return NULL;
+
+ bat_table = &cqm_handle->bat_table;
+
+ /* The data flow path takes performance into consideration and
+ * does not check input parameters.
+ */
+ switch (object_type) {
+ case CQM_OBJECT_SERVICE_CTX:
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_QPC);
+ break;
+ case CQM_OBJECT_MPT:
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_MPT);
+ break;
+ case CQM_OBJECT_RDMA_SRQ:
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SRQC);
+ break;
+ case CQM_OBJECT_RDMA_SCQ:
+ case CQM_OBJECT_NONRDMA_SCQ:
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SCQC);
+ break;
+ default:
+ return NULL;
+ }
+
+ if (!cla_table) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_table_get));
+ return NULL;
+ }
+
+ object_table = &cla_table->obj_table;
+ object = cqm_object_table_get(cqm_handle, object_table, index, bh);
+ return object;
+}
+EXPORT_SYMBOL(cqm5_object_get);
+
+/**
+ * Prototype : cqm5_object_put
+ * Description : This function must be called after the cqm5_object_get
+ * function. Otherwise, the object cannot be released.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm5_object_put(struct tag_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(cqm5_object_put);
+
+/**
+ * Prototype : cqm5_object_funcid
+ * Description : Obtain the ID of the function to which the object belongs.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : If successful, the ID of the function will be returned.
+ * If fail CQM_FAIL(-1) will be returned.
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm5_object_funcid(struct tag_cqm_object *object)
+{
+ struct tag_cqm_handle *cqm_handle = NULL;
+
+ if (unlikely(object == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object));
+ return CQM_FAIL;
+ }
+ if (unlikely(object->cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)object->cqm_handle;
+
+ return cqm_handle->func_attribute.func_global_idx;
+}
+EXPORT_SYMBOL(cqm5_object_funcid);
+
+/**
+ * Prototype : cqm5_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_cqm_object *object
+ * u32 object_size
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm5_object_resize_alloc_new(struct tag_cqm_object *object, u32 object_size)
+{
+ struct tag_cqm_rdma_qinfo *qinfo =
+ (struct tag_cqm_rdma_qinfo *)(void *)object;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_service *service = NULL;
+ struct tag_cqm_buf *q_room_buf = NULL;
+ struct hinic5_hwdev *handle = NULL;
+ u32 order, buf_size;
+
+ if (unlikely(object == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object));
+ return CQM_FAIL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)object->cqm_handle;
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object->cqm_handle));
+ return CQM_FAIL;
+ }
+ handle = cqm_handle->ex_handle;
+
+ /* This interface is used only for the CQ of RoCE service. */
+ if (object->service_type == CQM_SERVICE_T_ROCE &&
+ object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ service = cqm_handle->service + object->service_type;
+ order = service->buf_order;
+ buf_size = (u32)(PAGE_SIZE << order);
+
+ if (qinfo->common.current_q_room == 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 (cqm_buf_alloc(cqm_handle, q_room_buf, true) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_buf_alloc));
+ return CQM_FAIL;
+ }
+
+ qinfo->new_object_size = object_size;
+ return CQM_SUCCESS;
+ }
+
+ cqm_err(handle->dev_hdl,
+ CQM_WRONG_VALUE(qinfo->room_header_alloc));
+ return CQM_FAIL;
+ }
+
+ 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 CQM_FAIL;
+}
+EXPORT_SYMBOL(cqm5_object_resize_alloc_new);
+
+/**
+ * Prototype : cqm5_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_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm5_object_resize_free_new(struct tag_cqm_object *object)
+{
+ struct tag_cqm_rdma_qinfo *qinfo =
+ (struct tag_cqm_rdma_qinfo *)(void *)object;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_buf *q_room_buf = NULL;
+ struct hinic5_hwdev *handle = NULL;
+
+ if (unlikely(object == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object));
+ return;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)object->cqm_handle;
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+ handle = cqm_handle->ex_handle;
+
+ /* This interface is used only for the CQ of RoCE service. */
+ if (object->service_type == CQM_SERVICE_T_ROCE &&
+ object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ if (qinfo->common.current_q_room == 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;
+
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+ } else {
+ 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(cqm5_object_resize_free_new);
+
+/**
+ * Prototype : cqm5_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_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm5_object_resize_free_old(struct tag_cqm_object *object)
+{
+ struct tag_cqm_rdma_qinfo *qinfo =
+ (struct tag_cqm_rdma_qinfo *)(void *)object;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_buf *q_room_buf = NULL;
+
+ if (unlikely(object == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(object));
+ return;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)object->cqm_handle;
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+
+ /* This interface is used only for the CQ of RoCE service. */
+ if (object->service_type == CQM_SERVICE_T_ROCE &&
+ object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ if (qinfo->common.current_q_room == CQM_RDMA_Q_ROOM_1) {
+ q_room_buf = &qinfo->common.q_room_buf_1;
+ qinfo->common.current_q_room = CQM_RDMA_Q_ROOM_2;
+ } else {
+ q_room_buf = &qinfo->common.q_room_buf_2;
+ qinfo->common.current_q_room = CQM_RDMA_Q_ROOM_1;
+ }
+
+ object->object_size = qinfo->new_object_size;
+
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+ }
+}
+EXPORT_SYMBOL(cqm5_object_resize_free_old);
+
+/**
+ * Prototype : 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 *cqm_gid_base(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bat_table *bat_table = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_buf *cla_z_buf = NULL;
+ u32 entry_type, i;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return NULL;
+ }
+
+ bat_table = &cqm_handle->bat_table;
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ entry_type = bat_table->bat_entry_type[i];
+ if (entry_type == 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 : cqm5_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 *cqm5_timer_base(void *ex_handle)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bat_table *bat_table = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_buf *cla_z_buf = NULL;
+ u32 entry_type, i;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return NULL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return NULL;
+ }
+
+ /* Timer resource is configured on PPF. */
+ if (!CQM_IS_PPF(cqm_handle)) {
+ cqm_err(handle->dev_hdl, "%s: wrong function type:%d\n",
+ __func__, handle->hwif->attr.func_type);
+ return NULL;
+ }
+
+ bat_table = &cqm_handle->bat_table;
+
+ for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
+ entry_type = bat_table->bat_entry_type[i];
+ if (entry_type != 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 (cqm_buf_alloc_direct(cqm_handle, cla_z_buf, true) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(
+ cqm_buf_alloc_direct));
+ return NULL;
+ }
+ }
+
+ return cla_z_buf->direct.va;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(cqm5_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 cqm_timer_get_func_offset(struct hinic5_hwdev *ex_handle,
+ u32 func_id, u32 *func_offset)
+{
+ struct tag_cqm_handle *cqm_handle = ex_handle->cqm_hdl;
+ struct tag_cqm_func_capability *cap = &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 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 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 CQM_SUCCESS;
+ }
+ vf_offset += seg->num;
+ }
+
+fail:
+ cqm_err(ex_handle->dev_hdl, "Timer clear: wrong func id %u\n", func_id);
+ return CQM_FAIL;
+}
+
+STATIC void cqm_clear_timer(struct hinic5_hwdev *handle, u32 func_id,
+ struct tag_cqm_cla_table *cla_table)
+{
+ struct tag_cqm_handle *cqm_handle = handle->cqm_hdl;
+ struct tag_cqm_func_capability *cap = &cqm_handle->func_capability;
+ struct tag_cqm_buf *cla_buf = &cla_table->cla_z_buf;
+ u32 func_timer_size = 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 = cqm_timer_get_func_offset(handle, func_id, &func_offset);
+ if (ret == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(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) {
+ cqm_err(handle->dev_hdl,
+ "Timer clear: func buffer end %u overflow, limit %u.\n",
+ func_buf_end, cla_buf->buf_number);
+ goto fail;
+ }
+
+ 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++) {
+ cqm_dbg_on(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);
+ (void)memset_s(cla_buf->buf_list[i].va, cla_buf->buf_size, 0,
+ cla_buf->buf_size);
+ }
+ return;
+
+fail:
+ 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);
+ 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 : cqm5_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 cqm5_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_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ u32 loop, i;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_func_timer_clear_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+
+ if (CQM_IS_LB_MODE_1_OR_2(cqm_handle)) {
+ cla_table = &cqm_handle->bat_table.timer_entry[0];
+ loop = cqm_handle->func_capability.smf_max_num;
+ } else {
+ cla_table = cqm_cla_table_get(&cqm_handle->bat_table,
+ CQM_BAT_ENTRY_T_TIMER);
+ loop = 1;
+ }
+
+ if (unlikely(cla_table == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cla_table));
+ return;
+ }
+ for (i = 0; i < loop; i++) {
+ cqm_clear_timer(handle, function_id, cla_table);
+ cla_table++;
+ }
+}
+EXPORT_SYMBOL(cqm5_function_timer_clear);
+
+/**
+ * Prototype : cqm5_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 cqm5_function_hash_buf_clear(void *ex_handle, s32 global_funcid)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_func_capability *func_cap = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_buf *cla_z_buf = NULL;
+ s32 fake_funcid;
+ u32 loop;
+ u32 i;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_func_hash_buf_clear_cnt);
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+ func_cap = &cqm_handle->func_capability;
+
+ /* fake vf adaption, switch to corresponding VF. */
+ if (CQM_IS_FAKE_PARENT(cqm_handle)) {
+ fake_funcid = global_funcid -
+ (s32)(func_cap->fake_cfg.child_func_start);
+ cqm_info(handle->dev_hdl, "fake_funcid =%d\n", fake_funcid);
+ if (fake_funcid < 0 || fake_funcid >= CQM_FAKE_FUNC_MAX) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(fake_funcid));
+ return;
+ }
+
+ cqm_handle = cqm_handle->fake_cqm_handle[fake_funcid];
+ }
+
+ if (CQM_IS_LB_MODE_1_OR_2(cqm_handle)) {
+ cla_table = &cqm_handle->bat_table.hash_entry[0];
+ loop = cqm_handle->func_capability.smf_max_num;
+ } else {
+ cla_table = cqm_cla_table_get(&cqm_handle->bat_table,
+ CQM_BAT_ENTRY_T_HASH);
+ loop = 1;
+ }
+
+ if (unlikely(cla_table == NULL)) {
+ CQM_PTR_CHECK_ERR(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++)
+ (void)memset_s(cla_z_buf->buf_list[i].va,
+ cla_z_buf->buf_size, 0,
+ cla_z_buf->buf_size);
+
+ cla_table++;
+ loop--;
+ }
+}
+EXPORT_SYMBOL(cqm5_function_hash_buf_clear);
+
+void cqm5_srq_used_rq_container_delete(struct tag_cqm_object *object,
+ u8 *container)
+{
+ struct tag_cqm_queue *common = NULL;
+ struct tag_cqm_nonrdma_qinfo *qinfo = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_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_cqm_queue, object);
+ qinfo = container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
+ cqm_handle = (struct tag_cqm_handle *)(common->object.cqm_handle);
+ handle = cqm_handle->ex_handle;
+
+ /* 1. Obtain the current container pa through link wqe table,
+ * unmap pa
+ */
+ srq_link_wqe = (struct tag_cqm_srq_linkwqe *)((uintptr_t)container +
+ link_wqe_offset);
+ /* shift right by 2 bits to get the length of dw(4B) */
+ cqm_swab32((u8 *)(srq_link_wqe), sizeof(struct tag_cqm_linkwqe) >> 2);
+
+ addr = CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_gpa_h,
+ srq_link_wqe->current_buffer_gpa_l);
+ if (addr == 0) {
+ cqm_err(handle->dev_hdl,
+ "Rq container del: buffer physical addr is null\n");
+ return;
+ }
+ dma_unmap_single(cqm_handle->dev, addr, qinfo->container_size,
+ DMA_BIDIRECTIONAL);
+
+ /* 2. Obtain the current container va through link wqe table, free va */
+ addr = CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_addr_h,
+ srq_link_wqe->current_buffer_addr_l);
+ if (addr == 0) {
+ cqm_err(handle->dev_hdl,
+ "Rq container del: buffer virtual addr is null\n");
+ return;
+ }
+ kfree((void *)(uintptr_t)addr);
+}
+EXPORT_SYMBOL(cqm5_srq_used_rq_container_delete);
+
+s32 cqm5_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_cqm_toe_private_capability *tow_own_cap = NULL;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ u32 step;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return CQM_FAIL;
+ }
+ if (unlikely(index_count == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(index_count));
+ return CQM_FAIL;
+ }
+ if (unlikely(index == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(index));
+ return CQM_FAIL;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return CQM_FAIL;
+ }
+
+ tow_own_cap = &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 = cqm_bitmap_alloc(bitmap, step, *index_count,
+ cqm_handle->func_capability.xid_alloc_mode);
+ if (*index >= bitmap->max_num) {
+ cqm_err(handle->dev_hdl,
+ "Srq create: queue index %u exceeds max_num %u\n",
+ *index, bitmap->max_num);
+ return CQM_FAIL;
+ }
+ *index += tow_own_cap->toe_srqc_start_id;
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_srq_create_cnt);
+
+ return CQM_SUCCESS;
+}
+EXPORT_SYMBOL(cqm5_dtoe_share_recv_queue_create);
+
+void cqm5_dtoe_free_srq_bitmap_index(void *ex_handle, u32 index_count,
+ u32 index)
+{
+ struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
+ struct tag_cqm_handle *cqm_handle = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+
+ if (unlikely(ex_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(ex_handle));
+ return;
+ }
+
+ cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (unlikely(cqm_handle == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_PTR_NULL(cqm_handle));
+ return;
+ }
+
+ bitmap = &cqm_handle->toe_own_capability.srqc_bitmap;
+ if ((index + index_count) > bitmap->max_num ||
+ (index + index_count) <= index) { // 避免翻圈
+ CQM_PTR_CHECK_ERR(CQM_WRONG_VALUE(index + index_count));
+ return;
+ }
+
+ cqm_bitmap_free(bitmap, index, index_count);
+}
+EXPORT_SYMBOL(cqm5_dtoe_free_srq_bitmap_index);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.h
new file mode 100644
index 000000000..02b2c0f20
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object.h
@@ -0,0 +1,385 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_OBJECT_H
+#define CQM_OBJECT_H
+
+#include "comm_defs.h"
+#include "hinic5_cqm.h"
+
+#define CQM_LINKWQE_128B 128
+#define CQM_MOD_TOE HINIC5_MOD_TOE
+#define CQM_MOD_CQM HINIC5_MOD_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_cqm_queue*: queue structure pointer
+ * @date: 2019-5-4
+ */
+struct tag_cqm_queue *
+cqm5_object_fc_srq_create(void *ex_handle, u32 service_type,
+ enum 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_cqm_queue*: queue structure pointer
+ * @date: 2019-5-4
+ */
+struct tag_cqm_queue *cqm5_object_recv_queue_create(
+ void *ex_handle, u32 service_type, enum 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 cqm5_object_share_recv_queue_add_container(struct tag_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 cqm5_object_srq_add_container_free(struct tag_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_cqm_queue*: queue structure pointer
+ * @date: 2019-5-4
+ */
+struct tag_cqm_queue *cqm5_object_share_recv_queue_create(
+ void *ex_handle, u32 service_type, enum 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 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_cqm_qpc_mpt *: pointer to the QPC/MPT structure
+ * @date: 2019-5-4
+ */
+struct tag_cqm_qpc_mpt *
+cqm5_object_qpc_mpt_create(void *ex_handle, u32 service_type,
+ enum 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_cqm_queue *: queue structure pointer
+ * @date: 2019-5-4
+ */
+struct tag_cqm_queue *cqm5_object_nonrdma_queue_create(
+ void *ex_handle, u32 service_type, enum 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 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_cqm_queue *: queue structure pointer
+ * @date: 2019-5-4
+ */
+struct tag_cqm_queue *
+cqm5_object_rdma_queue_create(void *ex_handle, u32 service_type,
+ enum 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_cqm_mtt_rdmarc *: pointer to the MTT/RDMARC structure
+ * @date: 2019-5-4
+ */
+struct tag_cqm_mtt_rdmarc *
+cqm5_object_rdma_table_get(void *ex_handle, u32 service_type,
+ enum 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 cqm5_object_delete(struct tag_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 *cqm5_object_offset_addr(struct tag_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_cqm_object *: object pointer
+ * @date: 2019-5-4
+ */
+struct tag_cqm_object *cqm5_object_get(void *ex_handle,
+ enum cqm_object_type object_type,
+ u32 index, bool bh);
+
+/**
+ * @brief: object reference counting release
+ * @details: After the function cqm5_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 cqm5_object_put(struct tag_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 cqm5_object_funcid(struct tag_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 cqm5_object_resize_alloc_new(struct tag_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 cqm5_object_resize_free_new(struct tag_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 cqm5_object_resize_free_old(struct tag_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 cqm5_srq_used_rq_container_delete(struct tag_cqm_object *object,
+ u8 *container);
+
+void *cqm5_get_db_addr(void *ex_handle, u32 service_type);
+
+s32 cqm5_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 CQM converts the pri to cos.
+ * @details: provide interface of knocking on doorbell for the 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 cqm5_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 cqm5_ring_software_db(struct tag_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 *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 *cqm5_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 cqm5_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 cqm5_function_hash_buf_clear(void *ex_handle, s32 global_funcid);
+
+s32 cqm5_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
+ void *direct_wqe);
+
+/**
+ * @brief: 敲direct wqe db for fc
+ * @details: 敲direct wqe db for fc
+ * @param ex_handle: device pointer that represents the PF
+ * @param service_type: 服务类型
+ * @param direct_wqe: 要写入的direct wqe
+ * @retval: s32, 0成功,其他失败
+ */
+s32 cqm5_ring_direct_wqe_db_fc(void *ex_handle, u32 service_type,
+ void *direct_wqe);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif /* CQM_OBJECT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.c
new file mode 100644
index 000000000..28bd10c6f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.c
@@ -0,0 +1,1625 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#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 "cqm_object.h"
+#include "cqm_bitmap_table.h"
+#include "cqm_bat_cla.h"
+#include "cqm_main.h"
+#include "cqm_object_intern.h"
+
+#define srq_obj_intern_if_section
+
+/**
+ * Prototype : 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_cqm_queue *common
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2016/2/1
+ * Modification : Created function
+ */
+void cqm_container_free(u8 *srq_head_container, u8 *srq_tail_container,
+ struct tag_cqm_queue *common)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(common->object.cqm_handle);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ u32 link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_srq_linkwqe *srq_link_wqe = NULL;
+ u32 container_size = qinfo->container_size;
+ struct device *dev = cqm_handle->dev;
+ u64 addr;
+ u8 *srqhead_container = srq_head_container;
+ u8 *srqtail_container = srq_tail_container;
+
+ if (unlikely(srqhead_container == NULL)) {
+ CQM_PTR_CHECK_ERR(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_cqm_srq_linkwqe *)(srqtail_container +
+ link_wqe_offset);
+ /* Only the link wqe part needs to be converted. */
+ cqm_swab32((u8 *)(srq_link_wqe),
+ sizeof(struct tag_cqm_linkwqe) >> CQM_DW_SHIFT);
+ srqtail_container = (u8 *)(uintptr_t)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_cqm_srq_linkwqe *)(srqhead_container +
+ link_wqe_offset);
+ /* Only the link wqe part needs to be converted. */
+ cqm_swab32((u8 *)(srq_link_wqe),
+ sizeof(struct tag_cqm_linkwqe) >> CQM_DW_SHIFT);
+ /* Obtain the va of the next container using the link wqe. */
+ srqhead_container = (u8 *)(uintptr_t)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 = CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_gpa_h,
+ srq_link_wqe->current_buffer_gpa_l);
+ if (addr == 0) {
+ 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 = CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_addr_h,
+ srq_link_wqe->current_buffer_addr_l);
+ if (addr == 0) {
+ 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 cqm_update_srq_link_wqe(u32 link_wqe_offset, u8 *new_container,
+ dma_addr_t new_container_pa)
+{
+ struct tag_cqm_srq_linkwqe *srq_link_wqe =
+ (struct tag_cqm_srq_linkwqe *)((uintptr_t)new_container +
+ link_wqe_offset);
+ struct tag_cqm_linkwqe *link_wqe = &srq_link_wqe->linkwqe;
+
+ link_wqe->o = CQM_LINK_WQE_OWNER_INVALID;
+ link_wqe->ctrlsl = CQM_LINK_WQE_CTRLSL_VALUE;
+ link_wqe->lp = CQM_LINK_WQE_LP_INVALID;
+ link_wqe->wf = CQM_WQE_WF_LINK;
+ srq_link_wqe->current_buffer_gpa_h = CQM_ADDR_HI(new_container_pa);
+ srq_link_wqe->current_buffer_gpa_l = CQM_ADDR_LW(new_container_pa);
+ srq_link_wqe->current_buffer_addr_h =
+ CQM_ADDR_HI((uintptr_t)new_container);
+ srq_link_wqe->current_buffer_addr_l =
+ CQM_ADDR_LW((uintptr_t)new_container);
+
+ /* Convert only the area accessed by the chip to the network sequence */
+ cqm_swab32((u8 *)link_wqe,
+ sizeof(struct tag_cqm_linkwqe) >> CQM_DW_SHIFT);
+}
+
+/**
+ * Prototype : 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_cqm_object *object
+ * u8 **container_addr
+ * bool link
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2016/2/16
+ * Modification : Created function
+ */
+s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr,
+ bool link)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(object->cqm_handle);
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ u32 link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_srq_linkwqe *srq_link_wqe = NULL;
+ struct tag_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) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(new_container));
+ return CQM_FAIL;
+ }
+
+ /* Container PCI mapping */
+ new_container_pa = dma_map_single(cqm_handle->dev, new_container,
+ qinfo->container_size,
+ DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(cqm_handle->dev, new_container_pa) != 0) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(new_container_pa));
+ kfree(new_container);
+ return 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_cqm_srq_linkwqe
+ *)(common->tail_container +
+ link_wqe_offset);
+ link_wqe = &srq_link_wqe->linkwqe;
+ link_wqe->next_page_gpa_h =
+ __swab32((u32)CQM_ADDR_HI(new_container_pa));
+ link_wqe->next_page_gpa_l =
+ __swab32((u32)CQM_ADDR_LW(new_container_pa));
+ link_wqe->next_buffer_addr_h = __swab32(
+ (u32)CQM_ADDR_HI((uintptr_t)new_container));
+ link_wqe->next_buffer_addr_l = __swab32(
+ (u32)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)CQM_ADDR_HI((uintptr_t)new_container);
+ srq_link_wqe->fixed_next_buffer_addr_l =
+ (u32)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. */
+ 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 CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_srq_container_init
+ * Description : Initialize the SRQ to create all containers and link them.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2016/2/3
+ * Modification : Created function
+ */
+static s32 cqm_srq_container_init(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 container_num = object->object_size;
+ s32 ret;
+ u32 i;
+
+ if (common->head_container || common->tail_container) {
+ cqm_err(handle->dev_hdl,
+ "Srq container init: srq tail/head container not null\n");
+ return CQM_FAIL;
+ }
+
+ /* Applying for a Container
+ * During initialization, the head/tail pointer is null.
+ * After the first application is successful, head=tail.
+ */
+ ret = cqm_container_create(&qinfo->common.object, NULL, true);
+ if (ret == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ "Srq container init: cqm_srq_container_add fail\n");
+ return 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 = cqm_container_create(&qinfo->common.object, NULL, true);
+ if (ret == CQM_FAIL) {
+ cqm_container_free(common->head_container, NULL,
+ &qinfo->common);
+ return CQM_FAIL;
+ }
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_share_recv_queue_create
+ * Description : Create SRQ(share receive queue)
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2016/1/27
+ * Modification : Created function
+ */
+s32 cqm_share_recv_queue_create(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_toe_private_capability *toe_own_cap =
+ &cqm_handle->toe_own_capability;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ u32 step;
+ s32 ret;
+
+ /* 1. Create srq container, including initializing the link wqe. */
+ ret = cqm_srq_container_init(object);
+ if (ret == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_srq_container_init));
+ return 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 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 = cqm_bitmap_alloc(bitmap, step, qinfo->index_count,
+ func_cap->xid_alloc_mode);
+ if (qinfo->common.index >= bitmap->max_num) {
+ 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) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
+ goto err2;
+ }
+ return CQM_SUCCESS;
+
+err2:
+ cqm_bitmap_free(bitmap,
+ qinfo->common.index - toe_own_cap->toe_srqc_start_id,
+ qinfo->index_count);
+err1:
+ cqm_container_free(common->head_container, common->tail_container,
+ &qinfo->common);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_srq_used_rq_delete
+ * Description : Delete RQ in TOE SRQ mode.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2016/5/19
+ * Modification : Created function
+ */
+static void cqm_srq_used_rq_delete(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)(common->object.cqm_handle);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ u32 link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_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)) {
+ 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_cqm_srq_linkwqe *)(common->head_container +
+ link_wqe_offset);
+ /* Only the link wqe part needs to be converted. */
+ cqm_swab32((u8 *)(srq_link_wqe),
+ sizeof(struct tag_cqm_linkwqe) >> CQM_DW_SHIFT);
+
+ addr = CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_gpa_h,
+ srq_link_wqe->current_buffer_gpa_l);
+ if (addr == 0) {
+ cqm_err(handle->dev_hdl,
+ "Rq del: buffer physical addr is null\n");
+ return;
+ }
+ dma_unmap_single(cqm_handle->dev, addr, qinfo->container_size,
+ DMA_BIDIRECTIONAL);
+
+ /* 2. Obtain the container va through the linkwqe and release. */
+ addr = CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_addr_h,
+ srq_link_wqe->current_buffer_addr_l);
+ if (addr == 0) {
+ cqm_err(handle->dev_hdl,
+ "Rq del: buffer virtual addr is null\n");
+ return;
+ }
+ kfree((void *)(uintptr_t)addr);
+}
+
+/**
+ * Prototype : 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_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2016/2/2
+ * Modification : Created function
+ */
+void cqm_share_recv_queue_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_bitmap *bitmap =
+ &cqm_handle->toe_own_capability.srqc_bitmap;
+ u32 index = common->index -
+ cqm_handle->toe_own_capability.toe_srqc_start_id;
+ struct hinic5_hwdev *handle = 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
+ 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. */
+ cqm_bitmap_free(bitmap, index, qinfo->index_count);
+
+ /* 3. SRQC resource release */
+ if (unlikely(common->q_ctx_vaddr == NULL)) {
+ CQM_PTR_CHECK_ERR(
+ "Srq del: srqc kfree, context virtual addr is null\n");
+ return;
+ }
+ kfree(common->q_ctx_vaddr);
+ common->q_ctx_vaddr = NULL;
+
+ /* 4. The SRQ queue is released. */
+ cqm_container_free(common->head_container, NULL, &qinfo->common);
+}
+
+#define obj_intern_if_section
+
+/* include dynamic and static applications. */
+static u32 cqm_general_bitmap_alloc(struct tag_cqm_object *object,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_bitmap_range *bp_range,
+ u32 xid, u32 count)
+{
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_func_capability *func_cap = &cqm_handle->func_capability;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_bitmap *bitmap = &cla_table->bitmap;
+ u32 index;
+
+ if (CQM_DYNAMIC_XID_ALLOC_MODE(xid)) {
+ if (CQM_DYNAMIC_XID_LB_MODE(xid) != CQM_XID_LOW_BIT_NONE ||
+ CQM_DYNAMIC_XID_SEARCH_MODE(xid) != CQM_XID_SEARCH_ALL) {
+ if (count > 1) {
+ cqm_warn(handle->dev_hdl,
+ "Not support alloc multiple bits.\n");
+ return CQM_INDEX_INVALID;
+ }
+ index = cqm_bitmap_alloc_lowbits_align(
+ bitmap, bp_range, cqm_handle, xid,
+ func_cap->xid_alloc_mode);
+ } else {
+ /* apply for an index normally */
+ index = cqm_bitmap_alloc(bitmap,
+ 1U << (cla_table->z + 1),
+ count,
+ func_cap->xid_alloc_mode);
+ }
+
+ if (index >= bitmap->max_num - bitmap->reserved_back) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_bitmap_alloc));
+ return 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 = cqm_bitmap_alloc_by_xid(bitmap, count, xid);
+ } else {
+ /* apply for index to be reserved */
+ index = cqm_bitmap_alloc_reserved(bitmap, count, xid);
+ }
+ if (index != xid) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_bitmap_alloc_reserved));
+ return CQM_INDEX_INVALID;
+ }
+ }
+
+ return index;
+}
+
+/**
+ * Prototype : cqm_qpc_mpt_bitmap_alloc
+ * Description : Apply for index from the bitmap when creating QPC or MPT.
+ * Input : struct tag_cqm_object *object
+ * struct tag_cqm_cla_table *cla_table
+ * struct tag_cqm_bitmap_range *bp_range
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+static s32 cqm_qpc_mpt_bitmap_alloc(struct tag_cqm_object *object,
+ struct tag_cqm_cla_table *cla_table,
+ struct tag_cqm_bitmap_range *bp_range)
+{
+ struct tag_cqm_qpc_mpt *common =
+ container_of(object, struct tag_cqm_qpc_mpt, object);
+ struct tag_cqm_qpc_mpt_info *qpc_mpt_info =
+ container_of(common, struct tag_cqm_qpc_mpt_info, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = 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 = cqm_general_bitmap_alloc(
+ object, cla_table, bp_range, xid, qpc_mpt_info->index_count);
+ if (qpc_mpt_info->common.xid == CQM_INDEX_INVALID) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_general_bitmap_alloc));
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_qpc_mpt_create
+ * Description : Create QPC or MPT
+ * Input : struct tag_cqm_object *object
+ * struct tag_cqm_bitmap_range *bp_range
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_qpc_mpt_create(struct tag_cqm_object *object,
+ struct tag_cqm_bitmap_range *bp_range)
+{
+ struct tag_cqm_qpc_mpt *common =
+ container_of(object, struct tag_cqm_qpc_mpt, object);
+ struct tag_cqm_qpc_mpt_info *qpc_mpt_info =
+ container_of(common, struct tag_cqm_qpc_mpt_info, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ bool is_lock_bh;
+ u32 index, count;
+
+ /* find the corresponding cla table */
+ if (object->object_type == CQM_OBJECT_SERVICE_CTX) {
+ cla_table = cqm_cla_table_get(&cqm_handle->bat_table,
+ CQM_BAT_ENTRY_T_QPC);
+ } else if (object->object_type == CQM_OBJECT_MPT) {
+ cla_table = cqm_cla_table_get(&cqm_handle->bat_table,
+ CQM_BAT_ENTRY_T_MPT);
+ } else {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->object_type));
+ return CQM_FAIL;
+ }
+
+ if (unlikely(cla_table == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_FUNCTION_FAIL(cqm_cla_table_get));
+ return CQM_FAIL;
+ }
+
+ /* Bitmap applies for index. */
+ if (cqm_qpc_mpt_bitmap_alloc(object, cla_table, bp_range) == CQM_FAIL) {
+ cqm_warn(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_qpc_mpt_bitmap_alloc));
+ return 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 (!CQM_IS_FAKE_CHILD(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 = cqm_cla_get(
+ cqm_handle, cla_table, index, count, &common->paddr);
+
+ if (!qpc_mpt_info->common.vaddr) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_cla_get));
+ 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 != CQM_SERVICE_T_FC);
+ if (cqm_object_table_insert(cqm_handle, object_table, index, object,
+ is_lock_bh) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_object_table_insert));
+ goto err2;
+ }
+
+ return CQM_SUCCESS;
+
+err2:
+ cqm_cla_put(cqm_handle, cla_table, index, count);
+err1:
+ cqm_bitmap_free(bitmap, index, count);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_qpc_mpt_delete
+ * Description : Delete QPC or MPT.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_qpc_mpt_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *common =
+ container_of(object, struct tag_cqm_qpc_mpt, object);
+ struct tag_cqm_qpc_mpt_info *qpc_mpt_info =
+ container_of(common, struct tag_cqm_qpc_mpt_info, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ u32 count = qpc_mpt_info->index_count;
+ u32 index = qpc_mpt_info->common.xid;
+ struct tag_cqm_bitmap *bitmap = NULL;
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_qpc_mpt_delete_cnt);
+
+ /* find the corresponding cla table */
+ if (object->object_type == CQM_OBJECT_SERVICE_CTX) {
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_QPC);
+ } else if (object->object_type == CQM_OBJECT_MPT) {
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_MPT);
+ } else {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->object_type));
+ return;
+ }
+
+ if (unlikely(cla_table == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_FUNCTION_FAIL(cqm_cla_table_get_qpc));
+ return;
+ }
+
+ /* disassociate index and object */
+ object_table = &cla_table->obj_table;
+ if (object->service_type == CQM_SERVICE_T_FC)
+ cqm_object_table_remove(cqm_handle, object_table, index, object,
+ false);
+ else
+ cqm_object_table_remove(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
+ 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 == CQM_SERVICE_T_ROCE ||
+ object->service_type == 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 */
+ cqm_cla_put(cqm_handle, cla_table, index, count);
+
+ /* release the index to the bitmap */
+ bitmap = &cla_table->bitmap;
+ cqm_bitmap_free(bitmap, index, count);
+}
+
+/**
+ * Prototype : 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 cqm_linkwqe_fill(struct tag_cqm_buf *buf, u32 wqe_per_buf,
+ u32 wqe_size, u32 wqe_number, bool tail,
+ u8 link_mode)
+{
+ struct tag_cqm_linkwqe_128B *linkwqe = NULL;
+ struct tag_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_cqm_linkwqe *)(va +
+ (u32)(wqe_size *
+ wqe_per_buf));
+ wqe->wf = CQM_WQE_WF_LINK;
+ wqe->ctrlsl = CQM_LINK_WQE_CTRLSL_VALUE;
+ wqe->lp = 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 = CQM_LINK_WQE_OWNER_VALID;
+ addr = buf->buf_list[(u32)(i + 1)].pa;
+ wqe->next_page_gpa_h = CQM_ADDR_HI(addr);
+ wqe->next_page_gpa_l = 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_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_cqm_linkwqe *)tmp;
+ }
+ wqe->wf = CQM_WQE_WF_LINK;
+ wqe->ctrlsl = 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 == CQM_QUEUE_LINK_MODE) {
+ wqe->o = 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 = CQM_LINK_WQE_LP_VALID;
+ wqe->o = CQM_LINK_WQE_OWNER_VALID;
+ addr = buf->buf_list[0].pa;
+ wqe->next_page_gpa_h = CQM_ADDR_HI(addr);
+ wqe->next_page_gpa_l = CQM_ADDR_LW(addr);
+ }
+ }
+
+ if (wqe_size == 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_cqm_linkwqe_128B *)(void *)wqe;
+ linkwqe->second64B.third_16B.bs.toe_o =
+ CQM_LINK_WQE_OWNER_VALID;
+ linkwqe->second64B.forth_16B.bs.ifoe_o =
+ CQM_LINK_WQE_OWNER_VALID;
+
+ /* shift 2 bits by right to get length of dw(4B) */
+ cqm_swab32((u8 *)wqe,
+ sizeof(struct tag_cqm_linkwqe_128B) >> 2);
+ } else {
+ /* shift 2 bits by right to get length of dw(4B) */
+ cqm_swab32((u8 *)wqe,
+ sizeof(struct tag_cqm_linkwqe) >> 2);
+ }
+ }
+}
+
+static int cqm_nonrdma_queue_ctx_create_scq(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ bool bh = false;
+
+ /* find the corresponding cla table */
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SCQC);
+ if (!cla_table) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(nonrdma_cqm_cla_table_get));
+ return 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 = cqm_bitmap_alloc(
+ bitmap, 1U << (cla_table->z + 1), qinfo->index_count,
+ cqm_handle->func_capability.xid_alloc_mode);
+ if (qinfo->common.index >= bitmap->max_num) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(nonrdma_cqm_bitmap_alloc));
+ return CQM_FAIL;
+ }
+
+ /* find the trunk page from BAT/CLA and allocate the buffer */
+ common->q_ctx_vaddr =
+ cqm_cla_get(cqm_handle, cla_table, qinfo->common.index,
+ qinfo->index_count, &common->q_ctx_paddr);
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(nonrdma_cqm_cla_get_lock));
+ cqm_bitmap_free(bitmap, qinfo->common.index,
+ qinfo->index_count);
+ return CQM_FAIL;
+ }
+
+ /* index and object association */
+ object_table = &cla_table->obj_table;
+ bh = (object->service_type == CQM_SERVICE_T_FC) ? false : true;
+ if (cqm_object_table_insert(cqm_handle, object_table,
+ qinfo->common.index, object,
+ bh) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(nonrdma_cqm_object_table_insert));
+ cqm_cla_put(cqm_handle, cla_table, qinfo->common.index,
+ qinfo->index_count);
+ cqm_bitmap_free(bitmap, qinfo->common.index,
+ qinfo->index_count);
+
+ return CQM_FAIL;
+ }
+
+ return 0;
+}
+
+static s32 cqm_nonrdma_queue_ctx_create(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 shift;
+ int ret;
+
+ if (object->object_type == CQM_OBJECT_NONRDMA_SRQ) {
+ shift = cqm_shift(qinfo->q_ctx_size);
+ common->q_ctx_vaddr = cqm_kmalloc_align(
+ qinfo->q_ctx_size, GFP_KERNEL | __GFP_ZERO, (u16)shift);
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
+ return CQM_FAIL;
+ }
+
+ common->q_ctx_paddr =
+ dma_map_single(cqm_handle->dev, common->q_ctx_vaddr,
+ qinfo->q_ctx_size, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(cqm_handle->dev, common->q_ctx_paddr) !=
+ 0) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(q_ctx_vaddr));
+ cqm_kfree_align(common->q_ctx_vaddr);
+ common->q_ctx_vaddr = NULL;
+ return CQM_FAIL;
+ }
+ } else if (object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
+ ret = cqm_nonrdma_queue_ctx_create_scq(object);
+ if (ret != 0)
+ return ret;
+ }
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_free_queue_header(struct tag_cqm_queue *common,
+ struct tag_cqm_handle *cqm_handle,
+ struct hinic5_hwdev *handle)
+{
+ dma_unmap_single(cqm_handle->dev, common->q_header_paddr,
+ sizeof(struct tag_cqm_queue_header),
+ DMA_BIDIRECTIONAL);
+
+ cqm_kfree_align(common->q_header_vaddr);
+ common->q_header_vaddr = NULL;
+}
+
+static s32 cqm_alloc_queue_header(struct tag_cqm_queue *common,
+ struct tag_cqm_handle *cqm_handle,
+ struct hinic5_hwdev *handle)
+{
+ common->q_header_vaddr = cqm_kmalloc_align(
+ sizeof(struct tag_cqm_queue_header), GFP_KERNEL | __GFP_ZERO,
+ CQM_QHEAD_ALIGN_ORDER);
+ if (!common->q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
+ return CQM_FAIL;
+ }
+
+ common->q_header_paddr = dma_map_single(
+ cqm_handle->dev, common->q_header_vaddr,
+ sizeof(struct tag_cqm_queue_header), DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(cqm_handle->dev, common->q_header_paddr) != 0) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(q_header_vaddr));
+ cqm_kfree_align(common->q_header_vaddr);
+ common->q_header_vaddr = NULL;
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+/**
+ * Prototype : cqm_nonrdma_queue_create
+ * Description : Create a queue for non-RDMA services.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_nonrdma_queue_create(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_buf *q_room_buf = &common->q_room_buf_1;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ u32 wqe_number = qinfo->common.object.object_size;
+ u32 wqe_size = qinfo->wqe_size;
+ u32 order = 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 == CQM_OBJECT_NONRDMA_EMBEDDED_CQ ||
+ object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
+ /* depth: 2^n-aligned; depth range: 256-32 K */
+ if (wqe_number < CQM_CQ_DEPTH_MIN ||
+ wqe_number > CQM_CQ_DEPTH_MAX) {
+ cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_number));
+ return CQM_FAIL;
+ }
+ if (!cqm_check_align(wqe_number)) {
+ cqm_err(handle->dev_hdl,
+ "Nonrdma queue alloc: wqe_number is not align on 2^n\n");
+ return CQM_FAIL;
+ }
+
+ order = CQM_4K_PAGE_ORDER; /* wqe page 4k */
+ tail = true; /* The linkwqe must be at the end of the page. */
+ buf_size = 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 (cqm_buf_alloc(cqm_handle, q_room_buf, false) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_buf_alloc));
+ return CQM_FAIL;
+ }
+ /* fill link wqe, wqe_number - buf_number is the number of wqe without
+ * link wqe
+ */
+ 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 (cqm_alloc_queue_header(common, cqm_handle, handle) != CQM_SUCCESS) {
+ goto err1;
+ }
+
+ /* create queue ctx */
+ if (cqm_nonrdma_queue_ctx_create(object) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_nonrdma_queue_ctx_create));
+ goto err2;
+ }
+
+ return CQM_SUCCESS;
+
+err2:
+ cqm_free_queue_header(common, cqm_handle, handle);
+err1:
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+ return CQM_FAIL;
+}
+
+/**
+ * Prototype : cqm_nonrdma_queue_delete
+ * Description : Delete the queues of non-RDMA services.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_nonrdma_queue_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_nonrdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_nonrdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct tag_cqm_buf *q_room_buf = &common->q_room_buf_1;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ u32 index = qinfo->common.index;
+ u32 count = qinfo->index_count;
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_nonrdma_queue_delete_cnt);
+
+ /* The SCQ has an independent SCQN association. */
+ if (object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
+ cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SCQC);
+ if (unlikely(cla_table == NULL)) {
+ CQM_PTR_CHECK_ERR(
+ CQM_FUNCTION_FAIL(cqm_cla_table_get_queue));
+ return;
+ }
+
+ /* disassociate index and object */
+ object_table = &cla_table->obj_table;
+ cqm_object_table_remove(cqm_handle, object_table, index, object,
+ object->service_type !=
+ 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
+ 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(cqm_handle->dev, common->q_header_paddr,
+ sizeof(struct tag_cqm_queue_header),
+ DMA_BIDIRECTIONAL);
+
+ 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 == CQM_QUEUE_TOE_SRQ_LINK_MODE)
+ cqm_srq_used_rq_delete(&common->object);
+ else
+ /* If q room exists, release. */
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+ /* SRQ and SCQ have independent CTXs and release. */
+ if (object->object_type == CQM_OBJECT_NONRDMA_SRQ) {
+ /* The CTX of the SRQ of the nordma is
+ * applied for independently.
+ */
+ if (common->q_ctx_vaddr) {
+ dma_unmap_single(cqm_handle->dev, common->q_ctx_paddr,
+ qinfo->q_ctx_size, DMA_BIDIRECTIONAL);
+
+ cqm_kfree_align(common->q_ctx_vaddr);
+ common->q_ctx_vaddr = NULL;
+ }
+ } else if (object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
+ /* The CTX of the SCQ of the nordma is managed by BAT/CLA. */
+ cqm_cla_put(cqm_handle, cla_table, index, count);
+
+ /* release the index to the bitmap */
+ bitmap = &cla_table->bitmap;
+ cqm_bitmap_free(bitmap, index, count);
+ }
+}
+
+static s32 cqm_rdma_queue_ctx_create(struct tag_cqm_object *object,
+ struct tag_cqm_bitmap_range *bp_range)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_rdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_rdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+
+ if (object->object_type == CQM_OBJECT_RDMA_SRQ ||
+ object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ if (object->object_type == CQM_OBJECT_RDMA_SRQ)
+ cla_table = cqm_cla_table_get(bat_table,
+ CQM_BAT_ENTRY_T_SRQC);
+ else
+ cla_table = cqm_cla_table_get(bat_table,
+ CQM_BAT_ENTRY_T_SCQC);
+
+ if (!cla_table) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(rdma_cqm_cla_table_get));
+ return CQM_FAIL;
+ }
+
+ qinfo->index_count =
+ (ALIGN(qinfo->q_ctx_size, cla_table->obj_size)) /
+ cla_table->obj_size;
+ qinfo->common.index = cqm_general_bitmap_alloc(
+ object, cla_table, bp_range, qinfo->common.index,
+ qinfo->index_count);
+ if (qinfo->common.index == CQM_INDEX_INVALID) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_general_bitmap_alloc));
+ return CQM_FAIL;
+ }
+
+ /* bitmap applies for index */
+ bitmap = &cla_table->bitmap;
+
+ /* find the trunk page from BAT/CLA and allocate the buffer */
+ if (!CQM_IS_FAKE_CHILD(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 = cqm_cla_get(
+ cqm_handle, cla_table, qinfo->common.index,
+ qinfo->index_count, &qinfo->common.q_ctx_paddr);
+ if (!qinfo->common.q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(
+ rdma_cqm_cla_get_lock));
+ cqm_bitmap_free(bitmap, qinfo->common.index,
+ qinfo->index_count);
+ return CQM_FAIL;
+ }
+ }
+
+ /* associate index and object */
+ object_table = &cla_table->obj_table;
+ if (cqm_object_table_insert(cqm_handle, object_table,
+ qinfo->common.index, object,
+ true) != CQM_SUCCESS) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(
+ rdma_cqm_object_table_insert));
+ cqm_cla_put(cqm_handle, cla_table, qinfo->common.index,
+ qinfo->index_count);
+ cqm_bitmap_free(bitmap, qinfo->common.index,
+ qinfo->index_count);
+ return CQM_FAIL;
+ }
+ }
+
+ return CQM_SUCCESS;
+}
+
+static s32 cqm_qinfo_judgment(struct tag_cqm_rdma_qinfo *qinfo,
+ struct tag_cqm_buf *q_room_buf,
+ struct tag_cqm_handle *cqm_handle,
+ struct hinic5_hwdev *handle)
+{
+ if (cqm_buf_alloc(cqm_handle, q_room_buf, true) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_buf_alloc));
+ return CQM_FAIL;
+ }
+
+ /* queue header */
+ qinfo->common.q_header_vaddr = cqm_kmalloc_align(
+ sizeof(struct tag_cqm_queue_header), GFP_KERNEL | __GFP_ZERO,
+ CQM_QHEAD_ALIGN_ORDER);
+ if (!qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
+
+ if (qinfo->room_header_alloc)
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+
+ return CQM_FAIL;
+ }
+
+ qinfo->common.q_header_paddr = dma_map_single(
+ cqm_handle->dev, qinfo->common.q_header_vaddr,
+ sizeof(struct tag_cqm_queue_header), DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(cqm_handle->dev, qinfo->common.q_header_paddr) !=
+ 0) {
+ cqm_err(handle->dev_hdl, CQM_MAP_FAIL(q_header_vaddr));
+
+ if (qinfo->room_header_alloc) {
+ cqm_kfree_align(qinfo->common.q_header_vaddr);
+ qinfo->common.q_header_vaddr = NULL;
+ }
+
+ if (qinfo->room_header_alloc)
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+
+ return CQM_FAIL;
+ }
+
+ return 0;
+}
+
+/**
+ * Prototype : cqm_rdma_queue_create
+ * Description : Create rdma queue.
+ * Input : struct tag_cqm_object *object
+ * : struct tag_cqm_bitmap_range *bp_range
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_rdma_queue_create(struct tag_cqm_object *object,
+ struct tag_cqm_bitmap_range *bp_range)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_rdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_rdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_service *service =
+ cqm_handle->service + object->service_type;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_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 == 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 (cqm_qinfo_judgment(qinfo, q_room_buf, cqm_handle, handle) ==
+ CQM_FAIL) {
+ return CQM_FAIL;
+ }
+ }
+
+ /* queue ctx */
+ if (cqm_rdma_queue_ctx_create(object, bp_range) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_rdma_queue_ctx_create));
+
+ if (qinfo->room_header_alloc) {
+ dma_unmap_single(cqm_handle->dev,
+ qinfo->common.q_header_paddr,
+ sizeof(struct tag_cqm_queue_header),
+ DMA_BIDIRECTIONAL);
+ }
+
+ if (qinfo->room_header_alloc) {
+ cqm_kfree_align(qinfo->common.q_header_vaddr);
+ qinfo->common.q_header_vaddr = NULL;
+ }
+
+ if (qinfo->room_header_alloc) {
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+ }
+
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_rdma_queue_delete
+ * Description : Create rdma queue.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_rdma_queue_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *common =
+ container_of(object, struct tag_cqm_queue, object);
+ struct tag_cqm_rdma_qinfo *qinfo =
+ container_of(common, struct tag_cqm_rdma_qinfo, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_object_table *object_table = NULL;
+ struct tag_cqm_cla_table *cla_table = NULL;
+ struct tag_cqm_buf *q_room_buf = NULL;
+ struct tag_cqm_bitmap *bitmap = NULL;
+ u32 index = qinfo->common.index;
+ u32 count = qinfo->index_count;
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_rdma_queue_delete_cnt);
+
+ q_room_buf = (qinfo->common.current_q_room == 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 == CQM_OBJECT_RDMA_SCQ ||
+ object->object_type == CQM_OBJECT_RDMA_SRQ) {
+ if (object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ cla_table = cqm_cla_table_get(bat_table,
+ CQM_BAT_ENTRY_T_SCQC);
+ } else if (object->object_type == CQM_OBJECT_RDMA_SRQ) {
+ cla_table = cqm_cla_table_get(bat_table,
+ CQM_BAT_ENTRY_T_SRQC);
+ }
+ if (unlikely(cla_table == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_FUNCTION_FAIL(cqm_cla_table_get));
+ return;
+ }
+ /* disassociate index and object */
+ object_table = &cla_table->obj_table;
+ cqm_object_table_remove(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
+ 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(cqm_handle->dev, qinfo->common.q_header_paddr,
+ sizeof(struct tag_cqm_queue_header),
+ DMA_BIDIRECTIONAL);
+
+ cqm_kfree_align(qinfo->common.q_header_vaddr);
+ qinfo->common.q_header_vaddr = NULL;
+ }
+
+ /* If q room exists, release. */
+ cqm_buf_free(q_room_buf, cqm_handle->dev);
+
+ /* SRQ and SCQ have independent CTX, released. */
+ if (object->object_type == CQM_OBJECT_RDMA_SRQ ||
+ object->object_type == CQM_OBJECT_RDMA_SCQ) {
+ cqm_cla_put(cqm_handle, cla_table, index, count);
+
+ /* release the index to the bitmap */
+ bitmap = &cla_table->bitmap;
+ cqm_bitmap_free(bitmap, index, count);
+ }
+}
+
+/**
+ * Prototype : cqm_rdma_table_create
+ * Description : Create RDMA-related entries.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : s32
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+s32 cqm_rdma_table_create(struct tag_cqm_object *object)
+{
+ struct tag_cqm_mtt_rdmarc *common =
+ container_of(object, struct tag_cqm_mtt_rdmarc, object);
+ struct tag_cqm_rdma_table *rdma_table =
+ container_of(common, struct tag_cqm_rdma_table, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_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 == 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(cqm_handle->dev, buf->buf_size,
+ &buf->direct.pa, GFP_ATOMIC);
+ if (unlikely(buf->direct.va == NULL)) {
+ CQM_PTR_CHECK_ERR(CQM_ALLOC_FAIL(direct));
+ return 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 (cqm_buf_alloc(cqm_handle, buf, true) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl,
+ CQM_FUNCTION_FAIL(cqm_buf_alloc));
+ return CQM_FAIL;
+ }
+ }
+
+ rdma_table->common.vaddr = (u8 *)(buf->direct.va);
+
+ return CQM_SUCCESS;
+}
+
+/**
+ * Prototype : cqm_rdma_table_delete
+ * Description : Delete RDMA-related Entries.
+ * Input : struct tag_cqm_object *object
+ * Output : None
+ * Return Value : void
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+void cqm_rdma_table_delete(struct tag_cqm_object *object)
+{
+ struct tag_cqm_mtt_rdmarc *common =
+ container_of(object, struct tag_cqm_mtt_rdmarc, object);
+ struct tag_cqm_rdma_table *rdma_table =
+ container_of(common, struct tag_cqm_rdma_table, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf *buf = &rdma_table->buf;
+
+ atomic_inc(&handle->hw_stats.cqm_stats.cqm_rdma_table_delete_cnt);
+
+ if (buf->buf_number == 1) {
+ if (buf->direct.va) {
+ dma_free_coherent(cqm_handle->dev, buf->buf_size,
+ buf->direct.va, buf->direct.pa);
+ buf->direct.va = NULL;
+ }
+ } else {
+ cqm_buf_free(buf, cqm_handle->dev);
+ }
+}
+
+/**
+ * Prototype : 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_cqm_object *object
+ * u32 offset
+ * dma_addr_t *paddr
+ * Output : None
+ * Return Value : u8 *
+ * 1.Date : 2015/4/15
+ * Modification : Created function
+ */
+u8 *cqm_rdma_table_offset_addr(struct tag_cqm_object *object, u32 offset,
+ dma_addr_t *paddr)
+{
+ struct tag_cqm_mtt_rdmarc *common =
+ container_of(object, struct tag_cqm_mtt_rdmarc, object);
+ struct tag_cqm_rdma_table *rdma_table =
+ container_of(common, struct tag_cqm_rdma_table, common);
+ struct tag_cqm_handle *cqm_handle =
+ (struct tag_cqm_handle *)object->cqm_handle;
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct tag_cqm_buf *buf = &rdma_table->buf;
+ struct tag_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)) {
+ cqm_err(handle->dev_hdl, 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) {
+ cqm_err(handle->dev_hdl, 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/cqm/cqm_object_intern.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.h
new file mode 100644
index 000000000..3def553ee
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_object_intern.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef CQM_OBJECT_INTERN_H
+#define CQM_OBJECT_INTERN_H
+
+#include "ossl_knl.h"
+#include "cqm_object.h"
+#include "cqm_bitmap_table.h"
+
+#define CQM_CQ_DEPTH_MAX 32768
+#define CQM_CQ_DEPTH_MIN 256
+
+/* linkwqe */
+#define CQM_LINK_WQE_CTRLSL_VALUE 2
+#define CQM_LINK_WQE_LP_VALID 1
+#define CQM_LINK_WQE_LP_INVALID 0
+#define CQM_LINK_WQE_OWNER_VALID 1
+#define CQM_LINK_WQE_OWNER_INVALID 0
+
+#define CQM_ADDR_COMBINE(high_addr, low_addr) \
+ ((((dma_addr_t)(high_addr)) << 32) + ((dma_addr_t)(low_addr)))
+#define CQM_ADDR_HI(addr) ((u32)((u64)(addr) >> 32))
+#define CQM_ADDR_LW(addr) ((u32)((u64)(addr)&0xffffffff))
+
+#define CQM_QPC_LAYOUT_TABLE_SIZE 16
+
+/* cla bitmap */
+#define CQM_DYNAMIC_XID_LOW_BIT_MASK(lb_mode) \
+ ((~(lb_mode)) & CQM_XID_LOW_BITS_MASK)
+
+#define CQM_DYNAMIC_XID_ALLOC_MODE(xid) \
+ (((xid)&CQM_DYNAMIC_XID_MASK) == CQM_DYNAMIC_XID_MASK)
+#define CQM_DYNAMIC_XID_LB_MODE(xid) \
+ (((xid) >> CQM_XID_LB_MODE_SHIFT) & CQM_XID_LB_MODE_MASK)
+#define CQM_DYNAMIC_XID_LOW_BITS(xid) \
+ (((xid) >> CQM_XID_LOW_BITS_SHIFT) & CQM_XID_LOW_BITS_MASK)
+#define CQM_DYNAMIC_XID_SEARCH_MODE(xid) \
+ (((xid) >> CQM_XID_SEARCH_MODE_SHIFT) & CQM_XID_SEARCH_MODE_MASK)
+
+#define 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_cqm_qpc_layout_table_node {
+ u32 type;
+ u32 size;
+ u32 offset;
+ struct tag_cqm_object *object;
+};
+
+struct tag_cqm_qpc_mpt_info {
+ struct tag_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_cqm_qpc_layout_table_node
+ qpc_layout_table[CQM_QPC_LAYOUT_TABLE_SIZE];
+};
+
+struct tag_cqm_nonrdma_qinfo {
+ struct tag_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_cqm_rdma_qinfo {
+ struct tag_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_cqm_rdma_table {
+ struct tag_cqm_mtt_rdmarc common;
+ struct tag_cqm_buf buf;
+};
+
+void cqm_container_free(u8 *srq_head_container, u8 *srq_tail_container,
+ struct tag_cqm_queue *common);
+s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr,
+ bool link);
+s32 cqm_share_recv_queue_create(struct tag_cqm_object *object);
+void cqm_share_recv_queue_delete(struct tag_cqm_object *object);
+s32 cqm_qpc_mpt_create(struct tag_cqm_object *object,
+ struct tag_cqm_bitmap_range *bp_range);
+void cqm_qpc_mpt_delete(struct tag_cqm_object *object);
+s32 cqm_nonrdma_queue_create(struct tag_cqm_object *object);
+void cqm_nonrdma_queue_delete(struct tag_cqm_object *object);
+s32 cqm_rdma_queue_create(struct tag_cqm_object *object,
+ struct tag_cqm_bitmap_range *bp_range);
+void cqm_rdma_queue_delete(struct tag_cqm_object *object);
+s32 cqm_rdma_table_create(struct tag_cqm_object *object);
+void cqm_rdma_table_delete(struct tag_cqm_object *object);
+u8 *cqm_rdma_table_offset_addr(struct tag_cqm_object *object, u32 offset,
+ dma_addr_t *paddr);
+
+#endif /* CQM_OBJECT_INTERN_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_secure_mem.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_secure_mem.c
new file mode 100644
index 000000000..bbb646cec
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/cqm/cqm_secure_mem.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+
+#include "ossl_knl.h"
+#include "hinic5_hw_comm.h"
+#include "cqm_main.h"
+#include "cqm_bat_cla.h"
+
+#ifndef SECURE_MEM_STUB
+#ifdef __UEFI__
+#define SECURE_MEM_STUB
+#endif
+#endif
+
+/* mem_size should be none-zero and be 2^n */
+#define CQM_IS_SECURE_MEMSIZE_VALID(mem_size) \
+ (((mem_size) != 0) && (((mem_size) & ((mem_size)-1)) == 0))
+
+/* SCQC must be first (UB-VTP Table Use SCQC) */
+static const u8 SEC_MEM_CLA_TYPES[] = { CQM_BAT_ENTRY_T_SCQC,
+ CQM_BAT_ENTRY_T_QPC,
+ CQM_BAT_ENTRY_T_MPT,
+ CQM_BAT_ENTRY_T_SRQC };
+
+/**
+ * This flag enables the fast path for unsupported secure memory.
+ */
+static bool secure_memory_disable = false;
+
+static u32 cqm_cap_get_cla_size(struct tag_cqm_func_capability *cap, u32 type)
+{
+ if (type == CQM_BAT_ENTRY_T_SCQC)
+ return cap->scqc_basic_size * cap->scqc_number;
+
+ if (type == CQM_BAT_ENTRY_T_SRQC)
+ return cap->srqc_basic_size * cap->srqc_number;
+
+ if (type == CQM_BAT_ENTRY_T_QPC)
+ return cap->qpc_basic_size * cap->qpc_number;
+
+ if (type == CQM_BAT_ENTRY_T_MPT)
+ return cap->mpt_basic_size * cap->mpt_number;
+
+ WARN_ON_ONCE(true);
+ return 0;
+}
+
+#ifdef SECURE_MEM_STUB
+static int required_secure_mem_size(struct tag_cqm_handle *cqm_handle,
+ u32 *required_size)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ u32 i, size, total_size = 0;
+
+ for (i = 0; i < ARRAY_SIZE(SEC_MEM_CLA_TYPES); i++) {
+ size = cqm_cap_get_cla_size(capability, SEC_MEM_CLA_TYPES[i]);
+ if (!CQM_IS_SECURE_MEMSIZE_VALID(size)) {
+ cqm_err(cqm_handle->dev,
+ "invalid ctx size 0x%x, type %d\n", size,
+ SEC_MEM_CLA_TYPES[i]);
+ return -EFAULT;
+ }
+ total_size += size;
+ }
+
+ *required_size = total_size;
+ return 0;
+}
+
+static int cqm_get_secure_mem(struct tag_cqm_handle *cqm_handle)
+{
+ struct device *dev = cqm_handle->dev;
+ struct cqm_secure_mem_info *secure_mem =
+ &cqm_handle->bat_table.secure_mem;
+ u32 required_size = 0, order;
+ size_t size = 0;
+ dma_addr_t pa = 0;
+ void *va = NULL;
+ int err;
+
+ err = required_secure_mem_size(cqm_handle, &required_size);
+ if (err != 0)
+ return err;
+
+ order = (u32)get_order(required_size);
+ size = 1 << (order + PAGE_SHIFT);
+
+ cqm_info(dev, "secure mem req 0x%x, align 0x%x, order %u\n",
+ required_size, size, order);
+
+ va = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+ if (!va) {
+ cqm_err(dev, CQM_ALLOC_FAIL(secure_mem));
+ return -ENOMEM;
+ }
+
+ pa = dma_map_single(dev, va, size, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dev, pa)) {
+ cqm_err(dev, CQM_MAP_FAIL(secure_mem));
+ free_pages((ulong)va, order);
+ return -ENOMEM;
+ }
+
+ secure_mem->va = va;
+ secure_mem->pa = pa;
+ secure_mem->size = size;
+ return 0;
+}
+
+static inline void cqm_put_secure_mem(struct tag_cqm_handle *cqm_handle,
+ struct cqm_secure_mem_info *secure_mem)
+{
+ u32 order = (u32)get_order(secure_mem->size);
+ dma_unmap_single(cqm_handle->dev, secure_mem->pa, secure_mem->size,
+ DMA_BIDIRECTIONAL);
+ free_pages((ulong)(secure_mem->va), order);
+}
+
+#else
+
+static int cqm_get_secure_mem(struct tag_cqm_handle *cqm_handle)
+{
+ struct hinic5_hwdev *handle = cqm_handle->ex_handle;
+ struct cqm_secure_mem_info *secure_mem =
+ &cqm_handle->bat_table.secure_mem;
+ u32 size = 0;
+ dma_addr_t pa = 0;
+ void *va = NULL;
+ int err;
+
+ err = hinic5_get_secure_mem_cfg(handle, &pa, &size);
+ if (err == -EOPNOTSUPP) {
+ secure_memory_disable = true;
+ return 0;
+ }
+ if (err != 0) {
+ cqm_err(cqm_handle->dev, "failed to get secure mem, err %d\n",
+ err);
+ return err;
+ }
+
+ va = ioremap(pa, size);
+ if (!va) {
+ cqm_err(cqm_handle->dev,
+ "failed to remap secure mem, gpa 0x%lx, size 0x%x\n",
+ (uintptr_t)pa, size);
+ return -ENOMEM;
+ }
+
+ secure_mem->va = va;
+ secure_mem->pa = pa;
+ secure_mem->size = size;
+ return 0;
+}
+
+static inline void cqm_put_secure_mem(struct tag_cqm_handle *cqm_handle,
+ struct cqm_secure_mem_info *secure_mem)
+{
+ iounmap(secure_mem->va);
+}
+#endif
+
+static int cqm_cla_assign_secure_mem(struct tag_cqm_handle *cqm_handle)
+{
+ struct tag_cqm_func_capability *capability =
+ &cqm_handle->func_capability;
+ struct tag_cqm_bat_table *bat_table = &cqm_handle->bat_table;
+ struct cqm_secure_mem_info *secure_mem = &bat_table->secure_mem;
+ struct tag_cqm_cla_table *entry = NULL;
+ size_t i, entry_size, mem_offset = 0;
+
+ for (i = 0; i < ARRAY_SIZE(SEC_MEM_CLA_TYPES); i++) {
+ u32 entry_type = SEC_MEM_CLA_TYPES[i];
+ entry = cqm_bat_table_find_entry(bat_table, entry_type);
+ entry_size = cqm_cap_get_cla_size(capability, entry_type);
+ if (unlikely(!entry || entry_size == 0)) {
+ cqm_err(cqm_handle->dev,
+ "Invalid entry %u, size 0x%lx\n", entry_type,
+ entry_size);
+ return -EFAULT;
+ }
+
+ if (unlikely(entry_size > secure_mem->size - mem_offset)) {
+ cqm_err(cqm_handle->dev,
+ "Insufficient secure mem, remain 0x%lx, entry %u req 0x%lx\n",
+ secure_mem->size - mem_offset, entry_type,
+ entry_size);
+ return -ENOMEM;
+ }
+
+ entry->secure_mem.va = secure_mem->va + mem_offset;
+ entry->secure_mem.pa = secure_mem->pa + mem_offset;
+ entry->secure_mem.size = entry_size;
+ mem_offset += entry_size;
+ }
+
+ return 0;
+}
+
+void cqm_free_secure_mem(struct tag_cqm_handle *cqm_handle)
+{
+ struct cqm_secure_mem_info *secure_mem =
+ &cqm_handle->bat_table.secure_mem;
+
+ if (secure_mem->va) {
+ cqm_put_secure_mem(cqm_handle, secure_mem);
+ secure_mem->va = NULL;
+ secure_mem->pa = 0;
+ secure_mem->size = 0;
+ }
+}
+
+s32 cqm_try_init_secure_mem(struct tag_cqm_handle *cqm_handle)
+{
+ struct cqm_secure_mem_info *secure_mem =
+ &cqm_handle->bat_table.secure_mem;
+ int err;
+
+ if (secure_memory_disable || !CQM_IS_VF(cqm_handle)) {
+ cqm_dbg_on(secure_memory_disable, cqm_handle->dev,
+ "Skip init secure memory\n");
+ return CQM_SUCCESS;
+ }
+
+ err = cqm_get_secure_mem(cqm_handle);
+ if (err != 0) {
+ cqm_err(cqm_handle->dev,
+ "Failed to init secure memory, err %d\n", err);
+ return CQM_FAIL;
+ }
+ if (!secure_mem->va)
+ return CQM_SUCCESS;
+
+ cqm_info(cqm_handle->dev,
+ "Get secure mem, pa 0x%lx, va 0x%lx, size 0x%lx\n",
+ (uintptr_t)secure_mem->pa, (uintptr_t)secure_mem->va,
+ secure_mem->size);
+
+ err = cqm_cla_assign_secure_mem(cqm_handle);
+ if (err != 0) {
+ cqm_err(cqm_handle->dev,
+ "Failed to assign secure memory, err %d\n", err);
+ cqm_free_secure_mem(cqm_handle);
+ return CQM_FAIL;
+ }
+
+ return CQM_SUCCESS;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_mgmt_msg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_mgmt_msg.c
new file mode 100644
index 000000000..1bc41e592
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_mgmt_msg.c
@@ -0,0 +1,817 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
+
+#include <linux/kernel.h>
+#include <linux/rtc.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+#include "mpu_inband_cmd.h"
+
+#include "ossl_knl.h"
+#include "hinic5_hw_cfg.h"
+#include "hinic5_hw_comm.h"
+#include "hinic5_hwdev.h"
+#include "hisdk5_hwif.h"
+#include "hinic5_prof_adap.h"
+
+#ifdef __LINUX__
+#include "hinic5_dev_mgmt.h"
+#endif
+
+#define UNKNOWN_LEN 7
+
+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 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] = { 0 };
+ u8 level;
+ int ret;
+
+ level = event->event.chip.err_level;
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strncpy_s(level_str, FAULT_SHOW_STR_LEN + 1,
+ fault_level[level], FAULT_SHOW_STR_LEN);
+ if (ret != 0) {
+ return;
+ }
+ } else {
+ ret = strncpy_s(level_str, FAULT_SHOW_STR_LEN + 1, "Unknown",
+ UNKNOWN_LEN);
+ if (ret != 0) {
+ return;
+ }
+ }
+
+ 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", "heartbeat lost"
+ };
+ char type_str[FAULT_SHOW_STR_LEN + 1] = { 0 };
+ struct fault_event_stats *fault = NULL;
+ int ret;
+
+ 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) {
+ ret = strncpy_s(type_str, FAULT_SHOW_STR_LEN + 1,
+ fault_type[event->type], FAULT_SHOW_STR_LEN);
+ if (ret != 0) {
+ return;
+ }
+ atomic_inc(&fault->fault_type_stat[event->type]);
+ } else {
+ ret = strncpy_s(type_str, FAULT_SHOW_STR_LEN + 1, "Unknown",
+ UNKNOWN_LEN);
+ if (ret != 0) {
+ return;
+ }
+ }
+
+ 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;
+ case FAULT_TYPE_HEARTBEAT_LOST:
+ sdk_err(hwdev->dev_hdl, "err_type: %u,\n",
+ event->event.heartbeat_lost.err_type);
+ 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;
+ (void)memcpy_s(fault, sizeof(struct hinic5_fault_event),
+ &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 (ffm_idx > 0 && 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, multiplied 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 %lu.\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: %hu, 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: %hu, 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_VROCE);
+ 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_VROCE);
+ 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");
+ }
+
+ return;
+}
+
+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 detach 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");
+ }
+ }
+ return;
+}
+
+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;
+ }
+ return;
+}
+
+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);
+
+ return;
+}
+#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 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
+};
+
+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(mgmt_event_proc);
+
+ if (!hwdev)
+ return;
+
+ for (i = 0; i < event_num; i++) {
+ if (cmd == mgmt_event_proc[i].cmd) {
+ if (mgmt_event_proc[i].proc)
+ 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;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_hwif.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_hwif.h
new file mode 100644
index 000000000..63a212066
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_hwif.h
@@ -0,0 +1,363 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef HISDK5_HWIF_H
+#define HISDK5_HWIF_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; /* pcie场景下代表的是pdev ub场景下代表ub dev */
+#endif
+ void *hwdev;
+
+ u64 rsvd;
+};
+
+/**
+ * @brief enum hinic5_wait_return - 等待处理的返回值枚举类
+ * @details 有三种情况,处理完成,正在处理,处理出错
+ */
+enum hinic5_wait_return {
+ WAIT_PROCESS_CPL = 0, /**< 表示处理完成,可以进行下一步操作 */
+ WAIT_PROCESS_WAITING = 1, /**< 表示正在处理,需要继续等待 */
+ WAIT_PROCESS_ERR = 2, /**< 表示处理出错,需要进行错误处理 */
+};
+
+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 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 - CPI hardware生成的AEQ事件类型
+ * @details aeqe.sw 属性为0(aeqe由cpi hardware产生的)支持的事件类型
+ */
+enum hinic5_aeq_type {
+ HINIC5_HW_INTER_INT = 0, /**< 硬件中断事件 */
+ HINIC5_MBX_FROM_FUNC = 1, /**< 来自function的mailbox */
+ HINIC5_MSG_FROM_MGMT_CPU = 2, /**< 来自MPU的mailbox */
+ 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 /**< 支持的事件类型个数 */
+};
+
+/**
+ * @brief enum hinic5_aeq_sw_type - 微码(Tile)生成的AEQ事件类型
+ * @details aeqe.sw 属性为1(aeqe有微码产生的)支持的事件类型
+ */
+enum hinic5_aeq_sw_type {
+ HINIC5_STATELESS_EVENT = 0, /**< 无状态事件 */
+ HINIC5_STATEFUL_EVENT = 1, /**< 有状态事件 */
+ HINIC5_MAX_AEQ_SW_EVENTS /**< 支持的事件类型个数 */
+};
+
+/**
+ * @brief 定义一个名为wait_cpl_handler的函数指针类型
+ * @param priv_data:私有数据,可以是任何类型的数据
+ *
+ * @return 返回hinic5_wait_return枚举类型
+ */
+typedef enum hinic5_wait_return (*wait_cpl_handler)(void *priv_data);
+
+/**
+ * @brief 在等待一定时间后,检查是否完成
+ * @param priv_data:用于传递私有数据
+ * @param handler:等待操作的处理函数
+ * @param wait_total_ms:等待总时间,单位:毫秒
+ * @param wait_once_us:每次等待时间,单位:微秒
+ *
+ * @details 在等待一定时间后,检查是否完成
+ *
+ * @return 返回检查结果
+ * @retval 0:成功
+ * @retval -EINVAL:参数无效
+ * @retval -EIO:处理过程出错
+ * @retval -ETIMEDOUT:超时
+ */
+int hinic5_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
+ u32 wait_total_ms, u32 wait_once_us);
+
+/**
+ * @brief 定义一个函数指针类型,用于处理AEQ中断
+ * @param pri_handle 设备句柄
+ * @param data 中断数据
+ * @param size 中断数据大小
+ *
+ * @return 无
+ */
+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/hisdk5_typedef.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_typedef.h
new file mode 100644
index 000000000..3e5cd2b11
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hisdk5_typedef.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2025 Huawei Technologies Co., Ltd */
+
+#ifndef HINIC5_TYPESDEF_INNER_H
+#define HINIC5_TYPESDEF_INNER_H
+
+/* static methods testable */
+#ifdef EXPORT_STATIC_SYMBOL
+#define STATIC __attribute__((weak, noinline))
+#define INLINE __attribute__((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 */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/CMakeLists.txt b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/CMakeLists.txt
new file mode 100644
index 000000000..4462b5142
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/CMakeLists.txt
@@ -0,0 +1,94 @@
+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)
+
+if("${BUILD_VERSION}" MATCHES "b173")
+ set(B173_VALUE y)
+else()
+ set(B173_VALUE n)
+endif()
+
+if("${BUILD_VERSION}" MATCHES "b177" OR "${BUILD_VERSION}" MATCHES "b180")
+ set(B177_VALUE y)
+ set(B173_VALUE y)
+else()
+ set(B177_VALUE n)
+endif()
+
+# =============================== 使用KCompat自动化工具时适配1650的SDK 驱动编译 ===============================
+set(SDK_KCOMPAT_GENERATOR_PATH "${TOP_DIR}/ChipSolution/build/host/linux/sdk/sdk-kcompat-generator.sh")
+set(SDK_KCOMPAT_PATH "${TOP_DIR}/ChipSolution/src/dpu_develop_interface/drv_sdk_intf/ossl/sdk_kcompat.h")
+if("${KDIR}" MATCHES "2403_SP2")
+ message(STATUS "KNL_HEADER_TYPE: UB1650")
+ set(KERN_VER "NULL")
+ set(KSRC "${KDIR}/../../../../open_source/2403_SP2")
+ message(STATUS "KSRC = ${KSRC}")
+
+ if(EXISTS ${SDK_KCOMPAT_GENERATOR_PATH})
+ message(STATUS "${SDK_KCOMPAT_GENERATOR_PATH} file is exist!")
+ endif()
+
+ string(RANDOM LENGTH 4 RAND_NUM)
+ set(SDK_KCOMPAT_GENERATOR_PATH_TMP "${TOP_DIR}/ChipSolution/build/host/linux/sdk/sdk-kcompat-generator_${RAND_NUM}.sh")
+
+ if(EXISTS ${SDK_KCOMPAT_GENERATOR_PATH_TMP})
+ file(REMOVE ${SDK_KCOMPAT_GENERATOR_PATH_TMP})
+ endif()
+
+ file(COPY_FILE "${SDK_KCOMPAT_GENERATOR_PATH}" "${SDK_KCOMPAT_GENERATOR_PATH_TMP}")
+ if(EXISTS ${SDK_KCOMPAT_GENERATOR_PATH_TMP})
+ message(STATUS "${SDK_KCOMPAT_GENERATOR_PATH_TMP} file copy succeed")
+ else()
+ message(STATUS "${SDK_KCOMPAT_GENERATOR_PATH_TMP} file copy failed")
+ endif()
+
+ file(READ ${SDK_KCOMPAT_GENERATOR_PATH_TMP} FILE_CONTENTS)
+ string(REPLACE "KERN_VER=\$(uname -r)" "KERN_VER=${KERN_VER}" FILE_CONTENTS "${FILE_CONTENTS}")
+ string(REPLACE "KSRC=\"\"" "KSRC=\"${KSRC}\"" FILE_CONTENTS "${FILE_CONTENTS}")
+ file(WRITE ${SDK_KCOMPAT_GENERATOR_PATH_TMP} "${FILE_CONTENTS}")
+
+ execute_process(
+ COMMAND bash -c "source ${SDK_KCOMPAT_GENERATOR_PATH_TMP} && gen_sdk_kcompat ${SDK_KCOMPAT_PATH}"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ RESULT_VARIABLE RESULT
+ )
+ if(EXISTS ${SDK_KCOMPAT_GENERATOR_PATH_TMP})
+ file(REMOVE ${SDK_KCOMPAT_GENERATOR_PATH_TMP})
+ endif()
+else()
+ message(STATUS "KNL_HEADER_TYPE: DEFAULT")
+ execute_process(
+ COMMAND bash -c "source ${SDK_KCOMPAT_GENERATOR_PATH} && gen_sdk_kcompat ${SDK_KCOMPAT_PATH}"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ RESULT_VARIABLE RESULT
+ )
+endif()
+
+if("${PRODUCT}" STREQUAL "ascend910D" OR "${PRODUCT}" STREQUAL "ascend910Desl")
+ set(hisdk5_depends ubus)
+ add_device_ko(LOCAL_MODULE hisdk5
+ KO_SRC_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}
+ MAKE_ARGS "IS_ASCEND=true"
+ TARGETE_DPENDS "${hisdk5_depends}")
+else()
+add_custom_target(hisdk5_ko
+ COMMENT echo "build ${CMAKE_CURRENT_SOURCE_DIR} start."
+ COMMAND cd ${TOP_DIR}/ChipSolution && git apply build/host/linux/sdk/patch_code/knl6_6_compile.patch && cd -
+ 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} UMMU_CORE_BUILD_DIR=${UMMU_CORE_BUILD_DIR} HI1823_TRUNK_DIR=${TOP_DIR}/ChipSolution HI1823_BUILD_DIR=${TOP_DIR}/ChipSolution CONFIG_UBUS_DEVICE=y HI1823_OS_TYPE=openEuler UB_BUILD_B173=${B173_VALUE} UB_BUILD_B177=${B177_VALUE}
+ COMMAND cp -f *.ko ${CMAKE_INSTALL_PREFIX}/ko
+ COMMAND cd ${TOP_DIR}/ChipSolution && git apply --reverse build/host/linux/sdk/patch_code/knl6_6_compile.patch && cd -
+ DEPENDS kernel
+)
+
+add_dependencies(hisdk5_ko ubus_ko)
+add_dependencies(hisdk5_ko ummu_core_ko)
+endif()
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/Makefile b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/Makefile
new file mode 100644
index 000000000..ab2b61c08
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/Makefile
@@ -0,0 +1,185 @@
+# SDK Makefile
+EXPORT_SYMBOL := true
+
+# Version information
+GIT_COMMIT_ID := $(shell cd $(M) && git rev-parse --short=8 HEAD 2>/dev/null || echo "unknown")
+EXTRA_CFLAGS += -DGIT_COMMIT_ID=\"$(GIT_COMMIT_ID)\"
+
+# HUAWEI SEC
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/platform/huawei_secure_c/include
+EXTRA_CFLAGS += -DSECUREC_EXPORT_KERNEL_SYMBOL=0
+
+# HWSDK INNER
+HWSDK_SRC_PATH = $(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/sdk/knldk/
+EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/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$(HI1823_TRUNK_DIR)/src/dpu_platform_library/include
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/include/drv_tool_msg
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/include/drv_fw_msg/mpu
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/include/sdk/knldk
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/include/cfm/fast_msg
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/ossl
+
+# DBGTOOL
+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/mag
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cqm
+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/cfm
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/tools/micro_log
+
+EXTRA_CFLAGS += -Wframe-larger-than=2048
+EXTRA_CFLAGS += -Wno-implicit-fallthrough -Wno-error=deprecated-declarations
+
+ifeq ($(CONFIG_SP_DEVICE), y)
+EXTRA_CFLAGS += -DCONFIG_SP_VID_DID
+endif
+
+EXTRA_CFLAGS += -Werror
+
+obj-m += hisdk5.o
+hisdk5-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/sscanf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/snprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/sprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsscanf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsnprintf_s.o \
+ ../vram/vram_common.o \
+ ../vram/hinic5_vram.o \
+ ../../../cfm/fast_msg/hinic5_fast_msg_init.o \
+ ../../../cfm/fast_msg/hinic5_fast_msg.o \
+ ../crm/hinic5_hwdev.o \
+ ../crm/hinic5_hw_cfg.o \
+ ../crm/hinic5_hw_comm.o \
+ ../crm/hinic5_mgmt_msg.o \
+ ../crm/hinic5_prof_adap.o \
+ hinic5_sriov.o \
+ hinic5_lld.o \
+ hinic5_bus.o \
+ hinic5_pcie.o \
+ hinic5_sysfs.o \
+ hinic5_dev_mgmt.o \
+ ../hwif/hinic5_common.o \
+ ../hwif/hinic5_hwif.o \
+ ../hwif/hinic5_wq.o \
+ ../hwif/hinic5_cmdq.o \
+ ../hwif/hinic5_enhance_cmdq.o \
+ ../hwif/hinic5_eqs.o \
+ ../hwif/hinic5_mbox.o \
+ ../hwif/hinic5_mgmt.o \
+ ../hwif/hinic5_api_cmd.o \
+ ../hwif/hinic5_hw_api.o \
+ ../hwif/hinic5_sml_lt.o \
+ ../mt/hinic5_fw_update.o \
+ ../mt/hinic5_hw_mt.o \
+ ../mt/hinic5_nictool.o \
+ ../mt/hinic5_non_ptp.o \
+ ../mt/hinic5_devlink.o \
+ ../../ossl/linux/kernel/ossl_knl_linux.o \
+ ../cqm/cqm_secure_mem.o \
+ ../cqm/cqm_bat_cla.o \
+ ../cqm/cqm_bitmap_table.o \
+ ../cqm/cqm_object_intern.o \
+ ../cqm/cqm_bloomfilter.o \
+ ../cqm/cqm_cmd.o \
+ ../cqm/cqm_db.o \
+ ../cqm/cqm_object.o \
+ ../cqm/cqm_main.o \
+ ../cqm/cqm_cmdq_adapt.o \
+ ../cqm/cqm_182x_cmdq_adapt/cqm_182x_cmdq_ops.o \
+ ../cqm/cqm_187x_cmdq_adapt/cqm_187x_cmdq_ops.o
+
+# SDK Debug
+ifneq ($(CONFIG_HINIC5_SDK_DEBUG),)
+EXTRA_CFLAGS += -D__CQM_DEBUG__ -DCONFIG_HINIC5_SDK_DEBUG
+hisdk5-objs += ../mt/hinic5_sdk_attack.o
+endif
+
+# Micro log
+ifneq ($(CONFIG_HINIC5_SDK_DEBUG),)
+EXTRA_CFLAGS += -DCONFIG_HINIC5_MICRO_LOG
+hisdk5-objs += \
+ ../../../../../../src/tools/micro_log/micro_log_comm.o \
+ ../../../../../../src/tools/micro_log/micro_log_procfs_cmd.o \
+ ../../../../../../src/tools/micro_log/micro_log_index.o \
+ ../../../../../../src/tools/micro_log/hinic5_micro_log.o
+endif
+
+# UB release support
+ifeq ($(CONFIG_UB), y)
+hisdk5-objs += hinic5_ubus.o 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 += hinic5_ubus.o
+hisdk5-objs += 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
+
+ifeq ($(CONFIG_UB_UNIFIED_UBUS), y)
+hisdk5-objs += hinic5_ubus.o hinic5_ubus_sriov.o
+EXTRA_CFLAGS += -D__UBUS_DRIVER__ -DUB_SUPPORT_ENTITY -DUB_SUPPORT_B177
+ifneq ($(CONFIG_UB_UBUS_B188), y)
+KBUILD_EXTRA_SYMBOLS += $(UBUS_MODULE_DIR)/Module.symvers
+endif
+endif
+
+# 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
+
+all:build_info default
+
+build_info:
+ mkdir -p build
+ @echo "CURDIR=$(CURDIR)" > build/build_src.txt
+ @for obj in $(hisdk5-objs); do \
+ echo $$(realpath $$obj) >> build/build_src.txt; \
+ done
+
+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 ($(HI1823_RELEASE_TYPE), LLT)
+ ccflags-y += -D_LLT_TEST_
+else
+ ccflags-y += -DHW_CONVERT_ENDIAN
+endif
+
+ccflags-y += -D__LINUX__
+
+include $(HI1823_TRUNK_DIR)/build/host/linux/Makefile.ko
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/hinic5_vram.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/hinic5_vram.c
new file mode 100644
index 000000000..1d714353c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/hinic5_vram.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
+ * Description: hinic5_vram.c
+ * Author: -
+ * Create:
+ */
+
+#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 "hisdk5_typedef.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 "vram_common.h"
+#include "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 == NULL) {
+ 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 == NULL) {
+ 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 ctrl 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 == NULL) {
+ 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 == NULL || cur_dev->flush_ops == NULL) {
+ 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 == NULL) {
+ 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:%hhu.\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 = hi5_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 = hi5_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 wait5_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(wait5_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 = wait5_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_vram_init(void)
+{
+ int err;
+
+ spin_lock_init(&g_hiudk_async_ctrl.lock);
+ lookup5_vram_related_symbols();
+
+ err = hi5_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_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_post_update);
+ (void)hi_unregister_nvwa_notifier(PRE_UPDATE_KERNEL,
+ &hiudk_notifier_pre_update);
+
+ spin_lock_deinit(&g_hiudk_async_ctrl.lock);
+
+ return;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/vram_common.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/vram_common.c
new file mode 100644
index 000000000..3e3debea0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/vram/vram_common.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+ * Description: Header File, vram common
+ * Create: 2023/7/19
+ */
+#include <linux/kallsyms.h>
+#include <linux/errno.h>
+#include <linux/version.h>
+
+#include "ossl_knl.h"
+#include "hisdk5_typedef.h"
+#include "hinic5_vram_api.h"
+#include "vram_common.h"
+
+#ifndef __UEFI__
+
+static int g_use_vram = 0;
+static int g_in_kexec = 0;
+
+STATIC register_nvwa_notifier_t _register_nvwa_notifier = NULL;
+STATIC unregister_nvwa_notifier_t _unregister_nvwa_notifier = NULL;
+STATIC register_euleros_reboot_notifier_t _register_euleros_reboot_notifier =
+ NULL;
+STATIC unregister_euleros_reboot_notifier_t _unregister_euleros_reboot_notifier =
+ NULL;
+STATIC vram_kalloc_t _vram_kalloc = NULL;
+STATIC vpmem_kalloc_node_t _vram_kalloc_node = NULL;
+STATIC vram_kfree_t _vram_kfree = NULL;
+STATIC vram_get_gfp_vram_t _vram_get_gfp_vram = NULL;
+
+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 *hi5_vram_kalloc(char *name, u64 size)
+{
+ if (_vram_kalloc && strnlen(name, VRAM_NAME_SIZE) < VRAM_NAME_SIZE) {
+ return _vram_kalloc(name, size);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(hi5_vram_kalloc);
+
+void __iomem *hi5_vram_kalloc_node(char *name, u64 size, u8 numa)
+{
+ if (_vram_kalloc_node &&
+ strnlen(name, VRAM_NAME_SIZE) < VRAM_NAME_SIZE) {
+ if (numa == VRAM_AFFINITY_NUMA || numa == VRAM_NO_NUMA) {
+ return _vram_kalloc_node(name, size, numa);
+ }
+ return _vram_kalloc_node(
+ name, size, numa >= nr_node_ids ? VRAM_NO_NUMA : numa);
+ } else {
+ return hi5_vram_kalloc(name, size);
+ }
+}
+EXPORT_SYMBOL(hi5_vram_kalloc_node);
+
+void hi5_vram_kfree(void __iomem *vaddr, char *name, u64 size)
+{
+ if (_vram_kfree && vaddr &&
+ strnlen(name, VRAM_NAME_SIZE) < VRAM_NAME_SIZE) {
+ _vram_kfree(vaddr, name, size);
+ }
+
+ return;
+}
+EXPORT_SYMBOL(hi5_vram_kfree);
+
+gfp_t hi5_vram_get_gfp_vram(void)
+{
+ if (_vram_get_gfp_vram) {
+ return _vram_get_gfp_vram();
+ }
+ return 0;
+}
+EXPORT_SYMBOL(hi5_vram_get_gfp_vram);
+
+void lookup5_vram_related_symbols(void)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
+ _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");
+
+ _vram_kalloc = (vram_kalloc_t)kallsyms_lookup_name("vram_kalloc");
+
+ _vram_kalloc_node =
+ (vpmem_kalloc_node_t)kallsyms_lookup_name("vpmem_kalloc_node");
+
+ _vram_kfree = (vram_kfree_t)kallsyms_lookup_name("vram_kfree");
+
+ _vram_get_gfp_vram = (vram_get_gfp_vram_t)kallsyms_lookup_name(
+ "vram_get_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");
+
+ _vram_kalloc = (vram_kalloc_t)kallsyms_lookup_name_wrap("vram_kalloc");
+
+ _vram_kalloc_node = (vpmem_kalloc_node_t)kallsyms_lookup_name_wrap(
+ "vpmem_kalloc_node");
+
+ _vram_kfree = (vram_kfree_t)kallsyms_lookup_name_wrap("vram_kfree");
+
+ _vram_get_gfp_vram = (vram_get_gfp_vram_t)kallsyms_lookup_name_wrap(
+ "vram_get_vram_gfp_t");
+#endif
+#endif
+}
+EXPORT_SYMBOL(lookup5_vram_related_symbols);
+
+int hi5_set_kexec_status(int status)
+{
+ int *kexec_status_addr = NULL;
+
+ kexec_status_addr = hi5_vram_kalloc(KEXEC_SIGN, VRAM_BLOCK_SIZE_2M);
+ if (!kexec_status_addr) {
+ pr_err("set kexec status vram kalloc failed.\n");
+ return -ENOMEM;
+ }
+
+ *kexec_status_addr = status;
+ g_in_kexec = *kexec_status_addr;
+
+ return 0;
+}
+EXPORT_SYMBOL(hi5_set_kexec_status);
+
+int hi5_get_kexec_status(void)
+{
+ int *kexec_status_addr = NULL;
+
+ kexec_status_addr = hi5_vram_kalloc(KEXEC_SIGN, VRAM_BLOCK_SIZE_2M);
+ if (!kexec_status_addr) {
+ pr_err("get kexec status vram kalloc failed.\n");
+ return -ENOMEM;
+ }
+
+ g_in_kexec = *kexec_status_addr;
+ hi5_vram_kfree((void *)kexec_status_addr, KEXEC_SIGN,
+ VRAM_BLOCK_SIZE_2M);
+
+ return 0;
+}
+EXPORT_SYMBOL(hi5_get_kexec_status);
+
+int get5_use_vram_flag(void)
+{
+ return g_use_vram;
+}
+EXPORT_SYMBOL(get5_use_vram_flag);
+
+void set5_use_vram_flag(bool flag)
+{
+ g_use_vram = flag;
+}
+EXPORT_SYMBOL(set5_use_vram_flag);
+
+int vram5_get_kexec_flag(void)
+{
+ return g_in_kexec;
+}
+EXPORT_SYMBOL(vram5_get_kexec_flag);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_rdma.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_rdma.h
new file mode 100644
index 000000000..07c712a93
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_rdma.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2022. All rights reserved.
+ ******************************************************************************
+ History :
+ 1.Date : 2018/3/8
+ Modification: Created file
+***************************************************************************** */
+
+#ifndef HINIC_RDMA_H__
+#define HINIC_RDMA_H__
+
+#ifndef __UEFI__
+
+#define RDMA_ROCE_ENABLE 1
+#define RDMA_IWARP_ENABLE 1
+#define RDMA_ROCE_DISABLE 0
+#define RDMA_IWARP_DISABLE 0
+
+#define RDMA_MPT_FIX_BUG_LKEY 0
+
+struct mutex;
+struct tag_cqm_qpc_mpt;
+struct tag_cqm_object;
+struct net_device;
+struct rdma_gid_entry;
+
+#include "hinic5_cqm.h"
+
+enum mtt_check_type_e { MTT_CHECK_TYPE_0 = 0, MTT_CHECK_TYPE_1 };
+
+struct rdma_rdmarc {
+ u32 offset; /* 分配连续索引的首个索引 */
+ u32 order; /* 分配的rdmarc的order,代表了个数 */
+ u32 ext_order; /* 包含rc表和扩展表的个数 */
+ dma_addr_t dma_addr;
+ void *vaddr;
+};
+
+enum rdma_ib_access {
+ RDMA_IB_ACCESS_LOCAL_WRITE = 1,
+ RDMA_IB_ACCESS_REMOTE_WRITE = (1 << 1),
+ RDMA_IB_ACCESS_REMOTE_READ = (1 << 2),
+ RDMA_IB_ACCESS_REMOTE_ATOMIC = (1 << 3),
+ RDMA_IB_ACCESS_MW_BIND = (1 << 4),
+ RDMA_IB_ACCESS_ZERO_BASED = (1 << 5),
+ RDMA_IB_ACCESS_ON_DEMAND = (1 << 6),
+};
+
+int roce5_rdma_pd_alloc(void *hwdev, u32 *pdn);
+
+void roce5_rdma_pd_free(void *hwdev, u32 pdn);
+
+int roce5_rdma_rdmarc_alloc(void *hwdev, u32 num, struct rdma_rdmarc *rdmarc);
+
+void roce5_rdma_rdmarc_free(void *hwdev, struct rdma_rdmarc *rdmarc);
+
+/* 该接口在pf初始化时调用 */
+int roce5_rdma_init_resource(void *hwdev);
+
+/* 该接口在pf卸载时调用 */
+void roce5_rdma_cleanup_resource(void *hwdev);
+
+#endif /* __UEFI__ */
+
+#endif /* HINIC_RDMA_H__ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.c
new file mode 100644
index 000000000..22e117888
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#include "hinic5_compat.h"
+#include "base/hinic5_cmd.h"
+#include "base/hinic5_cmdq.h"
+#include "hinic5_nic_io.h"
+#include "182x_cmdq_ops.h"
+
+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;
+ qp_ctxt_hdr->start_qid = q_id;
+ qp_ctxt_hdr->rsvd = 0;
+
+ hinic5_cpu_to_be32(qp_ctxt_hdr, sizeof(*qp_ctxt_hdr));
+}
+
+static u8 prepare_cmd_buf_qp_context_multi_store(
+ struct hinic5_nic_dev *nic_dev, 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;
+
+ qp_ctxt_block = cmd_buf->buf;
+
+ hinic5_qp_prepare_cmdq_header(&qp_ctxt_block->cmdq_hdr, ctxt_type,
+ max_ctxts, start_qid);
+
+ for (i = 0; i < max_ctxts; i++) {
+ if (ctxt_type == HINIC5_QP_CTXT_TYPE_RQ)
+ hinic5_rq_prepare_ctxt(&nic_dev->rxqs[start_qid + i],
+ &qp_ctxt_block->rq_ctxt[i]);
+ else
+ hinic5_sq_prepare_ctxt(&nic_dev->txqs[start_qid + i],
+ start_qid + i,
+ &qp_ctxt_block->sq_ctxt[i]);
+ }
+
+ if (ctxt_type == HINIC5_QP_CTXT_TYPE_RQ)
+ cmd_buf->size = RQ_CTXT_SIZE(max_ctxts);
+ else
+ cmd_buf->size = SQ_CTXT_SIZE(max_ctxts);
+
+ return (u8)HINIC5_UCODE_CMD_MODIFY_QUEUE_CTX;
+}
+
+static u8
+prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_dev *nic_dev,
+ 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.num_queues = nic_dev->max_sqs;
+ ctxt_block->cmdq_hdr.queue_type = ctxt_type;
+ ctxt_block->cmdq_hdr.start_qid = 0;
+
+ hinic5_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));
+
+ cmd_buf->size = sizeof(*ctxt_block);
+ return (u8)HINIC5_UCODE_CMD_CLEAN_QUEUE_CONTEXT;
+}
+
+static u8 prepare_cmd_buf_set_rss_indir_table(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_cmd_buf *cmd_buf)
+{
+ (void)nic_dev;
+ (void)cmd_buf;
+ return (u8)HINIC5_UCODE_CMD_SET_RSS_INDIR_TABLE;
+}
+
+static u8 prepare_cmd_buf_get_rss_indir_table(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_cmd_buf *cmd_buf)
+{
+ (void)nic_dev;
+ (void)cmd_buf;
+
+ return (u8)HINIC5_UCODE_CMD_GET_RSS_INDIR_TABLE;
+}
+
+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)
+{
+ struct hinic5_vlan_ctx *vlan_ctx = NULL;
+
+ cmd_buf->size = sizeof(struct hinic5_vlan_ctx);
+ vlan_ctx = (struct hinic5_vlan_ctx *)cmd_buf->buf;
+
+ vlan_ctx->func_id = func_id;
+ vlan_ctx->qid = q_id;
+ vlan_ctx->vlan_id = vlan_tag;
+ vlan_ctx->vlan_sel = 0; /* TPID0 in IPSU */
+ vlan_ctx->vlan_mode = vlan_mode;
+
+ hinic5_cpu_to_be32(vlan_ctx, sizeof(struct hinic5_vlan_ctx));
+ return (u8)HINIC5_UCODE_CMD_MODIFY_VLAN_CTX;
+}
+
+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_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,
+ };
+
+ return &cmdq_182x_ops;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.h
new file mode 100644
index 000000000..fb6cdf1fb
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/182x_cmdq_adapt/182x_cmdq_ops.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef _182X_CMDQ_PRIVATE_H_
+#define _182X_CMDQ_PRIVATE_H_
+
+#include "hinic5_nic_io.h"
+
+struct hinic5_qp_ctxt_header {
+ u16 num_queues;
+ u16 queue_type;
+ u16 start_qid;
+ u16 rsvd;
+};
+
+struct hinic5_clean_queue_ctxt {
+ struct hinic5_qp_ctxt_header cmdq_hdr;
+ u32 rsvd;
+};
+
+struct hinic5_qp_ctxt_block {
+ 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_vlan_ctx {
+ u32 func_id;
+ u32 qid; /* if qid = 0xFFFF, config current function all queue */
+ u32 vlan_id;
+ u32 vlan_mode;
+ u32 vlan_sel;
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.c
new file mode 100644
index 000000000..c68776db0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#include "hinic5_compat.h"
+#include "../securec/securec.h"
+#include "base/hinic5_cmd.h"
+#include "base/hinic5_cmdq.h"
+#include "base/hinic5_hwif.h"
+#include "187x_cmdq_ops.h"
+
+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;
+ qp_ctxt_hdr->start_qid = q_id;
+ qp_ctxt_hdr->dest_func_id = func_id;
+
+ hinic5_cpu_to_be32(qp_ctxt_hdr, sizeof(*qp_ctxt_hdr));
+}
+
+static u8 prepare_cmd_buf_qp_context_multi_store(
+ struct hinic5_nic_dev *nic_dev, 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;
+ u16 i;
+
+ qp_ctxt_block = cmd_buf->buf;
+ func_id = hinic5_global_func_id(nic_dev->hwdev);
+ hinic5_qp_prepare_cmdq_header(&qp_ctxt_block->cmdq_hdr, ctxt_type,
+ max_ctxts, start_qid, func_id);
+
+ for (i = 0; i < max_ctxts; i++) {
+ if (ctxt_type == HINIC5_QP_CTXT_TYPE_RQ)
+ hinic5_rq_prepare_ctxt(&nic_dev->rxqs[start_qid + i],
+ &qp_ctxt_block->rq_ctxt[i]);
+ else
+ hinic5_sq_prepare_ctxt(&nic_dev->txqs[start_qid + i],
+ start_qid + i,
+ &qp_ctxt_block->sq_ctxt[i]);
+ }
+
+ if (ctxt_type == HINIC5_QP_CTXT_TYPE_RQ)
+ cmd_buf->size = RQ_CTXT_SIZE(max_ctxts);
+ else
+ cmd_buf->size = SQ_CTXT_SIZE(max_ctxts);
+
+ return (u8)HINIC5_HTN_CMD_SQ_RQ_CONTEXT_MULTI_ST;
+}
+
+static u8
+prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_dev *nic_dev,
+ 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_dev->hwdev);
+ ctxt_block->cmdq_hdr.num_queues = nic_dev->max_sqs;
+ ctxt_block->cmdq_hdr.queue_type = ctxt_type;
+ ctxt_block->cmdq_hdr.start_qid = 0;
+
+ hinic5_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));
+
+ cmd_buf->size = sizeof(*ctxt_block);
+ return (u8)HINIC5_HTN_CMD_TSO_LRO_SPACE_CLEAN;
+}
+
+static void prepare_rss_indir_table_cmd_header(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_cmd_buf *cmd_buf)
+{
+ struct hinic5_rss_cmd_header *header = cmd_buf->buf;
+
+ header->dest_func_id = hinic5_global_func_id(nic_dev->hwdev);
+ hinic5_cpu_to_be32(header, sizeof(*header));
+}
+
+static u8 prepare_cmd_buf_set_rss_indir_table(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_cmd_buf *cmd_buf)
+{
+ prepare_rss_indir_table_cmd_header(nic_dev, cmd_buf);
+
+ return (u8)HINIC5_HTN_CMD_SET_RSS_INDIR_TABLE;
+}
+
+static u8 prepare_cmd_buf_get_rss_indir_table(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_cmd_buf *cmd_buf)
+{
+ (void)memset_s(cmd_buf->buf, cmd_buf->size, 0, cmd_buf->size);
+ prepare_rss_indir_table_cmd_header(nic_dev, cmd_buf);
+
+ return (u8)HINIC5_HTN_CMD_GET_RSS_INDIR_TABLE;
+}
+
+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)
+{
+ struct hinic5_vlan_ctx *vlan_ctx = NULL;
+
+ cmd_buf->size = sizeof(struct hinic5_vlan_ctx);
+ vlan_ctx = (struct hinic5_vlan_ctx *)cmd_buf->buf;
+
+ vlan_ctx->dest_func_id = func_id;
+ vlan_ctx->start_qid = q_id;
+ vlan_ctx->vlan_tag = vlan_tag;
+ vlan_ctx->vlan_sel = 0; /* TPID0 in IPSU */
+ vlan_ctx->vlan_mode = vlan_mode;
+
+ hinic5_cpu_to_be32(vlan_ctx, sizeof(struct hinic5_vlan_ctx));
+ return (u8)HINIC5_HTN_CMD_SVLAN_MODIFY;
+}
+
+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_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,
+ };
+
+ return &cmdq_187x_ops;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.h
new file mode 100644
index 000000000..4cdf83d28
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/187x_cmdq_adapt/187x_cmdq_ops.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
+
+#ifndef _187X_CMDQ_OPS_H_
+#define _187X_CMDQ_OPS_H_
+
+#include "hinic5_nic_io.h"
+
+struct hinic5_qp_ctxt_header {
+ u32 rsvd[2];
+ u16 num_queues;
+ u16 queue_type;
+ u16 start_qid;
+ u16 dest_func_id;
+};
+
+struct hinic5_clean_queue_ctxt {
+ struct hinic5_qp_ctxt_header cmdq_hdr;
+};
+
+struct hinic5_qp_ctxt_block {
+ 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_rss_cmd_header {
+ u32 rsvd[3];
+ u16 rsvd1;
+ u16 dest_func_id;
+};
+
+/* NIC HTN CMD */
+enum hinic5_htn_cmd {
+ HINIC5_HTN_CMD_SQ_RQ_CONTEXT_MULTI_ST = 0x20,
+ HINIC5_HTN_CMD_SQ_RQ_CONTEXT_MULTI_LD,
+ HINIC5_HTN_CMD_TSO_LRO_SPACE_CLEAN,
+ HINIC5_HTN_CMD_SVLAN_MODIFY,
+ HINIC5_HTN_CMD_SET_RSS_INDIR_TABLE,
+ HINIC5_HTN_CMD_GET_RSS_INDIR_TABLE,
+};
+
+struct hinic5_vlan_ctx {
+ u32 rsvd[2];
+ u16 vlan_tag;
+ u8 vlan_sel;
+ u8 vlan_mode;
+ u16 start_qid;
+ u16 dest_func_id;
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmd.h
new file mode 100644
index 000000000..24c9105bf
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmd.h
@@ -0,0 +1,264 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_CMD_H_
+#define _HINIC5_CMD_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define NIC_RSS_TEMP_ID_TO_CTX_LT_IDX(tmp_id) (tmp_id)
+/* Begin of one temp tbl */
+#define NIC_RSS_TEMP_ID_TO_INDIR_LT_IDX(tmp_id) ((tmp_id) << 4)
+/* 4 ctx in one entry */
+#define NIC_RSS_CTX_TBL_ENTRY_SIZE 0x10
+/* Entry size = 16B, 16 entry/template */
+#define NIC_RSS_INDIR_TBL_ENTRY_SIZE 0x10
+/* Entry size = 16B, so entry_num = 256B/16B */
+#define NIC_RSS_INDIR_TBL_ENTRY_NUM 0x10
+
+#define NIC_UP_RSS_INVALID_TEMP_ID 0xFF
+#define NIC_UP_RSS_INVALID_FUNC_ID 0xFFFF
+#define NIC_UP_RSS_INVALID 0x00
+#define NIC_UP_RSS_EN 0x01
+#define NIC_UP_RSS_INVALID_GROUP_ID 0x7F
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+#define HINIC5_RSS_TYPE_VALID_SHIFT 23
+#define HINIC5_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
+#define HINIC5_RSS_TYPE_IPV6_EXT_SHIFT 25
+#define HINIC5_RSS_TYPE_TCP_IPV6_SHIFT 26
+#define HINIC5_RSS_TYPE_IPV6_SHIFT 27
+#define HINIC5_RSS_TYPE_TCP_IPV4_SHIFT 28
+#define HINIC5_RSS_TYPE_IPV4_SHIFT 29
+#define HINIC5_RSS_TYPE_UDP_IPV6_SHIFT 30
+#define HINIC5_RSS_TYPE_UDP_IPV4_SHIFT 31
+#define HINIC5_RSS_TYPE_SET(val, member) \
+ (((u32)(val)&0x1) << HINIC5_RSS_TYPE_##member##_SHIFT)
+
+#define HINIC5_RSS_TYPE_GET(val, member) \
+ (((u32)(val) >> HINIC5_RSS_TYPE_##member##_SHIFT) & 0x1)
+
+/* NIC CMDQ MODE */
+typedef enum hinic5_ucode_cmd {
+ HINIC5_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC5_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC5_UCODE_CMD_ARM_SQ,
+ HINIC5_UCODE_CMD_ARM_RQ,
+ HINIC5_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC5_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC5_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC5_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
+ HINIC5_UCODE_CMD_SET_IQ_ENABLE,
+ HINIC5_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC5_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC5_UCODE_CMD_PPA_FLOW
+} cmdq_nic_subtype_e;
+
+/*
+ * Commands between NIC to MPU
+ */
+enum hinic5_nic_cmd {
+ HINIC5_NIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */
+
+ /* FUNC CFG */
+ HINIC5_NIC_CMD_SET_FUNC_TBL = 5,
+ HINIC5_NIC_CMD_SET_VPORT_ENABLE,
+ HINIC5_NIC_CMD_SET_RX_MODE,
+ HINIC5_NIC_CMD_SQ_CI_ATTR_SET,
+ HINIC5_NIC_CMD_GET_VPORT_STAT,
+ HINIC5_NIC_CMD_CLEAN_VPORT_STAT,
+ HINIC5_NIC_CMD_CLEAR_QP_RESOURCE,
+ HINIC5_NIC_CMD_CFG_FLEX_QUEUE,
+ /* LRO CFG */
+ HINIC5_NIC_CMD_CFG_RX_LRO,
+ HINIC5_NIC_CMD_CFG_LRO_TIMER,
+ HINIC5_NIC_CMD_FEATURE_NEGO,
+
+ /* MAC & VLAN CFG */
+ HINIC5_NIC_CMD_GET_MAC = 20,
+ HINIC5_NIC_CMD_SET_MAC,
+ HINIC5_NIC_CMD_DEL_MAC,
+ HINIC5_NIC_CMD_UPDATE_MAC,
+ HINIC5_NIC_CMD_GET_ALL_DEFAULT_MAC,
+
+ HINIC5_NIC_CMD_CFG_FUNC_VLAN,
+ HINIC5_NIC_CMD_SET_VLAN_FILTER_EN,
+ HINIC5_NIC_CMD_SET_RX_VLAN_OFFLOAD,
+
+ /* SR-IOV */
+ HINIC5_NIC_CMD_CFG_VF_VLAN = 40,
+ HINIC5_NIC_CMD_SET_SPOOFCHK_STATE,
+ /* RATE LIMIT */
+ HINIC5_NIC_CMD_SET_MAX_MIN_RATE,
+
+ /* RSS CFG */
+ HINIC5_NIC_CMD_RSS_CFG = 60,
+ HINIC5_NIC_CMD_RSS_TEMP_MGR, /* delete after implement nego cmd */
+ HINIC5_NIC_CMD_GET_RSS_CTX_TBL, /* delete: move to ucode cmd */
+ HINIC5_NIC_CMD_CFG_RSS_HASH_KEY,
+ HINIC5_NIC_CMD_CFG_RSS_HASH_ENGINE,
+ HINIC5_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
+
+ /* PPA/FDIR */
+ HINIC5_NIC_CMD_ADD_TC_FLOW = 80,
+ HINIC5_NIC_CMD_DEL_TC_FLOW,
+ HINIC5_NIC_CMD_GET_TC_FLOW,
+ HINIC5_NIC_CMD_FLUSH_TCAM,
+ HINIC5_NIC_CMD_CFG_TCAM_BLOCK,
+ HINIC5_NIC_CMD_ENABLE_TCAM,
+ HINIC5_NIC_CMD_GET_TCAM_BLOCK,
+
+ HINIC5_NIC_CMD_CFG_PPA_TABLE_ID,
+ HINIC5_NIC_CMD_SET_PPA_EN,
+ HINIC5_NIC_CMD_CFG_PPA_MODE,
+ HINIC5_NIC_CMD_CFG_PPA_FLUSH,
+ HINIC5_NIC_CMD_SET_FDIR_STATUS,
+ HINIC5_NIC_CMD_GET_PPA_COUNTER,
+ HINIC5_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC5_NIC_CMD_SET_BOND_MASK,
+ HINIC5_NIC_CMD_GET_BLOCK_TC_FLOWS,
+
+ /* PORT CFG */
+ HINIC5_NIC_CMD_SET_PORT_ENABLE = 100,
+ HINIC5_NIC_CMD_CFG_PAUSE_INFO,
+
+ HINIC5_NIC_CMD_CFG_PORT_CAR,
+ HINIC5_NIC_CMD_SET_ER_DROP_PKT,
+
+ HINIC5_NIC_CMD_VF_COS,
+ HINIC5_NIC_CMD_SETUP_COS_MAPPING,
+ HINIC5_NIC_CMD_SET_ETS,
+ HINIC5_NIC_CMD_SET_PFC,
+ HINIC5_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
+
+ /* MISC */
+ HINIC5_NIC_CMD_BIOS_CFG = 120,
+ HINIC5_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG,
+
+ /* DFX */
+ HINIC5_NIC_CMD_GET_SM_TABLE = 140,
+ HINIC5_NIC_CMD_RD_LINE_TBL,
+
+ HINIC5_NIC_CMD_SET_VHD_CFG = 161,
+
+ /* Move to HILINK */
+ HINIC5_NIC_CMD_GET_PORT_STAT = 200,
+ HINIC5_NIC_CMD_CLEAN_PORT_STAT,
+
+ HINIC5_NIC_CMD_MAX = 256
+};
+
+enum hinic5_svc_type {
+ SVC_T_COMM = 0,
+ SVC_T_NIC,
+ SVC_T_OVS,
+ SVC_T_ROCE,
+ SVC_T_TOE,
+ SVC_T_IOE,
+ SVC_T_FC,
+ SVC_T_VBS,
+ SVC_T_IPSEC,
+ SVC_T_VIRTIO,
+ SVC_T_MIGRATE,
+ SVC_T_PPA,
+ SVC_T_MAX,
+};
+/* COMM commands between driver to MPU */
+enum hinic5_mgmt_cmd {
+ HINIC5_MGMT_CMD_FUNC_RESET = 0,
+ HINIC5_MGMT_CMD_FEATURE_NEGO,
+ HINIC5_MGMT_CMD_FLUSH_DOORBELL,
+ HINIC5_MGMT_CMD_START_FLUSH,
+ HINIC5_MGMT_CMD_SET_FUNC_FLR,
+ HINIC5_MGMT_CMD_SET_FUNC_SVC_USED_STATE = 7,
+
+ HINIC5_MGMT_CMD_CFG_MSIX_NUM = 10,
+
+ HINIC5_MGMT_CMD_SET_CMDQ_CTXT = 20,
+ HINIC5_MGMT_CMD_SET_VAT,
+ HINIC5_MGMT_CMD_CFG_PAGESIZE,
+ HINIC5_MGMT_CMD_CFG_MSIX_CTRL_REG,
+ HINIC5_MGMT_CMD_SET_CEQ_CTRL_REG,
+ HINIC5_MGMT_CMD_SET_DMA_ATTR,
+ HINIC5_MGMT_CMD_SET_ENHANCE_CMDQ_CTXT,
+
+ HINIC5_MGMT_CMD_GET_MQM_FIX_INFO = 40,
+ HINIC5_MGMT_CMD_SET_MQM_CFG_INFO,
+ HINIC5_MGMT_CMD_SET_MQM_SRCH_GPA,
+ HINIC5_MGMT_CMD_SET_PPF_TMR,
+ HINIC5_MGMT_CMD_SET_PPF_HT_GPA,
+ HINIC5_MGMT_CMD_SET_FUNC_TMR_BITMAT,
+
+ HINIC5_MGMT_CMD_GET_FW_VERSION = 60,
+ HINIC5_MGMT_CMD_GET_BOARD_INFO,
+ HINIC5_MGMT_CMD_SYNC_TIME,
+ HINIC5_MGMT_CMD_GET_HW_PF_INFOS,
+ HINIC5_MGMT_CMD_SEND_BDF_INFO,
+
+ HINIC5_MGMT_CMD_UPDATE_FW = 80,
+ HINIC5_MGMT_CMD_ACTIVE_FW,
+ HINIC5_MGMT_CMD_HOT_ACTIVE_FW,
+ HINIC5_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
+ HINIC5_MGMT_CMD_SWITCH_CFG,
+ HINIC5_MGMT_CMD_CHECK_FLASH,
+ HINIC5_MGMT_CMD_CHECK_FLASH_RW,
+ HINIC5_MGMT_CMD_RESOURCE_CFG,
+ HINIC5_MGMT_CMD_UPDATE_BIOS,
+
+ HINIC5_MGMT_CMD_FAULT_REPORT = 100,
+ HINIC5_MGMT_CMD_WATCHDOG_INFO,
+ HINIC5_MGMT_CMD_MGMT_RESET,
+ HINIC5_MGMT_CMD_FFM_SET,
+
+ HINIC5_MGMT_CMD_GET_LOG = 120,
+ HINIC5_MGMT_CMD_TEMP_OP,
+ HINIC5_MGMT_CMD_EN_AUTO_RST_CHIP,
+ HINIC5_MGMT_CMD_CFG_REG,
+ HINIC5_MGMT_CMD_GET_CHIP_ID,
+ HINIC5_MGMT_CMD_SYSINFO_DFX,
+ HINIC5_MGMT_CMD_PCIE_DFX_NTC,
+};
+
+enum mag_cmd {
+ SERDES_CMD_PROCESS = 0,
+
+ MAG_CMD_SET_PORT_CFG = 1,
+ MAG_CMD_SET_PORT_ADAPT = 2,
+ MAG_CMD_CFG_LOOPBACK_MODE = 3,
+
+ MAG_CMD_GET_PORT_ENABLE = 5,
+ MAG_CMD_SET_PORT_ENABLE = 6,
+ MAG_CMD_GET_LINK_STATUS = 7,
+ MAG_CMD_SET_LINK_FOLLOW = 8,
+ MAG_CMD_SET_PMA_ENABLE = 9,
+ MAG_CMD_CFG_FEC_MODE = 10,
+
+ /* LED */
+ MAG_CMD_SET_LED_CFG = 50,
+
+ /* PHY */
+ 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_CFG_XSFP_TEMPERATURE = 64,
+
+ MAG_CMD_WIRE_EVENT = 100,
+ MAG_CMD_LINK_ERR_EVENT = 101,
+
+ MAG_CMD_EVENT_PORT_INFO = 150,
+ MAG_CMD_GET_PORT_STAT = 151,
+ MAG_CMD_CLR_PORT_STAT = 152,
+ MAG_CMD_GET_PORT_INFO = 153,
+ MAG_CMD_GET_PCS_ERR_CNT = 154,
+ MAG_CMD_GET_MAG_CNT = 155,
+ MAG_CMD_DUMP_ANTRAIN_INFO = 156,
+
+ MAG_CMD_MAX = 0xFF
+};
+
+#endif /* _HINIC5_CMD_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.c
new file mode 100644
index 000000000..6f4b4294a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.c
@@ -0,0 +1,893 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ipxe/io.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_hwif.h"
+#include "hinic5_wq.h"
+#include "hinic5_cmd.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_cmdq.h"
+
+#define CMDQ_CMD_TIMEOUT 5000 /* Millisecond */
+
+#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_INFO_UPPER_32(val) ((u64)(val) << 32)
+
+#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_CTRL_SET(val, member) \
+ (((u32)(val)&CMDQ_CTRL_##member##_MASK) << CMDQ_CTRL_##member##_SHIFT)
+
+#define CMDQ_CTRL_GET(val, member) \
+ (((val) >> CMDQ_CTRL_##member##_SHIFT) & CMDQ_CTRL_##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_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_WQE_HEADER_SET(val, member) \
+ (((u32)(val)&CMDQ_WQE_HEADER_##member##_MASK) \
+ << CMDQ_WQE_HEADER_##member##_SHIFT)
+
+#define CMDQ_WQE_HEADER_GET(val, member) \
+ (((val) >> CMDQ_WQE_HEADER_##member##_SHIFT) & \
+ CMDQ_WQE_HEADER_##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_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_PAGE_INFO_SET(val, member) \
+ (((u64)(val)&CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)
+
+#define CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
+#define CMDQ_CTXT_CI_SHIFT 52
+
+#define CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
+#define CMDQ_CTXT_CI_MASK 0xFFF
+
+#define CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
+ (((u64)(val)&CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)
+
+#define SAVED_DATA_ARM_SHIFT 31
+
+#define SAVED_DATA_ARM_MASK 0x1U
+
+#define SAVED_DATA_SET(val, member) \
+ (((val)&SAVED_DATA_##member##_MASK) << SAVED_DATA_##member##_SHIFT)
+
+#define SAVED_DATA_CLEAR(val, member) \
+ ((val) & (~(SAVED_DATA_##member##_MASK << SAVED_DATA_##member##_SHIFT)))
+
+#define WQE_ERRCODE_VAL_SHIFT 0
+
+#define WQE_ERRCODE_VAL_MASK 0x7FFFFFFF
+
+#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 WQE_HEADER(wqe) ((struct hinic5_cmdq_header *)(wqe))
+
+#define CMDQ_DB_PI_OFF(pi) (((u16)LOWER_8_BITS(pi)) << 3)
+
+#define CMDQ_DB_ADDR(db_base, pi) (((u8 *)(db_base)) + CMDQ_DB_PI_OFF(pi))
+
+#define FIRST_DATA_TO_WRITE_LAST sizeof(u64)
+
+#define WQE_LCMD_SIZE 64
+#define WQE_SCMD_SIZE 64
+#define WQE_ENHANCED_CMDQ_SIZE 32
+
+#define COMPLETE_LEN 3
+
+#define CMDQ_WQEBB_SIZE 64
+#define CMDQ_WQEBB_SHIFT 6
+#define CMDQ_ENHANCE_WQEBB_SHIFT 4
+
+#define CMDQ_WQE_SIZE 64
+
+#define HINIC5_CMDQ_WQ_BUF_SIZE 4096
+
+#define WQE_NUM_WQEBBS(wqe_size, wq) \
+ ((u16)(HINIC5_ALIGN((u32)(wqe_size), (wq)->wqebb_size) / \
+ (wq)->wqebb_size))
+
+#define cmdq_to_cmdqs(cmdq) \
+ container_of((cmdq) - (cmdq)->cmdq_type, struct hinic5_cmdqs, (cmdq)[0])
+
+#define WAIT_CMDQ_ENABLE_TIMEOUT 300
+
+static int hinic5_cmdq_poll_msg(struct hinic5_cmdq *cmdq, u32 timeout);
+
+bool hinic5_cmdq_idle(struct hinic5_cmdq *cmdq)
+{
+ struct hinic5_wq *wq = cmdq->wq;
+
+ return (wq->delta == wq->q_depth ? true : false);
+}
+
+struct hinic5_cmd_buf *hinic5_alloc_cmd_buf(__attribute__((unused)) void *hwdev)
+{
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+ struct hinic5_page_addr *alloc_addr = NULL;
+
+ cmd_buf = zalloc(sizeof(*cmd_buf));
+ if (!cmd_buf) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd buffer failed");
+ return NULL;
+ }
+
+ alloc_addr =
+ hinic5_dma_alloc(HINIC5_CMDQ_BUF_SIZE, HINIC5_CMDQ_BUF_SIZE);
+ if (!alloc_addr) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd from the pool failed");
+ goto alloc_pci_buf_err;
+ }
+
+ cmd_buf->buf = alloc_addr->virt_addr;
+ cmd_buf->dma_addr = alloc_addr->phys_addr;
+ cmd_buf->alloc_addr = alloc_addr;
+
+ return cmd_buf;
+
+alloc_pci_buf_err:
+ free(cmd_buf);
+ return NULL;
+}
+
+void hinic5_free_cmd_buf(struct hinic5_cmd_buf *cmd_buf)
+{
+ hinic5_dma_free(cmd_buf->alloc_addr);
+ free(cmd_buf);
+}
+
+static void cmdq_set_completion(struct hinic5_cmdq_completion *complete,
+ struct hinic5_cmd_buf *buf_out)
+{
+ struct hinic5_sge_resp *sge_resp = &complete->sge_resp;
+
+ hinic5_set_sge(&sge_resp->sge, buf_out->dma_addr, HINIC5_CMDQ_BUF_SIZE);
+}
+
+static void cmdq_set_lcmd_bufdesc(struct hinic5_cmdq_wqe_lcmd *wqe,
+ struct hinic5_cmd_buf *buf_in)
+{
+ hinic5_set_sge(&wqe->buf_desc.sge, buf_in->dma_addr, buf_in->size);
+}
+
+static void cmdq_set_db(struct hinic5_cmdq *cmdq,
+ enum hinic5_cmdq_type cmdq_type, u16 prod_idx)
+{
+ u64 db = 0;
+
+ /* Hardware will do endianness coverting */
+ db = CMDQ_DB_INFO_SET(UPPER_8_BITS(prod_idx), HI_PROD_IDX);
+ db = CMDQ_DB_INFO_UPPER_32(db) |
+ 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);
+
+ wmb(); /* Write all before the doorbell */
+
+ writeq(db, CMDQ_DB_ADDR(cmdq->db_base, prod_idx));
+}
+
+static void cmdq_wqe_fill(void *dst, void *src, int wqe_size)
+{
+ int ret = memcpy_s(
+ (void *)((u8 *)dst + FIRST_DATA_TO_WRITE_LAST), /*lint !e746*/
+ CMDQ_WQE_SIZE - FIRST_DATA_TO_WRITE_LAST,
+ (void *)((u8 *)src + FIRST_DATA_TO_WRITE_LAST),
+ wqe_size - FIRST_DATA_TO_WRITE_LAST);
+ if (ret != 0) {
+ IPXE_DRV_LOG(ERR, "Copy cmdq wqe mem failed");
+ return;
+ }
+
+ wmb(); /* The first 8 bytes should be written last */
+
+ *(u64 *)dst = *(u64 *)src;
+}
+
+static void cmdq_prepare_wqe_ctrl(struct hinic5_cmdq_wqe *wqe, int wrapped,
+ enum hinic5_mod_type mod, u8 cmd,
+ u16 prod_idx,
+ enum completion_format complete_format,
+ enum data_format local_data_format,
+ enum bufdesc_len buf_len)
+{
+ struct hinic5_ctrl *ctrl = NULL;
+ enum ctrl_sect_len ctrl_len;
+ struct hinic5_cmdq_wqe_lcmd *wqe_lcmd = NULL;
+ struct hinic5_cmdq_wqe_scmd *wqe_scmd = NULL;
+ u32 saved_data = WQE_HEADER(wqe)->saved_data;
+
+ if (local_data_format == DATA_SGE) {
+ wqe_lcmd = &wqe->wqe_lcmd;
+
+ wqe_lcmd->status.status_info = 0;
+ ctrl = &wqe_lcmd->ctrl;
+ ctrl_len = CTRL_SECT_LEN;
+ } else {
+ wqe_scmd = &wqe->inline_wqe.wqe_scmd;
+
+ wqe_scmd->status.status_info = 0;
+ ctrl = &wqe_scmd->ctrl;
+ ctrl_len = CTRL_DIRECT_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);
+
+ WQE_HEADER(wqe)->header_info =
+ CMDQ_WQE_HEADER_SET(buf_len, BUFDESC_LEN) |
+ CMDQ_WQE_HEADER_SET(complete_format, COMPLETE_FMT) |
+ CMDQ_WQE_HEADER_SET(local_data_format, 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((u32)wrapped, HW_BUSY_BIT);
+
+ saved_data &= SAVED_DATA_CLEAR(saved_data, ARM);
+ if (cmd == CMDQ_SET_ARM_CMD && mod == HINIC5_MOD_COMM) {
+ WQE_HEADER(wqe)->saved_data = saved_data |
+ SAVED_DATA_SET(1, ARM);
+ } else {
+ WQE_HEADER(wqe)->saved_data = saved_data;
+ }
+}
+
+static void cmdq_set_lcmd_wqe(struct hinic5_cmdq_wqe *wqe,
+ enum cmdq_cmd_type cmd_type,
+ struct hinic5_cmd_buf *buf_in,
+ struct hinic5_cmd_buf *buf_out, int wrapped,
+ enum hinic5_mod_type mod, u8 cmd, u16 prod_idx)
+{
+ struct hinic5_cmdq_wqe_lcmd *wqe_lcmd = &wqe->wqe_lcmd;
+ enum completion_format complete_format = COMPLETE_DIRECT;
+
+ switch (cmd_type) {
+ case SYNC_CMD_DIRECT_RESP:
+ complete_format = COMPLETE_DIRECT;
+ wqe_lcmd->completion.direct_resp = 0;
+ break;
+ case SYNC_CMD_SGE_RESP:
+ if (buf_out) {
+ complete_format = COMPLETE_SGE;
+ cmdq_set_completion(&wqe_lcmd->completion, buf_out);
+ }
+ break;
+ case ASYNC_CMD:
+ complete_format = COMPLETE_DIRECT;
+ wqe_lcmd->completion.direct_resp = 0;
+ wqe_lcmd->buf_desc.saved_async_buf = (u64)(intptr_t)(buf_in);
+ break;
+ default:
+ break;
+ }
+
+ cmdq_prepare_wqe_ctrl(wqe, wrapped, mod, cmd, prod_idx, complete_format,
+ DATA_SGE, BUFDESC_LCMD_LEN);
+
+ cmdq_set_lcmd_bufdesc(wqe_lcmd, buf_in);
+}
+
+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_cmdq_wqe *curr_wqe, u16 curr_pi,
+ enum hinic5_cmdq_cmd_type nic_cmd_type)
+{
+ struct hinic5_cmdq_wqe wqe;
+ int wrapped, wqe_size;
+ enum cmdq_cmd_type cmd_type;
+
+ wqe_size = cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ ?
+ WQE_LCMD_SIZE :
+ WQE_ENHANCED_CMDQ_SIZE;
+
+ memset(&wqe, 0, (u32)wqe_size);
+
+ wrapped = cmdq->wrapped;
+
+ cmd_type = (nic_cmd_type == HINIC5_CMD_TYPE_DIRECT_RESP) ?
+ SYNC_CMD_DIRECT_RESP :
+ SYNC_CMD_SGE_RESP;
+ if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ)
+ cmdq_set_lcmd_wqe(&wqe, cmd_type, buf_in, buf_out, wrapped, mod,
+ cmd, curr_pi);
+ else
+ enhanced_cmdq_set_wqe(&wqe, cmd_type, buf_in, buf_out, wrapped,
+ mod, cmd);
+
+ /* The data that is written to HW should be in Big Endian Format */
+ hinic5_hw_be32_len(&wqe, wqe_size);
+
+ /* CMDQ WQE is not shadow, therefore wqe will be written to wq */
+ cmdq_wqe_fill(curr_wqe, &wqe, wqe_size);
+}
+
+#define NUM_WQEBBS_FOR_CMDQ_WQE 1
+#define NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE 2
+
+static int cmdq_sync_cmd(struct hinic5_cmdq *cmdq, enum hinic5_mod_type mod,
+ u8 cmd, struct hinic5_cmd_buf *buf_in,
+ struct hinic5_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, enum hinic5_cmdq_cmd_type nic_cmd_type)
+{
+ struct hinic5_wq *wq = cmdq->wq;
+ struct hinic5_cmdq_wqe wqe;
+ struct hinic5_cmdq_wqe *curr_wqe = NULL;
+ u16 curr_prod_idx, next_prod_idx, num_wqebbs;
+ u32 timeo;
+ u64 *direct_resp = NULL;
+ int err;
+
+ num_wqebbs = (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) ?
+ NUM_WQEBBS_FOR_CMDQ_WQE :
+ NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE;
+
+ curr_wqe = hinic5_get_wqe(cmdq->wq, num_wqebbs, &curr_prod_idx);
+ if (!curr_wqe) {
+ err = -EBUSY;
+ goto cmdq_unlock;
+ }
+
+ (void)memset_s(&wqe, sizeof(wqe), 0, sizeof(wqe));
+
+ cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe,
+ curr_prod_idx, nic_cmd_type);
+
+ cmdq->cmd_infos[curr_prod_idx].cmd_type = nic_cmd_type;
+
+ next_prod_idx = curr_prod_idx + num_wqebbs;
+ if (next_prod_idx >= wq->q_depth) {
+ cmdq->wrapped = !cmdq->wrapped;
+ next_prod_idx -= wq->q_depth;
+ }
+
+ cmdq_set_db(cmdq, HINIC5_CMDQ_SYNC, next_prod_idx);
+
+ timeo = msecs_to_jiffies((timeout != 0) ? timeout : CMDQ_CMD_TIMEOUT);
+ err = hinic5_cmdq_poll_msg(cmdq, timeo);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Cmdq poll msg ack failed, prod idx: 0x%x",
+ curr_prod_idx);
+ err = -ETIMEDOUT;
+ goto cmdq_unlock;
+ }
+
+ rmb(); /* Read error code after completion */
+
+ if (out_param) {
+ if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ)
+ direct_resp = (u64 *)(&curr_wqe->wqe_lcmd.completion
+ .direct_resp);
+ else
+ direct_resp =
+ (u64 *)(&curr_wqe->enhanced_cmdq_wqe.completion
+ .sge_resp_lo_addr);
+
+ *out_param = cpu_to_be64(*direct_resp);
+ }
+
+ if (cmdq->errcode[curr_prod_idx] != 0) {
+ err = cmdq->errcode[curr_prod_idx];
+ }
+
+cmdq_unlock:
+ return err;
+}
+
+static int cmdq_params_valid(void *hwdev, struct hinic5_cmd_buf *buf_in)
+{
+ if (!buf_in || !hwdev) {
+ IPXE_DRV_LOG(ERR, "Invalid CMDQ buffer or hwdev is NULL");
+ return -EINVAL;
+ }
+
+ if (buf_in->size == 0 || buf_in->size > HINIC5_CMDQ_BUF_SIZE) {
+ IPXE_DRV_LOG(ERR, "Invalid CMDQ buffer size: 0x%x",
+ buf_in->size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int wait_cmdqs_enable(struct hinic5_cmdqs *cmdqs)
+{
+ unsigned long cnt = 0;
+ do {
+ if ((cmdqs->status & HINIC5_CMDQ_ENABLE) != 0) {
+ return 0;
+ }
+ ++cnt;
+ usleep(HINIC5_MS_TO_US_UNIT);
+ } while (cnt < WAIT_CMDQ_ENABLE_TIMEOUT);
+
+ return -EBUSY;
+}
+
+int hinic5_cmdq_direct_resp(void *hwdev, enum hinic5_mod_type mod, u8 cmd,
+ struct hinic5_cmd_buf *buf_in, u64 *out_param,
+ u32 timeout)
+{
+ struct hinic5_cmdqs *cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
+ int err;
+
+ err = cmdq_params_valid(hwdev, buf_in);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Invalid cmdq parameters");
+ return err;
+ }
+
+ err = wait_cmdqs_enable(cmdqs);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Cmdq is disabled");
+ return err;
+ }
+
+ return cmdq_sync_cmd(&cmdqs->cmdq[HINIC5_CMDQ_SYNC], mod, cmd, buf_in,
+ NULL, out_param, timeout,
+ HINIC5_CMD_TYPE_DIRECT_RESP);
+}
+
+int hinic5_cmdq_detail_resp(void *hwdev, enum hinic5_mod_type mod, u8 cmd,
+ struct hinic5_cmd_buf *buf_in,
+ struct hinic5_cmd_buf *buf_out, u32 timeout)
+{
+ struct hinic5_cmdqs *cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
+ int err;
+
+ err = cmdq_params_valid(hwdev, buf_in);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Invalid cmdq parameters");
+ return err;
+ }
+
+ err = wait_cmdqs_enable(cmdqs);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Cmdq is disabled");
+ return err;
+ }
+
+ return cmdq_sync_cmd(&cmdqs->cmdq[HINIC5_CMDQ_SYNC], mod, cmd, buf_in,
+ buf_out, NULL, timeout, HINIC5_CMD_TYPE_SGE_RESP);
+}
+
+static void cmdq_update_errcode(struct hinic5_cmdq *cmdq, u16 prod_idx,
+ int errcode)
+{
+ cmdq->errcode[prod_idx] = errcode;
+}
+
+static void clear_wqe_complete_bit(struct hinic5_cmdq *cmdq,
+ struct hinic5_cmdq_wqe *wqe)
+{
+ struct hinic5_ctrl *ctrl = NULL;
+ u32 header_info = hinic5_hw_cpu32(WQE_HEADER(wqe)->header_info);
+ u16 num_wqebbs;
+ enum data_format df;
+
+ if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
+ df = CMDQ_WQE_HEADER_GET(header_info, DATA_FMT);
+ if (df == DATA_SGE)
+ ctrl = &wqe->wqe_lcmd.ctrl;
+ else
+ ctrl = &wqe->inline_wqe.wqe_scmd.ctrl;
+
+ ctrl->ctrl_info = 0; /* clear HW busy bit */
+ num_wqebbs = NUM_WQEBBS_FOR_CMDQ_WQE;
+ } else {
+ wqe->enhanced_cmdq_wqe.completion.cs_format =
+ 0; /* clear HW busy bit */
+ num_wqebbs = NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE;
+ }
+
+ wmb(); /* Verify wqe is cleared */
+
+ hinic5_put_wqe(cmdq->wq, num_wqebbs);
+}
+
+static void cmdq_init_queue_ctxt(struct hinic5_cmdq *cmdq,
+ struct hinic5_cmdq_ctxt_info *ctxt_info)
+{
+ struct hinic5_wq *wq = cmdq->wq;
+ u64 wq_first_page_paddr, pfn;
+
+ u16 start_ci = (u16)(wq->cons_idx);
+
+ /* The data in the HW is in Big Endian Format */
+ wq_first_page_paddr = wq->queue_buf_paddr;
+ pfn = CMDQ_PFN(wq_first_page_paddr, HINIC5_PGSIZE_4K);
+ ctxt_info->curr_wqe_page_pfn =
+ CMDQ_CTXT_PAGE_INFO_SET(1, HW_BUSY_BIT) |
+ CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_EN) |
+ CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_ARM) |
+ CMDQ_CTXT_PAGE_INFO_SET(HINIC5_CEQ_ID_CMDQ, EQ_ID) |
+ CMDQ_CTXT_PAGE_INFO_SET(pfn, CURR_WQE_PAGE_PFN);
+
+ ctxt_info->wq_block_pfn = CMDQ_CTXT_BLOCK_INFO_SET(start_ci, CI) |
+ CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN);
+}
+
+static int init_cmdq(struct hinic5_cmdq *cmdq, struct hinic5_hwdev *hwdev,
+ struct hinic5_wq *wq, enum hinic5_cmdq_type q_type)
+{
+ int err = 0;
+ size_t errcode_size;
+ size_t cmd_infos_size;
+
+ cmdq->wq = wq;
+ cmdq->cmdq_type = q_type;
+ cmdq->wrapped = 1;
+
+ errcode_size = wq->q_depth * sizeof(*cmdq->errcode);
+ cmdq->errcode = zalloc(errcode_size);
+ if (!cmdq->errcode) {
+ IPXE_DRV_LOG(ERR, "Allocate errcode for cmdq failed");
+ return -ENOMEM;
+ }
+
+ cmd_infos_size = wq->q_depth * sizeof(*cmdq->cmd_infos);
+ cmdq->cmd_infos = zalloc(cmd_infos_size);
+ if (!cmdq->cmd_infos) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd info for cmdq failed");
+ err = -ENOMEM;
+ goto cmd_infos_err;
+ }
+
+ cmdq->db_base = hwdev->cmdqs->cmdqs_db_base;
+
+ return 0;
+
+cmd_infos_err:
+ free(cmdq->errcode);
+
+ return err;
+}
+
+static void free_cmdq(struct hinic5_cmdq *cmdq)
+{
+ free(cmdq->cmd_infos);
+ free(cmdq->errcode);
+}
+
+static int hinic5_set_cmdq_ctxts(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_cmdqs *cmdqs = hwdev->cmdqs;
+ struct hinic5_cmd_cmdq_ctxt cmdq_ctxt = { 0 };
+ enum hinic5_cmdq_type cmdq_type;
+ u16 out_size = sizeof(cmdq_ctxt);
+ u16 cmd;
+ int err;
+
+ cmdq_type = HINIC5_CMDQ_SYNC;
+ for (; cmdq_type < HINIC5_MAX_CMDQ_TYPES; cmdq_type++) {
+ if (hwdev->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
+ (void)memcpy_s(
+ (void *)&cmdq_ctxt.ctxt_info,
+ sizeof(cmdq_ctxt.ctxt_info),
+ (void *)&cmdqs->cmdq[cmdq_type].cmdq_ctxt,
+ sizeof(cmdq_ctxt.ctxt_info));
+ cmd = HINIC5_MGMT_CMD_SET_CMDQ_CTXT;
+ } else {
+ (void)memcpy_s((void *)&cmdq_ctxt.ctxt_info,
+ sizeof(cmdq_ctxt.ctxt_info),
+ (void *)&cmdqs->cmdq[cmdq_type]
+ .cmdq_enhance_ctxt,
+ sizeof(cmdq_ctxt.ctxt_info));
+ cmd = HINIC5_MGMT_CMD_SET_ENHANCE_CMDQ_CTXT;
+ }
+
+ cmdq_ctxt.func_idx = hinic5_global_func_id(hwdev);
+ cmdq_ctxt.cmdq_id = cmdq_type;
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, cmd,
+ &cmdq_ctxt, sizeof(cmdq_ctxt),
+ &cmdq_ctxt, &out_size, 0);
+ if (err || !out_size || cmdq_ctxt.status) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Set cmdq ctxt failed, err: %d, status: 0x%x, out_size: 0x%x",
+ err, cmdq_ctxt.status, out_size);
+ return -EFAULT;
+ }
+ }
+
+ cmdqs->status |= HINIC5_CMDQ_ENABLE;
+
+ return 0;
+}
+
+int hinic5_reinit_cmdq_ctxts(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_cmdqs *cmdqs = hwdev->cmdqs;
+ enum hinic5_cmdq_type cmdq_type = HINIC5_CMDQ_SYNC;
+
+ for (; cmdq_type < HINIC5_MAX_CMDQ_TYPES; cmdq_type++) {
+ cmdqs->cmdq[cmdq_type].wrapped = 1;
+ hinic5_wq_wqe_pg_clear(cmdqs->cmdq[cmdq_type].wq);
+ }
+
+ return hinic5_set_cmdq_ctxts(hwdev);
+}
+
+static int hinic5_set_cmdqs(struct hinic5_hwdev *hwdev,
+ struct hinic5_cmdqs *cmdqs)
+{
+ void *db_base = NULL;
+ enum hinic5_cmdq_type type, cmdq_type;
+ int err;
+
+ err = hinic5_alloc_db_addr(hwdev, &db_base, HINIC5_DB_TYPE_CMDQ);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to allocate doorbell address\n");
+ goto alloc_db_err;
+ }
+ cmdqs->cmdqs_db_base = (u8 *)db_base;
+
+ cmdq_type = HINIC5_CMDQ_SYNC;
+ for (; cmdq_type < HINIC5_MAX_CMDQ_TYPES; cmdq_type++) {
+ cmdqs->cmdq[cmdq_type].cmdqs = cmdqs;
+ err = init_cmdq(&cmdqs->cmdq[cmdq_type], hwdev,
+ &cmdqs->saved_wqs[cmdq_type], cmdq_type);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Initialize cmdq failed");
+ goto init_cmdq_err;
+ }
+
+ if (cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
+ cmdq_init_queue_ctxt(&cmdqs->cmdq[cmdq_type],
+ &cmdqs->cmdq[cmdq_type].cmdq_ctxt);
+ } else {
+ /* HINIC5_ENHANCE_CMDQ */
+ enhanced_cmdq_init_queue_ctxt(&cmdqs->cmdq[cmdq_type]);
+ }
+ }
+
+ err = hinic5_set_cmdq_ctxts(hwdev);
+ if (err != 0) {
+ goto init_cmdq_err;
+ }
+
+ return 0;
+
+init_cmdq_err:
+ type = HINIC5_CMDQ_SYNC;
+ for (; type < cmdq_type; type++) {
+ free_cmdq(&cmdqs->cmdq[type]);
+ }
+
+alloc_db_err:
+ return err;
+}
+
+#define MEMPOOL_NAMESIZE 24
+int hinic5_cmdqs_init(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_cmdqs *cmdqs = NULL;
+ size_t saved_wqs_size;
+ u32 wqebb_shift;
+ int err;
+
+ cmdqs = zalloc(sizeof(*cmdqs));
+ if (!cmdqs) {
+ return -ENOMEM;
+ }
+
+ hwdev->cmdqs = cmdqs;
+ cmdqs->hwdev = hwdev;
+
+ if (HINIC5_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev)) {
+ cmdqs->cmdq_mode = HINIC5_ENHANCE_CMDQ;
+ } else {
+ cmdqs->cmdq_mode = HINIC5_NORMAL_CMDQ;
+ }
+
+ wqebb_shift = (cmdqs->cmdq_mode == HINIC5_ENHANCE_CMDQ) ?
+ CMDQ_ENHANCE_WQEBB_SHIFT :
+ CMDQ_WQEBB_SHIFT;
+
+ saved_wqs_size = HINIC5_MAX_CMDQ_TYPES * sizeof(struct hinic5_wq);
+ cmdqs->saved_wqs = zalloc(saved_wqs_size);
+ if (!cmdqs->saved_wqs) {
+ IPXE_DRV_LOG(ERR, "Allocate saved wqs failed");
+ err = -ENOMEM;
+ goto alloc_wqs_err;
+ }
+
+ err = hinic5_cmdq_alloc(cmdqs->saved_wqs, hwdev, HINIC5_MAX_CMDQ_TYPES,
+ HINIC5_CMDQ_WQ_BUF_SIZE, wqebb_shift,
+ HINIC5_CMDQ_DEPTH);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Allocate cmdq failed");
+ goto pool_create_err;
+ }
+
+ err = hinic5_set_cmdqs(hwdev, cmdqs);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "set_cmdqs failed");
+ goto cmdq_free;
+ }
+ return 0;
+
+cmdq_free:
+ hinic5_cmdq_free(cmdqs->saved_wqs, HINIC5_MAX_CMDQ_TYPES);
+
+pool_create_err:
+ free(cmdqs->saved_wqs);
+
+alloc_wqs_err:
+ free(cmdqs);
+
+ return err;
+}
+
+void hinic5_cmdqs_free(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_cmdqs *cmdqs = hwdev->cmdqs;
+ enum hinic5_cmdq_type cmdq_type = HINIC5_CMDQ_SYNC;
+
+ cmdqs->status &= ~HINIC5_CMDQ_ENABLE;
+
+ for (; cmdq_type < HINIC5_MAX_CMDQ_TYPES; cmdq_type++) {
+ free_cmdq(&cmdqs->cmdq[cmdq_type]);
+ }
+
+ hinic5_cmdq_free(cmdqs->saved_wqs, HINIC5_MAX_CMDQ_TYPES);
+
+ free(cmdqs->saved_wqs);
+
+ free(cmdqs);
+}
+
+static int hinic5_check_cmdq_done(struct hinic5_cmdq *cmdq,
+ struct hinic5_cmdq_wqe *wqe)
+{
+ struct hinic5_ctrl *ctrl = NULL;
+ u32 ctrl_info;
+ if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
+ /* only arm bit is using scmd wqe, the wqe is lcmd */
+ ctrl = &wqe->wqe_lcmd.ctrl;
+ ctrl_info = hinic5_hw_cpu32((ctrl)->ctrl_info);
+
+ if (!WQE_COMPLETED(ctrl_info))
+ return -EBUSY;
+ } else {
+ ctrl_info = wqe->enhanced_cmdq_wqe.completion.cs_format;
+ ctrl_info = hinic5_hw_cpu32(ctrl_info);
+ if (!ENHANCE_CMDQ_WQE_CS_GET(ctrl_info, HW_BUSY))
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int hinic5_cmdq_poll_msg(struct hinic5_cmdq *cmdq, u32 timeout)
+{
+ struct hinic5_cmdq_wqe *wqe = NULL;
+ struct hinic5_cmdq_wqe_lcmd *wqe_lcmd = NULL;
+ struct hinic5_cmdq_cmd_info *cmd_info = NULL;
+ u32 status_info;
+ u16 ci;
+ int errcode;
+ int done = 0;
+ int err = 0;
+ unsigned long cnt = 0;
+
+ wqe = hinic5_read_wqe(cmdq->wq, 1, &ci);
+ if (!wqe) {
+ IPXE_DRV_LOG(ERR, "No outstanding cmdq msg");
+ return -EINVAL;
+ }
+
+ cmd_info = &cmdq->cmd_infos[ci];
+ if (cmd_info->cmd_type == HINIC5_CMD_TYPE_NONE) {
+ IPXE_DRV_LOG(ERR,
+ "Cmdq msg has not been filled and send to hw, "
+ "or get TMO msg ack. cmdq ci: %d",
+ ci);
+ return -EINVAL;
+ }
+
+ /* Only arm bit is using scmd wqe, the wqe is lcmd */
+
+ do {
+ if (hinic5_check_cmdq_done(cmdq, wqe) == 0) {
+ done = 1;
+ break;
+ }
+
+ udelay(HINIC5_MS_TO_US_UNIT);
+ ++cnt;
+ } while (cnt < timeout);
+
+ if (done) {
+ if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
+ wqe_lcmd = &wqe->wqe_lcmd;
+ status_info =
+ hinic5_hw_cpu32(wqe_lcmd->status.status_info);
+ errcode = WQE_ERRCODE_GET(status_info, VAL);
+ } else {
+ status_info = hinic5_hw_cpu32(
+ wqe->enhanced_cmdq_wqe.completion.cs_format);
+ errcode =
+ ENHANCE_CMDQ_WQE_CS_GET(status_info, ERR_CODE);
+ }
+
+ cmdq_update_errcode(cmdq, ci, errcode);
+ clear_wqe_complete_bit(cmdq, wqe);
+ err = 0;
+ } else {
+ IPXE_DRV_LOG(ERR, "Poll cmdq msg time out, ci: %d", ci);
+ err = -ETIMEDOUT;
+ }
+
+ /* Set this cmd invalid */
+ cmd_info->cmd_type = HINIC5_CMD_TYPE_NONE;
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.h
new file mode 100644
index 000000000..b13635807
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq.h
@@ -0,0 +1,250 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_CMDQ_H_
+#define _HINIC5_CMDQ_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include "hinic5_mgmt.h"
+#include "hinic5_wq.h"
+#include "hinic5_cmdq_enhance.h"
+#include "hinic5_compat.h"
+
+#define HINIC5_SCMD_DATA_LEN 16
+
+/* Pmd driver uses 64, kernel l2nic uses 4096 */
+#define HINIC5_CMDQ_DEPTH 64
+
+#define HINIC5_CMDQ_BUF_SIZE 2048U
+
+#define HINIC5_CEQ_ID_CMDQ 0
+
+#define CMDQ_PFN(addr, page_size) ((addr) >> (ilog2(page_size)))
+#define WQ_BLOCK_PFN_SHIFT 9
+#define WQ_BLOCK_PFN(page_addr) ((page_addr) >> WQ_BLOCK_PFN_SHIFT)
+
+enum hinic5_cmdq_mode {
+ HINIC5_NORMAL_CMDQ,
+ HINIC5_ENHANCE_CMDQ,
+};
+
+enum cmdq_scmd_type {
+ CMDQ_SET_ARM_CMD = 2,
+};
+
+enum cmdq_wqe_type { WQE_LCMD_TYPE, WQE_SCMD_TYPE };
+
+enum ctrl_sect_len { CTRL_SECT_LEN = 1, CTRL_DIRECT_SECT_LEN = 2 };
+
+enum bufdesc_len { BUFDESC_LCMD_LEN = 2, BUFDESC_SCMD_LEN = 3 };
+
+enum data_format {
+ DATA_SGE,
+};
+
+enum completion_format { COMPLETE_DIRECT, COMPLETE_SGE };
+
+enum completion_request {
+ CEQ_SET = 1,
+};
+
+enum cmdq_cmd_type { SYNC_CMD_DIRECT_RESP, SYNC_CMD_SGE_RESP, ASYNC_CMD };
+
+enum hinic5_cmdq_type { HINIC5_CMDQ_SYNC, HINIC5_MAX_CMDQ_TYPES };
+
+enum hinic5_db_src_type {
+ HINIC5_DB_SRC_CMDQ_TYPE,
+ HINIC5_DB_SRC_L2NIC_SQ_TYPE
+};
+
+enum hinic5_cmdq_db_type { HINIC5_DB_SQ_RQ_TYPE, HINIC5_DB_CMDQ_TYPE };
+
+/* Cmdq ack type */
+enum hinic5_ack_type {
+ HINIC5_ACK_TYPE_CMDQ,
+ HINIC5_ACK_TYPE_SHARE_CQN,
+ HINIC5_ACK_TYPE_APP_CQN,
+
+ HINIC5_MOD_ACK_MAX = 15
+};
+
+/* Cmdq wqe ctrls */
+struct hinic5_cmdq_header {
+ u32 header_info;
+ u32 saved_data;
+};
+
+struct hinic5_scmd_bufdesc {
+ 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_cmdq_db {
+ u32 db_head;
+ u32 db_info;
+};
+
+struct hinic5_status {
+ u32 status_info;
+};
+
+struct hinic5_ctrl {
+ u32 ctrl_info;
+};
+
+struct hinic5_sge_resp {
+ struct hinic5_sge sge;
+ u32 rsvd;
+};
+
+struct hinic5_cmdq_completion {
+ /* HW format */
+ union {
+ 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_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_inline_wqe {
+ struct hinic5_cmdq_wqe_scmd wqe_scmd;
+};
+
+struct hinic5_cmdq_wqe {
+ /* HW format */
+ union {
+ struct hinic5_cmdq_inline_wqe inline_wqe;
+ struct hinic5_cmdq_wqe_lcmd wqe_lcmd;
+ struct enhanced_cmdq_wqe enhanced_cmdq_wqe;
+ };
+};
+
+struct hinic5_cmdq_ctxt_info {
+ u64 curr_wqe_page_pfn;
+ u64 wq_block_pfn;
+};
+
+struct hinic5_cmd_cmdq_ctxt {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_idx;
+ u8 cmdq_id;
+ u8 rsvd1[5];
+
+ union {
+ struct hinic5_cmdq_ctxt_info ctxt_info;
+ struct enhance_cmdq_ctxt_info enhance_ctxt_info;
+ };
+};
+
+enum hinic5_cmdq_status {
+ HINIC5_CMDQ_ENABLE = BIT(0),
+};
+
+enum hinic5_cmdq_cmd_type {
+ HINIC5_CMD_TYPE_NONE,
+ HINIC5_CMD_TYPE_SET_ARM,
+ HINIC5_CMD_TYPE_DIRECT_RESP,
+ HINIC5_CMD_TYPE_SGE_RESP
+};
+
+struct hinic5_cmdq_cmd_info {
+ enum hinic5_cmdq_cmd_type cmd_type;
+};
+
+struct hinic5_cmdq {
+ struct hinic5_wq *wq;
+
+ enum hinic5_cmdq_type cmdq_type;
+ int wrapped;
+
+ int *errcode;
+ u8 *db_base;
+
+ struct hinic5_cmdq_ctxt_info cmdq_ctxt;
+ struct enhance_cmdq_ctxt_info cmdq_enhance_ctxt;
+
+ struct hinic5_cmdq_cmd_info *cmd_infos;
+ struct hinic5_cmdqs *cmdqs;
+};
+
+struct hinic5_cmdqs {
+ struct hinic5_hwdev *hwdev;
+ u8 *cmdqs_db_base;
+
+ struct hinic5_wq *saved_wqs;
+
+ struct hinic5_cmdq cmdq[HINIC5_MAX_CMDQ_TYPES];
+
+ u32 status;
+ u8 cmdq_mode;
+};
+
+struct hinic5_cmd_buf {
+ void *buf;
+ uint64_t dma_addr;
+ u16 size;
+ struct hinic5_page_addr *alloc_addr;
+};
+
+int hinic5_reinit_cmdq_ctxts(struct hinic5_hwdev *hwdev);
+
+bool hinic5_cmdq_idle(struct hinic5_cmdq *cmdq);
+
+struct hinic5_cmd_buf *hinic5_alloc_cmd_buf(void *hwdev);
+
+void hinic5_free_cmd_buf(struct hinic5_cmd_buf *cmd_buf);
+
+/*
+ * PF/VF sends cmd to ucode by cmdq, and return 0 if success.
+ * timeout=0, use default timeout.
+ */
+int hinic5_cmdq_direct_resp(void *hwdev, enum hinic5_mod_type mod, u8 cmd,
+ struct hinic5_cmd_buf *buf_in, u64 *out_param,
+ u32 timeout);
+
+int hinic5_cmdq_detail_resp(void *hwdev, enum hinic5_mod_type mod, u8 cmd,
+ struct hinic5_cmd_buf *buf_in,
+ struct hinic5_cmd_buf *buf_out, u32 timeout);
+
+int hinic5_cmdqs_init(struct hinic5_hwdev *hwdev);
+
+void hinic5_cmdqs_free(struct hinic5_hwdev *hwdev);
+
+void enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe,
+ enum cmdq_cmd_type cmd_type,
+ const struct hinic5_cmd_buf *buf_in,
+ const struct hinic5_cmd_buf *buf_out, int wrapped,
+ u8 mod, u8 cmd);
+
+void enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdq *cmdq);
+
+#endif /* _HINIC5_CMDQ_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq_enhance.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq_enhance.h
new file mode 100644
index 000000000..8446745aa
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_cmdq_enhance.h
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef ENHANCED_CMDQ_H
+#define ENHANCED_CMDQ_H
+
+#include "hinic5_mgmt.h"
+#include "hinic5_compat.h"
+
+enum complete_format {
+ INLINE_DATA = 0,
+ SGE_RESPONSE = 1,
+};
+
+/* 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
+
+/* 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_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_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_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_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_CMD_MASK 0xFFU
+#define ENHANCE_CMDQ_WQE_CS_ACK_TYPE_MASK 0x3FU
+#define ENHANCE_CMDQ_WQE_CS_HW_BUSY_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)
+
+struct cmdq_enhance_completion {
+ u32 cs_format;
+ u32 sge_resp_hi_addr;
+ u32 sge_resp_lo_addr;
+ u32 sge_resp_len; /* bit 14~31 rsvd, soft can't use. */
+};
+
+struct cmdq_enhance_response {
+ u32 cs_format;
+ u32 resvd;
+ u64 direct_data;
+};
+
+struct sge_send_info {
+ u32 sge_hi_addr;
+ u32 sge_li_addr;
+ u32 seg_len;
+ u32 rsvd;
+};
+
+#define NORMAL_WQE_TYPE 0
+#define COMPACT_WQE_TYPE 1
+struct ctrl_section {
+ u32 header;
+ u32 rsv;
+ u32 sge_send_hi_addr;
+ u32 sge_send_lo_addr;
+};
+
+struct enhanced_cmdq_wqe {
+ struct ctrl_section ctrl_sec; /* 16B */
+ struct cmdq_enhance_completion completion; /* 16B */
+};
+
+/* hardware define: enhance cmdq context */
+struct enhance_cmdq_ctxt_info {
+ u64 eq_cfg;
+ u64 dfx_pi_ci;
+
+ u64 pft_thd;
+ u64 pft_ci;
+
+ u64 rsv;
+ u64 ci_cla_addr;
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_compat.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_compat.h
new file mode 100644
index 000000000..e215a4cbb
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_compat.h
@@ -0,0 +1,185 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_COMPAT_H_
+#define _HINIC5_COMPAT_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#undef ERRFILE
+#define ERRFILE ERRFILE_legacy
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <byteswap.h>
+
+#ifndef BIT
+#define BIT(n) (1U << (n))
+#endif
+
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
+#define lower_32_bits(n) ((u32)(n))
+
+#define HINIC5_ALIGN_FLOOR(val, align) \
+ (typeof(val))((val) & (~((typeof(val))((align)-1))))
+
+#define HINIC5_ALIGN_CEIL(val, align) \
+ HINIC5_ALIGN_FLOOR(((val) + ((typeof(val))(align)-1)), align)
+
+#define HINIC5_ALIGN(val, align) HINIC5_ALIGN_CEIL(val, align)
+
+#define HINIC5_MEM_ALLOC_ALIGN_MIN 1
+
+#define HINIC5_PGSIZE_4K 4096
+#define HINIC5_CACHE_LINE_SIZE 128
+#define HINIC5_WQ_PGSIZE_ALIGN (1ULL << 12)
+
+#define HINIC5_DRIVER_NAME "hinic5"
+
+#define ERR 0x00
+#define WARN 0x01
+#define INFO 0x02
+#define DEBUG 0x04
+
+#define IPXE_DEBUG
+#define DEBUG_PRINT_LEVEL (INFO | DEBUG)
+// Print everything
+#define IPXE_DRV_LOG(level, fmt, args...) \
+ (void)printf(HINIC5_DRIVER_NAME ": " fmt "\n", ##args)
+
+/* If csrs to enable endianness coverting are configed, hw will do the
+ * endianness coverting for stateless SQ ci, the fields less than 4B for
+ * doorbell, the fields less than 4B in the CQE data.
+ */
+#define hinic5_hw_be32(val) (val)
+#define hinic5_hw_cpu32(val) (val)
+#define hinic5_hw_cpu16(val) (val)
+
+#define ARRAY_LEN(arr) ((int)(sizeof(arr) / sizeof((arr)[0])))
+
+static inline void hinic5_hw_be32_len(void *data, int len)
+{
+ int i, chunk_sz = sizeof(u32);
+ u32 *mem = data;
+
+ if (!data)
+ return;
+
+ len = len / chunk_sz;
+
+ for (i = 0; i < len; i++) {
+ *mem = hinic5_hw_be32(*mem);
+ mem++;
+ }
+}
+
+/* if Joyce Kong's MR received, needs to use rte_bitops.h */
+static inline int hinic5_test_bit(int nr, volatile unsigned long *addr)
+{
+ int res;
+
+ res = ((*addr) & (1UL << nr)) != 0;
+ return res;
+}
+
+static inline void hinic5_set_bit(unsigned int nr, volatile unsigned long *addr)
+{
+ __sync_fetch_and_or(addr, (1UL << nr));
+}
+
+static inline void hinic5_clear_bit(int nr, volatile unsigned long *addr)
+{
+ __sync_fetch_and_and(addr, ~(1UL << nr));
+}
+
+static inline int hinic5_test_and_clear_bit(int nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = (1UL << nr);
+
+ return (int)(__sync_fetch_and_and(addr, ~mask) & mask);
+}
+
+static inline int hinic5_test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = (1UL << nr);
+
+ return (int)(__sync_fetch_and_or(addr, mask) & mask);
+}
+
+#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
+#define CLOCK_TYPE CLOCK_MONOTONIC_RAW
+#else
+#define CLOCK_TYPE CLOCK_MONOTONIC
+#endif
+
+#define HINIC5_MUTEX_TIMEOUT 10
+#define HINIC5_S_TO_MS_UNIT 1000
+#define HINIC5_MS_TO_US_UNIT 1000
+
+#define msecs_to_jiffies(ms) (ms)
+
+/**
+ * Convert data to big endian 32 bit format
+ *
+ * @param data
+ * The data to convert
+ * @param len
+ * Length of data to convert, must be Multiple of 4B
+ */
+static inline void hinic5_cpu_to_be32(void *data, int len)
+{
+ int i, chunk_sz = sizeof(u32);
+ u32 *mem = data;
+
+ if (!data)
+ return;
+
+ len = len / chunk_sz;
+
+ for (i = 0; i < len; i++) {
+ *mem = cpu_to_be32(*mem);
+ mem++;
+ }
+}
+
+/**
+ * Convert data from big endian 32 bit format
+ *
+ * @param data
+ * The data to convert
+ * @param len
+ * Length of data to convert, must be Multiple of 4B
+ */
+static inline void hinic5_be32_to_cpu(void *data, int len)
+{
+ int i, chunk_sz = sizeof(u32);
+ u32 *mem = data;
+
+ if (!data)
+ return;
+
+ len = len / chunk_sz;
+
+ for (i = 0; i < len; i++) {
+ *mem = be32_to_cpu(*mem);
+ mem++;
+ }
+}
+
+static inline u16 ilog2(u32 n)
+{
+ u16 res = 0;
+
+ while (n > 1) {
+ n >>= 1;
+ res++;
+ }
+
+ return res;
+}
+
+#endif /* _HINIC5_COMPAT_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_csr.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_csr.h
new file mode 100644
index 000000000..a6205f435
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_csr.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_CSR_H_
+#define _HINIC5_CSR_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define PCI_VENDOR_ID_HUAWEI 0x19e5
+#define HINIC5_DEV_ID_STANDARD 0x0222
+#define HINIC5_DEV_ID_STANDARD_1825 0x0230
+#define HINIC5_DEV_ID_STANDARD_1872 0x0229
+#define HINIC5_DEV_ID_VF 0x375F
+
+/*
+ * Bit30/bit31 for bar index flag
+ * 00: bar0
+ * 01: bar1
+ * 10: bar2
+ * 11: bar3
+ */
+#define HINIC5_CFG_REGS_FLAG 0x40000000
+
+#define HINIC5_MGMT_REGS_FLAG 0xC0000000
+
+#define HINIC5_REGS_FLAG_MASK 0x3FFFFFFF
+
+#define HINIC5_HOST_CSR_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x6000)
+
+/* 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_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_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_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)
+
+/* EQ registers */
+#define HINIC5_AEQ_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x210)
+
+#define HINIC5_AEQ_MTT_OFF_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x240)
+
+#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_LO_PHYS_ADDR_REG(pg_num) \
+ (HINIC5_AEQ_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_OPTION_ROM_EN_ADDR_1872 (HINIC5_MGMT_REGS_FLAG + 0xdf40)
+#define HINIC5_CSR_OPTION_ROM_EN_ADDR_1825 (HINIC5_MGMT_REGS_FLAG + 0xf750)
+
+#define HINIC5_IS_1872_DEV(device_id) \
+ ((device_id) == HINIC5_DEV_ID_STANDARD_1872)
+
+#define HINIC5_IS_1825_DEV(device_id) \
+ ((device_id) == HINIC5_DEV_ID_STANDARD_1825)
+
+#define HINIC5_PXE_REG_ADDR(device_id) \
+ (HINIC5_IS_1872_DEV(device_id) ? \
+ HINIC5_CSR_OPTION_ROM_EN_ADDR_1872 : \
+ HINIC5_IS_1825_DEV(device_id) ? \
+ HINIC5_CSR_OPTION_ROM_EN_ADDR_1825 : \
+ HINIC5_CSR_OPTION_ROM_EN_ADDR_1825) /* By default, use the 1825 address. */
+
+#endif /* _HINIC5_CSR_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_enhance_cmdq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_enhance_cmdq.c
new file mode 100644
index 000000000..78dd06f22
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_enhance_cmdq.c
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#include "hinic5_compat.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_hwif.h"
+#include "hinic5_wq.h"
+#include "hinic5_cmd.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_cmdq.h"
+
+void enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdq *cmdq)
+{
+ struct enhance_cmdq_ctxt_info *ctxt_info = &cmdq->cmdq_enhance_ctxt;
+ struct hinic5_wq *wq = cmdq->wq;
+ u64 cmdq_first_block_paddr, pfn;
+ u16 start_ci = (u16)wq->cons_idx;
+ u32 start_pi = (u16)wq->prod_idx;
+
+ /* The data in the HW is in Big Endian Format */
+ cmdq_first_block_paddr = wq->queue_buf_paddr;
+ pfn = CMDQ_PFN(cmdq_first_block_paddr, HINIC5_PGSIZE_4K);
+
+ /* first part 16B */
+ ctxt_info->eq_cfg = ENHANCED_CMDQ_SET(pfn, CTXT0_CI_WQE_ADDR) |
+ ENHANCED_CMDQ_SET(0, CTXT0_EQ) |
+ ENHANCED_CMDQ_SET(0, CTXT0_CEQ_ARM) |
+ ENHANCED_CMDQ_SET(0, CTXT0_CEQ_EN) |
+ 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);
+
+ /* second part 16B */
+ ctxt_info->pft_thd =
+ ENHANCED_CMDQ_SET(CI_HIGN_IDX(start_ci), CTXT2_PFT_CI) |
+ ENHANCED_CMDQ_SET(1, CTXT2_O_BIT) |
+ 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);
+
+ /* third part 16B */
+ pfn = WQ_BLOCK_PFN(cmdq_first_block_paddr);
+
+ ctxt_info->ci_cla_addr = ENHANCED_CMDQ_SET(pfn, CTXT4_CI_CLA_ADDR);
+}
+
+static void
+enhance_cmdq_set_completion(struct 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);
+ completion->sge_resp_len = HINIC5_CMDQ_BUF_SIZE;
+}
+
+void enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe,
+ enum cmdq_cmd_type cmd_type,
+ const struct hinic5_cmd_buf *buf_in,
+ const struct hinic5_cmd_buf *buf_out, int wrapped,
+ u8 mod, u8 cmd)
+{
+ struct enhanced_cmdq_wqe *enhanced_wqe = &wqe->enhanced_cmdq_wqe;
+
+ enhanced_wqe->ctrl_sec.header =
+ ENHANCE_CMDQ_WQE_HEADER_SET(buf_in->size, SEND_SGE_LEN) |
+ ENHANCE_CMDQ_WQE_HEADER_SET(1, BDSL) | /* now only one sge */
+ 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(buf_in->dma_addr);
+ enhanced_wqe->ctrl_sec.sge_send_lo_addr =
+ lower_32_bits(buf_in->dma_addr);
+
+ enhanced_wqe->completion.cs_format =
+ ENHANCE_CMDQ_WQE_CS_SET(cmd, CMD) |
+ ENHANCE_CMDQ_WQE_CS_SET(HINIC5_ACK_TYPE_CMDQ, ACK_TYPE) |
+ ENHANCE_CMDQ_WQE_CS_SET(mod, MOD);
+ switch (cmd_type) {
+ case SYNC_CMD_DIRECT_RESP:
+ enhanced_wqe->completion.cs_format |=
+ ENHANCE_CMDQ_WQE_CS_SET(INLINE_DATA, CF);
+ break;
+ case SYNC_CMD_SGE_RESP:
+ if (buf_out) {
+ enhanced_wqe->completion.cs_format |=
+ ENHANCE_CMDQ_WQE_CS_SET(SGE_RESPONSE, CF);
+ enhance_cmdq_set_completion(&enhanced_wqe->completion,
+ buf_out);
+ }
+ break;
+ case ASYNC_CMD: /* TODO need adapt buf_in free */
+ break;
+ }
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.c
new file mode 100644
index 000000000..c3ec5068d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.c
@@ -0,0 +1,665 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <ipxe/io.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_hwif.h"
+#include "hinic5_csr.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_mbox.h"
+#include "hinic5_eqs.h"
+
+#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_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_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_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 HINIC5_EQ_PROD_IDX_MASK 0xFFFFF
+#define HINIC5_TASK_PROCESS_EQE_LIMIT 1024
+#define HINIC5_EQ_UPDATE_CI_STEP 64
+
+#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_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_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_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 GET_EQ_NUM_PAGES(eq, size) \
+ ((u16)(HINIC5_ALIGN((u32)((eq)->eq_len * (eq)->elem_size), (size)) / \
+ (size)))
+
+#define GET_EQ_NUM_ELEMS(eq, pg_size) ((pg_size) / (u32)(eq)->elem_size)
+
+#define GET_EQ_ELEMENT(eq, idx) \
+ (((u8 *)(eq)->virt_addr[(idx) / (eq)->num_elem_in_pg]) + \
+ (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_CURR_AEQ_ELEM(eq) GET_AEQ_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 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 EQ_WRAPPED_SHIFT 20
+
+#define EQ_VALID_SHIFT 31
+
+#define aeq_to_aeqs(eq) \
+ container_of((eq) - (eq)->q_id, struct hinic5_aeqs, aeq[0])
+
+#define AEQ_MSIX_ENTRY_IDX_0 0
+
+#define AEQ_POLL_WAIT_USEC_1000 1000
+
+/**
+ * Write the cons idx to hw
+ *
+ * @param[in] eq
+ * The event queue to update the cons idx
+ * @param[in] arm_state
+ * Indicate whether report interrupts when generate eq element
+ */
+static void set_eq_cons_idx(struct hinic5_eq *eq, u32 arm_state)
+{
+ u32 eq_wrap_ci = 0;
+ u32 val = 0;
+ u32 addr = HINIC5_CSR_AEQ_CI_SIMPLE_INDIR_ADDR;
+
+ eq_wrap_ci = EQ_CONS_IDX(eq);
+
+ /* dpdk pmd driver only aeq0 use int_arm mode */
+ if (eq->q_id != 0) {
+ val = EQ_CI_SIMPLE_INDIR_SET(HINIC5_EQ_NOT_ARMED, ARMED);
+ } else {
+ val = EQ_CI_SIMPLE_INDIR_SET(arm_state, ARMED);
+ }
+
+ val = val | EQ_CI_SIMPLE_INDIR_SET(eq_wrap_ci, CI) |
+ EQ_CI_SIMPLE_INDIR_SET(eq->q_id, AEQ_IDX);
+
+ hinic5_hwif_write_reg(eq->hwdev->hwif, addr, val);
+}
+
+/**
+ * Set aeq's ctrls registers
+ *
+ * @param[in] eq
+ * The event queue for setting
+ */
+static void set_aeq_ctrls(struct hinic5_eq *eq)
+{
+ struct hinic5_hwif *hwif = eq->hwdev->hwif;
+ struct irq_info *eq_irq = &eq->eq_irq;
+ u32 addr, val, ctrl0, ctrl1, page_size_val, elem_size;
+ u32 pci_intf_idx = HINIC5_PCI_INTF_IDX(hwif);
+
+ /* Set ctrl0 */
+ addr = HINIC5_CSR_AEQ_CTRL_0_ADDR;
+
+ 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);
+
+ ctrl0 = AEQ_CTRL_0_SET(eq_irq->msix_entry_idx, INTR_IDX) |
+ AEQ_CTRL_0_SET(AEQ_DMA_ATTR_DEFAULT, DMA_ATTR) |
+ AEQ_CTRL_0_SET(pci_intf_idx, PCI_INTF_IDX) |
+ AEQ_CTRL_0_SET(HINIC5_INTR_MODE_ARMED, INTR_MODE);
+
+ val |= ctrl0;
+
+ hinic5_hwif_write_reg(hwif, addr, val);
+
+ /* Set ctrl1 */
+ addr = HINIC5_CSR_AEQ_CTRL_1_ADDR;
+
+ 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) |
+ AEQ_CTRL_1_SET(page_size_val, PAGE_SIZE);
+
+ hinic5_hwif_write_reg(hwif, addr, ctrl1);
+}
+
+/**
+ * Initialize all the elements in the aeq
+ *
+ * @param[in] eq
+ * The event queue
+ * @param[in] init_val
+ * Value to init
+ */
+static void aeq_elements_init(struct hinic5_eq *eq, u32 init_val)
+{
+ struct hinic5_aeq_elem *aeqe = NULL;
+ u32 i;
+
+ for (i = 0; i < eq->eq_len; i++) {
+ aeqe = GET_AEQ_ELEM(eq, i);
+ aeqe->desc = cpu_to_be32(init_val);
+ }
+
+ mb(); /* Write the init values */
+}
+
+static int set_eq_pages(struct hinic5_eq *eq)
+{
+ struct hinic5_hwif *hwif = eq->hwdev->hwif;
+ u32 reg, init_val;
+ u16 pg_num, i;
+ int err;
+
+ for (pg_num = 0; pg_num < eq->num_pages; pg_num++) {
+ eq->eq_mz[pg_num] =
+ hinic5_dma_alloc(eq->page_size, eq->page_size);
+ if (!eq->eq_mz[pg_num]) {
+ err = -ENOMEM;
+ goto dma_alloc_err;
+ }
+
+ eq->dma_addr[pg_num] = eq->eq_mz[pg_num]->phys_addr;
+ eq->virt_addr[pg_num] = eq->eq_mz[pg_num]->virt_addr;
+
+ reg = HINIC5_AEQ_HI_PHYS_ADDR_REG(pg_num);
+ hinic5_hwif_write_reg(hwif, reg,
+ upper_32_bits(eq->dma_addr[pg_num]));
+
+ reg = HINIC5_AEQ_LO_PHYS_ADDR_REG(pg_num);
+ hinic5_hwif_write_reg(hwif, reg,
+ lower_32_bits(eq->dma_addr[pg_num]));
+ }
+
+ 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) {
+ IPXE_DRV_LOG(ERR, "Number element in eq page != power of 2");
+ err = -EINVAL;
+ goto dma_alloc_err;
+ }
+ init_val = EQ_WRAPPED(eq);
+
+ aeq_elements_init(eq, init_val);
+
+ return 0;
+
+dma_alloc_err:
+ for (i = 0; i < pg_num; i++) {
+ hinic5_dma_free(eq->eq_mz[i]);
+ }
+
+ return err;
+}
+
+/**
+ * Allocate the pages for the queue
+ *
+ * @param[in] eq
+ * The event queue
+ *
+ * @retval zero : Success
+ * @retval negative : Failure.
+ */
+static int alloc_eq_pages(struct hinic5_eq *eq)
+{
+ u64 dma_addr_size, virt_addr_size, eq_mz_size;
+ int err;
+
+ dma_addr_size = eq->num_pages * sizeof(*eq->dma_addr);
+ virt_addr_size = eq->num_pages * sizeof(*eq->virt_addr);
+ eq_mz_size = eq->num_pages * sizeof(*eq->eq_mz);
+
+ eq->dma_addr = (u64 *)zalloc(dma_addr_size);
+ if (!eq->dma_addr) {
+ return -ENOMEM;
+ }
+
+ eq->virt_addr = (u8 **)zalloc(virt_addr_size);
+ if (!eq->virt_addr) {
+ err = -ENOMEM;
+ goto virt_addr_alloc_err;
+ }
+
+ eq->eq_mz = (const struct hinic5_page_addr **)zalloc(eq_mz_size);
+ if (!eq->eq_mz) {
+ err = -ENOMEM;
+ goto eq_mz_alloc_err;
+ }
+ err = set_eq_pages(eq);
+ if (err != 0) {
+ goto eq_pages_err;
+ }
+
+ return 0;
+
+eq_pages_err:
+ free(eq->eq_mz);
+
+eq_mz_alloc_err:
+ free(eq->virt_addr);
+
+virt_addr_alloc_err:
+ free(eq->dma_addr);
+
+ return err;
+}
+
+/**
+ * Free the pages of the queue
+ *
+ * @param[in] eq
+ * The event queue
+ */
+static void free_eq_pages(struct hinic5_eq *eq)
+{
+ u16 pg_num;
+
+ for (pg_num = 0; pg_num < eq->num_pages; pg_num++) {
+ hinic5_dma_free(eq->eq_mz[pg_num]);
+ }
+
+ free(eq->eq_mz);
+ free(eq->virt_addr);
+ free(eq->dma_addr);
+}
+
+static u32 get_page_size(struct hinic5_eq *eq)
+{
+ u32 total_size;
+ u16 count, n = 0;
+
+ total_size = HINIC5_ALIGN((eq->eq_len * eq->elem_size),
+ HINIC5_MIN_EQ_PAGE_SIZE);
+ if (total_size <= (HINIC5_EQ_MAX_PAGES * HINIC5_MIN_EQ_PAGE_SIZE)) {
+ return HINIC5_MIN_EQ_PAGE_SIZE;
+ }
+
+ count = (u16)(HINIC5_ALIGN((total_size / HINIC5_EQ_MAX_PAGES),
+ HINIC5_MIN_EQ_PAGE_SIZE) /
+ HINIC5_MIN_EQ_PAGE_SIZE);
+ if (!(count & (count - 1))) {
+ return HINIC5_MIN_EQ_PAGE_SIZE * count;
+ }
+
+ while (count != 0) {
+ count >>= 1;
+ n++;
+ }
+
+ return ((u32)HINIC5_MIN_EQ_PAGE_SIZE) << n;
+}
+
+/**
+ * Initialize aeq
+ *
+ * @param[in] eq
+ * The event queue
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ * @param[in] q_id
+ * Queue id number
+ * @param[in] q_len
+ * The number of EQ elements
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure.
+ */
+static int init_aeq(struct hinic5_eq *eq, struct hinic5_hwdev *hwdev, u16 q_id,
+ u32 q_len)
+{
+ int err = 0;
+
+ eq->hwdev = hwdev;
+ eq->q_id = q_id;
+ eq->eq_len = q_len;
+
+ /* Indirect access should set q_id first */
+ hinic5_hwif_write_reg(hwdev->hwif, HINIC5_AEQ_INDIR_IDX_ADDR, eq->q_id);
+ mb(); /* write index before config */
+
+ /* Clear eq_len to force eqe drop in hardware */
+ hinic5_hwif_write_reg(eq->hwdev->hwif, HINIC5_CSR_AEQ_CTRL_1_ADDR, 0);
+ mb();
+ /* Init aeq pi to 0 before allocating aeq pages */
+ hinic5_hwif_write_reg(eq->hwdev->hwif, HINIC5_CSR_AEQ_PROD_IDX_ADDR, 0);
+
+ eq->cons_idx = 0;
+ eq->wrapped = 0;
+
+ eq->elem_size = HINIC5_AEQE_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) {
+ IPXE_DRV_LOG(ERR, "Too many pages: %d for aeq", eq->num_pages);
+ return -EINVAL;
+ }
+
+ err = alloc_eq_pages(eq);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Allocate pages for eq failed");
+ return err;
+ }
+
+ /* Pmd driver uses AEQ_MSIX_ENTRY_IDX_0 */
+ eq->eq_irq.msix_entry_idx = AEQ_MSIX_ENTRY_IDX_0;
+ set_aeq_ctrls(eq);
+
+ set_eq_cons_idx(eq, HINIC5_EQ_ARMED);
+
+ if (eq->q_id == 0) {
+ hinic5_set_msix_state(hwdev, 0, HINIC5_MSIX_ENABLE);
+ }
+
+ eq->poll_retry_nr = HINIC5_RETRY_NUM;
+
+ return 0;
+}
+
+/**
+ * Remove aeq
+ *
+ * @param[in] eq
+ * The event queue
+ */
+static void remove_aeq(struct hinic5_eq *eq)
+{
+ struct irq_info *entry = &eq->eq_irq;
+
+ if (eq->q_id == 0) {
+ hinic5_set_msix_state(eq->hwdev, entry->msix_entry_idx,
+ HINIC5_MSIX_DISABLE);
+ }
+
+ /* Indirect access should set q_id first */
+ hinic5_hwif_write_reg(eq->hwdev->hwif, HINIC5_AEQ_INDIR_IDX_ADDR,
+ eq->q_id);
+
+ mb(); /* Write index before config */
+
+ /* Clear eq_len to avoid hw access host memory */
+ hinic5_hwif_write_reg(eq->hwdev->hwif, HINIC5_CSR_AEQ_CTRL_1_ADDR, 0);
+
+ /* Update cons_idx to avoid invalid interrupt */
+ eq->cons_idx = hinic5_hwif_read_reg(eq->hwdev->hwif,
+ HINIC5_CSR_AEQ_PROD_IDX_ADDR);
+ set_eq_cons_idx(eq, HINIC5_EQ_NOT_ARMED);
+
+ free_eq_pages(eq);
+}
+
+/**
+ * Init all aeqs
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure.
+ */
+int hinic5_aeqs_init(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_aeqs *aeqs = NULL;
+ u16 num_aeqs;
+ int err;
+ u16 i, q_id;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ num_aeqs = HINIC5_HWIF_NUM_AEQS(hwdev->hwif);
+ if (num_aeqs > HINIC5_MAX_AEQS) {
+ IPXE_DRV_LOG(INFO, "Adjust aeq num to %d", HINIC5_MAX_AEQS);
+ num_aeqs = HINIC5_MAX_AEQS;
+ } else if (num_aeqs < HINIC5_MIN_AEQS) {
+ IPXE_DRV_LOG(ERR, "PMD needs %d AEQs, Chip has %d",
+ HINIC5_MIN_AEQS, num_aeqs);
+ return -EINVAL;
+ }
+ num_aeqs = HINIC5_MIN_AEQS;
+ aeqs = (struct hinic5_aeqs *)zalloc(sizeof(*aeqs));
+ if (!aeqs) {
+ return -ENOMEM;
+ }
+
+ hwdev->aeqs = aeqs;
+ aeqs->hwdev = hwdev;
+ aeqs->num_aeqs = num_aeqs;
+
+ for (q_id = 0; q_id < num_aeqs; q_id++) {
+ err = init_aeq(&aeqs->aeq[q_id], hwdev, q_id,
+ HINIC5_DEFAULT_AEQ_LEN);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init aeq %d failed", q_id);
+ goto init_aeq_err;
+ }
+ }
+
+ return 0;
+
+init_aeq_err:
+ for (i = 0; i < q_id; i++) {
+ remove_aeq(&aeqs->aeq[i]);
+ }
+
+ free(aeqs);
+ return err;
+}
+
+/**
+ * Free all aeqs
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ */
+void hinic5_aeqs_free(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_aeqs *aeqs = hwdev->aeqs;
+ u16 q_id;
+
+ for (q_id = 0; q_id < aeqs->num_aeqs; q_id++) {
+ remove_aeq(&aeqs->aeq[q_id]);
+ }
+
+ free(aeqs);
+}
+
+static int aeq_elem_handler(struct hinic5_eq *eq, u32 aeqe_desc,
+ struct hinic5_aeq_elem *aeqe_pos, void *param)
+{
+ enum hinic5_aeq_type event;
+ u8 data[HINIC5_AEQE_DATA_SIZE];
+ u8 size;
+
+ event = EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
+ if (EQ_ELEM_DESC_GET(aeqe_desc, SRC) != 0) {
+ /* SW event uses only the first 8B */
+ if (memcpy_s(data, HINIC5_AEQE_DATA_SIZE, aeqe_pos->aeqe_data,
+ HINIC5_AEQE_DATA_SIZE) != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to memcpy");
+ return -ENOMEM;
+ }
+ hinic5_be32_to_cpu(data, HINIC5_AEQE_DATA_SIZE);
+
+ IPXE_DRV_LOG(
+ ERR,
+ "Received ucode aeq event type: 0x%x, data: 0x%llx",
+ event, *((u64 *)data));
+ return 0;
+ }
+
+ if (memcpy_s(data, HINIC5_AEQE_DATA_SIZE, aeqe_pos->aeqe_data,
+ HINIC5_AEQE_DATA_SIZE) != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to memcpy to aeqe_data");
+ return -ENOMEM;
+ }
+ hinic5_be32_to_cpu(data, HINIC5_AEQE_DATA_SIZE);
+ size = EQ_ELEM_DESC_GET(aeqe_desc, SIZE);
+
+ if (event == HINIC5_MSG_FROM_MGMT_CPU) {
+ return hinic5_mgmt_msg_aeqe_handler(
+ eq->hwdev, data, size, param, HINIC5_AEQE_DATA_SIZE);
+ } else if (event == HINIC5_MBX_FROM_FUNC) {
+ return hinic5_mbox_func_aeqe_handler(
+ eq->hwdev, data, size, param, HINIC5_AEQE_DATA_SIZE);
+ } else {
+ IPXE_DRV_LOG(ERR, "AEQ hw event not support %d", event);
+ return -EINVAL;
+ }
+}
+
+/**
+ * Poll one or continue aeqe, and call dedicated process
+ *
+ * @param[in] eq
+ * The event queue
+ * @param[in] timeout
+ * 0 - Poll all aeqe in eq, used in interrupt mode,
+ * > 0 - Poll aeq until get aeqe with 'last' field set to 1,
+ * used in polling mode.
+ * @param[in] param
+ * Customized parameter
+ *
+ * @retval zero : Success
+ * @retval -EIO : Poll timeout
+ * @retval -ENODEV : Swe not support
+ */
+int hinic5_aeq_poll_msg(struct hinic5_eq *eq, u32 timeout, void *param)
+{
+ struct hinic5_aeq_elem *aeqe_pos = NULL;
+ u32 aeqe_desc = 0;
+ u32 eqe_cnt = 0;
+ int err = -EFAULT;
+ int done = HINIC5_MSG_HANDLER_RES;
+ unsigned long cnt = 0;
+ u16 i;
+
+ for (i = 0; ((timeout == 0) && (i < eq->eq_len)) ||
+ ((timeout > 0) && (done != 0) && (i < eq->eq_len));
+ i++) {
+ err = -EIO;
+ do {
+ aeqe_pos = GET_CURR_AEQ_ELEM(eq);
+ mb();
+
+ /* Data in HW is in Big endian Format */
+ aeqe_desc = be32_to_cpu(aeqe_pos->desc);
+
+ /*
+ * HW updates wrapped bit,
+ * when it adds eq element event
+ */
+ if (EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) !=
+ eq->wrapped) {
+ err = 0;
+ break;
+ }
+
+ if (timeout != 0) {
+ usleep(AEQ_POLL_WAIT_USEC_1000);
+ }
+
+ ++cnt;
+ } while (cnt < timeout);
+
+ /* Poll time out */
+ if (err != 0) {
+ break;
+ }
+
+ done = aeq_elem_handler(eq, aeqe_desc, aeqe_pos, param);
+
+ eq->cons_idx++;
+ if (eq->cons_idx == eq->eq_len) {
+ eq->cons_idx = 0;
+ eq->wrapped = !eq->wrapped;
+ }
+
+ if (++eqe_cnt >= HINIC5_EQ_UPDATE_CI_STEP) {
+ eqe_cnt = 0;
+ set_eq_cons_idx(eq, HINIC5_EQ_NOT_ARMED);
+ }
+ }
+
+ set_eq_cons_idx(eq, HINIC5_EQ_ARMED);
+
+ return err;
+}
+
+void hinic5_dev_handle_aeq_event(struct hinic5_hwdev *hwdev, void *param)
+{
+ struct hinic5_eq *aeq = &hwdev->aeqs->aeq[0];
+
+ (void)hinic5_aeq_poll_msg(aeq, 0, param);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.h
new file mode 100644
index 000000000..f3dadf594
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_eqs.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_EQS_H_
+#define _HINIC5_EQS_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define HINIC5_MAX_AEQS 4
+#define HINIC5_MIN_AEQS 2
+#define HINIC5_EQ_MAX_PAGES 4
+
+#define HINIC5_AEQE_SIZE 64
+
+#define HINIC5_AEQE_DESC_SIZE 4
+#define HINIC5_AEQE_DATA_SIZE (HINIC5_AEQE_SIZE - HINIC5_AEQE_DESC_SIZE)
+
+/* Linux is 1K, dpdk is 64 */
+#define HINIC5_DEFAULT_AEQ_LEN 64
+
+#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 \
+ ((HINIC5_MAX_EQ_PAGE_SIZE / HINIC5_AEQE_SIZE) * HINIC5_EQ_MAX_PAGES)
+
+#define EQ_IRQ_NAME_LEN 64
+
+enum hinic5_eq_intr_mode { HINIC5_INTR_MODE_ARMED, HINIC5_INTR_MODE_ALWAYS };
+
+enum hinic5_eq_ci_arm_state { HINIC5_EQ_NOT_ARMED, HINIC5_EQ_ARMED };
+
+struct irq_info {
+ u16 msix_entry_idx; /* IRQ corresponding index number */
+ u32 irq_id; /* The IRQ number from OS */
+};
+
+#define HINIC5_RETRY_NUM 10
+
+enum hinic5_aeq_type {
+ HINIC5_HW_INTER_INT = 0,
+ HINIC5_MBX_FROM_FUNC = 1,
+ HINIC5_MSG_FROM_MGMT_CPU = 2,
+ HINIC5_API_RSP = 3,
+ HINIC5_API_CHAIN_STS = 4,
+ HINIC5_MBX_SEND_RSLT = 5,
+ HINIC5_MAX_AEQ_EVENTS
+};
+
+struct hinic5_eq {
+ struct hinic5_hwdev *hwdev;
+ u16 q_id;
+ u32 page_size;
+ u32 orig_page_size;
+ u32 eq_len;
+
+ u32 cons_idx;
+ u16 wrapped;
+
+ u16 elem_size;
+ u16 num_pages;
+ u32 num_elem_in_pg;
+
+ struct irq_info eq_irq;
+
+ const struct hinic5_page_addr **eq_mz;
+ u64 *dma_addr;
+ u8 **virt_addr;
+
+ u16 poll_retry_nr;
+};
+
+struct hinic5_aeq_elem {
+ u8 aeqe_data[HINIC5_AEQE_DATA_SIZE];
+ u32 desc;
+};
+
+struct hinic5_aeqs {
+ struct hinic5_hwdev *hwdev;
+
+ struct hinic5_eq aeq[HINIC5_MAX_AEQS];
+ u16 num_aeqs;
+};
+
+int hinic5_aeqs_init(struct hinic5_hwdev *hwdev);
+
+void hinic5_aeqs_free(struct hinic5_hwdev *hwdev);
+
+int hinic5_aeq_poll_msg(struct hinic5_eq *eq, u32 timeout, void *param);
+
+void hinic5_dev_handle_aeq_event(struct hinic5_hwdev *hwdev, void *param);
+
+#endif /* _HINIC5_EQS_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.c
new file mode 100644
index 000000000..b2087fc71
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.c
@@ -0,0 +1,228 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_mbox.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_hwif.h"
+#include "hinic5_hw_cfg.h"
+
+static void parse_pub_res_cap(struct service_cap *cap,
+ struct hinic5_cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ cap->host_id = dev_cap->host_id;
+ cap->ep_id = dev_cap->ep_id;
+ cap->er_id = dev_cap->er_id;
+ cap->port_id = dev_cap->port_id;
+
+ cap->svc_type = dev_cap->svc_cap_en;
+ cap->chip_svc_type = cap->svc_type;
+
+ cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap;
+ cap->flexq_en = dev_cap->flexq_en;
+
+ cap->host_total_function = dev_cap->host_total_func;
+ cap->max_vf = 0;
+ if (type == TYPE_PF || type == TYPE_PPF) {
+ cap->max_vf = dev_cap->max_vf;
+ cap->pf_num = dev_cap->host_pf_num;
+ cap->pf_id_start = dev_cap->pf_id_start;
+ cap->vf_num = dev_cap->host_vf_num;
+ cap->vf_id_start = dev_cap->vf_id_start;
+ }
+
+ IPXE_DRV_LOG(INFO, "Get public resource capability: ");
+ IPXE_DRV_LOG(INFO,
+ "host_id: 0x%x, ep_id: 0x%x, er_id: 0x%x, "
+ "port_id: 0x%x",
+ cap->host_id, cap->ep_id, cap->er_id, cap->port_id);
+ IPXE_DRV_LOG(INFO, "host_total_function: 0x%x, max_vf: 0x%x",
+ cap->host_total_function, cap->max_vf);
+ IPXE_DRV_LOG(
+ INFO,
+ "host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x",
+ cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
+}
+
+static void parse_l2nic_res_cap(struct service_cap *cap,
+ struct hinic5_cfg_cmd_dev_cap *dev_cap)
+{
+ struct nic_service_cap *nic_cap = &cap->nic_cap;
+
+ nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
+ nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
+
+ IPXE_DRV_LOG(INFO,
+ "L2nic resource capbility, max_sqs: 0x%x, "
+ "max_rqs: 0x%x",
+ nic_cap->max_sqs, nic_cap->max_rqs);
+}
+
+static void parse_dev_cap(struct hinic5_hwdev *dev,
+ struct hinic5_cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct service_cap *cap = &dev->cfg_mgmt->svc_cap;
+
+ parse_pub_res_cap(cap, dev_cap, type);
+
+ if (IS_NIC_TYPE(dev) != 0) {
+ parse_l2nic_res_cap(cap, dev_cap);
+ }
+}
+
+static int get_cap_from_fw(struct hinic5_hwdev *hwdev, enum func_type type)
+{
+ struct hinic5_cfg_cmd_dev_cap dev_cap;
+ u16 out_len = sizeof(dev_cap);
+ int err;
+
+ (void)memset_s(&dev_cap, sizeof(dev_cap), 0, sizeof(dev_cap));
+ dev_cap.func_id = hinic5_global_func_id(hwdev);
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFGM,
+ HINIC5_CFG_CMD_GET_DEV_CAP, &dev_cap,
+ sizeof(dev_cap), &dev_cap, &out_len, 0);
+ if (err || dev_cap.status || !out_len) {
+ IPXE_DRV_LOG(ERR,
+ "Get capability from FW failed, err: %d, "
+ "status: 0x%x, out size: 0x%x",
+ err, dev_cap.status, out_len);
+ return -EFAULT;
+ }
+
+ parse_dev_cap(hwdev, &dev_cap, type);
+ return 0;
+}
+
+static int get_dev_cap(struct hinic5_hwdev *hwdev)
+{
+ enum func_type type = HINIC5_FUNC_TYPE(hwdev);
+
+ switch (type) {
+ case TYPE_PF:
+ case TYPE_PPF:
+ case TYPE_VF:
+ if (get_cap_from_fw(hwdev, type) != 0) {
+ return -EFAULT;
+ }
+ break;
+ default:
+ IPXE_DRV_LOG(ERR, "Unsupported PCIe function type: %d", type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int cfg_mbx_vf_proc_msg(void *hwdev, __attribute__((unused)) void *pri_handle,
+ u16 cmd, __attribute__((unused)) void *buf_in,
+ __attribute__((unused)) u16 in_size,
+ __attribute__((unused)) void *buf_out,
+ __attribute__((unused)) u16 *out_size)
+{
+ struct hinic5_hwdev *dev = hwdev;
+
+ if (!dev) {
+ return -EINVAL;
+ }
+
+ IPXE_DRV_LOG(WARN, "Unsupported cfg mbox vf event %d to process", cmd);
+
+ return 0;
+}
+
+int hinic5_init_cfg_mgmt(void *dev)
+{
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
+ struct cfg_mgmt_info *cfg_mgmt = NULL;
+
+ cfg_mgmt = (struct cfg_mgmt_info *)zalloc(sizeof(*cfg_mgmt));
+ if (!cfg_mgmt) {
+ return -ENOMEM;
+ }
+
+ hwdev->cfg_mgmt = cfg_mgmt;
+ cfg_mgmt->hwdev = hwdev;
+
+ return 0;
+}
+
+int hinic5_init_capability(void *dev)
+{
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
+
+ return get_dev_cap(hwdev);
+}
+
+void hinic5_deinit_cfg_mgmt(void *dev)
+{
+ free(((struct hinic5_hwdev *)dev)->cfg_mgmt);
+ ((struct hinic5_hwdev *)dev)->cfg_mgmt = NULL;
+}
+
+u16 hinic5_func_max_sqs(void *hwdev)
+{
+ struct hinic5_hwdev *dev = hwdev;
+
+ if (!dev) {
+ IPXE_DRV_LOG(INFO, "Hwdev is NULL for getting max_sqs");
+ return 0;
+ }
+
+ return dev->cfg_mgmt->svc_cap.nic_cap.max_sqs;
+}
+
+u16 hinic5_func_max_rqs(void *hwdev)
+{
+ struct hinic5_hwdev *dev = hwdev;
+
+ if (!dev) {
+ IPXE_DRV_LOG(INFO, "Hwdev is NULL for getting max_rqs");
+ return 0;
+ }
+
+ return dev->cfg_mgmt->svc_cap.nic_cap.max_rqs;
+}
+
+u8 hinic5_physical_port_id(void *hwdev)
+{
+ struct hinic5_hwdev *dev = hwdev;
+
+ if (!dev) {
+ IPXE_DRV_LOG(INFO,
+ "Hwdev is NULL for getting physical port id");
+ return 0;
+ }
+
+ return dev->cfg_mgmt->svc_cap.port_id;
+}
+
+bool hinic5_support_nic(void *hwdev, struct nic_service_cap *cap)
+{
+ struct hinic5_hwdev *dev = (struct hinic5_hwdev *)hwdev;
+
+ if (!hwdev) {
+ return false;
+ }
+
+ if (!IS_NIC_TYPE(dev)) {
+ return false;
+ }
+
+ if (cap) {
+ (void)memcpy_s(cap, sizeof(*cap),
+ &dev->cfg_mgmt->svc_cap.nic_cap, sizeof(*cap));
+ }
+
+ return true;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.h
new file mode 100644
index 000000000..f8383044f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_cfg.h
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_HW_CFG_H_
+#define _HINIC5_HW_CFG_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define CFG_MAX_CMD_TIMEOUT 30000 /* ms */
+
+#define K_UNIT BIT(10)
+#define M_UNIT BIT(20)
+#define G_UNIT BIT(30)
+
+/* Number of PFs and VFs */
+#define HOST_PF_NUM 4
+#define HOST_VF_NUM 0
+#define HOST_OQID_MASK_VAL 2
+
+#define L2NIC_SQ_DEPTH (4 * K_UNIT)
+#define L2NIC_RQ_DEPTH (4 * K_UNIT)
+
+enum intr_type { INTR_TYPE_MSIX, INTR_TYPE_MSI, INTR_TYPE_INT, INTR_TYPE_NONE };
+
+/* Service type relates define */
+enum cfg_svc_type_en { CFG_SVC_NIC_BIT0 = 1 };
+
+struct nic_service_cap {
+ u16 max_sqs;
+ u16 max_rqs;
+};
+
+/* Device capability */
+struct service_cap {
+ enum cfg_svc_type_en svc_type; /* User input service type */
+ enum cfg_svc_type_en chip_svc_type; /* HW supported service type */
+
+ u8 host_id;
+ u8 ep_id;
+ u8 er_id; /* PF/VF's ER */
+ u8 port_id; /* PF/VF's physical port */
+
+ u16 host_total_function;
+ u8 pf_num;
+ u8 pf_id_start;
+ u16 vf_num; /* max numbers of vf in current host */
+ u16 vf_id_start;
+
+ u8 flexq_en;
+ u8 cos_valid_bitmap;
+ u16 max_vf; /* max VF number that PF supported */
+
+ struct nic_service_cap nic_cap; /* NIC capability */
+};
+
+struct cfg_mgmt_info {
+ void *hwdev;
+ struct service_cap svc_cap;
+};
+
+enum hinic5_cfg_cmd {
+ HINIC5_CFG_CMD_GET_DEV_CAP = 0,
+};
+
+struct hinic5_cfg_cmd_dev_cap {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u16 rsvd1;
+
+ /* Public resource */
+ u8 host_id;
+ u8 ep_id;
+ u8 er_id;
+ u8 port_id;
+
+ u16 host_total_func;
+ u8 host_pf_num;
+ u8 pf_id_start;
+ u16 host_vf_num;
+ u16 vf_id_start;
+ u32 rsvd_host;
+
+ u16 svc_cap_en;
+ u16 max_vf;
+ u8 flexq_en;
+ u8 valid_cos_bitmap;
+ /* Reserved for func_valid_cos_bitmap */
+ u16 rsvd_cos;
+
+ u32 rsvd[11];
+
+ /* l2nic */
+ u16 nic_max_sq_id;
+ u16 nic_max_rq_id;
+ u32 rsvd_nic[3];
+
+ u32 rsvd_glb[60];
+};
+
+#define IS_NIC_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SVC_NIC_BIT0)
+
+int hinic5_init_capability(void *dev);
+int hinic5_init_cfg_mgmt(void *dev);
+void hinic5_deinit_cfg_mgmt(void *dev);
+
+u16 hinic5_func_max_sqs(void *hwdev);
+u16 hinic5_func_max_rqs(void *hwdev);
+
+u8 hinic5_physical_port_id(void *hwdev);
+
+bool hinic5_support_nic(void *hwdev, struct nic_service_cap *cap);
+
+int cfg_mbx_vf_proc_msg(void *hwdev, void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
+
+#endif /* _HINIC5_HW_CFG_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.c
new file mode 100644
index 000000000..8b26559ce
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.c
@@ -0,0 +1,459 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <string.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_hwif.h"
+#include "hinic5_wq.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_cmdq.h"
+#include "hinic5_cmd.h"
+#include "hinic5_hw_comm.h"
+
+#define DEFAULT_RX_BUF_SIZE ((u16)0xB)
+
+enum hinic5_rx_buf_size {
+ HINIC5_RX_BUF_SIZE_32B = 0x20,
+ HINIC5_RX_BUF_SIZE_64B = 0x40,
+ HINIC5_RX_BUF_SIZE_96B = 0x60,
+ HINIC5_RX_BUF_SIZE_128B = 0x80,
+ HINIC5_RX_BUF_SIZE_192B = 0xC0,
+ HINIC5_RX_BUF_SIZE_256B = 0x100,
+ HINIC5_RX_BUF_SIZE_384B = 0x180,
+ HINIC5_RX_BUF_SIZE_512B = 0x200,
+ HINIC5_RX_BUF_SIZE_768B = 0x300,
+ HINIC5_RX_BUF_SIZE_1K = 0x400,
+ HINIC5_RX_BUF_SIZE_1_5K = 0x600,
+ HINIC5_RX_BUF_SIZE_2K = 0x800,
+ HINIC5_RX_BUF_SIZE_3K = 0xC00,
+ HINIC5_RX_BUF_SIZE_4K = 0x1000,
+ HINIC5_RX_BUF_SIZE_8K = 0x2000,
+ HINIC5_RX_BUF_SIZE_16K = 0x4000,
+};
+
+const u32 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,
+};
+
+int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info)
+{
+ struct hinic5_hwdev *hwdev = dev;
+ struct hinic5_cmd_msix_config msix_cfg;
+ u16 out_size = sizeof(msix_cfg);
+ int err;
+
+ if (!hwdev || !info) {
+ return -EINVAL;
+ }
+
+ (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 = HINIC5_MGMT_CMD_OP_GET;
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_CFG_MSIX_CTRL_REG,
+ &msix_cfg, sizeof(msix_cfg), &msix_cfg,
+ &out_size, 0);
+ if (err || !out_size || msix_cfg.status) {
+ IPXE_DRV_LOG(ERR,
+ "Get interrupt config failed, err: %d, "
+ "status: 0x%x, out size: 0x%x",
+ err, msix_cfg.status, out_size);
+ return -EINVAL;
+ }
+
+ info->lli_credit_limit = msix_cfg.lli_credit_cnt;
+ info->lli_timer_cfg = msix_cfg.lli_timer_cnt;
+ info->pending_limit = msix_cfg.pending_cnt;
+ info->coalesce_timer_cfg = msix_cfg.coalesct_timer_cnt;
+ info->resend_timer_cfg = msix_cfg.resend_timer_cnt;
+
+ return 0;
+}
+
+/**
+ * Set interrupt cfg
+ *
+ * @param[in] dev
+ * The pointer to the private hardware device object
+ * @param[in] info
+ * Interrupt info
+ *
+ * @retval zero : Success
+ * @retval negative : Failure.
+ */
+int hinic5_set_interrupt_cfg(void *dev, struct interrupt_info info)
+{
+ struct hinic5_hwdev *hwdev = dev;
+ struct hinic5_cmd_msix_config msix_cfg;
+ struct interrupt_info temp_info;
+ u16 out_size = sizeof(msix_cfg);
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ temp_info.msix_index = info.msix_index;
+ err = hinic5_get_interrupt_cfg(hwdev, &temp_info);
+ if (err != 0) {
+ return -EIO;
+ }
+
+ (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 = (u16)info.msix_index;
+ msix_cfg.opcode = HINIC5_MGMT_CMD_OP_SET;
+
+ msix_cfg.lli_credit_cnt = temp_info.lli_credit_limit;
+ msix_cfg.lli_timer_cnt = temp_info.lli_timer_cfg;
+ msix_cfg.pending_cnt = temp_info.pending_limit;
+ msix_cfg.coalesct_timer_cnt = temp_info.coalesce_timer_cfg;
+ msix_cfg.resend_timer_cnt = temp_info.resend_timer_cfg;
+
+ if (info.lli_set != 0) {
+ msix_cfg.lli_credit_cnt = info.lli_credit_limit;
+ msix_cfg.lli_timer_cnt = info.lli_timer_cfg;
+ }
+
+ if (info.interrupt_coalesc_set != 0) {
+ msix_cfg.pending_cnt = info.pending_limit;
+ msix_cfg.coalesct_timer_cnt = info.coalesce_timer_cfg;
+ msix_cfg.resend_timer_cnt = info.resend_timer_cfg;
+ }
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_CFG_MSIX_CTRL_REG,
+ &msix_cfg, sizeof(msix_cfg), &msix_cfg,
+ &out_size, 0);
+ if (err || !out_size || msix_cfg.status) {
+ IPXE_DRV_LOG(ERR,
+ "Set interrupt config failed, err: %d, "
+ "status: 0x%x, out size: 0x%x",
+ err, msix_cfg.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size)
+{
+ struct hinic5_cmd_wq_page_size page_size_info;
+ u16 out_size = sizeof(page_size_info);
+ int err;
+
+ (void)memset_s(&page_size_info, sizeof(page_size_info), 0,
+ sizeof(page_size_info));
+ page_size_info.func_idx = func_idx;
+ page_size_info.page_size = HINIC5_PAGE_SIZE_HW(page_size);
+ page_size_info.opcode = HINIC5_MGMT_CMD_OP_SET;
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_CFG_PAGESIZE,
+ &page_size_info, sizeof(page_size_info),
+ &page_size_info, &out_size, 0);
+ if (err || !out_size || page_size_info.status) {
+ IPXE_DRV_LOG(ERR,
+ "Set wq page size failed, err: %d, "
+ "status: 0x%x, out_size: 0x%0x",
+ err, page_size_info.status, out_size);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int hinic5_func_reset(void *hwdev, u64 reset_flag)
+{
+ struct hinic5_reset func_reset;
+ struct hinic5_hwif *hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+ u16 out_size = sizeof(func_reset);
+ int err = 0;
+
+ IPXE_DRV_LOG(INFO, "Function is reset");
+
+ (void)memset_s(&func_reset, sizeof(func_reset), 0, sizeof(func_reset));
+ func_reset.func_id = HINIC5_HWIF_GLOBAL_IDX(hwif);
+ func_reset.reset_flag = reset_flag;
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_FUNC_RESET, &func_reset,
+ sizeof(func_reset), &func_reset,
+ &out_size, 0);
+ if (err || !out_size || func_reset.status) {
+ IPXE_DRV_LOG(ERR,
+ "Reset func resources failed, err: %d, "
+ "status: 0x%x, out_size: 0x%x",
+ err, func_reset.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static u16 get_hw_rx_buf_size(void *hwdev, u32 rx_buf_sz)
+{
+ u16 num_hw_types = sizeof(hinic5_hw_rx_buf_size) /
+ sizeof(hinic5_hw_rx_buf_size[0]);
+ u16 i;
+
+ if (HINIC5_IS_USE_REAL_RX_BUF_SIZE(hwdev))
+ return rx_buf_sz;
+
+ for (i = 0; i < num_hw_types; i++) {
+ if (hinic5_hw_rx_buf_size[i] == rx_buf_sz) {
+ return i;
+ }
+ }
+
+ IPXE_DRV_LOG(WARN, "Chip can't support rx buf size of %d", rx_buf_sz);
+
+ return DEFAULT_RX_BUF_SIZE; /* Default 2K */
+}
+
+int hinic5_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz)
+{
+ struct hinic5_cmd_root_ctxt root_ctxt;
+ u16 out_size = sizeof(root_ctxt);
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&root_ctxt, sizeof(root_ctxt), 0, sizeof(root_ctxt));
+ root_ctxt.func_idx = hinic5_global_func_id(hwdev);
+ root_ctxt.set_cmdq_depth = 0;
+ root_ctxt.cmdq_depth = 0;
+ root_ctxt.lro_en = 1;
+ 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);
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_SET_VAT, &root_ctxt,
+ sizeof(root_ctxt), &root_ctxt, &out_size,
+ 0);
+ if (err || !out_size || root_ctxt.status) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Set root context failed, err: %d, status: 0x%x, out_size: 0x%x",
+ err, root_ctxt.status, out_size);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int hinic5_clean_root_ctxt(void *hwdev)
+{
+ struct hinic5_cmd_root_ctxt root_ctxt;
+ u16 out_size = sizeof(root_ctxt);
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&root_ctxt, sizeof(root_ctxt), 0, sizeof(root_ctxt));
+ root_ctxt.func_idx = hinic5_global_func_id(hwdev);
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_SET_VAT, &root_ctxt,
+ sizeof(root_ctxt), &root_ctxt, &out_size,
+ 0);
+ if (err || !out_size || root_ctxt.status) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Clean root context failed, err: %d, status: 0x%x, out_size: 0x%x",
+ err, root_ctxt.status, out_size);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int hinic5_set_cmdq_depth(void *hwdev, u16 cmdq_depth)
+{
+ struct hinic5_cmd_root_ctxt root_ctxt;
+ u16 out_size = sizeof(root_ctxt);
+ int err;
+
+ (void)memset_s(&root_ctxt, sizeof(root_ctxt), 0, sizeof(root_ctxt));
+ root_ctxt.func_idx = hinic5_global_func_id(hwdev);
+ root_ctxt.set_cmdq_depth = 1;
+ root_ctxt.cmdq_depth = (u8)ilog2(cmdq_depth);
+
+ if (((struct hinic5_hwdev *)hwdev)->cmdqs->cmdq_mode ==
+ HINIC5_ENHANCE_CMDQ)
+ root_ctxt.cmdq_depth--;
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_SET_VAT, &root_ctxt,
+ sizeof(root_ctxt), &root_ctxt, &out_size,
+ 0);
+ if (err || !out_size || root_ctxt.status) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Set cmdq depth failed, err: %d, status: 0x%x, out_size: 0x%x",
+ err, root_ctxt.status, out_size);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int hinic5_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len)
+{
+ struct hinic5_cmd_get_fw_version fw_ver;
+ u16 out_size = sizeof(fw_ver);
+ int err;
+
+ if (!hwdev || !mgmt_ver) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&fw_ver, sizeof(fw_ver), 0, sizeof(fw_ver));
+ fw_ver.fw_type = HINIC5_FW_VER_TYPE_MPU;
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_GET_FW_VERSION, &fw_ver,
+ sizeof(fw_ver), &fw_ver, &out_size, 0);
+ if (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, fw_ver.status)) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Get mgmt version failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, fw_ver.status, out_size);
+ return -EIO;
+ }
+
+ err = strcpy_s(mgmt_ver, max_mgmt_len, (char *)fw_ver.ver);
+ if (err != EOK) {
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic5_get_board_info(void *hwdev, struct hinic5_board_info *info)
+{
+ struct hinic5_cmd_board_info board_info;
+ u16 out_size = sizeof(board_info);
+ int err;
+
+ if (!hwdev || !info) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&board_info, sizeof(board_info), 0, sizeof(board_info));
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_GET_BOARD_INFO,
+ &board_info, sizeof(board_info),
+ &board_info, &out_size, 0);
+ if (err || board_info.status || !out_size) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Get board info failed, err: %d, status: 0x%x, out size: 0x%x",
+ err, board_info.status, out_size);
+ return -EFAULT;
+ }
+
+ (void)memcpy_s(info, sizeof(*info), &board_info.info, sizeof(*info));
+
+ return 0;
+}
+
+int hinic5_set_func_svc_used_state(void *hwdev, u16 svc_type, u8 state)
+{
+ struct hinic5_cmd_func_svc_used_state used_state;
+ u16 out_size = sizeof(used_state);
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ (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;
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
+ &used_state, sizeof(used_state),
+ &used_state, &out_size, 0);
+ if (err || !out_size || used_state.status) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Failed to set func service used state, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, used_state.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic5_comm_features_nego(void *hwdev, u8 opcode, u64 *s_feature,
+ u16 size)
+{
+ struct comm_cmd_feature_nego feature_nego;
+ u16 out_size = sizeof(feature_nego);
+ int err;
+
+ if (!hwdev || !s_feature || size > COMM_MAX_FEATURE_QWORD)
+ return -EINVAL;
+
+ (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)
+ (void)memcpy_s(feature_nego.s_feature,
+ sizeof(feature_nego.s_feature), s_feature,
+ (size * sizeof(u64)));
+
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ HINIC5_MGMT_CMD_FEATURE_NEGO,
+ &feature_nego, sizeof(feature_nego),
+ &feature_nego, &out_size, 0);
+ if (err || !out_size || feature_nego.head.status) {
+ IPXE_DRV_LOG(
+ ERR,
+ "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)
+ (void)memcpy_s(s_feature, (size * sizeof(u64)),
+ feature_nego.s_feature, (size * sizeof(u64)));
+
+ return 0;
+}
+
+int hinic5_get_comm_features(void *hwdev, u64 *s_feature, u16 size)
+{
+ return hinic5_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_GET, s_feature,
+ size);
+}
+
+int hinic5_set_comm_features(void *hwdev, u64 *s_feature, u16 size)
+{
+ return hinic5_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_SET, s_feature,
+ size);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.h
new file mode 100644
index 000000000..21f4ad9b6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hw_comm.h
@@ -0,0 +1,223 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_HW_COMM_H_
+#define _HINIC5_HW_COMM_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include "hinic5_mgmt.h"
+#include "hinic5_hwdev.h"
+
+#define HINIC5_MGMT_CMD_OP_GET 0
+#define HINIC5_MGMT_CMD_OP_SET 1
+
+#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_SET(val, member) \
+ (((val)&HINIC5_MSIX_CNT_##member##_MASK) \
+ << HINIC5_MSIX_CNT_##member##_SHIFT)
+
+#define MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, status) \
+ ((err) || (status) || !(out_size))
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+struct hinic5_cmd_msix_config {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 msix_index;
+ u8 pending_cnt;
+ u8 coalesct_timer_cnt;
+ u8 resend_timer_cnt;
+ u8 lli_timer_cnt;
+ u8 lli_credit_cnt;
+ u8 rsvd2[5];
+};
+
+#define HINIC5_PAGE_SIZE_HW(pg_size) ((u8)ilog2((u32)((pg_size) >> 12)))
+
+struct hinic5_cmd_wq_page_size {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_idx;
+ u8 opcode;
+ /*
+ * Real size is 4KB * 2^page_size, range(0~20) must be checked
+ * by driver
+ */
+ u8 page_size;
+
+ u32 rsvd1;
+};
+
+struct hinic5_reset {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u16 rsvd1[3];
+ u64 reset_flag;
+};
+
+struct hinic5_cmd_func_svc_used_state {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u16 svc_type;
+ u8 used_state;
+ u8 rsvd[35];
+};
+
+struct hinic5_cmd_root_ctxt {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_idx;
+ u8 set_cmdq_depth;
+ u8 cmdq_depth;
+ u16 rx_buf_sz;
+ u8 lro_en;
+ u8 rsvd1;
+ u16 sq_depth;
+ u16 rq_depth;
+ u32 rsvd2;
+ u64 rsvd3;
+};
+
+enum hinic5_fw_ver_type {
+ HINIC5_FW_VER_TYPE_BOOT,
+ HINIC5_FW_VER_TYPE_MPU,
+ HINIC5_FW_VER_TYPE_NPU,
+ HINIC5_FW_VER_TYPE_SMU,
+ HINIC5_FW_VER_TYPE_CFG,
+};
+
+struct comm_cmd_feature_nego {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[COMM_MAX_FEATURE_QWORD];
+};
+
+#define HINIC5_FW_VERSION_LEN 16
+#define HINIC5_FW_COMPILE_TIME_LEN 20
+struct hinic5_cmd_get_fw_version {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 fw_type;
+ u16 rsvd1;
+ u8 ver[HINIC5_FW_VERSION_LEN];
+ u8 time[HINIC5_FW_COMPILE_TIME_LEN];
+};
+
+struct hinic5_cmd_clear_doorbell {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_idx;
+ u16 rsvd1[3];
+};
+
+struct hinic5_cmd_clear_resource {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_idx;
+ u16 rsvd1[3];
+};
+
+struct hinic5_cmd_board_info {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ struct hinic5_board_info info;
+
+ u32 rsvd1[23];
+};
+
+struct interrupt_info {
+ u32 lli_set;
+ u32 interrupt_coalesc_set;
+ u16 msix_index;
+ u8 lli_credit_limit;
+ u8 lli_timer_cfg;
+ u8 pending_limit;
+ u8 coalesce_timer_cfg;
+ u8 resend_timer_cfg;
+};
+
+enum cfg_msix_operation {
+ CFG_MSIX_OPERATION_FREE = 0,
+ CFG_MSIX_OPERATION_ALLOC = 1,
+};
+
+struct comm_cmd_cfg_msix_num {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u8 op_code; /* 1: alloc 0: free */
+ u8 rsvd1;
+
+ u16 msix_num;
+ u16 rsvd2;
+};
+
+int hinic5_func_reset(void *hwdev, u64 reset_flag);
+
+int hinic5_get_mgmt_version(void *hwdev, char *mgmt_ver, int max_mgmt_len);
+
+int hinic5_get_board_info(void *hwdev, struct hinic5_board_info *info);
+
+int hinic5_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth,
+ u16 rx_buf_sz);
+
+int hinic5_clean_root_ctxt(void *hwdev);
+
+int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info);
+
+int hinic5_set_interrupt_cfg(void *dev, struct interrupt_info info);
+
+int hinic5_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size);
+
+int hinic5_set_cmdq_depth(void *hwdev, u16 cmdq_depth);
+
+int hinic5_set_func_svc_used_state(void *hwdev, u16 svc_type, u8 state);
+
+int hinic5_get_comm_features(void *hwdev, u64 *s_feature, u16 size);
+
+int hinic5_set_comm_features(void *hwdev, u64 *s_feature, u16 size);
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.c
new file mode 100644
index 000000000..4566849d4
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.c
@@ -0,0 +1,481 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <ipxe/pci.h>
+#include <ipxe/malloc.h>
+#include <ipxe/io.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_csr.h"
+#include "hinic5_hwif.h"
+#include "hinic5_eqs.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_cmd.h"
+#include "hinic5_mbox.h"
+#include "hinic5_wq.h"
+#include "hinic5_cmdq.h"
+#include "hinic5_hw_cfg.h"
+#include "hinic5_hw_comm.h"
+#include "hinic5_hwdev.h"
+
+enum hinic5_pcie_nosnoop { HINIC5_PCIE_SNOOP = 0, HINIC5_PCIE_NO_SNOOP = 1 };
+
+enum hinic5_pcie_tph {
+ HINIC5_PCIE_TPH_DISABLE = 0,
+ HINIC5_PCIE_TPH_ENABLE = 1
+};
+
+#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_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_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_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 PCIE_MSIX_ATTR_ENTRY 0
+
+#define HINIC5_CHIP_PRESENT 1
+#define HINIC5_CHIP_ABSENT 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
+
+/**
+ * Set the dma attributes for entry
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ * @param[in] entry_idx
+ * The entry index in the dma table
+ * @param[in] st
+ * PCIE TLP steering tag
+ * @param[in] at
+ * PCIE TLP AT field
+ * @param[in] ph
+ * PCIE TLP Processing Hint field
+ * @param[in] no_snooping
+ * PCIE TLP No snooping
+ * @param[in] tph_en
+ * PCIE TLP Processing Hint Enable
+ */
+static void set_pf_dma_attr_entry(struct hinic5_hwdev *hwdev, u32 entry_idx,
+ u8 st, u8 at, u8 ph,
+ enum hinic5_pcie_nosnoop no_snooping,
+ enum hinic5_pcie_tph tph_en)
+{
+ u32 addr, val, dma_attr_entry, _entry_idx;
+
+ /* Use indirect access should set entry_idx first */
+ addr = HINIC5_CSR_DMA_ATTR_INDIR_IDX_ADDR;
+ val = hinic5_hwif_read_reg(hwdev->hwif, addr);
+ val = HINIC5_DMA_ATTR_INDIR_IDX_CLEAR(val, IDX);
+
+ _entry_idx = HINIC5_DMA_ATTR_INDIR_IDX_SET(entry_idx, IDX);
+
+ val |= _entry_idx;
+
+ hinic5_hwif_write_reg(hwdev->hwif, addr, val);
+
+ wmb(); /* Write index before config */
+
+ addr = HINIC5_CSR_DMA_ATTR_TBL_ADDR;
+
+ val = hinic5_hwif_read_reg(hwdev->hwif, addr);
+ val = HINIC5_DMA_ATTR_ENTRY_CLEAR(val, ST) &
+ HINIC5_DMA_ATTR_ENTRY_CLEAR(val, AT) &
+ HINIC5_DMA_ATTR_ENTRY_CLEAR(val, PH) &
+ HINIC5_DMA_ATTR_ENTRY_CLEAR(val, NO_SNOOPING) &
+ HINIC5_DMA_ATTR_ENTRY_CLEAR(val, TPH_EN);
+
+ dma_attr_entry = HINIC5_DMA_ATTR_ENTRY_SET(st, ST) |
+ HINIC5_DMA_ATTR_ENTRY_SET(at, AT) |
+ HINIC5_DMA_ATTR_ENTRY_SET(ph, PH) |
+ HINIC5_DMA_ATTR_ENTRY_SET(no_snooping, NO_SNOOPING) |
+ HINIC5_DMA_ATTR_ENTRY_SET(tph_en, TPH_EN);
+
+ val |= dma_attr_entry;
+ hinic5_hwif_write_reg(hwdev->hwif, addr, val);
+}
+
+/**
+ * Initialize the the default dma attributes
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+static int dma_attr_table_init(struct hinic5_hwdev *hwdev)
+{
+ /* Check if set pf dma attr through uP */
+ set_pf_dma_attr_entry(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 0;
+}
+
+static int init_aeqs_msix_attr(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_aeqs *aeqs = hwdev->aeqs;
+ struct interrupt_info info = { 0 };
+ struct hinic5_eq *eq = NULL;
+ u16 q_id;
+ int err;
+
+ info.lli_set = 0;
+ info.interrupt_coalesc_set = 1;
+ info.pending_limit = HINIC5_DEAULT_EQ_MSIX_PENDING_LIMIT;
+ info.coalesce_timer_cfg = HINIC5_DEAULT_EQ_MSIX_COALESC_TIMER_CFG;
+ info.resend_timer_cfg = HINIC5_DEAULT_EQ_MSIX_RESEND_TIMER_CFG;
+
+ for (q_id = 0; q_id < aeqs->num_aeqs; q_id++) {
+ eq = &aeqs->aeq[q_id];
+ info.msix_index = eq->eq_irq.msix_entry_idx;
+ err = hinic5_set_interrupt_cfg(hwdev, info);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Set msix attr for aeq %d failed",
+ q_id);
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic5_comm_pf_to_mgmt_init(struct hinic5_hwdev *hwdev)
+{
+ int err;
+ err = hinic5_pf_to_mgmt_init(hwdev);
+ if (err != 0) {
+ return err;
+ }
+
+ return 0;
+}
+
+static void hinic5_comm_pf_to_mgmt_free(struct hinic5_hwdev *hwdev)
+{
+ hinic5_pf_to_mgmt_free(hwdev);
+}
+
+static int hinic5_comm_cmdqs_init(struct hinic5_hwdev *hwdev)
+{
+ int err;
+
+ err = hinic5_cmdqs_init(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init cmd queues failed");
+ return err;
+ }
+
+ err = hinic5_set_cmdq_depth(hwdev, HINIC5_CMDQ_DEPTH);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Set cmdq depth failed");
+ goto set_cmdq_depth_err;
+ }
+
+ return 0;
+
+set_cmdq_depth_err:
+ hinic5_cmdqs_free(hwdev);
+
+ return err;
+}
+
+static void hinic5_comm_cmdqs_free(struct hinic5_hwdev *hwdev)
+{
+ hinic5_cmdqs_free(hwdev);
+}
+
+static void hinic5_sync_mgmt_func_state(struct hinic5_hwdev *hwdev)
+{
+ hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_ACTIVE_FLAG);
+}
+
+static int get_func_misc_info(struct hinic5_hwdev *hwdev)
+{
+ int err;
+
+ err = hinic5_get_board_info(hwdev, &hwdev->board_info);
+ if (err != 0) {
+ /* For the PF/VF of slave host, return error */
+ if (hinic5_pcie_itf_id(hwdev) != 0) {
+ return err;
+ }
+
+ (void)memset_s(&hwdev->board_info,
+ sizeof(struct hinic5_board_info), 0xff,
+ sizeof(struct hinic5_board_info));
+ }
+
+ err = hinic5_get_mgmt_version(hwdev, hwdev->mgmt_ver,
+ MGMT_VERSION_MAX_LEN);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Get mgmt cpu version failed");
+ return err;
+ }
+
+ return 0;
+}
+
+static int init_mgmt_channel(struct hinic5_hwdev *hwdev)
+{
+ int err;
+
+ err = hinic5_aeqs_init(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init async event queues failed");
+ return err;
+ }
+
+ err = hinic5_comm_pf_to_mgmt_init(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init mgmt channel failed");
+ goto msg_init_err;
+ }
+
+ err = hinic5_func_to_func_init(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init mailbox channel failed");
+ goto func_to_func_init_err;
+ }
+
+ return 0;
+
+func_to_func_init_err:
+ hinic5_comm_pf_to_mgmt_free(hwdev);
+
+msg_init_err:
+ hinic5_aeqs_free(hwdev);
+
+ return err;
+}
+
+static void free_mgmt_channel(struct hinic5_hwdev *hwdev)
+{
+ hinic5_func_to_func_free(hwdev);
+ hinic5_comm_pf_to_mgmt_free(hwdev);
+ hinic5_aeqs_free(hwdev);
+}
+
+static int init_cmdqs_channel(struct hinic5_hwdev *hwdev)
+{
+ int err;
+
+ err = dma_attr_table_init(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init dma attr table failed");
+ goto dma_attr_init_err;
+ }
+
+ err = init_aeqs_msix_attr(hwdev);
+ if (err != 0) {
+ goto init_aeqs_msix_err;
+ }
+
+ /* Set default wq page_size */
+ hwdev->wq_page_size = HINIC5_DEFAULT_WQ_PAGE_SIZE;
+ err = hinic5_set_wq_page_size(hwdev, hinic5_global_func_id(hwdev),
+ hwdev->wq_page_size);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Set wq page size failed");
+ goto init_wq_pg_size_err;
+ }
+
+ err = hinic5_comm_cmdqs_init(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init cmd queues failed");
+ goto cmdq_init_err;
+ }
+
+ return 0;
+
+cmdq_init_err:
+ if (HINIC5_FUNC_TYPE(hwdev) != TYPE_VF) {
+ hinic5_set_wq_page_size(hwdev, hinic5_global_func_id(hwdev),
+ HINIC5_HW_WQ_PAGE_SIZE);
+ }
+init_wq_pg_size_err:
+init_aeqs_msix_err:
+dma_attr_init_err:
+
+ return err;
+}
+
+static int hinic5_init_comm_ch(struct hinic5_hwdev *hwdev)
+{
+ int err;
+
+ err = init_mgmt_channel(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init mgmt channel failed");
+ return err;
+ }
+
+ err = get_func_misc_info(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Get function msic information failed");
+ goto get_func_info_err;
+ }
+
+ err = hinic5_func_reset(hwdev, HINIC5_NIC_RES | HINIC5_COMM_RES);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Reset function failed");
+ goto func_reset_err;
+ }
+
+ err = hinic5_get_comm_features(hwdev, hwdev->features,
+ COMM_MAX_FEATURE_QWORD);
+ if (err) {
+ IPXE_DRV_LOG(ERR, "Get comm features failed");
+ goto func_reset_err;
+ }
+
+ err = init_cmdqs_channel(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init cmdq channel failed");
+ goto init_cmdqs_channel_err;
+ }
+
+ hinic5_sync_mgmt_func_state(hwdev);
+
+ return 0;
+
+init_cmdqs_channel_err:
+func_reset_err:
+get_func_info_err:
+ free_mgmt_channel(hwdev);
+
+ return err;
+}
+
+static void hinic5_uninit_comm_ch(struct hinic5_hwdev *hwdev)
+{
+ hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_INIT);
+
+ hinic5_comm_cmdqs_free(hwdev);
+
+ if (HINIC5_FUNC_TYPE(hwdev) != TYPE_VF) {
+ hinic5_set_wq_page_size(hwdev, hinic5_global_func_id(hwdev),
+ HINIC5_HW_WQ_PAGE_SIZE);
+ }
+
+ hinic5_func_to_func_free(hwdev);
+
+ hinic5_comm_pf_to_mgmt_free(hwdev);
+
+ hinic5_aeqs_free(hwdev);
+}
+
+int hinic5_init_hwdev(struct hinic5_hwdev *hwdev)
+{
+ int err;
+
+ err = hinic5_init_hwif(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Initialize hwif failed");
+ goto init_hwif_err;
+ }
+
+ err = hinic5_init_comm_ch(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init communication channel failed");
+ goto init_comm_ch_err;
+ }
+
+ err = hinic5_init_cfg_mgmt(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init cfg_mgnt failed");
+ goto init_cfg_err;
+ }
+
+ err = hinic5_init_capability(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init capability failed");
+ goto init_cap_err;
+ }
+
+ return 0;
+
+init_cap_err:
+ hinic5_deinit_cfg_mgmt(hwdev);
+init_cfg_err:
+ hinic5_uninit_comm_ch(hwdev);
+
+init_comm_ch_err:
+ hinic5_free_hwif(hwdev);
+
+init_hwif_err:
+
+ return err;
+}
+
+void hinic5_free_hwdev(struct hinic5_hwdev *hwdev)
+{
+ hinic5_deinit_cfg_mgmt(hwdev);
+
+ hinic5_uninit_comm_ch(hwdev);
+
+ hinic5_free_hwif(hwdev);
+}
+
+struct hinic5_page_addr *hinic5_dma_alloc(size_t len, size_t align)
+{
+ struct hinic5_page_addr *addr =
+ (struct hinic5_page_addr *)zalloc(sizeof(*addr));
+ if (addr == NULL) {
+ return NULL;
+ }
+
+ addr->virt_addr = malloc_phys(len, align);
+ if (addr->virt_addr == NULL) {
+ free(addr);
+ return NULL;
+ }
+ addr->len = len;
+ addr->phys_addr = virt_to_bus(addr->virt_addr);
+ return addr;
+}
+
+void hinic5_dma_free(const struct hinic5_page_addr *addr)
+{
+ free_phys(addr->virt_addr, addr->len);
+ free((void *)addr);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.h
new file mode 100644
index 000000000..f9a14362c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwdev.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_HWDEV_H_
+#define _HINIC5_HWDEV_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+struct cfg_mgmt_info;
+struct hinic5_hwif;
+struct hinic5_aeqs;
+struct hinic5_mbox;
+struct hinic5_msg_pf_to_mgmt;
+
+#define HINIC5_CHIP_FAULT_SIZE (110 * 1024)
+#define MGMT_VERSION_MAX_LEN 32
+#define COMM_MAX_FEATURE_QWORD 4
+
+struct hinic5_page_addr {
+ void *virt_addr;
+ u64 phys_addr;
+ size_t len;
+};
+
+enum {
+ HINIC5_F_API_CHAIN = 1U << 0,
+ HINIC5_F_CLP = 1U << 1,
+ HINIC5_F_CHANNEL_DETECT = 1U << 2,
+ HINIC5_F_MBOX_SEGMENT = 1U << 3,
+ HINIC5_F_CMDQ_NUM = 1U << 4,
+ HINIC5_F_VIRTIO_VQ_SIZE = 1U << 5,
+ HINIC5_F_EXTEND_CAP = 1U << 6,
+ HINIC5_F_SMF_CACHE_INVALID = 1U << 7,
+ HINIC5_F_ONLY_ENHANCE_CMDQ = 1U << 8,
+ HINIC5_F_USE_REAL_RX_BUF_SIZE = 1U << 9,
+};
+
+#define HINIC5_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev) \
+ ((((struct hinic5_hwdev *)hwdev)->features[0] & \
+ HINIC5_F_ONLY_ENHANCE_CMDQ))
+#define HINIC5_IS_USE_REAL_RX_BUF_SIZE(hwdev) \
+ ((((struct hinic5_hwdev *)hwdev)->features[0] & \
+ HINIC5_F_USE_REAL_RX_BUF_SIZE))
+
+struct hinic5_board_info {
+ u8 board_type;
+ u8 port_num;
+ u8 port_speed;
+ u8 host_width;
+ u8 host_num;
+ u8 pf_num;
+ u16 vf_total_num;
+ u8 tile_num;
+ u8 qcm_num;
+ u8 core_num;
+ u8 work_mode;
+ u8 service_mode;
+ u8 board_mode;
+ u8 boot_sel;
+ u8 board_id;
+ u32 rsvd;
+ u32 service_en_bitmap;
+ u8 scenes_id;
+ u8 cfg_template_id;
+ u16 rsvd0;
+};
+
+struct hinic5_hwdev {
+ void *dev_handle; /* Pointer to hinic5_nic_dev */
+ void *pci_dev; /* Pointer to rte_pci_device */
+ void *eth_dev; /* Pointer to rte_eth_dev */
+
+ uint16_t port_id;
+
+ u32 wq_page_size;
+
+ struct hinic5_hwif *hwif;
+ struct cfg_mgmt_info *cfg_mgmt;
+
+ struct hinic5_cmdqs *cmdqs;
+ struct hinic5_aeqs *aeqs;
+ struct hinic5_mbox *func_to_func;
+ struct hinic5_msg_pf_to_mgmt *pf_to_mgmt;
+
+ struct hinic5_board_info board_info;
+ char mgmt_ver[MGMT_VERSION_MAX_LEN];
+
+ u16 max_vfs;
+ u16 link_status;
+
+ u64 features[COMM_MAX_FEATURE_QWORD];
+};
+
+void pf_handle_mgmt_comm_event(void *handle, void *pri_handle, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size);
+
+int hinic5_init_hwdev(struct hinic5_hwdev *hwdev);
+
+void hinic5_free_hwdev(struct hinic5_hwdev *hwdev);
+
+struct hinic5_page_addr *hinic5_dma_alloc(size_t len, size_t align);
+
+void hinic5_dma_free(const struct hinic5_page_addr *addr);
+
+#endif /* _HINIC5_HWDEV_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.c
new file mode 100644
index 000000000..c5c03007c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.c
@@ -0,0 +1,823 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <byteswap.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/ethernet.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/dma.h>
+#include <ipxe/pci.h>
+#include <ipxe/profile.h>
+#include "hinic5_csr.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_compat.h"
+#include "hinic5_hwif.h"
+
+#define WAIT_HWIF_READY_TIMEOUT 10000
+
+#define DB_IDX(db, db_base) \
+ ((u32)(((unsigned long)(db) - (unsigned long)(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_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) \
+ (((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_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) \
+ (((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_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) \
+ (((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_MASK 0xFFF
+#define HINIC5_AF3_GLOBAL_VF_ID_OF_PF_MASK 0xFFF
+
+#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_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_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_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_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_FUNC_MAX_QUEUE_SHIFT 23
+#define HINIC5_AF6_FUNC_MAX_QUEUE_MASK 0x1FF
+
+#define HINIC5_AF6_MSIX_FLEX_EN_SHIFT 22
+#define HINIC5_AF6_MSIX_FLEX_EN_MASK 0x1
+
+#define HINIC5_AF6_SET(val, member) \
+ ((((u32)(val)) & HINIC5_AF6_##member##_MASK) \
+ << HINIC5_AF6_##member##_SHIFT)
+
+#define HINIC5_AF6_GET(val, member) \
+ (((val) >> HINIC5_AF6_##member##_SHIFT) & HINIC5_AF6_##member##_MASK)
+
+#define HINIC5_AF6_CLEAR(val, member) \
+ ((val) & (~(HINIC5_AF6_##member##_MASK << HINIC5_AF6_##member##_SHIFT)))
+
+#define HINIC5_PPF_ELECTION_IDX_SHIFT 0
+
+#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_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_MPF_ELECTION_IDX_SHIFT 0
+
+#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_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_GET_REG_FLAG(reg) ((reg) & (~(HINIC5_REGS_FLAG_MASK)))
+
+#define HINIC5_GET_REG_ADDR(reg) ((reg) & (HINIC5_REGS_FLAG_MASK))
+
+#define HINIC5_IS_VF_DEV(pdev) ((pdev)->id->device == HINIC5_DEV_ID_VF)
+
+#define HINIC5_MAX_PF_NUM 32
+
+u32 hinic5_hwif_read_reg(struct hinic5_hwif *hwif, u32 reg)
+{
+ if (HINIC5_GET_REG_FLAG(reg) == HINIC5_MGMT_REGS_FLAG) {
+ return be32_to_cpu(
+ readl(hwif->mgmt_regs_base + HINIC5_GET_REG_ADDR(reg)));
+ } else {
+ return be32_to_cpu(
+ readl(hwif->cfg_regs_base + HINIC5_GET_REG_ADDR(reg)));
+ }
+}
+
+void hinic5_hwif_write_reg(struct hinic5_hwif *hwif, u32 reg, u32 val)
+{
+ if (HINIC5_GET_REG_FLAG(reg) == HINIC5_MGMT_REGS_FLAG) {
+ writel(cpu_to_be32(val),
+ hwif->mgmt_regs_base + HINIC5_GET_REG_ADDR(reg));
+ } else {
+ writel(cpu_to_be32(val),
+ hwif->cfg_regs_base + HINIC5_GET_REG_ADDR(reg));
+ }
+}
+
+/**
+ * Judge whether HW initialization ok
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ *
+ * @retval zero: Success
+ * @retval negative: Failure
+ */
+static int hwif_ready(struct hinic5_hwdev *hwdev)
+{
+ u32 addr, attr1;
+
+ addr = HINIC5_CSR_FUNC_ATTR1_ADDR;
+ attr1 = hinic5_hwif_read_reg(hwdev->hwif, addr);
+ if (attr1 == HINIC5_PCIE_LINK_DOWN) {
+ return -EBUSY;
+ }
+
+ if (!HINIC5_AF1_GET(attr1, MGMT_INIT_STATUS)) {
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int wait_hwif_ready(struct hinic5_hwdev *hwdev)
+{
+ unsigned long timeout = 0;
+
+ do {
+ if (!hwif_ready(hwdev)) {
+ return 0;
+ }
+
+ mdelay(1);
+ timeout++;
+ } while (timeout < WAIT_HWIF_READY_TIMEOUT);
+
+ IPXE_DRV_LOG(ERR, "Hwif is not ready");
+ return -EBUSY;
+}
+
+/**
+ * Set the attributes as members in hwif
+ *
+ * @param[in] hwif
+ * The hardware interface of a pci function device
+ * @param[in] attr0
+ * The first attribute that was read from the hw
+ * @param[in] attr1
+ * The second attribute that was read from the hw
+ * @param[in] attr2
+ * The third attribute that was read from the hw
+ * @param[in] attr3
+ * The fourth attribute that was read from the hw
+ */
+static void set_hwif_attr(struct hinic5_hwif *hwif, u32 attr0, u32 attr1,
+ u32 attr2, u32 attr3)
+{
+ hwif->attr.func_global_idx = HINIC5_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+ hwif->attr.port_to_port_idx = HINIC5_AF0_GET(attr0, P2P_IDX);
+ hwif->attr.pci_intf_idx = HINIC5_AF0_GET(attr0, PCI_INTF_IDX);
+ hwif->attr.vf_in_pf = HINIC5_AF0_GET(attr0, VF_IN_PF);
+ hwif->attr.func_type = HINIC5_AF0_GET(attr0, FUNC_TYPE);
+
+ hwif->attr.ppf_idx = HINIC5_AF1_GET(attr1, PPF_IDX);
+ hwif->attr.num_aeqs = BIT(HINIC5_AF1_GET(attr1, AEQS_PER_FUNC));
+
+ hwif->attr.num_ceqs = (u8)HINIC5_AF2_GET(attr2, CEQS_PER_FUNC);
+ hwif->attr.num_irqs = HINIC5_AF2_GET(attr2, IRQS_PER_FUNC);
+ 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);
+}
+
+/**
+ * Read and set the attributes as members in hwif
+ *
+ * @param[in] hwif
+ * The hardware interface of a pci function device
+ */
+static void get_hwif_attr(struct hinic5_hwif *hwif)
+{
+ u32 addr, attr0, attr1, attr2, attr3;
+
+ addr = HINIC5_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic5_hwif_read_reg(hwif, addr);
+
+ addr = HINIC5_CSR_FUNC_ATTR1_ADDR;
+ attr1 = hinic5_hwif_read_reg(hwif, addr);
+
+ addr = HINIC5_CSR_FUNC_ATTR2_ADDR;
+ attr2 = hinic5_hwif_read_reg(hwif, addr);
+
+ addr = HINIC5_CSR_FUNC_ATTR3_ADDR;
+ attr3 = hinic5_hwif_read_reg(hwif, addr);
+
+ set_hwif_attr(hwif, attr0, attr1, attr2, attr3);
+}
+
+void hinic5_update_msix_info(struct hinic5_hwif *hwif)
+{
+ u32 attr6 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR6_ADDR);
+ hwif->attr.num_queue = HINIC5_AF6_GET(attr6, FUNC_MAX_QUEUE);
+ hwif->attr.msix_flex_en = HINIC5_AF6_GET(attr6, MSIX_FLEX_EN);
+ IPXE_DRV_LOG(INFO, "msix_flex_en: %d, queue msix: %d\n",
+ hwif->attr.msix_flex_en, hwif->attr.num_queue);
+}
+
+void hinic5_set_pf_status(struct hinic5_hwif *hwif,
+ enum hinic5_pf_status status)
+{
+ u32 attr6 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR6_ADDR);
+
+ attr6 = HINIC5_AF6_CLEAR(attr6, PF_STATUS);
+ attr6 |= HINIC5_AF6_SET(status, PF_STATUS);
+
+ if (hwif->attr.func_type == TYPE_VF) {
+ return;
+ }
+
+ hinic5_hwif_write_reg(hwif, HINIC5_CSR_FUNC_ATTR6_ADDR, attr6);
+}
+
+enum hinic5_pf_status hinic5_get_pf_status(struct hinic5_hwif *hwif)
+{
+ u32 attr6 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR6_ADDR);
+
+ return HINIC5_AF6_GET(attr6, PF_STATUS);
+}
+
+static enum hinic5_doorbell_ctrl
+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 enum hinic5_outbound_ctrl
+hinic5_get_outbound_ctrl_status(struct hinic5_hwif *hwif)
+{
+ u32 attr5 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR5_ADDR);
+
+ return HINIC5_AF5_GET(attr5, OUTBOUND_CTRL);
+}
+
+void hinic5_enable_doorbell(struct hinic5_hwif *hwif)
+{
+ u32 addr, attr4;
+
+ addr = HINIC5_CSR_FUNC_ATTR4_ADDR;
+ attr4 = hinic5_hwif_read_reg(hwif, addr);
+
+ attr4 = HINIC5_AF4_CLEAR(attr4, DOORBELL_CTRL);
+ attr4 |= HINIC5_AF4_SET(ENABLE_DOORBELL, DOORBELL_CTRL);
+
+ hinic5_hwif_write_reg(hwif, addr, attr4);
+}
+
+void hinic5_disable_doorbell(struct hinic5_hwif *hwif)
+{
+ u32 addr, attr4;
+
+ addr = HINIC5_CSR_FUNC_ATTR4_ADDR;
+ attr4 = hinic5_hwif_read_reg(hwif, addr);
+
+ attr4 = HINIC5_AF4_CLEAR(attr4, DOORBELL_CTRL);
+ attr4 |= HINIC5_AF4_SET(DISABLE_DOORBELL, DOORBELL_CTRL);
+
+ hinic5_hwif_write_reg(hwif, addr, attr4);
+}
+
+/**
+ * Try to set hwif as ppf and set the type of hwif in this case
+ *
+ * @param[in] hwif
+ * The hardware interface of a pci function device
+ */
+static void set_ppf(struct hinic5_hwif *hwif)
+{
+ struct hinic5_func_attr *attr = &hwif->attr;
+ u32 addr, val, ppf_election;
+
+ 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);
+ val |= ppf_election;
+
+ hinic5_hwif_write_reg(hwif, addr, val);
+
+ /* Check PPF */
+ val = hinic5_hwif_read_reg(hwif, addr);
+
+ attr->ppf_idx = HINIC5_PPF_ELECTION_GET(val, IDX);
+ if (attr->ppf_idx == attr->func_global_idx) {
+ attr->func_type = TYPE_PPF;
+ }
+}
+
+/**
+ * Get the mpf index from the hwif
+ *
+ * @param[in] hwif
+ * The hardware interface of a pci function device
+ */
+static void get_mpf(struct hinic5_hwif *hwif)
+{
+ struct hinic5_func_attr *attr = &hwif->attr;
+ u32 mpf_election, addr;
+
+ addr = HINIC5_CSR_GLOBAL_MPF_ELECTION_ADDR;
+
+ mpf_election = hinic5_hwif_read_reg(hwif, addr);
+ attr->mpf_idx = HINIC5_MPF_ELECTION_GET(mpf_election, IDX);
+}
+
+/**
+ * Try to set hwif as mpf and set the mpf idx in hwif
+ *
+ * @param[in] hwif
+ * The hardware interface of a pci function device
+ */
+static void set_mpf(struct hinic5_hwif *hwif)
+{
+ struct hinic5_func_attr *attr = &hwif->attr;
+ u32 addr, val, mpf_election;
+
+ addr = HINIC5_CSR_GLOBAL_MPF_ELECTION_ADDR;
+
+ val = hinic5_hwif_read_reg(hwif, addr);
+
+ val = HINIC5_MPF_ELECTION_CLEAR(val, IDX);
+ mpf_election = HINIC5_MPF_ELECTION_SET(attr->func_global_idx, IDX);
+
+ val |= mpf_election;
+ hinic5_hwif_write_reg(hwif, addr, val);
+}
+
+int hinic5_alloc_db_addr(void *hwdev, void **db_base,
+ enum hinic5_db_type queue_type)
+{
+ struct hinic5_hwif *hwif = NULL;
+
+ if (!hwdev || !db_base) {
+ return -EINVAL;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+ *db_base = hwif->db_base + queue_type * HINIC5_DB_PAGE_SIZE;
+
+ return 0;
+}
+
+void hinic5_set_msix_auto_mask_state(void *hwdev, u16 msix_idx,
+ enum hinic5_msix_auto_mask flag)
+{
+ struct hinic5_hwif *hwif = NULL;
+ u32 mask_bits;
+ u32 addr;
+
+ if (!hwdev) {
+ return;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ if (flag != 0) {
+ mask_bits = HINIC5_MSI_CLR_INDIR_SET(1, AUTO_MSK_SET);
+ } else {
+ mask_bits = HINIC5_MSI_CLR_INDIR_SET(1, AUTO_MSK_CLR);
+ }
+
+ mask_bits = mask_bits |
+ HINIC5_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
+
+ addr = HINIC5_CSR_FUNC_MSI_CLR_WR_ADDR;
+ hinic5_hwif_write_reg(hwif, addr, mask_bits);
+}
+
+/**
+ * Set msix state
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ * @param[in] msix_idx
+ * MSIX index
+ * @param[in] flag
+ * MSIX state flag, 0-enable, 1-disable
+ */
+void hinic5_set_msix_state(void *hwdev, u16 msix_idx,
+ enum hinic5_msix_state flag)
+{
+ struct hinic5_hwif *hwif = NULL;
+ u32 mask_bits;
+ u32 addr;
+ u8 int_msk = 1;
+
+ if (!hwdev) {
+ return;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ if (flag != 0) {
+ mask_bits = HINIC5_MSI_CLR_INDIR_SET(int_msk, INT_MSK_SET);
+ } else {
+ mask_bits = HINIC5_MSI_CLR_INDIR_SET(int_msk, INT_MSK_CLR);
+ }
+ mask_bits = mask_bits |
+ HINIC5_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
+
+ addr = HINIC5_CSR_FUNC_MSI_CLR_WR_ADDR;
+ hinic5_hwif_write_reg(hwif, addr, mask_bits);
+}
+
+static void disable_all_msix(struct hinic5_hwdev *hwdev)
+{
+ u16 num_irqs = hwdev->hwif->attr.num_irqs;
+ u16 i;
+
+ for (i = 0; i < num_irqs; i++) {
+ hinic5_set_msix_state(hwdev, i, HINIC5_MSIX_DISABLE);
+ }
+}
+
+/**
+ * Clear msix resend bit
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ * @param[in] msix_idx
+ * MSI_X index
+ * @param[in] clear_resend_en
+ * Clear resend en flag, 1-clear
+ */
+void hinic5_msix_intr_clear_resend_bit(void *hwdev, u16 msix_idx,
+ u8 clear_resend_en)
+{
+ struct hinic5_hwif *hwif = NULL;
+ u32 msix_ctrl = 0, addr;
+
+ if (!hwdev) {
+ return;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ msix_ctrl = HINIC5_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX) |
+ HINIC5_MSI_CLR_INDIR_SET(clear_resend_en, RESEND_TIMER_CLR);
+
+ addr = HINIC5_CSR_FUNC_MSI_CLR_WR_ADDR;
+ hinic5_hwif_write_reg(hwif, addr, msix_ctrl);
+}
+
+static int wait_until_doorbell_and_outbound_enabled(struct hinic5_hwif *hwif)
+{
+ enum hinic5_doorbell_ctrl db_ctrl;
+ enum hinic5_outbound_ctrl outbound_ctrl;
+ u32 cnt = 0;
+
+ while (cnt < HINIC5_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT) {
+ db_ctrl = hinic5_get_doorbell_ctrl_status(hwif);
+ outbound_ctrl = hinic5_get_outbound_ctrl_status(hwif);
+ if (outbound_ctrl == ENABLE_OUTBOUND &&
+ db_ctrl == ENABLE_DOORBELL) {
+ return 0;
+ }
+
+ mdelay(1);
+ cnt++;
+ }
+
+ return -EFAULT;
+}
+
+static void *hinic_ioremap_bar(struct pci_device *pdev, unsigned int reg)
+{
+ unsigned long reg_base, reg_size, _reg;
+ _reg = PCI_BASE_ADDRESS(reg);
+ reg_base = pci_bar_start(pdev, _reg);
+ reg_size = pci_bar_size(pdev, _reg);
+
+ return pci_ioremap(pdev, reg_base, reg_size);
+}
+
+static int hinic5_get_bar_addr(struct hinic5_hwdev *hwdev)
+{
+ int cfg_bar;
+ struct pci_device *pdev = hwdev->pci_dev;
+ struct hinic5_hwif *hwif = hwdev->hwif;
+
+ cfg_bar = HINIC5_IS_VF_DEV(pdev) ? HINIC5_VF_PCI_CFG_REG_BAR :
+ HINIC5_PF_PCI_CFG_REG_BAR;
+ hwif->cfg_regs_base = hinic_ioremap_bar(pdev, cfg_bar);
+ if (!hwif->cfg_regs_base) {
+ IPXE_DRV_LOG(ERR, "Failed to map configuration regs\n");
+ return -ENOMEM;
+ }
+
+ if (!HINIC5_IS_VF_DEV(pdev)) {
+ hwif->mgmt_regs_base =
+ hinic_ioremap_bar(pdev, HINIC5_PCI_MGMT_REG_BAR);
+ if (!hwif->mgmt_regs_base) {
+ IPXE_DRV_LOG(ERR, "Failed to map mgmt regs\n");
+ goto map_mgmt_bar_err;
+ }
+ }
+
+ hwif->db_dwqe_len =
+ pci_bar_size(pdev, PCI_BASE_ADDRESS(HINIC5_PCI_DB_BAR));
+ hwif->db_base = hinic_ioremap_bar(pdev, HINIC5_PCI_DB_BAR);
+ if (!hwif->db_base) {
+ IPXE_DRV_LOG(ERR, "Failed to map doorbell regs\n");
+ goto map_db_err;
+ }
+
+ return 0;
+
+map_db_err:
+ if (!HINIC5_IS_VF_DEV(pdev)) {
+ iounmap(hwif->mgmt_regs_base);
+ }
+
+map_mgmt_bar_err:
+ iounmap(hwif->cfg_regs_base);
+
+ return -ENOMEM;
+}
+
+static void hinic5_free_bar(struct hinic5_hwdev *hwdev)
+{
+ struct pci_device *pdev = hwdev->pci_dev;
+ struct hinic5_hwif *hwif = hwdev->hwif;
+
+ if (!HINIC5_IS_VF_DEV(pdev)) {
+ iounmap(hwif->mgmt_regs_base);
+ hwdev->hwif->mgmt_regs_base = NULL;
+ }
+ iounmap(hwif->cfg_regs_base);
+ iounmap(hwif->db_base);
+ hwdev->hwif->cfg_regs_base = NULL;
+ hwdev->hwif->db_base = NULL;
+}
+
+/**
+ * Initialize the hw interface
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure.
+ */
+int hinic5_init_hwif(void *dev)
+{
+ struct hinic5_hwdev *hwdev = NULL;
+ struct hinic5_hwif *hwif;
+ int err;
+ u32 attr4, attr5;
+
+ hwif = zalloc(sizeof(struct hinic5_hwif));
+ if (!hwif) {
+ return -ENOMEM;
+ }
+
+ hwdev = (struct hinic5_hwdev *)dev;
+ hwdev->hwif = hwif;
+
+ err = hinic5_get_bar_addr(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "get bar addr fail");
+ goto hwif_bar_init_err;
+ }
+
+ err = wait_hwif_ready(hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Chip status is not ready");
+ goto hwif_ready_err;
+ }
+
+ get_hwif_attr(hwif);
+
+ err = wait_until_doorbell_and_outbound_enabled(hwif);
+ 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);
+ IPXE_DRV_LOG(
+ ERR,
+ "Hw doorbell/outbound is disabled, attr4 0x%x attr5 0x%x\n",
+ attr4, attr5);
+ goto hwif_ready_err;
+ }
+
+ if (!HINIC5_IS_VF(hwdev)) {
+ set_ppf(hwif);
+
+ if (HINIC5_IS_PPF(hwdev)) {
+ set_mpf(hwif);
+ }
+
+ get_mpf(hwif);
+ }
+
+ disable_all_msix(hwdev);
+ /* Disable mgmt cpu reporting any event */
+ hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_INIT);
+
+ IPXE_DRV_LOG(
+ INFO,
+ "global_func_idx: %d, func_type: %d, host_id: %d, ppf: %d, mpf: %d",
+ hwif->attr.func_global_idx, hwif->attr.func_type,
+ hwif->attr.pci_intf_idx, hwif->attr.ppf_idx,
+ hwif->attr.mpf_idx);
+
+ return 0;
+
+hwif_ready_err:
+ hinic5_free_bar(hwdev);
+hwif_bar_init_err:
+ free(hwdev->hwif);
+ hwdev->hwif = NULL;
+
+ return err;
+}
+
+/**
+ * Free the hw interface
+ *
+ * @param[in] dev
+ * The pointer to the private hardware device object
+ */
+void hinic5_free_hwif(void *dev)
+{
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
+
+ hinic5_free_bar(hwdev);
+ free(hwdev->hwif);
+}
+
+u16 hinic5_global_func_id(void *hwdev)
+{
+ struct hinic5_hwif *hwif = NULL;
+
+ if (!hwdev) {
+ return 0;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ return hwif->attr.func_global_idx;
+}
+
+u8 hinic5_pf_id_of_vf(void *hwdev)
+{
+ struct hinic5_hwif *hwif = NULL;
+
+ if (!hwdev) {
+ return 0;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ return hwif->attr.port_to_port_idx;
+}
+
+u8 hinic5_pcie_itf_id(void *hwdev)
+{
+ struct hinic5_hwif *hwif = NULL;
+
+ if (!hwdev) {
+ return 0;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ return hwif->attr.pci_intf_idx;
+}
+
+enum func_type hinic5_func_type(void *hwdev)
+{
+ struct hinic5_hwif *hwif = NULL;
+
+ if (!hwdev) {
+ return 0;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ return hwif->attr.func_type;
+}
+
+u16 hinic5_glb_pf_vf_offset(void *hwdev)
+{
+ struct hinic5_hwif *hwif = NULL;
+
+ if (!hwdev) {
+ return 0;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+
+ return hwif->attr.global_vf_id_of_pf;
+}
+
+bool hinic5_get_pxe_en(void *hwdev)
+{
+ struct hinic5_hwif *hwif = NULL;
+ struct pci_device *pdev = NULL;
+ u32 pxe_en;
+ u32 reg_addr;
+ u16 func_id;
+
+ if (!hwdev) {
+ return false;
+ }
+
+ func_id = hinic5_global_func_id(hwdev);
+ if (func_id >= HINIC5_MAX_PF_NUM) {
+ return false;
+ }
+
+ hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
+ pdev = ((struct hinic5_hwdev *)hwdev)->pci_dev;
+
+ reg_addr = HINIC5_PXE_REG_ADDR(pdev->device);
+ if (!(HINIC5_IS_1872_DEV(pdev->device) ||
+ HINIC5_IS_1825_DEV(pdev->device))) {
+ IPXE_DRV_LOG(
+ WARN,
+ "Unknown device id: 0x%x, use default OPTION_ROM_EN address",
+ pdev->device);
+ }
+ pxe_en = hinic5_hwif_read_reg(hwif, reg_addr);
+
+ IPXE_DRV_LOG(INFO, "pxe en bitmap: 0x%x, func id: %d", pxe_en, func_id);
+
+ return pxe_en & (1U << func_id) ? true : false;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.h
new file mode 100644
index 000000000..b3d146f88
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_hwif.h
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_HWIF_H_
+#define _HINIC5_HWIF_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define HINIC5_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT 60000
+#define HINIC5_PCIE_LINK_DOWN 0xFFFFFFFF
+
+/* PCIe bar space */
+#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 has mgmt bar */
+#define HINIC5_PCI_DB_BAR 4
+
+/* Doorbell or direct wqe page size is 4K */
+#define HINIC5_DB_PAGE_SIZE 0x00001000ULL
+#define HINIC5_DWQE_OFFSET 0x00000800ULL
+
+enum func_type { TYPE_PF, TYPE_VF, TYPE_PPF, TYPE_UNKNOWN };
+#define HINIC5_MSIX_RESEND_TIMER_CLEAR 1
+enum hinic5_msix_state { HINIC5_MSIX_ENABLE, HINIC5_MSIX_DISABLE };
+
+enum hinic5_msix_auto_mask {
+ HINIC5_CLR_MSIX_AUTO_MASK,
+ HINIC5_SET_MSIX_AUTO_MASK,
+};
+
+struct hinic5_func_attr {
+ u16 func_global_idx;
+ u8 port_to_port_idx;
+ u8 pci_intf_idx;
+ u8 vf_in_pf;
+ 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_queue; /* max: 2 ^ 8 */
+ u8 num_dma_attr; /* max: 2 ^ 6 */
+ u8 msix_flex_en;
+
+ u16 global_vf_id_of_pf;
+};
+
+struct hinic5_hwif {
+ /* Configure virtual address, PF is bar1, VF is bar0/1 */
+ u8 *cfg_regs_base;
+ /* For PF bar3 virtual address, if function is VF should set NULL */
+ u8 *mgmt_regs_base;
+ u8 *db_base;
+ u64 db_dwqe_len;
+
+ struct hinic5_func_attr attr;
+
+ void *pdev;
+};
+
+enum hinic5_outbound_ctrl { ENABLE_OUTBOUND = 0x0, DISABLE_OUTBOUND = 0x1 };
+
+enum hinic5_doorbell_ctrl { ENABLE_DOORBELL = 0x0, DISABLE_DOORBELL = 0x1 };
+
+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
+};
+
+enum hinic5_db_type {
+ HINIC5_DB_TYPE_CMDQ = 0x0,
+ HINIC5_DB_TYPE_SQ = 0x1,
+ HINIC5_DB_TYPE_RQ = 0x2,
+ HINIC5_DB_TYPE_MAX = 0x3
+};
+
+#define HINIC5_HWIF_NUM_AEQS(hwif) ((hwif)->attr.num_aeqs)
+#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)
+
+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_msix_auto_mask_state(void *hwdev, u16 msix_idx,
+ enum hinic5_msix_auto_mask flag);
+
+void hinic5_set_msix_state(void *hwdev, u16 msix_idx,
+ enum hinic5_msix_state flag);
+
+void hinic5_msix_intr_clear_resend_bit(void *hwdev, u16 msix_idx,
+ u8 clear_resend_en);
+
+u16 hinic5_global_func_id(void *hwdev);
+
+u8 hinic5_pf_id_of_vf(void *hwdev);
+
+u8 hinic5_pcie_itf_id(void *hwdev);
+
+enum func_type hinic5_func_type(void *hwdev);
+
+u16 hinic5_glb_pf_vf_offset(void *hwdev);
+void hinic5_update_msix_info(struct hinic5_hwif *hwif);
+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);
+
+int hinic5_alloc_db_addr(void *hwdev, void **db_base,
+ enum hinic5_db_type queue_type);
+
+void hinic5_disable_doorbell(struct hinic5_hwif *hwif);
+
+void hinic5_enable_doorbell(struct hinic5_hwif *hwif);
+
+int hinic5_init_hwif(void *dev);
+
+void hinic5_free_hwif(void *dev);
+
+bool hinic5_get_pxe_en(void *hwdev);
+
+#endif /* _HINIC5_HWIF_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.c
new file mode 100644
index 000000000..f4e96d1b4
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.c
@@ -0,0 +1,1236 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <ipxe/io.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_csr.h"
+#include "hinic5_mgmt.h"
+#include "hinic5_hwif.h"
+#include "hinic5_eqs.h"
+#include "hinic5_hw_cfg.h"
+#include "hinic5_mbox.h"
+
+#define HINIC5_MBOX_INT_DST_FUNC_SHIFT 0
+#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
+/* 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_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_SET(val, field) \
+ (((val)&HINIC5_MBOX_INT_##field##_MASK) \
+ << HINIC5_MBOX_INT_##field##_SHIFT)
+
+enum hinic5_mbox_tx_status {
+ TX_NOT_DONE = 1,
+};
+
+#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_TRIGGER_AEQE_MASK 0x1
+#define HINIC5_MBOX_CTRL_TX_STATUS_MASK 0x1
+#define HINIC5_MBOX_CTRL_DST_FUNC_MASK 0x1FFF
+
+#define HINIC5_MBOX_CTRL_SET(val, field) \
+ (((val)&HINIC5_MBOX_CTRL_##field##_MASK) \
+ << HINIC5_MBOX_CTRL_##field##_SHIFT)
+
+#define MBOX_SEGLEN_MASK \
+ HINIC5_MSG_HEADER_SET(HINIC5_MSG_HEADER_SEG_LEN_MASK, SEG_LEN)
+
+#define MBOX_MSG_POLLING_TIMEOUT 500000 /* unit is 10us */
+#define HINIC5_MBOX_COMP_TIME 40000U
+#define MBOX_MSG_POLLING_WAIT 10
+
+#define MBOX_MAX_BUF_SZ 2048UL
+#define MBOX_HEADER_SZ 8
+#define HINIC5_MBOX_DATA_SIZE (MBOX_MAX_BUF_SZ - MBOX_HEADER_SZ)
+
+#define MBOX_TLP_HEADER_SZ 16
+
+/* 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
+
+/* Mbox write back status is 16B, only first 4B 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_STATUS_ERRCODE(wb) ((wb)&MBOX_WB_ERROR_CODE_MASK)
+
+#define SEQ_ID_START_VAL 0
+#define SEQ_ID_MAX_VAL 42
+
+#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_BODY_FROM_HDR(header) ((u8 *)(header) + MBOX_HEADER_SZ)
+#define MBOX_AREA(hwif) \
+ ((hwif)->cfg_regs_base + HINIC5_FUNC_CSR_MAILBOX_DATA_OFF)
+
+#define IS_PF_OR_PPF_SRC(src_func_idx) ((src_func_idx) < HINIC5_MAX_PF_FUNCS)
+
+#define MBOX_RESPONSE_ERROR 0x1
+#define MBOX_MSG_ID_MASK 0xF
+#define MBOX_MSG_ID(func_to_func) ((func_to_func)->send_msg_id)
+#define MBOX_MSG_ID_INC(func_to_func) \
+ (MBOX_MSG_ID(func_to_func) = (MBOX_MSG_ID(func_to_func) + 1) & \
+ MBOX_MSG_ID_MASK)
+
+/* Max message counter waits to process for one function */
+#define HINIC5_MAX_MSG_CNT_TO_PROCESS 10
+
+enum mbox_ordering_type {
+ STRONG_ORDER,
+};
+
+enum mbox_write_back_type {
+ WRITE_BACK = 1,
+};
+
+enum mbox_aeq_trig_type {
+ NOT_TRIGGER,
+ TRIGGER,
+};
+
+static int send_mbox_to_func(struct hinic5_mbox *func_to_func,
+ enum hinic5_mod_type mod, u16 cmd, void *msg,
+ u16 msg_len, u16 dst_func,
+ enum hinic5_msg_direction_type direction,
+ enum hinic5_msg_ack_type ack_type,
+ struct mbox_msg_info *msg_info);
+static int send_tlp_mbox_to_func(struct hinic5_mbox *func_to_func,
+ enum hinic5_mod_type mod, u16 cmd, void *msg,
+ u16 msg_len, u16 dst_func,
+ enum hinic5_msg_direction_type direction,
+ enum hinic5_msg_ack_type ack_type,
+ struct mbox_msg_info *msg_info);
+
+static int recv_vf_mbox_handler(struct hinic5_mbox *func_to_func,
+ struct hinic5_recv_mbox *recv_mbox,
+ void *buf_out, u16 *out_size,
+ __attribute__((unused)) void *param)
+{
+ int err = 0;
+
+ switch (recv_mbox->mod) {
+ case HINIC5_MOD_COMM:
+ break;
+ case HINIC5_MOD_CFGM:
+ err = cfg_mbx_vf_proc_msg(func_to_func->hwdev,
+ func_to_func->hwdev->cfg_mgmt,
+ recv_mbox->cmd, recv_mbox->mbox,
+ recv_mbox->mbox_len, buf_out,
+ out_size);
+ break;
+ case HINIC5_MOD_L2NIC:
+ break;
+ case HINIC5_MOD_HILINK:
+ break;
+ default:
+ IPXE_DRV_LOG(ERR, "No handler, mod: %d", recv_mbox->mod);
+ err = HINIC5_MBOX_VF_CMD_ERROR;
+ break;
+ }
+
+ return err;
+}
+
+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 };
+
+ if (recv_mbox->ack_type == HINIC5_MSG_ACK) {
+ msg_info.msg_id = recv_mbox->msg_info.msg_id;
+ if (err != 0) {
+ msg_info.status = HINIC5_MBOX_PF_SEND_ERR;
+ }
+
+ if (IS_TLP_MBX(src_func_idx)) {
+ send_tlp_mbox_to_func(func_to_func, recv_mbox->mod,
+ recv_mbox->cmd,
+ recv_mbox->buf_out, out_size,
+ src_func_idx, HINIC5_MSG_RESPONSE,
+ HINIC5_MSG_NO_ACK, &msg_info);
+ } else {
+ send_mbox_to_func(func_to_func, recv_mbox->mod,
+ recv_mbox->cmd, recv_mbox->buf_out,
+ out_size, src_func_idx,
+ HINIC5_MSG_RESPONSE,
+ HINIC5_MSG_NO_ACK, &msg_info);
+ }
+ }
+}
+
+static void recv_func_mbox_handler(struct hinic5_mbox *func_to_func,
+ struct hinic5_recv_mbox *recv_mbox,
+ u16 src_func_idx, void *param)
+{
+ struct hinic5_hwdev *hwdev = func_to_func->hwdev;
+ void *buf_out = recv_mbox->buf_out;
+ u16 out_size = MBOX_MAX_BUF_SZ;
+ int err = 0;
+
+ if (HINIC5_IS_VF(hwdev)) {
+ err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out,
+ &out_size, param);
+ } else {
+ err = -EINVAL;
+ IPXE_DRV_LOG(
+ ERR,
+ "PMD doesn't support non-VF handle mailbox message");
+ }
+
+ if (!out_size || err) {
+ out_size = MBOX_MSG_NO_DATA_LEN;
+ }
+
+ if (recv_mbox->ack_type == HINIC5_MSG_ACK) {
+ response_for_recv_func_mbox(func_to_func, recv_mbox, err,
+ out_size, src_func_idx);
+ }
+}
+
+static int resp_mbox_handler(struct hinic5_mbox *func_to_func,
+ struct hinic5_recv_mbox *recv_mbox)
+{
+ int ret;
+ if (recv_mbox->msg_info.msg_id == func_to_func->send_msg_id &&
+ func_to_func->event_flag == EVENT_START) {
+ func_to_func->event_flag = EVENT_SUCCESS;
+ ret = 0;
+ } else {
+ IPXE_DRV_LOG(
+ ERR,
+ "Mbox response timeout, current send msg id(0x%x), "
+ "recv msg id(0x%x), status(0x%x)",
+ func_to_func->send_msg_id, recv_mbox->msg_info.msg_id,
+ recv_mbox->msg_info.status);
+ ret = HINIC5_MSG_HANDLER_RES;
+ }
+ return ret;
+}
+
+static bool check_mbox_segment(struct hinic5_recv_mbox *recv_mbox,
+ u64 mbox_header)
+{
+ u8 seq_id, seg_len, msg_id, mod;
+ u16 src_func_idx, cmd;
+
+ seq_id = HINIC5_MSG_HEADER_GET(mbox_header, SEQID);
+ seg_len = HINIC5_MSG_HEADER_GET(mbox_header, SEG_LEN);
+ src_func_idx = HINIC5_MSG_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
+ msg_id = HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID);
+ mod = HINIC5_MSG_HEADER_GET(mbox_header, MODULE);
+ cmd = HINIC5_MSG_HEADER_GET(mbox_header, CMD);
+
+ if (seq_id > SEQ_ID_MAX_VAL || seg_len > MBOX_SEG_LEN) {
+ goto seg_err;
+ }
+
+ if (seq_id == 0) {
+ recv_mbox->seq_id = seq_id;
+ recv_mbox->msg_info.msg_id = msg_id;
+ recv_mbox->mod = mod;
+ recv_mbox->cmd = cmd;
+ } else {
+ if ((seq_id != recv_mbox->seq_id + 1) ||
+ msg_id != recv_mbox->msg_info.msg_id ||
+ mod != recv_mbox->mod || cmd != recv_mbox->cmd) {
+ goto seg_err;
+ }
+
+ recv_mbox->seq_id = seq_id;
+ }
+
+ return true;
+
+seg_err:
+ IPXE_DRV_LOG(ERR,
+ "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, recv_mbox->seq_id,
+ recv_mbox->msg_info.msg_id, recv_mbox->mod,
+ recv_mbox->cmd);
+ IPXE_DRV_LOG(ERR,
+ "Current seg info: seg len: 0x%x, seq id: 0x%x, "
+ "msg id: 0x%x, mod: 0x%x, cmd: 0x%x\n",
+ seg_len, seq_id, msg_id, mod, cmd);
+
+ return false;
+}
+
+static int recv_mbox_handler(struct hinic5_mbox *func_to_func, void *header,
+ struct hinic5_recv_mbox *recv_mbox, void *param)
+{
+ u64 mbox_header = *((u64 *)header);
+ void *mbox_body = MBOX_BODY_FROM_HDR(header);
+ u16 src_func_idx;
+ int pos;
+ u8 seq_id;
+
+ seq_id = HINIC5_MSG_HEADER_GET(mbox_header, SEQID);
+ src_func_idx = HINIC5_MSG_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
+
+ if (!check_mbox_segment(recv_mbox, mbox_header)) {
+ recv_mbox->seq_id = SEQ_ID_MAX_VAL;
+ return HINIC5_MSG_HANDLER_RES;
+ }
+
+ pos = seq_id * MBOX_SEG_LEN;
+ if (memcpy_s((void *)((u8 *)recv_mbox->mbox + pos),
+ (MBOX_MAX_BUF_SZ - pos), (void *)mbox_body,
+ (size_t)HINIC5_MSG_HEADER_GET(mbox_header, SEG_LEN)) !=
+ EOK) {
+ IPXE_DRV_LOG(ERR, "Memcpy mbox body failed.\n");
+ return HINIC5_MSG_HANDLER_RES;
+ }
+
+ if (!HINIC5_MSG_HEADER_GET(mbox_header, LAST)) {
+ return HINIC5_MSG_HANDLER_RES;
+ }
+
+ recv_mbox->cmd = HINIC5_MSG_HEADER_GET(mbox_header, CMD);
+ recv_mbox->mod = HINIC5_MSG_HEADER_GET(mbox_header, MODULE);
+ recv_mbox->mbox_len = HINIC5_MSG_HEADER_GET(mbox_header, MSG_LEN);
+ recv_mbox->ack_type = HINIC5_MSG_HEADER_GET(mbox_header, NO_ACK);
+ recv_mbox->msg_info.msg_id = HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID);
+ recv_mbox->msg_info.status = HINIC5_MSG_HEADER_GET(mbox_header, STATUS);
+ recv_mbox->seq_id = SEQ_ID_MAX_VAL;
+
+ if (HINIC5_MSG_HEADER_GET(mbox_header, DIRECTION) ==
+ HINIC5_MSG_RESPONSE) {
+ return resp_mbox_handler(func_to_func, recv_mbox);
+ }
+
+ recv_func_mbox_handler(func_to_func, recv_mbox, src_func_idx, param);
+ return HINIC5_MSG_HANDLER_RES;
+}
+
+static inline int hinic5_mbox_get_index(int func)
+{
+ return (func == HINIC5_MGMT_SRC_ID) ? HINIC5_MBOX_MPU_INDEX :
+ HINIC5_MBOX_PF_INDEX;
+}
+
+int hinic5_mbox_func_aeqe_handler(void *handle, u8 *header,
+ __attribute__((unused)) u8 size, void *param,
+ __attribute__((unused)) size_t header_len)
+{
+ struct hinic5_mbox *func_to_func = NULL;
+ struct hinic5_recv_mbox *recv_mbox = NULL;
+ u64 mbox_header = *((u64 *)header);
+ u64 src, dir;
+
+ func_to_func = ((struct hinic5_hwdev *)handle)->func_to_func;
+
+ dir = HINIC5_MSG_HEADER_GET(mbox_header, DIRECTION);
+ src = HINIC5_MSG_HEADER_GET(mbox_header, SRC_GLB_FUNC_IDX);
+
+ src = hinic5_mbox_get_index((int)src);
+ recv_mbox = (dir == HINIC5_MSG_DIRECT_SEND) ?
+ &func_to_func->mbox_send[src] :
+ &func_to_func->mbox_resp[src];
+
+ return recv_mbox_handler(func_to_func, (u64 *)header, recv_mbox, param);
+}
+
+static void clear_mbox_status(struct hinic5_send_mbox *mbox)
+{
+ *mbox->wb_status = 0;
+
+ /* Clear mailbox write back status */
+ wmb();
+}
+
+static void mbox_copy_header(struct hinic5_send_mbox *mbox, u64 *header)
+{
+ u32 *data = (u32 *)header;
+ u32 i, idx_max = MBOX_HEADER_SZ / sizeof(u32);
+
+ for (i = 0; i < idx_max; i++) {
+ writel(cpu_to_be32(*(data + i)), mbox->data + i * sizeof(u32));
+ }
+}
+
+#define MBOX_DMA_MSG_INIT_XOR_VAL 0x5a5a5a5a
+static u32 mbox_dma_msg_xor(u32 *data, u16 msg_len)
+{
+ u32 mbox_xor = MBOX_DMA_MSG_INIT_XOR_VAL;
+ u16 dw_len = msg_len / sizeof(u32);
+ u16 i;
+
+ for (i = 0; i < dw_len; i++) {
+ mbox_xor ^= data[i];
+ }
+
+ return mbox_xor;
+}
+
+static void mbox_copy_send_data_addr(struct hinic5_send_mbox *mbox, u16 seg_len)
+{
+ u32 addr_h, addr_l, mbox_xor;
+
+ mbox_xor = mbox_dma_msg_xor(mbox->sbuff_vaddr, seg_len);
+ addr_h = upper_32_bits(mbox->sbuff_paddr);
+ addr_l = lower_32_bits(mbox->sbuff_paddr);
+
+ writel(cpu_to_be32(mbox_xor), mbox->data + MBOX_HEADER_SZ);
+ writel(cpu_to_be32(addr_h), mbox->data + MBOX_HEADER_SZ + sizeof(u32));
+ writel(cpu_to_be32(addr_l),
+ mbox->data + MBOX_HEADER_SZ + 0x2 * sizeof(u32));
+ writel(cpu_to_be32((u32)seg_len),
+ mbox->data + MBOX_HEADER_SZ + 0x3 * sizeof(u32));
+ /* Reserved */
+ writel(0, mbox->data + MBOX_HEADER_SZ + 0x4 * sizeof(u32));
+ writel(0, mbox->data + MBOX_HEADER_SZ + 0x5 * sizeof(u32));
+}
+
+static void mbox_copy_send_data(struct hinic5_send_mbox *mbox, void *seg,
+ u16 seg_len)
+{
+ u32 *data = seg;
+ u32 data_len, chk_sz = sizeof(u32);
+ u32 i, idx_max;
+ u8 mbox_max_buf[MBOX_SEG_LEN] = { 0 };
+
+ /* The mbox message should be aligned in 4 bytes. */
+ if ((seg_len % chk_sz) != 0) {
+ if (memcpy_s(mbox_max_buf, MBOX_SEG_LEN, seg, seg_len) != EOK) {
+ IPXE_DRV_LOG(ERR, "Memcpy mbox buf failed.\n");
+ return;
+ }
+ data = (u32 *)mbox_max_buf;
+ }
+
+ data_len = seg_len;
+ idx_max = HINIC5_ALIGN(data_len, chk_sz) / chk_sz;
+
+ for (i = 0; i < idx_max; i++) {
+ writel(cpu_to_be32(*(data + i)),
+ mbox->data + MBOX_HEADER_SZ + i * sizeof(u32));
+ }
+}
+
+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 _dst_func = dst_func;
+
+ /* If VF, function ids must self-learning by HW(PPF=1 PF=0) */
+ if (HINIC5_IS_VF(func_to_func->hwdev) &&
+ _dst_func != HINIC5_MGMT_SRC_ID) {
+ if (_dst_func ==
+ HINIC5_HWIF_PPF_IDX(func_to_func->hwdev->hwif)) {
+ _dst_func = 1;
+ } else {
+ _dst_func = 0;
+ }
+ }
+
+ mbox_int = HINIC5_MBOX_INT_SET(dst_aeqn, DST_AEQN) |
+ HINIC5_MBOX_INT_SET(0, SRC_RESP_AEQN) |
+ HINIC5_MBOX_INT_SET(NO_DMA_ATTRIBUTE_VAL, STAT_DMA) |
+ HINIC5_MBOX_INT_SET(HINIC5_ALIGN(seg_len + MBOX_HEADER_SZ,
+ 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(); /* Writing the mbox intr attributes */
+ mbox_ctrl = HINIC5_MBOX_CTRL_SET(TX_NOT_DONE, TX_STATUS);
+
+ mbox_ctrl |= HINIC5_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE);
+
+ mbox_ctrl |= HINIC5_MBOX_CTRL_SET(_dst_func, DST_FUNC);
+
+ hinic5_hwif_write_reg(func_to_func->hwdev->hwif,
+ HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF, mbox_ctrl);
+}
+
+static void dump_mbox_reg(struct hinic5_hwdev *hwdev)
+{
+ u32 val;
+
+ val = hinic5_hwif_read_reg(hwdev->hwif,
+ HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF);
+ IPXE_DRV_LOG(ERR, "Mailbox control reg: 0x%x", val);
+ val = hinic5_hwif_read_reg(hwdev->hwif,
+ HINIC5_FUNC_CSR_MAILBOX_INT_OFFSET_OFF);
+ IPXE_DRV_LOG(ERR, "Mailbox interrupt offset: 0x%x", val);
+}
+
+static u16 get_mbox_status(struct hinic5_send_mbox *mbox)
+{
+ /* Write back is 16B, but only use first 4B */
+ u64 wb_val = be64_to_cpu(*mbox->wb_status);
+
+ rmb(); /* Verify reading before check */
+
+ return (u16)(wb_val & MBOX_WB_STATUS_ERRCODE_MASK);
+}
+
+static int send_mbox_seg(struct hinic5_mbox *func_to_func, u64 header,
+ u16 dst_func, void *seg, u16 seg_len,
+ __attribute__((unused)) void *msg_info)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+ struct hinic5_hwdev *hwdev = func_to_func->hwdev;
+ u8 num_aeqs = hwdev->hwif->attr.num_aeqs;
+ u16 dst_aeqn, wb_status = 0, errcode;
+ u16 seq_dir = HINIC5_MSG_HEADER_GET(header, DIRECTION);
+ u32 cnt = 0;
+
+ /* Mbox to mgmt cpu, hardware doesn't care dst aeq id */
+ if (num_aeqs >= HINIC5_MGMT_RSP_MSG_AEQ) {
+ dst_aeqn = (seq_dir == HINIC5_MSG_DIRECT_SEND) ?
+ HINIC5_ASYNC_MSG_AEQ :
+ HINIC5_MBOX_RSP_MSG_AEQ;
+ } else {
+ dst_aeqn = 0;
+ }
+
+ clear_mbox_status(send_mbox);
+
+ mbox_copy_header(send_mbox, &header);
+
+ mbox_copy_send_data(send_mbox, seg, seg_len);
+
+ write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_len);
+
+ wmb(); /* Writing the mbox msg attributes */
+
+ while (cnt < MBOX_MSG_POLLING_TIMEOUT) {
+ wb_status = get_mbox_status(send_mbox);
+ if (MBOX_STATUS_FINISHED(wb_status)) {
+ break;
+ }
+
+ udelay(MBOX_MSG_POLLING_WAIT);
+ cnt++;
+ }
+
+ if (cnt == MBOX_MSG_POLLING_TIMEOUT) {
+ IPXE_DRV_LOG(ERR,
+ "Send mailbox segment timeout, wb status: 0x%x",
+ wb_status);
+ dump_mbox_reg(hwdev);
+ return -ETIMEDOUT;
+ }
+
+ if (!MBOX_STATUS_SUCCESS(wb_status)) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Send mailbox segment to function %d error, wb status: 0x%x",
+ dst_func, wb_status);
+ errcode = MBOX_STATUS_ERRCODE(wb_status);
+ return errcode ? errcode : -EFAULT;
+ }
+
+ return 0;
+}
+
+static int send_tlp_mbox_seg(struct hinic5_mbox *func_to_func, u64 header,
+ u16 dst_func, void *seg, u16 seg_len,
+ __attribute__((unused)) void *msg_info)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+ struct hinic5_hwdev *hwdev = func_to_func->hwdev;
+ u8 num_aeqs = hwdev->hwif->attr.num_aeqs;
+ u16 dst_aeqn, wb_status = 0, errcode;
+ u16 seq_dir = HINIC5_MSG_HEADER_GET(header, DIRECTION);
+ u32 cnt = 0;
+
+ /* Mbox to mgmt cpu, hardware doesn't care dst aeq id */
+ if (num_aeqs >= HINIC5_MGMT_RSP_MSG_AEQ) {
+ dst_aeqn = (seq_dir == HINIC5_MSG_DIRECT_SEND) ?
+ HINIC5_ASYNC_MSG_AEQ :
+ HINIC5_MBOX_RSP_MSG_AEQ;
+ } else {
+ dst_aeqn = 0;
+ }
+
+ clear_mbox_status(send_mbox);
+
+ mbox_copy_header(send_mbox, &header);
+
+ /* Copy data to DMA buffer */
+ if (memcpy_s((void *)send_mbox->sbuff_vaddr, MBOX_MAX_BUF_SZ,
+ (void *)seg, (size_t)seg_len) != EOK) {
+ IPXE_DRV_LOG(ERR, "Memcpy mbox buf failed.\n");
+ return -ENOMEM;
+ }
+
+ /* Copy data address to mailbox ctrl csr */
+ mbox_copy_send_data_addr(send_mbox, seg_len);
+
+ /* Send tlp mailbox, needs to change the txsize to 16 */
+ write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn,
+ MBOX_TLP_HEADER_SZ);
+
+ wmb(); /* Writing the mbox msg attributes */
+
+ while (cnt < MBOX_MSG_POLLING_TIMEOUT) {
+ wb_status = get_mbox_status(send_mbox);
+ if (MBOX_STATUS_FINISHED(wb_status)) {
+ break;
+ }
+
+ udelay(MBOX_MSG_POLLING_WAIT);
+ cnt++;
+ }
+
+ if (cnt == MBOX_MSG_POLLING_TIMEOUT) {
+ IPXE_DRV_LOG(ERR,
+ "Send mailbox segment timeout, wb status: 0x%x",
+ wb_status);
+ dump_mbox_reg(hwdev);
+ return -ETIMEDOUT;
+ }
+
+ if (!MBOX_STATUS_SUCCESS(wb_status)) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Send mailbox segment to function %d error, wb status: 0x%x",
+ dst_func, wb_status);
+ errcode = MBOX_STATUS_ERRCODE(wb_status);
+ return errcode ? errcode : -EFAULT;
+ }
+
+ return 0;
+}
+
+static int send_mbox_to_func(struct hinic5_mbox *func_to_func,
+ enum hinic5_mod_type mod, u16 cmd, void *msg,
+ u16 msg_len, u16 dst_func,
+ enum hinic5_msg_direction_type direction,
+ enum hinic5_msg_ack_type ack_type,
+ struct mbox_msg_info *msg_info)
+{
+ int err = 0;
+ u32 seq_id = 0;
+ u16 seg_len = MBOX_SEG_LEN;
+ u16 rsp_aeq_id, left = msg_len;
+ u8 *msg_seg = (u8 *)msg;
+ u64 header = 0;
+
+ rsp_aeq_id = HINIC5_MBOX_RSP_MSG_AEQ;
+
+ header = HINIC5_MSG_HEADER_SET(msg_len, MSG_LEN) |
+ HINIC5_MSG_HEADER_SET(mod, MODULE) |
+ HINIC5_MSG_HEADER_SET(seg_len, SEG_LEN) |
+ HINIC5_MSG_HEADER_SET(ack_type, NO_ACK) |
+ HINIC5_MSG_HEADER_SET(HINIC5_DATA_INLINE, DATA_TYPE) |
+ HINIC5_MSG_HEADER_SET(SEQ_ID_START_VAL, SEQID) |
+ HINIC5_MSG_HEADER_SET(NOT_LAST_SEGMENT, LAST) |
+ HINIC5_MSG_HEADER_SET(direction, DIRECTION) |
+ HINIC5_MSG_HEADER_SET(cmd, CMD) |
+ /* The VF's offset to it's associated PF */
+ HINIC5_MSG_HEADER_SET(msg_info->msg_id, MSG_ID) |
+ HINIC5_MSG_HEADER_SET(rsp_aeq_id, AEQ_ID) |
+ HINIC5_MSG_HEADER_SET(HINIC5_MSG_FROM_MBOX, SOURCE) |
+ HINIC5_MSG_HEADER_SET(!!msg_info->status, STATUS);
+
+ while (!(HINIC5_MSG_HEADER_GET(header, LAST))) {
+ if (left <= MBOX_SEG_LEN) {
+ header &= ~MBOX_SEGLEN_MASK;
+ header |= HINIC5_MSG_HEADER_SET(left, SEG_LEN);
+ header |= HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST);
+
+ seg_len = left;
+ }
+
+ err = send_mbox_seg(func_to_func, header, dst_func, msg_seg,
+ seg_len, msg_info);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR,
+ "Send mbox seg failed, seq_id: 0x%llx",
+ HINIC5_MSG_HEADER_GET(header, SEQID));
+
+ goto send_err;
+ }
+
+ left -= MBOX_SEG_LEN;
+ msg_seg += MBOX_SEG_LEN;
+
+ seq_id++;
+ header &= ~(HINIC5_MSG_HEADER_SET(HINIC5_MSG_HEADER_SEQID_MASK,
+ SEQID));
+ header |= HINIC5_MSG_HEADER_SET(seq_id, SEQID);
+ }
+
+send_err:
+
+ return err;
+}
+
+static int send_tlp_mbox_to_func(struct hinic5_mbox *func_to_func,
+ enum hinic5_mod_type mod, u16 cmd, void *msg,
+ u16 msg_len, u16 dst_func,
+ enum hinic5_msg_direction_type direction,
+ enum hinic5_msg_ack_type ack_type,
+ struct mbox_msg_info *msg_info)
+{
+ struct hinic5_hwdev *hwdev = func_to_func->hwdev;
+ u8 *msg_seg = (u8 *)msg;
+ int err = 0;
+ u16 rsp_aeq_id;
+ u64 header = 0;
+
+ rsp_aeq_id = HINIC5_MBOX_RSP_MSG_AEQ;
+
+ header = HINIC5_MSG_HEADER_SET(MBOX_TLP_HEADER_SZ, MSG_LEN) |
+ HINIC5_MSG_HEADER_SET(MBOX_TLP_HEADER_SZ, SEG_LEN) |
+ HINIC5_MSG_HEADER_SET(mod, MODULE) |
+ HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
+ HINIC5_MSG_HEADER_SET(ack_type, NO_ACK) |
+ HINIC5_MSG_HEADER_SET(HINIC5_DATA_DMA, DATA_TYPE) |
+ HINIC5_MSG_HEADER_SET(SEQ_ID_START_VAL, SEQID) |
+ HINIC5_MSG_HEADER_SET(direction, DIRECTION) |
+ HINIC5_MSG_HEADER_SET(cmd, CMD) |
+ /* The VF's offset to it's associated PF */
+ HINIC5_MSG_HEADER_SET(msg_info->msg_id, MSG_ID) |
+ HINIC5_MSG_HEADER_SET(rsp_aeq_id, AEQ_ID) |
+ HINIC5_MSG_HEADER_SET(HINIC5_MSG_FROM_MBOX, SOURCE) |
+ HINIC5_MSG_HEADER_SET(!!msg_info->status, STATUS) |
+ HINIC5_MSG_HEADER_SET(hinic5_global_func_id(hwdev),
+ SRC_GLB_FUNC_IDX);
+
+ err = send_tlp_mbox_seg(func_to_func, header, dst_func, msg_seg,
+ msg_len, msg_info);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Send mbox seg failed, seq_id: 0x%llx",
+ HINIC5_MSG_HEADER_GET(header, SEQID));
+ }
+
+ return err;
+}
+
+static void set_mbox_to_func_event(struct hinic5_mbox *func_to_func,
+ enum mbox_event_state event_flag)
+{
+ func_to_func->event_flag = event_flag;
+}
+
+static int mbox_to_func_process(struct hinic5_mbox *func_to_func, u16 dst_func,
+ enum hinic5_mod_type mod, u16 cmd, u32 timeout,
+ struct hinic5_recv_mbox *mbox_for_resp,
+ u16 in_size, void *buf_in)
+{
+ int err = 0;
+ struct mbox_msg_info msg_info = { 0 };
+ struct hinic5_eq *aeq = NULL;
+ u32 time;
+
+ msg_info.msg_id = MBOX_MSG_ID_INC(func_to_func);
+ if (IS_TLP_MBX(dst_func)) {
+ err = send_tlp_mbox_to_func(func_to_func, mod, cmd, buf_in,
+ in_size, dst_func,
+ HINIC5_MSG_DIRECT_SEND,
+ HINIC5_MSG_ACK, &msg_info);
+ } else {
+ err = send_mbox_to_func(func_to_func, mod, cmd, buf_in, in_size,
+ dst_func, HINIC5_MSG_DIRECT_SEND,
+ HINIC5_MSG_ACK, &msg_info);
+ }
+
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Send mailbox failed, msg_id: %d",
+ msg_info.msg_id);
+ set_mbox_to_func_event(func_to_func, EVENT_FAIL);
+ return -EFAULT;
+ }
+
+ time = msecs_to_jiffies((timeout != 0) ? timeout :
+ HINIC5_MBOX_COMP_TIME);
+ aeq = &func_to_func->hwdev->aeqs->aeq[HINIC5_MBOX_RSP_MSG_AEQ];
+ err = hinic5_aeq_poll_msg(aeq, time, NULL);
+ if (err != 0) {
+ set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
+ IPXE_DRV_LOG(ERR, "Send mailbox message time out");
+ return -ETIMEDOUT;
+ }
+
+ if (mod != mbox_for_resp->mod || cmd != mbox_for_resp->cmd) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Invalid response mbox message, mod: 0x%x, cmd: 0x%x, expect mod: 0x%x, cmd: 0x%x\n",
+ mbox_for_resp->mod, mbox_for_resp->cmd, mod, cmd);
+ return -EFAULT;
+ }
+
+ if (mbox_for_resp->msg_info.status != 0) {
+ err = mbox_for_resp->msg_info.status;
+ }
+
+ return err;
+}
+
+static int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func,
+ enum hinic5_mod_type mod, u16 cmd, u16 dst_func,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u32 timeout)
+{
+ /* Use mbox_resp to hole data which responsed from other function */
+ struct hinic5_recv_mbox *mbox_for_resp = NULL;
+ u16 mbox_rsp_idx;
+ int err;
+
+ mbox_rsp_idx = (u16)hinic5_mbox_get_index(dst_func);
+ mbox_for_resp = &func_to_func->mbox_resp[mbox_rsp_idx];
+
+ set_mbox_to_func_event(func_to_func, EVENT_START);
+
+ err = mbox_to_func_process(func_to_func, dst_func, mod, cmd, timeout,
+ mbox_for_resp, in_size, buf_in);
+ if (err != 0) {
+ goto send_err;
+ }
+
+ if (buf_out && out_size) {
+ if (*out_size < mbox_for_resp->mbox_len) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Invalid response mbox message length: %d for "
+ "mod: %d cmd: %d, should less than: %d",
+ mbox_for_resp->mbox_len, mod, cmd, *out_size);
+ err = -EFAULT;
+ goto send_err;
+ }
+
+ if (mbox_for_resp->mbox_len != 0) {
+ if (memcpy_s(buf_out, *out_size, mbox_for_resp->mbox,
+ (size_t)(mbox_for_resp->mbox_len)) !=
+ EOK) {
+ err = -ENOMEM;
+ goto send_err;
+ }
+ }
+
+ *out_size = mbox_for_resp->mbox_len;
+ }
+
+send_err:
+
+ return err;
+}
+
+static int
+mbox_func_params_valid(__attribute__((unused)) struct hinic5_mbox *func_to_func,
+ void *buf_in, u16 in_size)
+{
+ if (!buf_in || !in_size) {
+ return -EINVAL;
+ }
+
+ if (in_size > HINIC5_MBOX_DATA_SIZE) {
+ IPXE_DRV_LOG(ERR, "Mbox msg len(%d) exceed limit(%lu)", in_size,
+ HINIC5_MBOX_DATA_SIZE);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hinic5_mbox_to_func_no_ack(struct hinic5_hwdev *hwdev, u16 func_idx,
+ enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size)
+{
+ struct hinic5_mbox *func_to_func = hwdev->func_to_func;
+ struct mbox_msg_info msg_info = { 0 };
+ int err;
+
+ err = mbox_func_params_valid(hwdev->func_to_func, buf_in, in_size);
+ if (err != 0) {
+ return err;
+ }
+
+ /* Temp test,only get version api will use tlp mailbox */
+ if (IS_TLP_MBX(func_idx)) {
+ err = send_tlp_mbox_to_func(func_to_func, mod, cmd, buf_in,
+ in_size, func_idx,
+ HINIC5_MSG_DIRECT_SEND,
+ HINIC5_MSG_NO_ACK, &msg_info);
+ } else {
+ err = send_mbox_to_func(func_to_func, mod, cmd, buf_in, in_size,
+ func_idx, HINIC5_MSG_DIRECT_SEND,
+ HINIC5_MSG_NO_ACK, &msg_info);
+ }
+
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Send mailbox no ack failed");
+ }
+
+ return err;
+}
+
+int hinic5_send_mbox_to_mgmt(struct hinic5_hwdev *hwdev,
+ enum hinic5_mod_type mod, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size,
+ u32 timeout)
+{
+ struct hinic5_mbox *func_to_func = hwdev->func_to_func;
+ int err;
+
+ err = mbox_func_params_valid(func_to_func, buf_in, in_size);
+ if (err != 0) {
+ return err;
+ }
+
+ return hinic5_mbox_to_func(func_to_func, mod, cmd, HINIC5_MGMT_SRC_ID,
+ buf_in, in_size, buf_out, out_size, timeout);
+}
+
+void hinic5_response_mbox_to_mgmt(struct hinic5_hwdev *hwdev,
+ enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size, u16 msg_id)
+{
+ struct mbox_msg_info msg_info;
+ u16 dst_func;
+
+ msg_info.msg_id = (u8)msg_id;
+ msg_info.status = 0;
+ dst_func = HINIC5_MGMT_SRC_ID;
+
+ if (IS_TLP_MBX(dst_func)) {
+ send_tlp_mbox_to_func(hwdev->func_to_func, mod, cmd, buf_in,
+ in_size, HINIC5_MGMT_SRC_ID,
+ HINIC5_MSG_RESPONSE, HINIC5_MSG_NO_ACK,
+ &msg_info);
+ } else {
+ send_mbox_to_func(hwdev->func_to_func, mod, cmd, buf_in,
+ in_size, HINIC5_MGMT_SRC_ID,
+ HINIC5_MSG_RESPONSE, HINIC5_MSG_NO_ACK,
+ &msg_info);
+ }
+}
+
+int hinic5_send_mbox_to_mgmt_no_ack(struct hinic5_hwdev *hwdev,
+ enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size)
+{
+ struct hinic5_mbox *func_to_func = hwdev->func_to_func;
+ int err;
+
+ err = mbox_func_params_valid(func_to_func, buf_in, in_size);
+ if (err != 0) {
+ return err;
+ }
+
+ return hinic5_mbox_to_func_no_ack(hwdev, HINIC5_MGMT_SRC_ID, mod, cmd,
+ buf_in, in_size);
+}
+
+int hinic5_mbox_to_pf(struct hinic5_hwdev *hwdev, enum hinic5_mod_type mod,
+ u16 cmd, void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u32 timeout)
+{
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ err = mbox_func_params_valid(hwdev->func_to_func, buf_in, in_size);
+ if (err != 0) {
+ return err;
+ }
+
+ if (!HINIC5_IS_VF(hwdev)) {
+ IPXE_DRV_LOG(ERR, "Params error, func_type: %d",
+ hinic5_func_type(hwdev));
+ return -EINVAL;
+ }
+
+ return hinic5_mbox_to_func(hwdev->func_to_func, mod, cmd,
+ hinic5_pf_id_of_vf(hwdev), buf_in, in_size,
+ buf_out, out_size, timeout);
+}
+
+int hinic5_mbox_to_vf(struct hinic5_hwdev *hwdev, enum hinic5_mod_type mod,
+ u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size, u32 timeout)
+{
+ struct hinic5_mbox *func_to_func = NULL;
+ u16 dst_func_idx;
+ int err = 0;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ func_to_func = hwdev->func_to_func;
+ err = mbox_func_params_valid(func_to_func, buf_in, in_size);
+ if (err != 0) {
+ return err;
+ }
+
+ if (HINIC5_IS_VF(hwdev)) {
+ IPXE_DRV_LOG(ERR, "Params error, func_type: %d",
+ hinic5_func_type(hwdev));
+ return -EINVAL;
+ }
+
+ if (!vf_id) {
+ IPXE_DRV_LOG(ERR, "VF id: %d error!", vf_id);
+ return -EINVAL;
+ }
+
+ /*
+ * The sum of vf_offset_to_pf + vf_id is the VF's global function id of
+ * VF in this pf
+ */
+ dst_func_idx = hinic5_glb_pf_vf_offset(hwdev) + vf_id;
+
+ return hinic5_mbox_to_func(func_to_func, mod, cmd, dst_func_idx, buf_in,
+ in_size, buf_out, out_size, timeout);
+}
+
+static int init_mbox_info(struct hinic5_recv_mbox *mbox_info,
+ int mbox_max_buf_sz)
+{
+ int err;
+
+ mbox_info->seq_id = SEQ_ID_MAX_VAL;
+
+ mbox_info->mbox = zalloc((size_t)mbox_max_buf_sz); /*lint !e571*/
+ if (!mbox_info->mbox) {
+ return -ENOMEM;
+ }
+
+ mbox_info->buf_out = zalloc((size_t)mbox_max_buf_sz); /*lint !e571*/
+ if (!mbox_info->buf_out) {
+ err = -ENOMEM;
+ goto alloc_buf_out_err;
+ }
+
+ return 0;
+
+alloc_buf_out_err:
+ free(mbox_info->mbox);
+
+ return err;
+}
+
+static void clean_mbox_info(struct hinic5_recv_mbox *mbox_info)
+{
+ free(mbox_info->buf_out);
+ free(mbox_info->mbox);
+}
+
+static int alloc_mbox_info(struct hinic5_recv_mbox *mbox_info,
+ int mbox_max_buf_sz)
+{
+ u16 func_idx, i;
+ int err;
+
+ for (func_idx = 0; func_idx < HINIC5_MAX_FUNCTIONS + 1; func_idx++) {
+ err = init_mbox_info(&mbox_info[func_idx], mbox_max_buf_sz);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init mbox info failed");
+ goto init_mbox_info_err;
+ }
+ }
+
+ return 0;
+
+init_mbox_info_err:
+ for (i = 0; i < func_idx; i++) {
+ clean_mbox_info(&mbox_info[i]);
+ }
+
+ return err;
+}
+
+static void free_mbox_info(struct hinic5_recv_mbox *mbox_info)
+{
+ u16 func_idx;
+
+ for (func_idx = 0; func_idx < HINIC5_MAX_FUNCTIONS + 1; func_idx++) {
+ clean_mbox_info(&mbox_info[func_idx]);
+ }
+}
+
+static void prepare_send_mbox(struct hinic5_mbox *func_to_func)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+
+ send_mbox->data = MBOX_AREA(func_to_func->hwdev->hwif);
+}
+
+static int alloc_mbox_wb_status(struct hinic5_mbox *func_to_func)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+ struct hinic5_hwdev *hwdev = func_to_func->hwdev;
+ u32 addr_h, addr_l;
+
+ send_mbox->wb_mz =
+ hinic5_dma_alloc(MBOX_WB_STATUS_LEN, HINIC5_CACHE_LINE_SIZE);
+ if (!send_mbox->wb_mz) {
+ return -ENOMEM;
+ }
+
+ send_mbox->wb_vaddr = send_mbox->wb_mz->virt_addr;
+ send_mbox->wb_paddr = send_mbox->wb_mz->phys_addr;
+ send_mbox->wb_status = send_mbox->wb_vaddr;
+
+ addr_h = upper_32_bits(send_mbox->wb_paddr);
+ addr_l = lower_32_bits(send_mbox->wb_paddr);
+
+ hinic5_hwif_write_reg(hwdev->hwif, HINIC5_FUNC_CSR_MAILBOX_RESULT_H_OFF,
+ addr_h);
+ hinic5_hwif_write_reg(hwdev->hwif, HINIC5_FUNC_CSR_MAILBOX_RESULT_L_OFF,
+ addr_l);
+
+ return 0;
+}
+
+static void free_mbox_wb_status(struct hinic5_mbox *func_to_func)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+ struct hinic5_hwdev *hwdev = func_to_func->hwdev;
+
+ hinic5_hwif_write_reg(hwdev->hwif, HINIC5_FUNC_CSR_MAILBOX_RESULT_H_OFF,
+ 0);
+ hinic5_hwif_write_reg(hwdev->hwif, HINIC5_FUNC_CSR_MAILBOX_RESULT_L_OFF,
+ 0);
+
+ hinic5_dma_free(send_mbox->wb_mz);
+}
+
+static int alloc_mbox_tlp_buffer(struct hinic5_mbox *func_to_func)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+
+ send_mbox->sbuff_mz =
+ hinic5_dma_alloc(MBOX_MAX_BUF_SZ, MBOX_MAX_BUF_SZ);
+ if (!send_mbox->sbuff_mz) {
+ return -ENOMEM;
+ }
+
+ send_mbox->sbuff_vaddr = send_mbox->sbuff_mz->virt_addr;
+ send_mbox->sbuff_paddr = send_mbox->sbuff_mz->phys_addr;
+
+ return 0;
+}
+
+static void free_mbox_tlp_buffer(struct hinic5_mbox *func_to_func)
+{
+ struct hinic5_send_mbox *send_mbox = &func_to_func->send_mbox;
+
+ hinic5_dma_free(send_mbox->sbuff_mz);
+}
+
+int hinic5_func_to_func_init(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_mbox *func_to_func;
+ int err;
+
+ func_to_func = (struct hinic5_mbox *)zalloc(sizeof(*func_to_func));
+ if (!func_to_func) {
+ return -ENOMEM;
+ }
+
+ hwdev->func_to_func = func_to_func;
+ func_to_func->hwdev = hwdev;
+
+ err = alloc_mbox_info(func_to_func->mbox_send, MBOX_MAX_BUF_SZ);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Alloc mem for mbox_active failed");
+ goto alloc_mbox_for_send_err;
+ }
+
+ err = alloc_mbox_info(func_to_func->mbox_resp, MBOX_MAX_BUF_SZ);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Alloc mem for mbox_passive failed");
+ goto alloc_mbox_for_resp_err;
+ }
+
+ /* Need to modify, not ok in linux */
+ err = alloc_mbox_tlp_buffer(func_to_func);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Alloc mbox send buffer failed");
+ goto alloc_tlp_buffer_err;
+ }
+
+ err = alloc_mbox_wb_status(func_to_func);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Alloc mbox write back status failed");
+ goto alloc_wb_status_err;
+ }
+
+ prepare_send_mbox(func_to_func);
+
+ return 0;
+
+alloc_wb_status_err:
+ free_mbox_tlp_buffer(func_to_func);
+
+alloc_tlp_buffer_err:
+ free_mbox_info(func_to_func->mbox_resp);
+
+alloc_mbox_for_resp_err:
+ free_mbox_info(func_to_func->mbox_send);
+
+alloc_mbox_for_send_err:
+ hwdev->func_to_func = NULL;
+ free(func_to_func);
+
+ return err;
+}
+
+void hinic5_func_to_func_free(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_mbox *func_to_func = hwdev->func_to_func;
+
+ free_mbox_wb_status(func_to_func);
+ free_mbox_tlp_buffer(func_to_func);
+ free_mbox_info(func_to_func->mbox_resp);
+ free_mbox_info(func_to_func->mbox_send);
+
+ free(func_to_func);
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.h
new file mode 100644
index 000000000..bdf1a0a8d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mbox.h
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_MBOX_H_
+#define _HINIC5_MBOX_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include "hinic5_mgmt.h"
+
+#define HINIC5_MBOX_PF_SEND_ERR 0x1
+#define HINIC5_MBOX_PF_BUSY_ACTIVE_FW 0x2
+#define HINIC5_MBOX_VF_CMD_ERROR 0x3
+
+#define HINIC5_MGMT_SRC_ID 0x1FFF
+
+#define HINIC5_MAX_PF_FUNCS 32
+
+/* Message header define */
+#define HINIC5_MSG_HEADER_SRC_GLB_FUNC_IDX_SHIFT 0
+#define HINIC5_MSG_HEADER_STATUS_SHIFT 13
+#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_MSG_LEN_SHIFT 32
+#define HINIC5_MSG_HEADER_MODULE_SHIFT 43
+#define HINIC5_MSG_HEADER_SEG_LEN_SHIFT 48
+#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_CMD_MASK 0x3FF
+#define HINIC5_MSG_HEADER_MSG_ID_MASK 0xF
+#define HINIC5_MSG_HEADER_AEQ_ID_MASK 0x3
+#define HINIC5_MSG_HEADER_SOURCE_MASK 0x1
+#define HINIC5_MSG_HEADER_STATUS_MASK 0x1
+#define HINIC5_MSG_HEADER_SRC_GLB_FUNC_IDX_MASK 0x1FFF
+
+#define HINIC5_MSG_HEADER_MSG_LEN_MASK 0x7FF
+#define HINIC5_MSG_HEADER_MODULE_MASK 0x1F
+#define HINIC5_MSG_HEADER_SEG_LEN_MASK 0x3F
+#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 IS_TLP_MBX(dst_func) ((dst_func) == HINIC5_MGMT_SRC_ID)
+
+enum hinic5_msg_direction_type {
+ HINIC5_MSG_DIRECT_SEND = 0,
+ HINIC5_MSG_RESPONSE = 1
+};
+
+enum hinic5_msg_segment_type { NOT_LAST_SEGMENT = 0, LAST_SEGMENT = 1 };
+
+enum hinic5_msg_ack_type { HINIC5_MSG_ACK, HINIC5_MSG_NO_ACK };
+
+enum hinic5_data_type { HINIC5_DATA_INLINE = 0, HINIC5_DATA_DMA = 1 };
+
+enum hinic5_msg_src_type { HINIC5_MSG_FROM_MGMT = 0, HINIC5_MSG_FROM_MBOX = 1 };
+
+enum hinic5_msg_aeq_type {
+ HINIC5_ASYNC_MSG_AEQ = 0,
+ /* Indicate dest func or mgmt cpu which aeq to response mbox message */
+ HINIC5_MBOX_RSP_MSG_AEQ = 1,
+ /* Indicate mgmt cpu which aeq to response api cmd message */
+ HINIC5_MGMT_RSP_MSG_AEQ = 2
+};
+
+enum hinic5_mbox_seg_errcode {
+ MBOX_ERRCODE_NO_ERRORS = 0,
+ /* VF sends the mailbox data to the wrong destination functions */
+ MBOX_ERRCODE_VF_TO_WRONG_FUNC = 0x100,
+ /* PPF sends the mailbox data to the wrong destination functions */
+ MBOX_ERRCODE_PPF_TO_WRONG_FUNC = 0x200,
+ /* PF sends the mailbox data to the wrong destination functions */
+ MBOX_ERRCODE_PF_TO_WRONG_FUNC = 0x300,
+ /* The mailbox data size is set to all zero */
+ MBOX_ERRCODE_ZERO_DATA_SIZE = 0x400,
+ /* The sender function attribute has not been learned by CPI hardware */
+ MBOX_ERRCODE_UNKNOWN_SRC_FUNC = 0x500,
+ /* The receiver function attr has not been learned by CPI hardware */
+ MBOX_ERRCODE_UNKNOWN_DES_FUNC = 0x600
+};
+
+enum hinic5_mbox_func_index {
+ HINIC5_MBOX_MPU_INDEX = 0,
+ HINIC5_MBOX_PF_INDEX = 1,
+ HINIC5_MAX_FUNCTIONS = 2,
+};
+
+struct mbox_msg_info {
+ u8 msg_id;
+ u8 status; /* Can only use 3 bit */
+};
+
+struct hinic5_recv_mbox {
+ void *mbox;
+ u16 cmd;
+ enum hinic5_mod_type mod;
+ u16 mbox_len;
+ void *buf_out;
+ enum hinic5_msg_ack_type ack_type;
+ struct mbox_msg_info msg_info;
+ u8 seq_id;
+};
+
+struct hinic5_send_mbox {
+ u8 *data;
+
+ u64 *wb_status; /* Write back status */
+
+ const struct hinic5_page_addr *wb_mz;
+ void *wb_vaddr;
+ uint64_t wb_paddr;
+
+ const struct hinic5_page_addr *sbuff_mz;
+ void *sbuff_vaddr;
+ uint64_t sbuff_paddr;
+};
+
+enum mbox_event_state {
+ EVENT_START = 0,
+ EVENT_FAIL,
+ EVENT_SUCCESS,
+ EVENT_TIMEOUT,
+ EVENT_END
+};
+
+enum hinic5_mbox_cb_state {
+ HINIC5_VF_MBOX_CB_REG = 0,
+ HINIC5_VF_MBOX_CB_RUNNING,
+ HINIC5_PF_MBOX_CB_REG,
+ HINIC5_PF_MBOX_CB_RUNNING,
+ HINIC5_PPF_MBOX_CB_REG,
+ HINIC5_PPF_MBOX_CB_RUNNING,
+ HINIC5_PPF_TO_PF_MBOX_CB_REG,
+ HINIC5_PPF_TO_PF_MBOX_CB_RUNNING
+};
+
+struct hinic5_mbox {
+ struct hinic5_hwdev *hwdev;
+
+ struct hinic5_send_mbox send_mbox;
+
+ /* Last element for mgmt */
+ struct hinic5_recv_mbox mbox_resp[HINIC5_MAX_FUNCTIONS + 1];
+ struct hinic5_recv_mbox mbox_send[HINIC5_MAX_FUNCTIONS + 1];
+
+ u8 send_msg_id;
+ enum mbox_event_state event_flag;
+};
+
+int hinic5_mbox_func_aeqe_handler(void *handle, u8 *header,
+ __attribute__((unused)) u8 size, void *param,
+ __attribute__((unused)) size_t header_len);
+
+int hinic5_func_to_func_init(struct hinic5_hwdev *hwdev);
+
+void hinic5_func_to_func_free(struct hinic5_hwdev *hwdev);
+
+int hinic5_send_mbox_to_mgmt(struct hinic5_hwdev *hwdev,
+ enum hinic5_mod_type mod, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size,
+ u32 timeout);
+
+void hinic5_response_mbox_to_mgmt(struct hinic5_hwdev *hwdev,
+ enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size, u16 msg_id);
+
+int hinic5_send_mbox_to_mgmt_no_ack(struct hinic5_hwdev *hwdev,
+ enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size);
+
+int hinic5_mbox_to_pf(struct hinic5_hwdev *hwdev, enum hinic5_mod_type mod,
+ u16 cmd, void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u32 timeout);
+
+int hinic5_mbox_to_vf(struct hinic5_hwdev *hwdev, enum hinic5_mod_type mod,
+ u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size, u32 timeout);
+
+#endif /* _HINIC5_MBOX_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.c
new file mode 100644
index 000000000..ac7d2aae6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.c
@@ -0,0 +1,445 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <ipxe/malloc.h>
+#include <errno.h>
+#include <string.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_mbox.h"
+#include "hinic5_mgmt.h"
+
+#define HINIC5_MSG_TO_MGMT_MAX_LEN 2016
+
+#define MAX_PF_MGMT_BUF_SIZE 2048UL
+#define SEGMENT_LEN 48
+#define ASYNC_MSG_FLAG 0x20
+#define MGMT_MSG_MAX_SEQ_ID \
+ (HINIC5_ALIGN(HINIC5_MSG_TO_MGMT_MAX_LEN, SEGMENT_LEN) / SEGMENT_LEN)
+
+#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 SYNC_MSG_ID_MASK 0x1F
+#define ASYNC_MSG_ID_MASK 0x1F
+
+#define SYNC_FLAG 0
+#define ASYNC_FLAG 1
+
+#define MSG_NO_RESP 0xFFFF
+
+#define MGMT_MSG_TIMEOUT 5000 /* Millisecond */
+
+/**
+ * hinic5_register_mgmt_msg_cb - register sync msg handler for a module
+ * @hwdev: the pointer to hw device
+ * @mod: module in the chip that this handler will handle its sync messages
+ * @callback: the handler for a sync message that will handle messages
+ **/
+int hinic5_register_mgmt_msg_cb(void *hwdev, u8 mod,
+ hinic5_mgmt_msg_cb callback)
+{
+ struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = NULL;
+
+ if (mod >= HINIC5_MOD_HW_MAX || !hwdev) {
+ return -EFAULT;
+ }
+
+ pf_to_mgmt = ((struct hinic5_hwdev *)hwdev)->pf_to_mgmt;
+ if (!pf_to_mgmt) {
+ return -EINVAL;
+ }
+
+ pf_to_mgmt->recv_mgmt_msg_cb[mod] = callback;
+
+ return 0;
+}
+
+/**
+ * hinic5_unregister_mgmt_msg_cb - unregister sync msg handler for a module
+ * @hwdev: the pointer to hw device
+ * @mod: module in the chip that this handler will handle its sync messages
+ **/
+void hinic5_unregister_mgmt_msg_cb(void *hwdev, u8 mod)
+{
+ struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = NULL;
+
+ if (!hwdev || mod >= HINIC5_MOD_HW_MAX) {
+ return;
+ }
+
+ pf_to_mgmt = ((struct hinic5_hwdev *)hwdev)->pf_to_mgmt;
+ if (!pf_to_mgmt) {
+ return;
+ }
+
+ pf_to_mgmt->recv_mgmt_msg_cb[mod] = NULL;
+}
+
+int hinic5_msg_to_mgmt_sync(void *hwdev, enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u32 timeout)
+{
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ err = hinic5_send_mbox_to_mgmt(hwdev, mod, cmd, buf_in, in_size,
+ buf_out, out_size, timeout);
+ return err;
+}
+
+int hinic5_msg_to_mgmt_no_ack(void *hwdev, enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size)
+{
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ return hinic5_send_mbox_to_mgmt_no_ack(hwdev, mod, cmd, buf_in,
+ in_size);
+}
+
+static void send_mgmt_ack(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
+ enum hinic5_mod_type mod, u16 cmd, void *buf_in,
+ u16 in_size, u16 msg_id)
+{
+ u16 buf_size;
+
+ if (!in_size) {
+ buf_size = BUF_OUT_DEFAULT_SIZE;
+ } else {
+ buf_size = in_size;
+ }
+
+ hinic5_response_mbox_to_mgmt(pf_to_mgmt->hwdev, mod, cmd, buf_in,
+ buf_size, msg_id);
+}
+
+static bool check_mgmt_seq_id_and_seg_len(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) {
+ 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) {
+ recv_msg->seq_id = 0;
+ return false;
+ }
+
+ recv_msg->seq_id = seq_id;
+ }
+
+ return true;
+}
+
+static void
+hinic5_mgmt_recv_msg_handler(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
+ struct hinic5_recv_msg *recv_msg,
+ __attribute__((unused)) void *param)
+{
+ void *buf_out = pf_to_mgmt->mgmt_ack_buf;
+ bool ack_first = false;
+ u16 out_size = 0;
+
+ if (memset_s(buf_out, MAX_PF_MGMT_BUF_SIZE, 0, MAX_PF_MGMT_BUF_SIZE) !=
+ 0) {
+ IPXE_DRV_LOG(ERR, "Memset failed");
+ goto unsupported;
+ }
+
+ if (recv_msg->mod >= HINIC5_MOD_HW_MAX) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Not support mod, maybe need to response, mod: %d, cmd: %d",
+ recv_msg->mod, recv_msg->cmd);
+ goto unsupported;
+ }
+
+ if (!pf_to_mgmt->recv_mgmt_msg_cb[recv_msg->mod]) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Receive mgmt callback is null, mod = %d, cmd=%d\n",
+ recv_msg->mod, recv_msg->cmd);
+ goto unsupported;
+ }
+
+ pf_to_mgmt->recv_mgmt_msg_cb[recv_msg->mod](
+ pf_to_mgmt->hwdev, recv_msg->cmd, recv_msg->msg,
+ recv_msg->msg_len, buf_out, &out_size);
+
+unsupported:
+ if (!ack_first && !recv_msg->async_mgmt_to_pf) {
+ /* Mgmt sends async msg, sends the response */
+ send_mgmt_ack(pf_to_mgmt, recv_msg->mod, recv_msg->cmd, buf_out,
+ out_size, recv_msg->msg_id);
+ }
+}
+
+/**
+ * Handler a message from mgmt cpu
+ *
+ * @param[in] pf_to_mgmt
+ * PF to mgmt channel
+ * @param[in] recv_msg
+ * Received message details
+ * @param[in] param
+ * Customized parameter (unused_)
+ *
+ * @retval 0 : When aeqe is response message
+ * @retval -1 : Default result, when wrong message or not last message.
+ */
+static int recv_mgmt_msg_handler(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
+ u8 *header, struct hinic5_recv_msg *recv_msg,
+ void *param)
+{
+ u64 mbox_header = *((u64 *)header);
+ void *msg_body = header + sizeof(mbox_header);
+ u8 seq_id, seq_len;
+ u32 offset;
+ u8 front_id;
+ u16 msg_id;
+
+ /* Don't need to get anything from hw when cmd is async */
+ if (HINIC5_MSG_HEADER_GET(mbox_header, DIRECTION) ==
+ HINIC5_MSG_RESPONSE) {
+ return 0;
+ }
+
+ seq_len = HINIC5_MSG_HEADER_GET(mbox_header, SEG_LEN);
+ seq_id = HINIC5_MSG_HEADER_GET(mbox_header, SEQID);
+ msg_id = HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID);
+ front_id = recv_msg->seq_id;
+
+ if (!check_mgmt_seq_id_and_seg_len(recv_msg, seq_id, seq_len, msg_id)) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Mgmt msg sequence id and segment length check failed, "
+ "front seq_id: 0x%x, current seq_id: 0x%x, seg len: 0x%x "
+ "front msg_id: %d, cur msg_id: %d",
+ front_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 HINIC5_MSG_HANDLER_RES;
+ }
+
+ offset = seq_id * SEGMENT_LEN;
+ if (memcpy_s((u8 *)recv_msg->msg + offset,
+ (MAX_PF_MGMT_BUF_SIZE - offset), msg_body,
+ seq_len) != EOK) {
+ IPXE_DRV_LOG(ERR, "Memcpy msg failed, %d.\n", seq_len);
+ recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
+ return HINIC5_MSG_HANDLER_RES;
+ }
+
+ if (!HINIC5_MSG_HEADER_GET(mbox_header, LAST)) {
+ return HINIC5_MSG_HANDLER_RES;
+ }
+
+ recv_msg->cmd = HINIC5_MSG_HEADER_GET(mbox_header, CMD);
+ recv_msg->mod = HINIC5_MSG_HEADER_GET(mbox_header, MODULE);
+ recv_msg->async_mgmt_to_pf = HINIC5_MSG_HEADER_GET(mbox_header, NO_ACK);
+ recv_msg->msg_len = HINIC5_MSG_HEADER_GET(mbox_header, MSG_LEN);
+ recv_msg->msg_id = HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID);
+ recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
+
+ hinic5_mgmt_recv_msg_handler(pf_to_mgmt, recv_msg, param);
+
+ return HINIC5_MSG_HANDLER_RES;
+}
+
+/**
+ * Handler for a mgmt message event
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ * @param[in] header
+ * The header of the message
+ * @param[in] size
+ * Size (unused_)
+ * @param[in] param
+ * Customized parameter
+ * @param[in] header_len
+ * The len of the header
+ *
+ * @retval zero : When aeqe is response message
+ * @retval negative : When wrong message or not last message.
+ */
+int hinic5_mgmt_msg_aeqe_handler(void *hwdev, u8 *header, u8 size, void *param,
+ size_t header_len)
+{
+ struct hinic5_hwdev *dev = (struct hinic5_hwdev *)hwdev;
+ struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = NULL;
+ struct hinic5_recv_msg *recv_msg = NULL;
+ bool is_send_dir = false;
+
+ if ((HINIC5_MSG_HEADER_GET(*(u64 *)header, SOURCE) ==
+ HINIC5_MSG_FROM_MBOX)) {
+ return hinic5_mbox_func_aeqe_handler(hwdev, header, size, param,
+ header_len);
+ }
+
+ pf_to_mgmt = dev->pf_to_mgmt;
+
+ is_send_dir = (HINIC5_MSG_HEADER_GET(*(u64 *)header, DIRECTION) ==
+ 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;
+
+ return recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg, param);
+}
+
+/**
+ * Allocate received message memory
+ *
+ * @param[in] recv_msg
+ * Pointer that will hold the allocated data
+ *
+ * @retval zero : Success
+ * @retval negative : Failure.
+ */
+static int alloc_recv_msg(struct hinic5_recv_msg *recv_msg)
+{
+ recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
+
+ recv_msg->msg = zalloc(MAX_PF_MGMT_BUF_SIZE);
+ if (!recv_msg->msg) {
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
+ * Free received message memory
+ *
+ * @param[in] recv_msg
+ * Pointer that will hold the allocated data
+ */
+static void free_recv_msg(struct hinic5_recv_msg *recv_msg)
+{
+ free(recv_msg->msg);
+}
+
+/**
+ * Allocate all the message buffers of PF to mgmt channel
+ *
+ * @param[in] pf_to_mgmt
+ * PF to mgmt channel
+ *
+ * @retval zero : Success
+ * @retval negative : Failure.
+ */
+static int alloc_msg_buf(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt)
+{
+ int err;
+
+ err = alloc_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Allocate recv msg failed");
+ return err;
+ }
+
+ err = alloc_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Allocate resp recv msg failed");
+ goto alloc_msg_for_resp_err;
+ }
+
+ pf_to_mgmt->mgmt_ack_buf = zalloc(MAX_PF_MGMT_BUF_SIZE);
+ if (!pf_to_mgmt->mgmt_ack_buf) {
+ err = -ENOMEM;
+ goto ack_msg_buf_err;
+ }
+
+ return 0;
+
+ack_msg_buf_err:
+ free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
+
+alloc_msg_for_resp_err:
+ free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ return err;
+}
+
+/**
+ * Free all the message buffers of PF to mgmt channel
+ *
+ * @param[in] pf_to_mgmt
+ * PF to mgmt channel
+ */
+static void free_msg_buf(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt)
+{
+ free(pf_to_mgmt->mgmt_ack_buf);
+ free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
+ free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+}
+
+/**
+ * Initialize PF to mgmt channel
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ *
+ * @retval zero : Success
+ * @retval negative : Failure.
+ */
+int hinic5_pf_to_mgmt_init(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_msg_pf_to_mgmt *pf_to_mgmt;
+ int err;
+
+ pf_to_mgmt = zalloc(sizeof(*pf_to_mgmt));
+ if (!pf_to_mgmt) {
+ return -ENOMEM;
+ }
+
+ hwdev->pf_to_mgmt = pf_to_mgmt;
+ pf_to_mgmt->hwdev = hwdev;
+
+ err = alloc_msg_buf(pf_to_mgmt);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Allocate msg buffers failed");
+ goto alloc_msg_buf_err;
+ }
+
+ return 0;
+
+alloc_msg_buf_err:
+ free(pf_to_mgmt);
+
+ return err;
+}
+
+/**
+ * Free PF to mgmt channel
+ *
+ * @param[in] hwdev
+ * The pointer to the private hardware device object
+ */
+void hinic5_pf_to_mgmt_free(struct hinic5_hwdev *hwdev)
+{
+ struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = hwdev->pf_to_mgmt;
+
+ free_msg_buf(pf_to_mgmt);
+ free(pf_to_mgmt);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.h
new file mode 100644
index 000000000..1659b6116
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_mgmt.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_MGMT_H_
+#define _HINIC5_MGMT_H_
+
+#include "hinic5_compat.h"
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define HINIC5_MSG_HANDLER_RES (-1)
+
+/* Structures for l2nic and mag msg to mgmt sync interface */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/* Cmdq module type */
+enum hinic5_mod_type {
+ HINIC5_MOD_COMM = 0, /* HW communication module */
+ HINIC5_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC5_MOD_ROCE = 2,
+ HINIC5_MOD_PLOG = 3,
+ HINIC5_MOD_TOE = 4,
+ HINIC5_MOD_FLR = 5,
+ HINIC5_MOD_FC = 6,
+ HINIC5_MOD_CFGM = 7, /* Configuration module */
+ HINIC5_MOD_CQM = 8,
+ HINIC5_MOD_VSWITCH = 9,
+ COMM_MOD_FC = 10,
+ HINIC5_MOD_OVS = 11,
+ HINIC5_MOD_DSW = 12,
+ HINIC5_MOD_MIGRATE = 13,
+ HINIC5_MOD_HILINK = 14,
+ HINIC5_MOD_CRYPT = 15, /* Secure crypto module */
+ HINIC5_MOD_HW_MAX = 16, /* Hardware max module id */
+
+ /* Software module id, for PF/VF and multi-host */
+ HINIC5_MOD_SW_FUNC = 17,
+ HINIC5_MOD_IOE = 18,
+ HINIC5_MOD_MAX
+};
+
+typedef enum {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_MGMT_CH,
+ /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH,
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+} func_reset_flag_e;
+
+#define HINIC5_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_FLUSH_BIT) | \
+ (1 << RES_TYPE_MQM) | (1 << RES_TYPE_SMF) | \
+ (1 << RES_TYPE_PF_BW_CFG) | (1 << RES_TYPE_COMM_CMD_CH))
+#define HINIC5_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC5_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC5_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC5_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC5_FC_RES (1 << RES_TYPE_FC)
+#define HINIC5_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC5_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+struct hinic5_recv_msg {
+ void *msg;
+
+ u16 msg_len;
+ enum hinic5_mod_type mod;
+ u16 cmd;
+ u8 seq_id;
+ u16 msg_id;
+ int async_mgmt_to_pf;
+};
+
+enum comm_pf_to_mgmt_event_state {
+ SEND_EVENT_UNINIT = 0,
+ SEND_EVENT_START,
+ SEND_EVENT_SUCCESS,
+ SEND_EVENT_FAIL,
+ SEND_EVENT_TIMEOUT,
+ SEND_EVENT_END
+};
+
+typedef void (*hinic5_mgmt_msg_cb)(void *hwdev, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
+struct hinic5_msg_pf_to_mgmt {
+ struct hinic5_hwdev *hwdev;
+
+ void *mgmt_ack_buf;
+
+ struct hinic5_recv_msg recv_msg_from_mgmt;
+ struct hinic5_recv_msg recv_resp_msg_from_mgmt;
+ hinic5_mgmt_msg_cb recv_mgmt_msg_cb[HINIC5_MOD_HW_MAX];
+
+ u16 sync_msg_id;
+};
+
+int hinic5_mgmt_msg_aeqe_handler(void *hwdev, u8 *header, u8 size, void *param,
+ size_t header_len);
+
+int hinic5_pf_to_mgmt_init(struct hinic5_hwdev *hwdev);
+
+void hinic5_pf_to_mgmt_free(struct hinic5_hwdev *hwdev);
+
+int hinic5_msg_to_mgmt_sync(void *hwdev, enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u32 timeout);
+
+int hinic5_msg_to_mgmt_no_ack(void *hwdev, enum hinic5_mod_type mod, u16 cmd,
+ void *buf_in, u16 in_size);
+
+int hinic5_register_mgmt_msg_cb(void *hwdev, u8 mod,
+ hinic5_mgmt_msg_cb callback);
+
+void hinic5_unregister_mgmt_msg_cb(void *hwdev, u8 mod);
+#endif /* _HINIC5_MGMT_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.c
new file mode 100644
index 000000000..4cef69c7d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.c
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <ipxe/malloc.h>
+#include <ipxe/pci.h>
+#include <errno.h>
+
+#include "../securec/securec.h"
+#include "hinic5_compat.h"
+#include "hinic5_cmdq.h"
+#include "hinic5_hwdev.h"
+#include "hinic5_wq.h"
+
+static void free_wq_pages(struct hinic5_wq *wq)
+{
+ hinic5_dma_free(wq->alloc_addr);
+
+ wq->queue_buf_paddr = 0;
+ wq->queue_buf_vaddr = 0;
+}
+
+static int alloc_wq_pages(__attribute__((unused)) struct hinic5_hwdev *hwdev,
+ struct hinic5_wq *wq, __attribute__((unused)) int qid)
+{
+ struct hinic5_page_addr *alloc_addr = NULL;
+
+ alloc_addr = hinic5_dma_alloc(wq->wq_buf_size, HINIC5_WQ_PGSIZE_ALIGN);
+ if (!alloc_addr) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd buf failed");
+ return -ENOMEM;
+ }
+
+ wq->queue_buf_vaddr = (u64)(intptr_t)alloc_addr->virt_addr;
+ wq->queue_buf_paddr = alloc_addr->phys_addr;
+ wq->alloc_addr = alloc_addr;
+ return 0;
+}
+
+void hinic5_put_wqe(struct hinic5_wq *wq, int num_wqebbs)
+{
+ wq->cons_idx += num_wqebbs;
+ wq->delta += num_wqebbs;
+}
+
+void *hinic5_read_wqe(struct hinic5_wq *wq, int num_wqebbs, u16 *cons_idx)
+{
+ u16 curr_cons_idx;
+
+ if ((wq->delta + num_wqebbs) > wq->q_depth) {
+ return NULL;
+ }
+
+ curr_cons_idx = (u16)(wq->cons_idx);
+
+ curr_cons_idx = MASKED_WQE_IDX(wq, curr_cons_idx);
+
+ *cons_idx = curr_cons_idx;
+
+ return WQ_WQE_ADDR(wq, (u32)(*cons_idx)); /*lint !e647*/
+}
+
+int hinic5_cmdq_alloc(struct hinic5_wq *wq, void *dev, int cmdq_blocks,
+ u32 wq_buf_size, u32 wqebb_shift, u16 q_depth)
+{
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
+ int i, j;
+ int err;
+
+ /* Validate q_depth is power of 2 & wqebb_size is not 0 */
+ for (i = 0; i < cmdq_blocks; i++) {
+ wq[i].wqebb_size = 1U << wqebb_shift;
+ wq[i].wqebb_shift = wqebb_shift;
+ wq[i].wq_buf_size = wq_buf_size;
+ wq[i].q_depth = q_depth;
+
+ err = alloc_wq_pages(hwdev, &wq[i], i);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to alloc CMDQ blocks");
+ goto cmdq_block_err;
+ }
+
+ wq[i].cons_idx = 0;
+ wq[i].prod_idx = 0;
+ wq[i].delta = q_depth;
+
+ wq[i].mask = q_depth - 1;
+ }
+
+ return 0;
+
+cmdq_block_err:
+ for (j = 0; j < i; j++) {
+ free_wq_pages(&wq[j]);
+ }
+
+ return err;
+}
+
+void hinic5_cmdq_free(struct hinic5_wq *wq, int cmdq_blocks)
+{
+ int i;
+
+ for (i = 0; i < cmdq_blocks; i++) {
+ free_wq_pages(&wq[i]);
+ }
+}
+
+void hinic5_wq_wqe_pg_clear(struct hinic5_wq *wq)
+{
+ int ret;
+ wq->cons_idx = 0;
+ wq->prod_idx = 0;
+
+ ret = memset_s((void *)(intptr_t)wq->queue_buf_vaddr, wq->wq_buf_size,
+ 0, wq->wq_buf_size);
+ if (ret != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to memset");
+ }
+}
+
+void *hinic5_get_wqe(struct hinic5_wq *wq, int num_wqebbs, u16 *prod_idx)
+{
+ u16 curr_prod_idx;
+ if ((wq->delta) < (u16)num_wqebbs) {
+ return NULL;
+ }
+
+ wq->delta -= num_wqebbs;
+ curr_prod_idx = (u16)(wq->prod_idx);
+ wq->prod_idx += num_wqebbs;
+ *prod_idx = MASKED_WQE_IDX(wq, curr_prod_idx);
+
+ return WQ_WQE_ADDR(wq, (u32)(*prod_idx)); /*lint !e647*/
+}
+
+void hinic5_set_sge(struct hinic5_sge *sge, uint64_t addr, u32 len)
+{
+ sge->hi_addr = upper_32_bits(addr);
+ sge->lo_addr = lower_32_bits(addr);
+ sge->len = len;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.h
new file mode 100644
index 000000000..0fafe865c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/base/hinic5_wq.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_WQ_H_
+#define _HINIC5_WQ_H_
+
+#include "hinic5_compat.h"
+
+FILE_LICENCE(GPL2_ONLY);
+
+/* Use 0-level CLA, page size must be: SQ 16B(wqe) * 64k(max_q_depth) */
+#define HINIC5_DEFAULT_WQ_PAGE_SIZE 0x100000
+#define HINIC5_HW_WQ_PAGE_SIZE 0x1000
+
+#define MASKED_WQE_IDX(wq, idx) ((idx) & ((wq)->mask))
+
+#define WQ_WQE_ADDR(wq, idx) \
+ ((void *)((intptr_t)((wq)->queue_buf_vaddr) + \
+ ((idx) << (wq)->wqebb_shift)))
+
+struct hinic5_sge {
+ u32 hi_addr;
+ u32 lo_addr;
+ u32 len;
+};
+
+struct hinic5_wq {
+ /* The addresses are 64 bit in the HW */
+ u64 queue_buf_vaddr;
+
+ u16 q_depth;
+ u16 mask;
+ u16 delta;
+
+ u32 cons_idx;
+ u32 prod_idx;
+
+ u64 queue_buf_paddr;
+
+ u32 wqebb_size;
+ u32 wqebb_shift;
+
+ u32 wq_buf_size;
+
+ struct hinic5_page_addr *alloc_addr;
+ u32 rsvd[5];
+};
+
+void hinic5_wq_wqe_pg_clear(struct hinic5_wq *wq);
+
+int hinic5_cmdq_alloc(struct hinic5_wq *wq, void *dev, int cmdq_blocks,
+ u32 wq_buf_size, u32 wqebb_shift, u16 q_depth);
+
+void hinic5_cmdq_free(struct hinic5_wq *wq, int cmdq_blocks);
+
+void *hinic5_get_wqe(struct hinic5_wq *wq, int num_wqebbs, u16 *prod_idx);
+
+void hinic5_put_wqe(struct hinic5_wq *wq, int num_wqebbs);
+
+void *hinic5_read_wqe(struct hinic5_wq *wq, int num_wqebbs, u16 *cons_idx);
+
+void hinic5_set_sge(struct hinic5_sge *sge, uint64_t addr, u32 len);
+
+#endif /* _HINIC5_WQ_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_mag_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_mag_cfg.h
new file mode 100644
index 000000000..6ba15beb1
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_mag_cfg.h
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
+ */
+
+#ifndef _HINIC5_MAG_CFG_H_
+#define _HINIC5_MAG_CFG_H_
+
+#include <linux/types.h>
+
+#define MAG_CMD_PORT_DISABLE 0x0
+#define MAG_CMD_TX_ENABLE 0x1
+#define MAG_CMD_RX_ENABLE 0x2
+
+/* the physical port is disable only when all pf of the port are set to down, if any pf is enable, the port is enable */
+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 rsvd0;
+
+ u8 state; /* bitmap bit0:tx_en bit1:rx_en */
+ u8 rsvd1[3];
+};
+
+struct mag_cmd_get_port_enable {
+ struct mgmt_msg_head head;
+
+ u8 port;
+ u8 state; /* bitmap bit0:tx_en bit1:rx_en */
+ u8 rsvd0[2];
+};
+
+struct mag_phy_port_stats {
+ u64 mac_tx_fragment_pkt_num;
+ u64 mac_tx_undersize_pkt_num;
+ u64 mac_tx_undermin_pkt_num;
+ u64 mac_tx_64_oct_pkt_num;
+ u64 mac_tx_65_127_oct_pkt_num;
+ u64 mac_tx_128_255_oct_pkt_num;
+ u64 mac_tx_256_511_oct_pkt_num;
+ u64 mac_tx_512_1023_oct_pkt_num;
+ u64 mac_tx_1024_1518_oct_pkt_num;
+ u64 mac_tx_1519_2047_oct_pkt_num;
+ u64 mac_tx_2048_4095_oct_pkt_num;
+ u64 mac_tx_4096_8191_oct_pkt_num;
+ u64 mac_tx_8192_9216_oct_pkt_num;
+ u64 mac_tx_9217_12287_oct_pkt_num;
+ u64 mac_tx_12288_16383_oct_pkt_num;
+ u64 mac_tx_1519_max_bad_pkt_num;
+ u64 mac_tx_1519_max_good_pkt_num;
+ u64 mac_tx_oversize_pkt_num;
+ u64 mac_tx_jabber_pkt_num;
+ u64 mac_tx_bad_pkt_num;
+ u64 mac_tx_bad_oct_num;
+ u64 mac_tx_good_pkt_num;
+ u64 mac_tx_good_oct_num;
+ u64 mac_tx_total_pkt_num;
+ u64 mac_tx_total_oct_num;
+ u64 mac_tx_uni_pkt_num;
+ u64 mac_tx_multi_pkt_num;
+ u64 mac_tx_broad_pkt_num;
+ u64 mac_tx_pause_num;
+ u64 mac_tx_pfc_pkt_num;
+ u64 mac_tx_pfc_pri0_pkt_num;
+ u64 mac_tx_pfc_pri1_pkt_num;
+ u64 mac_tx_pfc_pri2_pkt_num;
+ u64 mac_tx_pfc_pri3_pkt_num;
+ u64 mac_tx_pfc_pri4_pkt_num;
+ u64 mac_tx_pfc_pri5_pkt_num;
+ u64 mac_tx_pfc_pri6_pkt_num;
+ u64 mac_tx_pfc_pri7_pkt_num;
+ u64 mac_tx_control_pkt_num;
+ u64 mac_tx_err_all_pkt_num;
+ u64 mac_tx_from_app_good_pkt_num;
+ u64 mac_tx_from_app_bad_pkt_num;
+
+ u64 mac_rx_fragment_pkt_num;
+ u64 mac_rx_undersize_pkt_num;
+ u64 mac_rx_undermin_pkt_num;
+ u64 mac_rx_64_oct_pkt_num;
+ u64 mac_rx_65_127_oct_pkt_num;
+ u64 mac_rx_128_255_oct_pkt_num;
+ u64 mac_rx_256_511_oct_pkt_num;
+ u64 mac_rx_512_1023_oct_pkt_num;
+ u64 mac_rx_1024_1518_oct_pkt_num;
+ u64 mac_rx_1519_2047_oct_pkt_num;
+ u64 mac_rx_2048_4095_oct_pkt_num;
+ u64 mac_rx_4096_8191_oct_pkt_num;
+ u64 mac_rx_8192_9216_oct_pkt_num;
+ u64 mac_rx_9217_12287_oct_pkt_num;
+ u64 mac_rx_12288_16383_oct_pkt_num;
+ u64 mac_rx_1519_max_bad_pkt_num;
+ u64 mac_rx_1519_max_good_pkt_num;
+ u64 mac_rx_oversize_pkt_num;
+ u64 mac_rx_jabber_pkt_num;
+ u64 mac_rx_bad_pkt_num;
+ u64 mac_rx_bad_oct_num;
+ u64 mac_rx_good_pkt_num;
+ u64 mac_rx_good_oct_num;
+ u64 mac_rx_total_pkt_num;
+ u64 mac_rx_total_oct_num;
+ u64 mac_rx_uni_pkt_num;
+ u64 mac_rx_multi_pkt_num;
+ u64 mac_rx_broad_pkt_num;
+ u64 mac_rx_pause_num;
+ u64 mac_rx_pfc_pkt_num;
+ u64 mac_rx_pfc_pri0_pkt_num;
+ u64 mac_rx_pfc_pri1_pkt_num;
+ u64 mac_rx_pfc_pri2_pkt_num;
+ u64 mac_rx_pfc_pri3_pkt_num;
+ u64 mac_rx_pfc_pri4_pkt_num;
+ u64 mac_rx_pfc_pri5_pkt_num;
+ u64 mac_rx_pfc_pri6_pkt_num;
+ u64 mac_rx_pfc_pri7_pkt_num;
+ u64 mac_rx_control_pkt_num;
+ u64 mac_rx_sym_err_pkt_num;
+ u64 mac_rx_fcs_err_pkt_num;
+ u64 mac_rx_send_app_good_pkt_num;
+ u64 mac_rx_send_app_bad_pkt_num;
+ u64 mac_rx_unfilter_pkt_num;
+};
+
+/* led type */
+enum mag_led_type {
+ MAG_CMD_LED_TYPE_ALARM = 0x0,
+ MAG_CMD_LED_TYPE_LOW_SPEED = 0x1,
+ MAG_CMD_LED_TYPE_HIGH_SPEED = 0x2
+};
+
+/* led mode */
+enum mag_led_mode {
+ MAG_CMD_LED_MODE_DEFAULT = 0x0,
+ MAG_CMD_LED_MODE_FORCE_ON = 0x1,
+ MAG_CMD_LED_MODE_FORCE_OFF = 0x2,
+ MAG_CMD_LED_MODE_FORCE_BLINK_1HZ = 0x3,
+ MAG_CMD_LED_MODE_FORCE_BLINK_2HZ = 0x4,
+ MAG_CMD_LED_MODE_FORCE_BLINK_4HZ = 0x5,
+ MAG_CMD_LED_MODE_1HZ = 0x6,
+ MAG_CMD_LED_MODE_2HZ = 0x7,
+ MAG_CMD_LED_MODE_4HZ = 0x8
+};
+
+/* the led is report alarm when any pf of the port is alram */
+struct mag_cmd_set_led_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 type;
+ u8 mode;
+};
+
+struct mag_cmd_port_stats_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+};
+
+struct mag_cmd_get_port_stat {
+ struct mgmt_msg_head head;
+
+ struct mag_phy_port_stats counter;
+ u64 rsvd1[15];
+};
+
+/**
+ * Set port status
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] enable
+ * 0-disable, 1-enable
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_port_enable(void *hwdev, bool enable);
+
+/**
+ * Set led status
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] type
+ * led type
+ * @param[in] mode
+ * led mode
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+int hinic5_set_led_status(void *hwdev, enum mag_led_type type,
+ enum mag_led_mode mode);
+
+/**
+ * Get port stats
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] stats
+ * Port stats
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+
+int hinic5_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats);
+
+#endif /* _HINIC5_NIC_CFG_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_main.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_main.c
new file mode 100644
index 000000000..424797a84
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_main.c
@@ -0,0 +1,699 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipxe/list.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/pci.h>
+#include <ipxe/dma.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/ethernet.h>
+#include <ipxe/vlan.h>
+#include <pci_rom_bdf.h>
+
+#include "securec/securec.h"
+#include "base/hinic5_cmd.h"
+#include "base/hinic5_compat.h"
+#include "base/hinic5_csr.h"
+#include "base/hinic5_hwdev.h"
+#include "base/hinic5_hwif.h"
+#include "base/hinic5_hw_cfg.h"
+#include "base/hinic5_hw_comm.h"
+#include "base/hinic5_eqs.h"
+#include "hinic5_nic_io.h"
+#include "hinic5_nic_cfg.h"
+#include "hinic5_nic_dev.h"
+#include "hinic5_tx.h"
+#include "hinic5_rx.h"
+#include "hinic5_nic_dev.h"
+#include "hinic5_settings.h"
+
+#define HINIC5_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 100
+#define HINIC5_MAX_LINKUP_WAIT_TIME 1500
+#define HINIC5_LINKUP_WAIT_TIME 500
+
+enum hinic5_rx_mod {
+ HINIC5_RX_MODE_UC = 1 << 0,
+ HINIC5_RX_MODE_MC = 1 << 1,
+ HINIC5_RX_MODE_BC = 1 << 2,
+ HINIC5_RX_MODE_MC_ALL = 1 << 3,
+ HINIC5_RX_MODE_PROMISC = 1 << 4,
+};
+
+#define HINIC5_RX_BUF_LEN 2048
+#define HINIC5_DEFAULT_RX_MODE \
+ (HINIC5_RX_MODE_UC | HINIC5_RX_MODE_MC | HINIC5_RX_MODE_BC)
+
+static int hinic5_pf_get_default_cos(struct hinic5_hwdev *hwdev, u8 *cos_id)
+{
+ u8 default_cos = 0;
+ u8 valid_cos_bitmap;
+ u8 i;
+
+ valid_cos_bitmap = hwdev->cfg_mgmt->svc_cap.cos_valid_bitmap;
+ if (!valid_cos_bitmap) {
+ IPXE_DRV_LOG(ERR, "PF has none cos to support\n");
+ return -EFAULT;
+ }
+
+ for (i = 0; i < HINIC5_COS_NUM_MAX; i++) {
+ if ((valid_cos_bitmap & BIT(i)) != 0) {
+ /* Find max cos id as default cos */
+ default_cos = i;
+ }
+ }
+
+ *cos_id = default_cos;
+
+ return 0;
+}
+
+static int hinic5_init_default_cos(struct hinic5_nic_dev *nic_dev)
+{
+ u8 cos_id = 0;
+ int err;
+
+ if (!HINIC5_IS_VF(nic_dev->hwdev)) {
+ err = hinic5_pf_get_default_cos(nic_dev->hwdev, &cos_id);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Get PF default cos failed, err: %d",
+ err);
+ return err;
+ }
+ }
+
+ nic_dev->default_cos = cos_id;
+ IPXE_DRV_LOG(INFO, "Default cos %d", nic_dev->default_cos);
+ return 0;
+}
+
+static int hinic5_set_default_hw_feature(struct hinic5_nic_dev *nic_dev)
+{
+ return hinic5_init_default_cos(nic_dev);
+}
+
+static int hinic5_alloc_txrxqs(struct hinic5_nic_dev *nic_dev)
+{
+ int err;
+
+ err = hinic5_alloc_txqs(nic_dev->netdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to alloc txqs\n");
+ return err;
+ }
+
+ err = hinic5_alloc_rxqs(nic_dev->netdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to alloc rxqs\n");
+ goto alloc_rxq_err;
+ }
+
+ return 0;
+
+alloc_rxq_err:
+ hinic5_free_txqs(nic_dev->netdev);
+ return err;
+}
+
+static void hinic5_free_txrxqs(struct hinic5_nic_dev *nic_dev)
+{
+ hinic5_free_rxqs(nic_dev->netdev);
+ hinic5_free_txqs(nic_dev->netdev);
+ return;
+}
+
+static void hinic5_deinit_nic(struct hinic5_nic_dev *nic_dev)
+{
+ if (!hinic5_support_nic(nic_dev->hwdev, NULL)) {
+ IPXE_DRV_LOG(WARN, "Hw don't support nic\n");
+ return;
+ }
+
+ hinic5_nic_unregister_event(nic_dev->hwdev);
+ hinic5_free_txrxqs(nic_dev);
+ (void)hinic5_set_rx_mode(nic_dev->hwdev, HINIC5_DEFAULT_RX_MODE);
+ (void)hinic5_set_func_svc_used_state(nic_dev->hwdev, SVC_T_NIC, 0);
+}
+
+static bool hinic5_is_187x_cmdq_support(struct hinic5_nic_dev *nic_dev)
+{
+ return hinic5_get_driver_feature(nic_dev) & NIC_F_HTN_CMDQ;
+}
+
+void hinic5_nic_cmdq_adapt_init(struct hinic5_nic_dev *nic_dev)
+{
+ if (!hinic5_is_187x_cmdq_support(nic_dev))
+ nic_dev->cmdq_ops = hinic5_nic_cmdq_get_182x_ops();
+ else {
+ nic_dev->cmdq_ops = hinic5_nic_cmdq_get_187x_ops();
+ }
+}
+
+static int hinic5_set_default_feature(struct hinic5_nic_dev *nic_dev,
+ struct net_device *netdev)
+{
+ int err = 0;
+ u16 func_id = 0;
+
+ err = hinic5_get_feature_from_hw(nic_dev->hwdev, &nic_dev->feature_cap,
+ 1);
+ IPXE_DRV_LOG(ERR, "nic_dev->feature_cap: %llu\n",
+ nic_dev->feature_cap);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to get nic features\n");
+ return err;
+ }
+
+ hinic5_nic_cmdq_adapt_init(nic_dev);
+
+ err = hinic5_init_function_table(nic_dev->hwdev, HINIC5_RX_BUF_LEN);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to init function table\n");
+ return err;
+ }
+
+ err = hinic5_get_default_mac(nic_dev->hwdev, netdev->hw_addr, ETH_ALEN);
+ if (err != 0 || (is_valid_ether_addr(netdev->hw_addr) == 0)) {
+ IPXE_DRV_LOG(ERR, "Failed to get perm MAC address\n");
+ return err;
+ }
+
+ IPXE_DRV_LOG(INFO, "Perm MAC address: %s\n", eth_ntoa(netdev->hw_addr));
+ func_id = hinic5_global_func_id(nic_dev->hwdev);
+
+ err = hinic5_set_mac(nic_dev->hwdev, netdev->hw_addr, 0, func_id);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to set MAC address\n");
+ return err;
+ }
+
+ /* Set hardware feature to default status */
+ err = hinic5_set_default_hw_feature(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Set hw default features failed");
+ return err;
+ }
+
+ err = hinic5_set_rx_mode(nic_dev->hwdev,
+ HINIC5_DEFAULT_RX_MODE |
+ HINIC5_RX_MODE_PROMISC);
+ if (err != 0) {
+ return err;
+ }
+
+ IPXE_DRV_LOG(INFO, "Set rx vlan offload off\n");
+ err = hinic5_set_rx_vlan_offload(nic_dev->hwdev, false);
+ return err;
+}
+
+static int hinic5_set_vlan_offload(struct hinic5_nic_dev *nic_dev,
+ struct net_device *netdev)
+{
+ int err = 0;
+
+ err = hinic5_set_rx_vlan_offload(nic_dev->hwdev, false);
+ if (err != 0) {
+ return err;
+ }
+
+ IPXE_DRV_LOG(INFO, "Set rx vlan filter off\n");
+ err = hinic5_set_vlan_filter(nic_dev->hwdev, false);
+ if (err != 0) {
+ return err;
+ }
+
+ netdev->max_pkt_len = HINIC5_MAX_JUMBO_FRAME_SIZE;
+ netdev->mtu = HINIC5_DEFAULT_MTU_SIZE;
+
+ nic_dev->max_sqs = HINIC5_PXE_DEFAULT_QNUM;
+ nic_dev->max_rqs = HINIC5_PXE_DEFAULT_QNUM;
+
+ /* pxe used one queue default */
+ nic_dev->num_rqs = HINIC5_PXE_DEFAULT_QNUM;
+ nic_dev->num_sqs = HINIC5_PXE_DEFAULT_QNUM;
+ nic_dev->rx_buff_len = HINIC5_RX_BUF_LEN;
+ nic_dev->mtu_size = HINIC5_DEFAULT_MTU_SIZE;
+
+ err = hinic5_alloc_txrxqs(nic_dev);
+ return err;
+}
+
+static int hinic5_init_nic(struct hinic5_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ int err;
+
+ if (!hinic5_support_nic(nic_dev->hwdev, NULL)) {
+ IPXE_DRV_LOG(WARN, "Hw don't support nic\n");
+ return -EINVAL;
+ }
+
+ err = hinic5_func_reset(nic_dev->hwdev, HINIC5_NIC_RES);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to reset function\n");
+ return err;
+ }
+
+ err = hinic5_set_func_svc_used_state(nic_dev->hwdev, SVC_T_NIC, 1);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to set function svc used state\n");
+ goto set_used_state_err;
+ }
+
+ err = hinic5_set_default_feature(nic_dev, netdev);
+ if (err != 0) {
+ goto get_feature_err;
+ }
+
+ IPXE_DRV_LOG(INFO, "Set rx vlan offload off\n");
+ err = hinic5_set_vlan_offload(nic_dev, netdev);
+ if (err != 0) {
+ goto set_vlan_offload_err;
+ }
+
+ IPXE_DRV_LOG(INFO, "NIC register event\n");
+ err = hinic5_nic_register_event(nic_dev->hwdev);
+ if (err != 0) {
+ goto nic_register_event_err;
+ }
+
+ return 0;
+
+nic_register_event_err:
+ hinic5_free_txrxqs(nic_dev);
+set_vlan_offload_err:
+ (void)hinic5_set_rx_mode(nic_dev->hwdev, HINIC5_DEFAULT_RX_MODE);
+get_feature_err:
+ (void)hinic5_set_func_svc_used_state(nic_dev->hwdev, SVC_T_NIC, 0);
+set_used_state_err:
+ return err;
+}
+
+static void hinic5_deinit_qps(struct hinic5_nic_dev *nic_dev)
+{
+ hinic5_remove_rxqs(nic_dev);
+ hinic5_free_qp_ctxts(nic_dev->hwdev);
+ hinic5_free_rx_resources(nic_dev);
+ hinic5_free_tx_resources(nic_dev);
+}
+
+static int hinic5_init_qps(struct hinic5_nic_dev *nic_dev)
+{
+ int err;
+
+ err = hinic5_alloc_tx_resources(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to alloc tx\n");
+ goto alloc_tx_err;
+ }
+
+ err = hinic5_alloc_rx_resources(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to alloc rx\n");
+ goto alloc_rx_err;
+ }
+
+ err = hinic5_init_qp_ctxts(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to init qp context\n");
+ goto init_qp_ctxt_err;
+ }
+
+ err = hinic5_configure_rxqs(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to configure rxqs\n");
+ goto configure_rxqs_err;
+ }
+
+ return 0;
+
+configure_rxqs_err:
+ hinic5_free_qp_ctxts(nic_dev->hwdev);
+init_qp_ctxt_err:
+ hinic5_free_rx_resources(nic_dev);
+alloc_rx_err:
+ hinic5_free_tx_resources(nic_dev);
+alloc_tx_err:
+ return err;
+}
+
+static void hinic5_check_link(struct hinic5_nic_dev *nic_dev)
+{
+ u8 link_status = 0;
+ int wait;
+ int err;
+
+ /* wait for link */
+ for (wait = 0; wait <= HINIC5_MAX_LINKUP_WAIT_TIME;
+ wait += HINIC5_LINKUP_WAIT_TIME) {
+ err = hinic5_get_link_state(nic_dev->hwdev, &link_status);
+ if (err) {
+ IPXE_DRV_LOG(ERR, "Failed to get link state\n");
+ return;
+ }
+
+ if (link_status) {
+ break;
+ }
+
+ usleep(HINIC5_LINKUP_WAIT_TIME * HINIC5_MS_TO_US_UNIT);
+ }
+
+ if (link_status) {
+ IPXE_DRV_LOG(INFO, "Netdev %s Link up\n",
+ nic_dev->netdev->name);
+ netdev_link_up(nic_dev->netdev);
+ } else {
+ IPXE_DRV_LOG(INFO, "Netdev %s Link down\n",
+ nic_dev->netdev->name);
+ netdev_link_down(nic_dev->netdev);
+ }
+}
+
+static int hinic5_create_vlan(struct hinic5_nic_dev *nic_dev)
+{
+ int err;
+ u32 opcode;
+ unsigned int vlan_id = 0;
+ struct nic_bios_cfg conf = { 0 };
+
+ opcode = NIC_NVM_DATA_ALL;
+ err = hinic5_get_persistent_conf(nic_dev->hwdev, opcode, &conf);
+ if (err) {
+ IPXE_DRV_LOG(ERR, "Hinic5 get vlan info failed, ret=%d", err);
+ return err;
+ }
+
+ if (conf.nlvc.pxe_vlan_en ==
+ 0) { /* PXE VLAN enable: 0 - disable 1 - enable */
+ IPXE_DRV_LOG(INFO, "Hinic5 vlan is disabled");
+ return 0;
+ }
+
+ vlan_id = conf.nlvc.pxe_vlan_id;
+
+ err = vlan_create(nic_dev->netdev, vlan_id, 0);
+ if (err) {
+ IPXE_DRV_LOG(ERR, "Failed to create vlan(%d)\n", vlan_id);
+ return err;
+ }
+
+ return err;
+}
+
+static void hinic5_destroy_vlan()
+{
+ struct net_device *netdev = NULL;
+
+ for_each_netdev(netdev) {
+ unsigned int tag = vlan_tag(netdev);
+ if (tag != 0) {
+ vlan_destroy(netdev);
+ IPXE_DRV_LOG(INFO, "Hinic5 vlan(%d) is destroyed", tag);
+ return;
+ }
+ }
+}
+
+static int hinic5_pxe_open(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ int err;
+
+ IPXE_DRV_LOG(INFO, "Hinic5 %s pxe open start", netdev->name);
+
+ err = hinic5_init_qps(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to init qps\n");
+ goto init_qps_err;
+ }
+
+ err = hinic5_set_port_mtu(nic_dev->hwdev, nic_dev->mtu_size);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to set port mtu\n");
+ goto set_port_mtu_err;
+ }
+
+ /* Open virtual port and ready to start packet receiving */
+ err = hinic5_set_vport_enable(nic_dev->hwdev, true);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Enable vport failed");
+ goto en_vport_fail;
+ }
+
+ /* Open physical port and start packet receiving */
+ err = hinic5_set_port_enable(nic_dev->hwdev, true);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Enable physical port failed");
+ goto en_port_fail;
+ }
+
+ hinic5_check_link(nic_dev);
+
+ IPXE_DRV_LOG(INFO, "Hinic5 %s pxe open success", netdev->name);
+
+ return 0;
+
+en_port_fail:
+ (void)hinic5_set_vport_enable(nic_dev->hwdev, false);
+en_vport_fail:
+ (void)hinic5_flush_qps_res(nic_dev->hwdev);
+ /* After set vport disable 100ms, no packets will be send to host */
+ usleep(HINIC5_WAIT_FLUSH_QP_RESOURCE_TIMEOUT * HINIC5_MS_TO_US_UNIT);
+set_port_mtu_err:
+ hinic5_deinit_qps(nic_dev);
+init_qps_err:
+ return err;
+}
+
+static void hinic5_pxe_close(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ int err;
+
+ IPXE_DRV_LOG(INFO, "Hinic5 %s pxe close start", netdev->name);
+
+ err = hinic5_set_port_enable(nic_dev->hwdev, false);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Disable physical port failed");
+ }
+
+ err = hinic5_set_vport_enable(nic_dev->hwdev, false);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Disable vport failed");
+ }
+
+ netdev_link_down(netdev);
+
+ hinic5_flush_txqs(nic_dev);
+
+ hinic5_flush_qps_res(nic_dev->hwdev);
+
+ /* After set vport disable 100ms, no packets will be send to host */
+ usleep(HINIC5_WAIT_FLUSH_QP_RESOURCE_TIMEOUT * HINIC5_MS_TO_US_UNIT);
+
+ hinic5_deinit_qps(nic_dev);
+
+ IPXE_DRV_LOG(INFO, "Hinic5 %s pxe close success", netdev->name);
+
+ return;
+}
+
+static void hinic5_pxe_poll(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+
+ hinic5_pxe_tx_poll(netdev);
+ hinic5_pxe_rx_poll(netdev);
+ hinic5_dev_handle_aeq_event(nic_dev->hwdev, nic_dev);
+}
+
+static void hinic5_pxe_irq(__attribute__((unused)) struct net_device *netdev,
+ __attribute__((unused)) int enable)
+{
+ return;
+}
+
+static struct net_device_operations hinic5_operations = {
+ .open = hinic5_pxe_open,
+ .close = hinic5_pxe_close,
+ .transmit = hinic5_pxe_transmit,
+ .poll = hinic5_pxe_poll,
+ .irq = hinic5_pxe_irq,
+};
+
+static int hinic5_pxe_process(struct net_device *netdev,
+ struct hinic5_nic_dev *nic_dev)
+{
+ int err = 0;
+ err = hinic5_init_hwdev(nic_dev->hwdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init chip hwdev failed");
+ goto init_hwdev_fail;
+ }
+
+ if (!hinic5_get_pxe_en(nic_dev->hwdev)) {
+ IPXE_DRV_LOG(WARN, "Function pxe is disable");
+ err = -EINVAL;
+ goto init_nic_fail;
+ }
+
+ err = hinic5_init_nic(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init nic failed");
+ goto init_nic_fail;
+ }
+
+ /* Register network device */
+ err = register_netdev(netdev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Register netdev failed");
+ goto register_netdev_err;
+ }
+
+ hinic5_check_link(nic_dev);
+
+ err = hinic5_settings_register(nic_dev);
+ if (err != 0) {
+ goto settings_register_err;
+ }
+
+ err = hinic5_create_vlan(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(
+ WARN,
+ "Create vlan failed, continue to register trunk netdev");
+ err = 0;
+ }
+
+ return err;
+
+settings_register_err:
+ unregister_netdev(netdev);
+register_netdev_err:
+ hinic5_deinit_nic(nic_dev);
+init_nic_fail:
+ hinic5_free_hwdev(nic_dev->hwdev);
+init_hwdev_fail:
+ free(nic_dev->hwdev);
+ nic_dev->hwdev = NULL;
+ return err;
+}
+
+int hinic5_pxe_probe(struct pci_device *pdev)
+{
+ struct hinic5_nic_dev *nic_dev = NULL;
+ struct net_device *netdev = NULL;
+ int err = 0;
+
+ IPXE_DRV_LOG(INFO,
+ "Hinic5 Bus:Dev:Func: %04x pxe probe start(rom bdf:%04x)",
+ pdev->busdevfn, get_pci_rom_bdf());
+
+ if (pdev->busdevfn != get_pci_rom_bdf()) {
+ IPXE_DRV_LOG(WARN, "BDF not match");
+ return -EINVAL;
+ }
+
+ IPXE_DRV_LOG(
+ INFO,
+ "PCI Device: Vendor: %04x Device: %04x BDF: %04x ROM BDF: %04x",
+ pdev->vendor, pdev->device, pdev->busdevfn, get_pci_rom_bdf());
+
+ netdev = alloc_etherdev(sizeof(struct hinic5_nic_dev));
+ if (!netdev) {
+ return -ENOMEM;
+ }
+
+ /* Associate igbvf-specific network operations operations with generic network device layer */
+ netdev_init(netdev, &hinic5_operations);
+
+ nic_dev = netdev->priv;
+ err = memset_s(nic_dev, (sizeof(*nic_dev)), 0, (sizeof(*nic_dev)));
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Failed to init memset\n");
+ return -EINVAL;
+ }
+
+ nic_dev->pdev = pdev;
+ nic_dev->netdev = netdev;
+
+ /* Associate this network device with given PCI device */
+ pci_set_drvdata(pdev, netdev);
+ netdev->dev = &pdev->dev;
+
+ /* Fix up PCI device */
+ adjust_pci_device(pdev);
+
+ /* Configure DMA */
+ nic_dev->dma = &pdev->dma;
+ dma_set_mask_64bit(nic_dev->dma);
+ netdev->dma = nic_dev->dma;
+
+ /* Create hardware device */
+ nic_dev->hwdev = zalloc(sizeof(*(nic_dev->hwdev)));
+ if (!nic_dev->hwdev) {
+ IPXE_DRV_LOG(ERR, "Allocate hwdev memory failed");
+ err = -ENOMEM;
+ goto alloc_hwdev_mem_fail;
+ }
+
+ nic_dev->hwdev->dev_handle = nic_dev;
+ nic_dev->hwdev->eth_dev = netdev;
+ nic_dev->hwdev->pci_dev = pdev;
+
+ err = hinic5_pxe_process(netdev, nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Pxe process failed");
+ goto alloc_hwdev_mem_fail;
+ }
+
+ IPXE_DRV_LOG(INFO, "Hinic5 Bus:Dev:Func: %04x pxe probe success",
+ pdev->busdevfn);
+
+ return 0;
+
+alloc_hwdev_mem_fail:
+ netdev_nullify(netdev);
+ netdev_put(netdev);
+ return err;
+}
+
+void hinic5_pxe_remove(struct pci_device *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+
+ IPXE_DRV_LOG(INFO, "Hinic5 Bus:Dev:Func: %04x pxe remove start",
+ pdev->busdevfn);
+
+ hinic5_destroy_vlan();
+ unregister_netdev(netdev);
+ hinic5_deinit_nic(nic_dev);
+ hinic5_free_hwdev(nic_dev->hwdev);
+ free(nic_dev->hwdev);
+ nic_dev->hwdev = NULL;
+ netdev_nullify(netdev);
+ netdev_put(netdev);
+
+ IPXE_DRV_LOG(INFO, "Hinic5 Bus:Dev:Func: %04x pxe remove success",
+ pdev->busdevfn);
+}
+
+static struct pci_device_id hinic5_pci_tbl[] = {
+ PCI_ROM(0x19e5, 0x0230, "Hinic_ipxe_1825", "HINIC5 NIC", 0), // Hi1825
+ PCI_ROM(0x19e5, 0x0229, "Hinic_ipxe_1872", "HINIC5 NIC", 0), // Hi1872
+};
+
+struct pci_driver hinic5_driver __pci_driver = {
+ .ids = hinic5_pci_tbl,
+ .id_count = (sizeof(hinic5_pci_tbl) / sizeof(hinic5_pci_tbl[0])),
+ .probe = hinic5_pxe_probe,
+ .remove = hinic5_pxe_remove,
+};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.c
new file mode 100644
index 000000000..61d0d5222
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.c
@@ -0,0 +1,1189 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "securec/securec.h"
+#include "base/hinic5_compat.h"
+#include "base/hinic5_cmd.h"
+#include "base/hinic5_mgmt.h"
+#include "base/hinic5_hwif.h"
+#include "base/hinic5_mbox.h"
+#include "base/hinic5_hwdev.h"
+#include "base/hinic5_wq.h"
+#include "base/hinic5_cmdq.h"
+#include "base/hinic5_hw_cfg.h"
+#include "hinic5_nic_dev.h"
+#include "hinic5_nic_cfg.h"
+
+#define NIC_NVM_DATA_SIGNATURE 0x1923E518
+
+struct vf_msg_handler {
+ u16 cmd;
+};
+
+static const struct vf_msg_handler vf_cmd_handler[] = {
+ {
+ .cmd = HINIC5_NIC_CMD_VF_REGISTER,
+ },
+
+ {
+ .cmd = HINIC5_NIC_CMD_GET_MAC,
+ },
+
+ {
+ .cmd = HINIC5_NIC_CMD_SET_MAC,
+ },
+
+ {
+ .cmd = HINIC5_NIC_CMD_DEL_MAC,
+ },
+
+ {
+ .cmd = HINIC5_NIC_CMD_UPDATE_MAC,
+ },
+
+ {
+ .cmd = HINIC5_NIC_CMD_VF_COS,
+ },
+};
+
+static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
+
+int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ bool cmd_to_pf = false;
+
+ if (hinic5_func_type(hwdev) == TYPE_VF) {
+ for (i = 0; i < cmd_cnt; i++) {
+ if (cmd == vf_cmd_handler[i].cmd) {
+ cmd_to_pf = true;
+ }
+ }
+ }
+
+ if (cmd_to_pf) {
+ return hinic5_mbox_to_pf(hwdev, HINIC5_MOD_L2NIC, cmd, buf_in,
+ in_size, buf_out, out_size, 0);
+ }
+
+ return hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_L2NIC, cmd, buf_in,
+ in_size, buf_out, out_size, 0);
+}
+
+int hinic5_set_ci_table(void *hwdev, struct hinic5_sq_attr *attr)
+{
+ struct hinic5_cmd_cons_idx_attr cons_idx_attr;
+ u16 out_size = sizeof(cons_idx_attr);
+ int err;
+
+ if (!hwdev || !attr)
+ return -EINVAL;
+
+ (void)memset_s(&cons_idx_attr, sizeof(cons_idx_attr), 0,
+ sizeof(cons_idx_attr));
+ cons_idx_attr.func_idx = hinic5_global_func_id(hwdev);
+ 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;
+
+ if (attr->intr_en != 0) {
+ cons_idx_attr.intr_en = attr->intr_en;
+ cons_idx_attr.intr_idx = attr->intr_idx;
+ }
+
+ cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
+ cons_idx_attr.ci_addr = attr->ci_dma_base;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SQ_CI_ATTR_SET,
+ &cons_idx_attr, sizeof(cons_idx_attr),
+ &cons_idx_attr, &out_size);
+ if (err || !out_size || cons_idx_attr.msg_head.status) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+#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 && status != HINIC5_MGMT_STATUS_EXIST) ||
+ ((vlan_id & CHECK_IPSU_15BIT) &&
+ status == HINIC5_MGMT_STATUS_EXIST)) {
+ if (PF_SET_VF_MAC(hwdev, status))
+ return 0;
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#define VLAN_N_VID 4096
+
+int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
+{
+ struct hinic5_port_mac_set mac_info;
+ u16 out_size = sizeof(mac_info);
+ int err;
+
+ if (!hwdev || !mac_addr)
+ return -EINVAL;
+
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
+
+ if (vlan_id >= VLAN_N_VID) {
+ return -EINVAL;
+ }
+
+ mac_info.func_id = func_id;
+ mac_info.vlan_id = vlan_id;
+
+ if (memmove_s(mac_info.mac, ETH_ALEN, mac_addr, ETH_ALEN) != EOK) {
+ return -ENOMEM;
+ }
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_MAC, &mac_info,
+ sizeof(mac_info), &mac_info, &out_size);
+ if (err || !out_size ||
+ hinic5_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0) {
+ return -EIO;
+ }
+
+ if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
+ return HINIC5_PF_SET_VF_ALREADY;
+ }
+
+ if (mac_info.msg_head.status == HINIC5_MGMT_STATUS_EXIST) {
+ return 0;
+ }
+
+ return 0;
+}
+
+int hinic5_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
+{
+ struct hinic5_port_mac_set mac_info;
+ u16 out_size = sizeof(mac_info);
+ int err;
+
+ if (!hwdev || !mac_addr)
+ return -EINVAL;
+
+ if (vlan_id >= VLAN_N_VID) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
+ mac_info.func_id = func_id;
+ mac_info.vlan_id = vlan_id;
+ if (memmove_s(mac_info.mac, ETH_ALEN, mac_addr, ETH_ALEN) != EOK) {
+ return -ENOMEM;
+ }
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_DEL_MAC, &mac_info,
+ sizeof(mac_info), &mac_info, &out_size);
+ if (err || !out_size ||
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ return -EIO;
+ }
+
+ if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
+ return HINIC5_PF_SET_VF_ALREADY;
+ }
+
+ return 0;
+}
+
+int hinic5_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+ u16 func_id)
+{
+ struct hinic5_port_mac_update mac_info;
+ u16 out_size = sizeof(mac_info);
+ int err;
+
+ if (!hwdev || !old_mac || !new_mac)
+ return -EINVAL;
+
+ if (vlan_id >= VLAN_N_VID) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
+ mac_info.func_id = func_id;
+ mac_info.vlan_id = vlan_id;
+ if ((memcpy_s(mac_info.old_mac, ETH_ALEN, old_mac, ETH_ALEN) != EOK) ||
+ (memcpy_s(mac_info.new_mac, ETH_ALEN, new_mac, ETH_ALEN) != EOK)) {
+ return -ENOMEM;
+ }
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_UPDATE_MAC,
+ &mac_info, sizeof(mac_info), &mac_info,
+ &out_size);
+ if (err || !out_size ||
+ hinic5_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0) {
+ return -EIO;
+ }
+
+ if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
+ return HINIC5_PF_SET_VF_ALREADY;
+ }
+
+ if (mac_info.msg_head.status == HINIC5_MGMT_STATUS_EXIST) {
+ return 0;
+ }
+
+ return 0;
+}
+
+int hinic5_get_default_mac(void *hwdev, u8 *mac_addr, int ether_len)
+{
+ struct hinic5_port_mac_set mac_info;
+ u16 out_size = sizeof(mac_info);
+ int err;
+
+ if (!hwdev || !mac_addr)
+ return -EINVAL;
+
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
+ mac_info.func_id = hinic5_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_MAC, &mac_info,
+ sizeof(mac_info), &mac_info, &out_size);
+ if (err || !out_size || mac_info.msg_head.status) {
+ return -EINVAL;
+ }
+
+ if (memmove_s(mac_addr, ether_len, mac_info.mac, ether_len) != EOK) {
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int hinic5_config_vlan(void *hwdev, u8 opcode, u16 vlan_id, u16 func_id)
+{
+ struct hinic5_cmd_vlan_config vlan_info;
+ u16 out_size = sizeof(vlan_info);
+ int err;
+
+ (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 = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_FUNC_VLAN,
+ &vlan_info, sizeof(vlan_info), &vlan_info,
+ &out_size);
+ if (err || !out_size || vlan_info.msg_head.status) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int hinic5_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
+{
+ if (!hwdev)
+ return -EINVAL;
+
+ return hinic5_config_vlan(hwdev, HINIC5_CMD_OP_ADD, vlan_id, func_id);
+}
+
+int hinic5_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
+{
+ if (!hwdev)
+ return -EINVAL;
+
+ return hinic5_config_vlan(hwdev, HINIC5_CMD_OP_DEL, vlan_id, func_id);
+}
+
+int hinic5_get_port_info(void *hwdev, struct nic_port_info *port_info)
+{
+ struct hinic5_cmd_port_info port_msg;
+ u16 out_size = sizeof(port_msg);
+ int err;
+
+ if (!hwdev || !port_info) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&port_msg, sizeof(port_msg), 0, sizeof(port_msg));
+ port_msg.port_id = hinic5_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_INFO, &port_msg,
+ sizeof(port_msg), &port_msg, &out_size);
+ if (err || !out_size || port_msg.msg_head.status) {
+ return -EINVAL;
+ }
+
+ port_info->autoneg_cap = port_msg.autoneg_cap;
+ port_info->autoneg_state = port_msg.autoneg_state;
+ port_info->duplex = port_msg.duplex;
+ port_info->port_type = port_msg.port_type;
+ port_info->speed = port_msg.speed;
+ port_info->fec = port_msg.fec;
+
+ return 0;
+}
+
+int hinic5_get_link_state(void *hwdev, u8 *link_state)
+{
+ struct hinic5_cmd_link_state get_link;
+ u16 out_size = sizeof(get_link);
+ int err;
+
+ if (!hwdev || !link_state) {
+ return -EINVAL;
+ }
+
+ (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 || !out_size || get_link.msg_head.status) {
+ return -EIO;
+ }
+
+ *link_state = get_link.state;
+
+ return 0;
+}
+
+int hinic5_set_vport_enable(void *hwdev, bool enable)
+{
+ struct hinic5_vport_state en_state;
+ u16 out_size = sizeof(en_state);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (void)memset_s(&en_state, sizeof(en_state), 0, sizeof(en_state));
+ en_state.func_id = hinic5_global_func_id(hwdev);
+ en_state.state = enable ? 1 : 0;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VPORT_ENABLE,
+ &en_state, sizeof(en_state), &en_state,
+ &out_size);
+ if (err || !out_size || en_state.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_set_port_enable(void *hwdev, bool enable)
+{
+ struct mag_cmd_set_port_enable en_state;
+ u16 out_size = sizeof(en_state);
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ if (hinic5_func_type(hwdev) == TYPE_VF) {
+ return 0;
+ }
+
+ (void)memset_s(&en_state, sizeof(en_state), 0, sizeof(en_state));
+ 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;
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_PORT_ENABLE, &en_state,
+ sizeof(en_state), &en_state, &out_size);
+ if (err || !out_size || en_state.head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_flush_qps_res(void *hwdev)
+{
+ struct hinic5_cmd_clear_qp_resource sq_res;
+ u16 out_size = sizeof(sq_res);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (void)memset_s(&sq_res, sizeof(sq_res), 0, sizeof(sq_res));
+ sq_res.func_id = hinic5_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CLEAR_QP_RESOURCE,
+ &sq_res, sizeof(sq_res), &sq_res,
+ &out_size);
+ if (err || !out_size || sq_res.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic5_cfg_hw_pause(void *hwdev, u8 opcode,
+ struct nic_pause_config *nic_pause)
+{
+ struct hinic5_cmd_pause_config pause_info;
+ u16 out_size = sizeof(pause_info);
+ int err;
+
+ (void)memset_s(&pause_info, sizeof(pause_info), 0, sizeof(pause_info));
+
+ pause_info.port_id = hinic5_physical_port_id(hwdev);
+ pause_info.opcode = opcode;
+ if (opcode == HINIC5_CMD_OP_SET) {
+ pause_info.auto_neg = nic_pause->auto_neg;
+ pause_info.rx_pause = nic_pause->rx_pause;
+ pause_info.tx_pause = nic_pause->tx_pause;
+ }
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_PAUSE_INFO,
+ &pause_info, sizeof(pause_info),
+ &pause_info, &out_size);
+ if (err || !out_size || pause_info.msg_head.status) {
+ return -EIO;
+ }
+
+ if (opcode == HINIC5_CMD_OP_GET) {
+ nic_pause->auto_neg = pause_info.auto_neg;
+ nic_pause->rx_pause = pause_info.rx_pause;
+ nic_pause->tx_pause = pause_info.tx_pause;
+ }
+
+ return 0;
+}
+
+int hinic5_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
+{
+ if (!hwdev)
+ return -EINVAL;
+
+ return hinic5_cfg_hw_pause(hwdev, HINIC5_CMD_OP_SET, &nic_pause);
+}
+
+int hinic5_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
+{
+ if (!hwdev || !nic_pause)
+ return -EINVAL;
+
+ return hinic5_cfg_hw_pause(hwdev, HINIC5_CMD_OP_GET, nic_pause);
+}
+
+int hinic5_get_vport_stats(void *hwdev, struct hinic5_vport_stats *stats)
+{
+ struct hinic5_port_stats_info stats_info;
+ struct hinic5_cmd_vport_stats vport_stats;
+ u16 out_size = sizeof(vport_stats);
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ if ((memset_s(&stats_info, sizeof(stats_info), 0, sizeof(stats_info)) !=
+ EOK) ||
+ (memset_s(&vport_stats, sizeof(vport_stats), 0,
+ sizeof(vport_stats)) != EOK)) {
+ return -ENOMEM;
+ }
+
+ stats_info.func_id = hinic5_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_VPORT_STAT,
+ &stats_info, sizeof(stats_info),
+ &vport_stats, &out_size);
+ if (err || !out_size || vport_stats.msg_head.status) {
+ return -EIO;
+ }
+
+ if (memcpy_s(stats, sizeof(*stats), &vport_stats.stats,
+ sizeof(*stats)) != EOK) {
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+int hinic5_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats)
+{
+ struct mag_cmd_get_port_stat *port_stats = NULL;
+ struct mag_cmd_port_stats_info stats_info;
+ u16 out_size = sizeof(*port_stats);
+ int err;
+
+ port_stats = zalloc(sizeof(*port_stats));
+ if (!port_stats) {
+ return -ENOMEM;
+ }
+
+ (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 || !out_size || port_stats->head.status) {
+ err = -EIO;
+ goto out;
+ }
+
+ if (memcpy_s(stats, sizeof(*stats), &port_stats->counter,
+ sizeof(*stats)) != EOK) {
+ err = -ENOMEM;
+ }
+
+out:
+ free(port_stats);
+
+ return err;
+}
+
+int hinic5_clear_vport_stats(void *hwdev)
+{
+ struct hinic5_cmd_clear_vport_stats clear_vport_stats;
+ u16 out_size = sizeof(clear_vport_stats);
+ int err;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&clear_vport_stats, sizeof(clear_vport_stats), 0,
+ sizeof(clear_vport_stats));
+ clear_vport_stats.func_id = hinic5_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CLEAN_VPORT_STAT,
+ &clear_vport_stats,
+ sizeof(clear_vport_stats),
+ &clear_vport_stats, &out_size);
+ if (err || !out_size || clear_vport_stats.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_clear_phy_port_stats(void *hwdev)
+{
+ struct mag_cmd_port_stats_info *port_stats = NULL;
+ u16 out_size = sizeof(*port_stats);
+ int err;
+
+ port_stats = zalloc(sizeof(*port_stats));
+ if (!port_stats) {
+ return -ENOMEM;
+ }
+
+ port_stats->port_id = hinic5_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_CLR_PORT_STAT, port_stats,
+ sizeof(*port_stats), port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ err = -EIO;
+ goto out;
+ }
+
+out:
+ free(port_stats);
+
+ return err;
+}
+
+static int hinic5_set_function_table(void *hwdev, u32 cfg_bitmap,
+ struct hinic5_func_tbl_cfg *cfg)
+{
+ struct hinic5_cmd_set_func_tbl cmd_func_tbl;
+ u16 out_size = sizeof(cmd_func_tbl);
+ int err;
+
+ (void)memset_s(&cmd_func_tbl, sizeof(cmd_func_tbl), 0,
+ sizeof(cmd_func_tbl));
+ cmd_func_tbl.func_id = hinic5_global_func_id(hwdev);
+ cmd_func_tbl.cfg_bitmap = cfg_bitmap;
+ cmd_func_tbl.tbl_cfg = *cfg;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_FUNC_TBL,
+ &cmd_func_tbl, sizeof(cmd_func_tbl),
+ &cmd_func_tbl, &out_size);
+ if (err || cmd_func_tbl.msg_head.status || !out_size) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int hinic5_init_function_table(void *hwdev, u16 rx_buff_len)
+{
+ struct hinic5_func_tbl_cfg func_tbl_cfg;
+ u32 cfg_bitmap = BIT(FUNC_CFG_INIT) | BIT(FUNC_CFG_MTU) |
+ BIT(FUNC_CFG_RX_BUF_SIZE);
+
+ (void)memset_s(&func_tbl_cfg, sizeof(func_tbl_cfg), 0,
+ sizeof(func_tbl_cfg));
+ func_tbl_cfg.mtu = 0x3FFF; /* Default, max mtu */
+ func_tbl_cfg.rx_wqe_buf_size = rx_buff_len;
+
+ return hinic5_set_function_table(hwdev, cfg_bitmap, &func_tbl_cfg);
+}
+
+int hinic5_set_port_mtu(void *hwdev, u16 new_mtu)
+{
+ struct hinic5_func_tbl_cfg func_tbl_cfg;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ if (new_mtu < HINIC5_MIN_MTU_SIZE) {
+ return -EINVAL;
+ }
+
+ if (new_mtu > HINIC5_MAX_JUMBO_FRAME_SIZE) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&func_tbl_cfg, sizeof(func_tbl_cfg), 0,
+ sizeof(func_tbl_cfg));
+ func_tbl_cfg.mtu = new_mtu;
+ return hinic5_set_function_table(hwdev, BIT(FUNC_CFG_MTU),
+ &func_tbl_cfg);
+}
+
+static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
+{
+ struct hinic5_cmd_feature_nego feature_nego;
+ u16 out_size = sizeof(feature_nego);
+ int err;
+
+ if (!hwdev || !s_feature || size > MAX_FEATURE_QWORD) {
+ return -EINVAL;
+ }
+
+ (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)
+ if (memcpy_s(feature_nego.s_feature,
+ sizeof(feature_nego.s_feature), s_feature,
+ size * sizeof(u64)) != EOK) {
+ return -ENOMEM;
+ }
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FEATURE_NEGO,
+ &feature_nego, sizeof(feature_nego),
+ &feature_nego, &out_size);
+ if (err || !out_size || feature_nego.msg_head.status) {
+ return -EFAULT;
+ }
+
+ if (opcode == HINIC5_CMD_OP_GET) {
+ if (memcpy_s(s_feature, size * sizeof(u64),
+ feature_nego.s_feature,
+ size * sizeof(u64)) != EOK) {
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+int hinic5_get_feature_from_hw(void *hwdev, u64 *s_feature, u16 size)
+{
+ return nic_feature_nego(hwdev, HINIC5_CMD_OP_GET, s_feature, size);
+}
+
+int hinic5_set_feature_to_hw(void *hwdev, u64 *s_feature, u16 size)
+{
+ return nic_feature_nego(hwdev, HINIC5_CMD_OP_SET, s_feature, size);
+}
+
+static int hinic5_vf_func_init(void *hwdev)
+{
+ struct hinic5_cmd_register_vf register_info;
+ u16 out_size = sizeof(register_info);
+ int err;
+
+ if (hinic5_func_type(hwdev) != TYPE_VF) {
+ return 0;
+ }
+
+ (void)memset_s(®ister_info, sizeof(register_info), 0,
+ sizeof(register_info));
+ register_info.op_register = 1;
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_VF_REGISTER,
+ ®ister_info, sizeof(register_info),
+ ®ister_info, &out_size);
+ if (err || register_info.msg_head.status || !out_size) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int hinic5_vf_func_free(void *hwdev)
+{
+ struct hinic5_cmd_register_vf unregister;
+ u16 out_size = sizeof(unregister);
+ int err;
+
+ if (hinic5_func_type(hwdev) != TYPE_VF) {
+ return 0;
+ }
+
+ (void)memset_s(&unregister, sizeof(unregister), 0, sizeof(unregister));
+ unregister.op_register = 0;
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_VF_REGISTER,
+ &unregister, sizeof(unregister),
+ &unregister, &out_size);
+ if (err || unregister.msg_head.status || !out_size) {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int hinic5_init_nic_hwdev(void *hwdev)
+{
+ return hinic5_vf_func_init(hwdev);
+}
+
+void hinic5_free_nic_hwdev(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ hinic5_vf_func_free(hwdev);
+}
+
+int hinic5_set_rx_mode(void *hwdev, u32 enable)
+{
+ struct hinic5_rx_mode_config rx_mode_cfg;
+ u16 out_size = sizeof(rx_mode_cfg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (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 = 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 || !out_size || rx_mode_cfg.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_set_rx_vlan_offload(void *hwdev, u8 en)
+{
+ struct hinic5_cmd_vlan_offload vlan_cfg;
+ u16 out_size = sizeof(vlan_cfg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (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 = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_RX_VLAN_OFFLOAD,
+ &vlan_cfg, sizeof(vlan_cfg), &vlan_cfg,
+ &out_size);
+ if (err || !out_size || vlan_cfg.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_set_vlan_filter(void *hwdev, u32 vlan_filter_ctrl)
+{
+ struct hinic5_cmd_set_vlan_filter vlan_filter;
+ u16 out_size = sizeof(vlan_filter);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (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 = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VLAN_FILTER_EN,
+ &vlan_filter, sizeof(vlan_filter),
+ &vlan_filter, &out_size);
+ if (err || !out_size || vlan_filter.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic5_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
+ u8 lro_max_pkt_len)
+{
+ struct hinic5_cmd_lro_config lro_cfg;
+ u16 out_size = sizeof(lro_cfg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (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 = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_RX_LRO, &lro_cfg,
+ sizeof(lro_cfg), &lro_cfg, &out_size);
+ if (err || !out_size || lro_cfg.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic5_set_rx_lro_timer(void *hwdev, u32 timer_value)
+{
+ struct hinic5_cmd_lro_timer lro_timer;
+ u16 out_size = sizeof(lro_timer);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ (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 = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_LRO_TIMER,
+ &lro_timer, sizeof(lro_timer), &lro_timer,
+ &out_size);
+ if (err || !out_size || lro_timer.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int hinic5_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
+ u32 lro_max_pkt_len)
+{
+ u8 ipv4_en = 0, ipv6_en = 0;
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ ipv4_en = (lro_en != 0) ? 1 : 0;
+ ipv6_en = (lro_en != 0) ? 1 : 0;
+
+ err = hinic5_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
+ if (err != 0)
+ return err;
+
+ /* We don't set LRO timer for VF */
+ if (hinic5_func_type(hwdev) == TYPE_VF)
+ return 0;
+
+ return hinic5_set_rx_lro_timer(hwdev, lro_timer);
+}
+
+int hinic5_set_rq_flush(void *hwdev, u16 q_id)
+{
+ struct hinic5_cmd_set_rq_flush *rq_flush_msg = NULL;
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+ u64 out_param = EIO;
+ int err;
+
+ cmd_buf = hinic5_alloc_cmd_buf(hwdev);
+ if (!cmd_buf) {
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(*rq_flush_msg);
+
+ rq_flush_msg = cmd_buf->buf;
+ rq_flush_msg->local_rq_id = q_id; //lint !e40 !e63
+ rq_flush_msg->value = cpu_to_be32(rq_flush_msg->value);
+
+ err = hinic5_cmdq_direct_resp(hwdev, HINIC5_MOD_L2NIC,
+ HINIC5_UCODE_CMD_SET_RQ_FLUSH, cmd_buf,
+ &out_param, 0);
+ if ((err) || (out_param != 0)) {
+ err = -EFAULT;
+ }
+
+ hinic5_free_cmd_buf(cmd_buf);
+
+ return err;
+}
+
+int hinic5_set_persistent_conf(void *hwdev, u32 op_code,
+ struct nic_bios_cfg *conf)
+{
+ struct nic_cmd_bios_cfg bios_conf = { 0 };
+ u16 out_size = sizeof(bios_conf);
+ int err;
+
+ if (!hwdev || !conf) {
+ return -EINVAL;
+ }
+
+ /* Make sure bit0 of opcode is set to 1 - which means write conf */
+ bios_conf.op_code = op_code | NIC_NVM_DATA_SET;
+ bios_conf.bios_cfg.signature = NIC_NVM_DATA_SIGNATURE;
+ bios_conf.msg_head.status = 0;
+ bios_conf.msg_head.version = 0;
+
+ bios_conf.bios_cfg.pxe_en = conf->pxe_en;
+ bios_conf.bios_cfg.nlvc.pxe_vlan_en = conf->nlvc.pxe_vlan_en;
+ bios_conf.bios_cfg.nlvc.pxe_vlan_pri = conf->nlvc.pxe_vlan_pri;
+ bios_conf.bios_cfg.nlvc.pxe_vlan_id = conf->nlvc.pxe_vlan_id;
+ bios_conf.bios_cfg.pf_bw = conf->pf_bw;
+ bios_conf.bios_cfg.speed = conf->speed;
+ bios_conf.bios_cfg.auto_neg = conf->auto_neg;
+ bios_conf.bios_cfg.lanes = conf->lanes;
+ bios_conf.bios_cfg.fec = conf->fec;
+ bios_conf.bios_cfg.auto_adapt = conf->auto_adapt;
+ bios_conf.bios_cfg.sriov_en = conf->sriov_en;
+ bios_conf.bios_cfg.func_valid = 1;
+ bios_conf.bios_cfg.func_id = (u8)hinic5_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_BIOS_CFG, &bios_conf,
+ sizeof(bios_conf), &bios_conf, &out_size);
+ if (err || !out_size || bios_conf.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void hinic5_bios_config_correction(struct nic_bios_cfg *conf)
+{
+ /* PXE configuration correction */
+ if (conf->pxe_en > HINIC5_PXE_ENABLE_MAX) {
+ conf->pxe_en = HINIC5_BIOS_DEFAULT_CFG_PXE_EN;
+ }
+
+ if (conf->nlvc.pxe_vlan_en > HINIC5_VLAN_ENABLE_MAX) {
+ conf->nlvc.pxe_vlan_en = HINIC5_BIOS_DEFAULT_CFG_VLAN_EN;
+ conf->nlvc.pxe_vlan_pri = HINIC5_BIOS_DEFAULT_CFG_VLAN_PRIORITY;
+ conf->nlvc.pxe_vlan_id = HINIC5_BIOS_DEFAULT_CFG_VLAN_ID;
+ } else {
+ if (conf->nlvc.pxe_vlan_pri > HINIC5_VLAN_PRIO_MAX) {
+ conf->nlvc.pxe_vlan_pri =
+ HINIC5_BIOS_DEFAULT_CFG_VLAN_PRIORITY;
+ }
+
+ if (conf->nlvc.pxe_vlan_id > HINIC5_VLAN_ID_MAX ||
+ conf->nlvc.pxe_vlan_id < HINIC5_VLAN_ID_MIN) {
+ conf->nlvc.pxe_vlan_id =
+ HINIC5_BIOS_DEFAULT_CFG_VLAN_ID;
+ }
+ }
+
+ if (conf->pf_bw > HINIC5_PF_SPEED_MAX ||
+ conf->pf_bw < HINIC5_PF_SPEED_MIN) {
+ conf->pf_bw = HINIC5_BIOS_DEFAULT_CFG_SPEED_LIMITATION;
+ }
+
+ if (conf->sriov_en > HINIC5_SRIOV_CONTROL_MAX ||
+ conf->sriov_en < HINIC5_SRIOV_CONTROL_MIN) {
+ conf->sriov_en = HINIC5_BIOS_DEFAULT_CFG_SRIOV;
+ }
+}
+
+int hinic5_get_persistent_conf(void *hwdev, u32 op_code,
+ struct nic_bios_cfg *conf)
+{
+ struct nic_cmd_bios_cfg bios_conf = { 0 };
+ u16 out_size = sizeof(bios_conf);
+ int err;
+
+ if (!hwdev || !conf) {
+ return -EINVAL;
+ }
+
+ /* make sure bit0 of opcode is cleared to 0, which means read */
+ bios_conf.op_code = op_code & (~NIC_NVM_DATA_SET);
+ bios_conf.bios_cfg.signature = 0;
+ bios_conf.msg_head.status = 0;
+ bios_conf.msg_head.version = 0;
+ bios_conf.bios_cfg.func_valid = 1;
+ bios_conf.bios_cfg.func_id = (u8)hinic5_global_func_id(hwdev);
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_BIOS_CFG, &bios_conf,
+ sizeof(bios_conf), &bios_conf, &out_size);
+ if (err || !out_size || bios_conf.msg_head.status) {
+ return -EIO;
+ }
+
+ if (bios_conf.bios_cfg.signature != NIC_NVM_DATA_SIGNATURE) {
+ return -EIO;
+ }
+
+ hinic5_bios_config_correction(&bios_conf.bios_cfg);
+
+ conf->pxe_en = bios_conf.bios_cfg.pxe_en;
+ conf->nlvc.pxe_vlan_en = bios_conf.bios_cfg.nlvc.pxe_vlan_en;
+ conf->nlvc.pxe_vlan_pri = bios_conf.bios_cfg.nlvc.pxe_vlan_pri;
+ conf->nlvc.pxe_vlan_id = bios_conf.bios_cfg.nlvc.pxe_vlan_id;
+ conf->pf_bw = bios_conf.bios_cfg.pf_bw;
+ conf->speed = bios_conf.bios_cfg.speed;
+ conf->auto_neg = bios_conf.bios_cfg.auto_neg;
+ conf->lanes = bios_conf.bios_cfg.lanes;
+ conf->fec = bios_conf.bios_cfg.fec;
+ conf->auto_adapt = bios_conf.bios_cfg.auto_adapt;
+ conf->sriov_en = bios_conf.bios_cfg.sriov_en;
+
+ return 0;
+}
+
+int hinic5_set_led_status(void *hwdev, enum mag_led_type type,
+ enum mag_led_mode mode)
+{
+ struct mag_cmd_set_led_cfg led_info = { 0 };
+ u16 out_size = sizeof(led_info);
+ int err;
+
+ if (!hwdev) {
+ return -EFAULT;
+ }
+
+ led_info.func_id = hinic5_global_func_id(hwdev);
+ led_info.type = type;
+ led_info.mode = mode;
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_LED_CFG, &led_info,
+ sizeof(led_info), &led_info, &out_size);
+ if (err || !out_size || led_info.msg_head.status) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ return hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_HILINK, cmd, buf_in,
+ in_size, buf_out, out_size, 0);
+}
+
+static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
+ out_size);
+}
+
+static void link_status_event_handler(void *hwdev, void *buf_in,
+ __attribute__((unused)) u16 in_size,
+ __attribute__((unused)) void *buf_out,
+ __attribute__((unused)) u16 *out_size)
+{
+ struct hinic5_cmd_link_state *link_status = NULL;
+ struct hinic5_hwdev *dev = hwdev;
+ struct hinic5_nic_dev *nic_dev = dev->dev_handle;
+
+ link_status = buf_in;
+ IPXE_DRV_LOG(INFO,
+ "Link status report received, func_id: %d, status: %d(%s)",
+ hinic5_global_func_id(hwdev), link_status->state,
+ link_status->state ? "UP" : "DOWN");
+
+ if (link_status->state) {
+ IPXE_DRV_LOG(INFO, "Netdev %s Link up\n",
+ nic_dev->netdev->name);
+ netdev_link_up(nic_dev->netdev);
+ } else {
+ IPXE_DRV_LOG(INFO, "Netdev %s Link down\n",
+ nic_dev->netdev->name);
+ netdev_link_down(nic_dev->netdev);
+ }
+}
+
+struct nic_event_handler {
+ u16 cmd;
+ void (*handler)(void *hwdev, void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size);
+};
+
+static const struct nic_event_handler mag_cmd_handler[] = {
+ {
+ .cmd = MAG_CMD_GET_LINK_STATUS,
+ .handler = link_status_event_handler,
+ },
+};
+
+static int hinic5_mag_event_handler(void *hwdev, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ u32 size = ARRAY_LEN(mag_cmd_handler);
+ u32 i;
+
+ if (!hwdev) {
+ return -EINVAL;
+ }
+
+ *out_size = 0;
+ for (i = 0; i < size; i++) {
+ if (cmd == mag_cmd_handler[i].cmd) {
+ mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
+ buf_out, out_size);
+ break;
+ }
+ }
+
+ /* can't find this event cmd */
+ if (i == size) {
+ IPXE_DRV_LOG(ERR, "Unsupported mag event, cmd: %d\n", cmd);
+ }
+
+ return 0;
+}
+
+void hinic5_pf_mag_event_handler(void *hwdev, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ hinic5_mag_event_handler(hwdev, cmd, buf_in, in_size, buf_out,
+ out_size);
+}
+
+int hinic5_nic_register_event(void *hwdev)
+{
+ return hinic5_register_mgmt_msg_cb(
+ hwdev, HINIC5_MOD_HILINK,
+ (hinic5_mgmt_msg_cb)hinic5_pf_mag_event_handler);
+}
+
+void hinic5_nic_unregister_event(void *hwdev)
+{
+ return hinic5_unregister_mgmt_msg_cb(hwdev, HINIC5_MOD_HILINK);
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.h
new file mode 100644
index 000000000..55a967255
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_cfg.h
@@ -0,0 +1,904 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_NIC_CFG_H_
+#define _HINIC5_NIC_CFG_H_
+
+#include <stdbool.h>
+#include "base/hinic5_mgmt.h"
+#include "hinic5_mag_cfg.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#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 HINIC5_VLAN_PRIORITY_SHIFT 13
+
+#define HINIC5_DCB_UP_MAX 0x8
+
+#define HINIC5_MAX_NUM_RQ 256
+
+#define HINIC5_MAX_MTU_SIZE 9600
+#define HINIC5_MIN_MTU_SIZE 384
+#define HINIC5_DEFAULT_MTU_SIZE 1500
+
+#define HINIC5_COS_NUM_MAX 8
+
+#define HINIC5_VLAN_TAG_SIZE 4
+
+#define HINIC5_ETHER_HDR_LEN 14
+#define HINIC5_ETHER_CRC_LEN 4
+
+#define HINIC5_ETH_OVERHEAD \
+ (HINIC5_ETHER_HDR_LEN + HINIC5_ETHER_CRC_LEN + HINIC5_VLAN_TAG_SIZE * 2)
+
+#define HINIC5_MIN_FRAME_SIZE (HINIC5_MIN_MTU_SIZE + HINIC5_ETH_OVERHEAD)
+#define HINIC5_MAX_JUMBO_FRAME_SIZE (HINIC5_MAX_MTU_SIZE + HINIC5_ETH_OVERHEAD)
+
+#define HINIC5_PF_SET_VF_ALREADY 0x4
+#define HINIC5_MGMT_STATUS_EXIST 0x6
+#define CHECK_IPSU_15BIT 0x8000
+
+#define HINIC5_MGMT_STATUS_TABLE_EMPTY 0xB
+#define HINIC5_MGMT_STATUS_TABLE_FULL 0xC
+
+#define HINIC5_MGMT_CMD_UNSUPPORTED 0xFF
+
+#define HINIC5_MAX_UC_MAC_ADDRS 128
+#define HINIC5_MAX_MC_MAC_ADDRS 2048
+
+#define MAX_FEATURE_QWORD 4
+
+#define NIC_F_HTN_CMDQ NIC_F(HTN_CMDQ)
+#define NIC_F_BIT(bit) ((u64)1 << (bit))
+#define NIC_F(name) NIC_F_BIT(NIC_F_##name##_BIT)
+
+struct hinic5_cmd_feature_nego {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u32 rsvd1;
+ u64 s_feature[MAX_FEATURE_QWORD];
+};
+
+/* Structures for port info */
+struct nic_port_info {
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+};
+
+enum nic_feature_cap {
+ 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计数 */
+};
+
+enum hinic5_link_status { HINIC5_LINK_DOWN = 0, HINIC5_LINK_UP };
+
+enum nic_media_type {
+ MEDIA_UNKNOWN = -1,
+ MEDIA_FIBRE = 0,
+ MEDIA_COPPER,
+ MEDIA_BACKPLANE
+};
+
+enum nic_speed_level {
+ LINK_SPEED_NOT_SET = 0,
+ LINK_SPEED_10MB,
+ LINK_SPEED_100MB,
+ LINK_SPEED_1GB,
+ LINK_SPEED_10GB,
+ LINK_SPEED_25GB,
+ LINK_SPEED_40GB,
+ LINK_SPEED_100GB,
+ LINK_SPEED_LEVELS,
+};
+
+struct hinic5_sq_attr {
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u64 ci_dma_base;
+};
+
+struct hinic5_cmd_cons_idx_attr {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+struct hinic5_port_mac_set {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic5_port_mac_update {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+#define HINIC5_CMD_OP_ADD 1
+#define HINIC5_CMD_OP_DEL 0
+
+struct hinic5_cmd_vlan_config {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u16 rsvd2;
+};
+
+struct hinic5_cmd_set_vlan_filter {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ /* Bit0: vlan filter en; bit1: broadcast filter en */
+ u32 vlan_filter_ctrl;
+};
+
+struct hinic5_cmd_port_info {
+ struct mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic5_cmd_link_state {
+ struct mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct nic_pause_config {
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+};
+
+struct hinic5_cmd_pause_config {
+ struct mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct hinic5_vport_state {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic5_cmd_clear_qp_resource {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic5_port_stats_info {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic5_vport_stats {
+ 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;
+};
+
+struct hinic5_cmd_vport_stats {
+ struct mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic5_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic5_phy_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ 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;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ 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;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic5_port_stats {
+ struct mgmt_msg_head msg_head;
+
+ struct hinic5_phy_port_stats stats;
+};
+
+struct hinic5_cmd_clear_vport_stats {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+};
+
+struct hinic5_cmd_clear_port_stats {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+};
+
+struct hinic5_cmd_qpn {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic5_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic5_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic5_cmd_set_func_tbl {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic5_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic5_rx_mode_config {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+struct hinic5_cmd_vlan_offload {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+#define HINIC5_CMD_OP_GET 0
+#define HINIC5_CMD_OP_SET 1
+
+struct hinic5_cmd_lro_config {
+ struct mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* Unit size is 1K */
+ u8 resv2[13];
+};
+
+struct hinic5_cmd_lro_timer {
+ struct mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+enum {
+ HINIC5_IFLA_VF_LINK_STATE_AUTO, /* Link state of the uplink */
+ HINIC5_IFLA_VF_LINK_STATE_ENABLE, /* Link always up */
+ HINIC5_IFLA_VF_LINK_STATE_DISABLE, /* Link always down */
+};
+
+struct hinic5_cmd_register_vf {
+ struct mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd[39];
+};
+struct hinic5_cmd_set_rq_flush {
+ union {
+ struct {
+ u16 global_rq_id;
+ u16 local_rq_id;
+ };
+ u32 value;
+ };
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define NIC_NVM_DATA_ALL \
+ (NIC_NVM_DATA_PXE | NIC_NVM_DATA_LEGACY_VLAN | \
+ NIC_NVM_DATA_LEGACY_VLAN_PRI | NIC_NVM_DATA_LEGACY_VLAN_ID | \
+ NIC_NVM_DATA_WORK_MODE | NIC_NVM_DATA_PF_SPEED_LIMIT | \
+ NIC_NVM_DATA_GE_MODE | NIC_NVM_DATA_AUTO_NEG | \
+ NIC_NVM_DATA_LINK_FEC | NIC_NVM_DATA_PF_ADAPTIVE_LINK | \
+ NIC_NVM_DATA_SRIOV_CONTROL)
+
+/* The default BIOS configuration */
+#define HINIC5_BIOS_DEFAULT_CFG_PXE_EN 1
+#define HINIC5_BIOS_DEFAULT_CFG_VLAN_EN 0
+#define HINIC5_BIOS_DEFAULT_CFG_VLAN_PRIORITY 0
+#define HINIC5_BIOS_DEFAULT_CFG_VLAN_ID 1
+#define HINIC5_BIOS_DEFAULT_CFG_WORK_MODE 2
+#define HINIC5_BIOS_DEFAULT_CFG_SPEED_LIMITATION 100
+
+#define HINIC5_BIOS_DEFAULT_CFG_GE_SPEED 0 /* PORT_SPEED_NOT_SET = 0 */
+#define HINIC5_BIOS_DEFAULT_CFG_AUTO_NEG 0 /* PORT_AN_NOT_SET = 0 */
+#define HINIC5_BIOS_DEFAULT_CFG_FEC 0 /* PORT_FEC_NOT_SET = 0 */
+#define HINIC5_BIOS_DEFAULT_CFG_ADAPTIVE 1 /* PORT_CFG_ADAPT_ON = 1 */
+#define HINIC5_BIOS_DEFAULT_CFG_SRIOV 1 /* PORT_CFG_SRIOV_ON = 1 */
+#define HINIC5_BIOS_CFG_UNSET 0
+
+#define HINIC5_PXE_ENABLE_MIN 0
+#define HINIC5_PXE_ENABLE_MAX 1
+
+#define HINIC5_VLAN_ENABLE_MIN 0
+#define HINIC5_VLAN_ENABLE_MAX 1
+
+#define HINIC5_VLAN_PRIO_MIN 0
+#define HINIC5_VLAN_PRIO_MAX 7
+
+#define HINIC5_VLAN_ID_MIN 1
+#define HINIC5_VLAN_ID_MAX 4094
+
+#define HINIC5_PF_SPEED_MIN 1
+#define HINIC5_PF_SPEED_MAX 100
+
+#define HINIC5_GE_SPEED_MIN 0
+#define HINIC5_GE_SPEED_MAX 9
+
+#define HINIC5_AUTO_NEG_MIN 1
+#define HINIC5_AUTO_NEG_MAX 2
+
+#define HINIC5_FEC_MIN 1
+#define HINIC5_FEC_MAX 5
+
+#define HINIC5_ADAPTIVE_MIN 1
+#define HINIC5_ADAPTIVE_MAX 2
+
+#define HINIC5_SRIOV_CONTROL_MIN 1
+#define HINIC5_SRIOV_CONTROL_MAX 2
+
+struct nic_legacy_vlan_cfg {
+ u16 pxe_vlan_en : 1; /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u16 pxe_vlan_pri : 3; /* Legacy mode PXE VLAN priority: 0-7 */
+ u16 pxe_vlan_id : 12; /* Legacy mode PXE VLAN ID 1-4094 */
+};
+
+/* 注意:此结构必须保证4字节对齐 */
+struct nic_bios_cfg {
+ u32 signature; /* 签名,用于判断FLASH的内容合法性 */
+ u8 pxe_en; /* PXE enable: 0 - disable 1 - enable */
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg
+ nlvc; /* Legacy vlan cfg, only used in legacy mode */
+ u8 pxe_vlan_en; /* UEFI PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_pri; /* UEFI PXE VLAN priority: 0-7 */
+ u16 pxe_vlan_id; /* UEFI 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 mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
+
+int hinic5_set_ci_table(void *hwdev, struct hinic5_sq_attr *attr);
+
+/**
+ * Update MAC address to hardware
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] old_mac
+ * Old MAC addr to delete
+ * @param[in] new_mac
+ * New MAC addr to update
+ * @param[in] vlan_id
+ * Vlan id
+ * @param func_id
+ * Function index
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+ u16 func_id);
+
+/**
+ * Get the default mac address
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] mac_addr
+ * Mac address from hardware
+ * @param[in] ether_len
+ * The length of mac address
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_get_default_mac(void *hwdev, u8 *mac_addr, int ether_len);
+
+/**
+ * Set mac address
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] mac_addr
+ * Mac address from hardware
+ * @param[in] vlan_id
+ * Vlan id
+ * @param[in] func_id
+ * Function index
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id);
+
+/**
+ * Delete MAC address
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] mac_addr
+ * MAC address from hardware
+ * @param[in] vlan_id
+ * Vlan id
+ * @param[in] func_id
+ * Function index
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id);
+
+/**
+ * Set function mtu
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] new_mtu
+ * MTU value
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_port_mtu(void *hwdev, u16 new_mtu);
+
+/**
+ * Set function valid status
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] enable
+ * 0-disable, 1-enable
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_vport_enable(void *hwdev, bool enable);
+
+/**
+ * Get link state
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] link_state
+ * Link state, 0-link down, 1-link up
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_get_link_state(void *hwdev, u8 *link_state);
+
+/**
+ * Flush queue pairs resource in hardware
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_flush_qps_res(void *hwdev);
+
+/**
+ * Set pause info
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] nic_pause
+ * Pause info
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_pause_info(void *hwdev, struct nic_pause_config nic_pause);
+
+/**
+ * Get pause info
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] nic_pause
+ * Pause info
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause);
+
+/**
+ * Get function stats
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] stats
+ * Function stats
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_get_vport_stats(void *hwdev, struct hinic5_vport_stats *stats);
+
+int hinic5_clear_vport_stats(void *hwdev);
+
+int hinic5_clear_phy_port_stats(void *hwdev);
+
+/**
+ * Init nic hwdev
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_init_nic_hwdev(void *hwdev);
+
+/**
+ * Free nic hwdev
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ */
+void hinic5_free_nic_hwdev(void *hwdev);
+
+/**
+ * Set function rx mode
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] enable
+ * Rx mode state, 0-disable, 1-enable
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_rx_mode(void *hwdev, u32 enable);
+
+/**
+ * Set function vlan offload valid state
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] enable
+ * Rx mode state, 0-disable, 1-enable
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_rx_vlan_offload(void *hwdev, u8 en);
+
+/**
+ * Set rx LRO configuration
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] lro_en
+ * LRO enable state, 0-disable, 1-enable
+ * @param[in] lro_timer
+ * LRO aggregation timeout
+ * @param[in] lro_max_pkt_len
+ * LRO coalesce packet size(unit size is 1K)
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
+ u32 lro_max_pkt_len);
+
+/**
+ * Get port info
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[out] port_info
+ * Port info, including autoneg, port type, duplex, speed and fec mode
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_get_port_info(void *hwdev, struct nic_port_info *port_info);
+
+int hinic5_init_function_table(void *hwdev, u16 rx_buff_len);
+
+/**
+ * Add vlan to hardware
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] vlan_id
+ * Vlan id
+ * @param[in] func_id
+ * Function id
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_add_vlan(void *hwdev, u16 vlan_id, u16 func_id);
+
+/**
+ * Delete vlan
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] vlan_id
+ * Vlan id
+ * @param[in] func_id
+ * Function id
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_del_vlan(void *hwdev, u16 vlan_id, u16 func_id);
+
+/**
+ * Set vlan filter
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] vlan_filter_ctrl
+ * Vlan filter enable flag, 0-disable, 1-enable
+ *
+ * @retval zero : Success
+ * @retval non-zero : Failure
+ */
+int hinic5_set_vlan_filter(void *hwdev, u32 vlan_filter_ctrl);
+
+int hinic5_set_rq_flush(void *hwdev, u16 q_id);
+
+/**
+ * Get service feature HW supported
+ *
+ * @param[in] dev
+ * Device pointer to hwdev
+ * @param[in] size
+ * s_feature's array size
+ * @param[out] s_feature
+ * s_feature HW supported
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+int hinic5_get_feature_from_hw(void *hwdev, u64 *s_feature, u16 size);
+
+/**
+ * Set service feature driver supported to hardware
+ *
+ * @param[in] dev
+ * Device pointer to hwdev
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+int hinic5_set_feature_to_hw(void *hwdev, u64 *s_feature, u16 size);
+
+/**
+ * Set bios config
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] op_code
+ * op_code to set
+ * @param[in] conf
+ * config value to set
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+int hinic5_set_persistent_conf(void *hwdev, u32 op_code,
+ struct nic_bios_cfg *conf);
+
+/**
+ * Get bios config
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] op_code
+ * op_code to get
+ * @param[out] conf
+ * current config value
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+int hinic5_get_persistent_conf(void *hwdev, u32 op_code,
+ struct nic_bios_cfg *conf);
+
+int hinic5_nic_register_event(void *hwdev);
+
+void hinic5_nic_unregister_event(void *hwdev);
+
+#endif /* _HINIC5_NIC_CFG_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_dev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_dev.h
new file mode 100644
index 000000000..1cfa1fde7
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_dev.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_NIC_DEV_H_
+#define _HINIC5_NIC_DEV_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <ipxe/netdevice.h>
+#include <ipxe/pci.h>
+#include <ipxe/dma.h>
+
+#include "base/hinic5_hwdev.h"
+#include "hinic5_tx.h"
+#include "hinic5_rx.h"
+
+#define HINIC5_PXE_DEFAULT_QNUM 1
+#define HINIC5_PXE_DEFAULT_QUEUE_DEPTH 256
+
+struct hinic5_nic_dev {
+ /* OS defined structs */
+ struct net_device *netdev;
+ struct pci_device *pdev;
+
+ struct hinic5_hwdev *hwdev; /* Hardware device */
+
+ struct hinic5_txq *txqs;
+ struct hinic5_rxq *rxqs;
+
+ u16 num_sqs;
+ u16 num_rqs;
+ u16 max_sqs;
+ u16 max_rqs;
+
+ u16 rx_buff_len;
+ u16 mtu_size;
+
+ u16 rss_state;
+ u8 num_rss;
+ u8 rsvd0;
+
+ u32 rx_mode;
+
+ u32 default_cos;
+
+ u64 feature_cap;
+
+ /** DMA device */
+ struct dma_device *dma;
+
+ struct hinic5_nic_cmdq_ops *cmdq_ops;
+};
+
+#endif /* _HINIC5_NIC_DEV_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.c
new file mode 100644
index 000000000..e981d9d5d
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.c
@@ -0,0 +1,633 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipxe/list.h>
+#include <ipxe/io.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/pci.h>
+#include <ipxe/dma.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/ethernet.h>
+
+#include "base/hinic5_compat.h"
+#include "base/hinic5_cmd.h"
+#include "base/hinic5_wq.h"
+#include "base/hinic5_mgmt.h"
+#include "base/hinic5_cmdq.h"
+#include "base/hinic5_hwdev.h"
+#include "base/hinic5_hw_comm.h"
+#include "base/hinic5_cmdq_enhance.h"
+#include "hinic5_nic_cfg.h"
+#include "hinic5_nic_dev.h"
+#include "hinic5_tx.h"
+#include "hinic5_rx.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_DROP_THD_ON 0xFFFF
+#define HINIC5_DEAULT_DROP_THD_OFF 0
+
+#define CI_IDX_HIGH_SHIFH 12
+
+#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_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_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_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_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_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_SET(val, member) \
+ (((val)&SQ_CTXT_PKT_DROP_##member##_MASK) \
+ << SQ_CTXT_PKT_DROP_##member##_SHIFT)
+
+#define SQ_CTXT_GLOBAL_SQ_ID_SHIFT 0
+
+#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_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_CEQ_SET(val, member) \
+ (((val)&SQ_CTXT_VLAN_##member##_MASK) << SQ_CTXT_VLAN_##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_MASK 0x3FFFU
+#define SQ_CTXT_PREF_CACHE_MAX_MASK 0x7FFU
+#define SQ_CTXT_PREF_CACHE_MIN_MASK 0x7FU
+
+#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_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_SET(val, member) \
+ (((val)&SQ_CTXT_PREF_##member##_MASK) << SQ_CTXT_PREF_##member##_SHIFT)
+
+#define SQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT 0
+
+#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 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_CI_PI_SET(val, member) \
+ (((val)&RQ_CTXT_##member##_MASK) << RQ_CTXT_##member##_SHIFT)
+
+#define RQ_CTXT_CEQ_ATTR_INTR_SHIFT 21
+#define RQ_CTXT_CEQ_ATTR_INTR_ARM_SHIFT 30
+#define RQ_CTXT_CEQ_ATTR_EN_SHIFT 31
+
+#define RQ_CTXT_CEQ_ATTR_INTR_MASK 0x3FFU
+#define RQ_CTXT_CEQ_ATTR_INTR_ARM_MASK 0x1U
+#define RQ_CTXT_CEQ_ATTR_EN_MASK 0x1U
+
+#define RQ_CTXT_CEQ_ATTR_SET(val, member) \
+ (((val)&RQ_CTXT_CEQ_ATTR_##member##_MASK) \
+ << RQ_CTXT_CEQ_ATTR_##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_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_CQE_LEN_SHIFT 28
+
+#define RQ_CTXT_CQE_LEN_MASK 0x3U
+
+#define RQ_CTXT_CQE_LEN_SET(val, member) \
+ (((val)&RQ_CTXT_##member##_MASK) << RQ_CTXT_##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_MASK 0x3FFFU
+#define RQ_CTXT_PREF_CACHE_MAX_MASK 0x7FFU
+#define RQ_CTXT_PREF_CACHE_MIN_MASK 0x7FU
+
+#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_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_SET(val, member) \
+ (((val)&RQ_CTXT_PREF_##member##_MASK) << RQ_CTXT_PREF_##member##_SHIFT)
+
+#define RQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT 0
+
+#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 SIZE_16BYTES(size) (HINIC5_ALIGN((size), 16) >> 4)
+
+#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)
+
+void hinic5_sq_prepare_ctxt(struct hinic5_txq *sq, u16 sq_id,
+ struct hinic5_sq_ctxt *sq_ctxt)
+{
+ u64 wq_page_addr;
+ u64 wq_page_pfn, wq_block_pfn;
+ u32 wq_page_pfn_hi, wq_page_pfn_lo;
+ u32 wq_block_pfn_hi, wq_block_pfn_lo;
+ u16 pi_start, ci_start;
+
+ ci_start = sq->cons_idx & sq->q_mask;
+ pi_start = sq->prod_idx & sq->q_mask;
+
+ /* Read the first page from hardware table */
+ wq_page_addr = sq->queue_buf_paddr;
+
+ wq_page_pfn = WQ_PAGE_PFN(wq_page_addr);
+ wq_page_pfn_hi = upper_32_bits(wq_page_pfn);
+ wq_page_pfn_lo = lower_32_bits(wq_page_pfn);
+
+ /* Use 0-level CLA */
+ wq_block_pfn = WQ_BLOCK_PFN(wq_page_addr);
+ 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->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_lo = wq_page_pfn_lo;
+
+ sq_ctxt->pkt_drop_thd =
+ SQ_CTXT_PKT_DROP_THD_SET(HINIC5_DEAULT_DROP_THD_ON, THD_ON) |
+ SQ_CTXT_PKT_DROP_THD_SET(HINIC5_DEAULT_DROP_THD_OFF, THD_OFF);
+
+ sq_ctxt->global_sq_id =
+ SQ_CTXT_GLOBAL_QUEUE_ID_SET(sq_id, GLOBAL_SQ_ID);
+
+ /* 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->rsvd0 = 0;
+
+ sq_ctxt->pref_cache =
+ SQ_CTXT_PREF_SET(WQ_PREFETCH_MIN, CACHE_MIN) |
+ SQ_CTXT_PREF_SET(WQ_PREFETCH_MAX, CACHE_MAX) |
+ SQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);
+
+ sq_ctxt->pref_ci_owner =
+ SQ_CTXT_PREF_SET(CI_HIGN_IDX(ci_start), CI_HI) |
+ SQ_CTXT_PREF_SET(1, OWNER);
+
+ sq_ctxt->pref_wq_pfn_hi_ci =
+ SQ_CTXT_PREF_SET(ci_start, CI_LOW) |
+ SQ_CTXT_PREF_SET(wq_page_pfn_hi, WQ_PFN_HI);
+
+ sq_ctxt->pref_wq_pfn_lo = wq_page_pfn_lo;
+
+ sq_ctxt->wq_block_pfn_hi =
+ SQ_CTXT_WQ_BLOCK_SET(wq_block_pfn_hi, PFN_HI);
+
+ sq_ctxt->wq_block_pfn_lo = wq_block_pfn_lo;
+
+ mb();
+
+ hinic5_cpu_to_be32(sq_ctxt, sizeof(*sq_ctxt));
+}
+
+void hinic5_rq_prepare_ctxt(struct hinic5_rxq *rq,
+ struct hinic5_rq_ctxt *rq_ctxt)
+{
+ u64 wq_page_addr, wq_page_pfn, wq_block_pfn;
+ u32 wq_page_pfn_hi, wq_page_pfn_lo, wq_block_pfn_hi, wq_block_pfn_lo;
+ u16 pi_start, ci_start;
+ u16 wqe_type = rq->wqebb_shift - HINIC5_RQ_WQEBB_SHIFT;
+
+ /* RQ depth is in unit of 8 Bytes */
+ ci_start =
+ (u16)((rq->cons_idx & rq->q_mask) << wqe_type); /*lint !e701*/
+ pi_start =
+ (u16)((rq->prod_idx & rq->q_mask) << wqe_type); /*lint !e701*/
+
+ /* Read the first page from hardware table */
+ wq_page_addr = rq->queue_buf_paddr;
+
+ wq_page_pfn = WQ_PAGE_PFN(wq_page_addr);
+ wq_page_pfn_hi = upper_32_bits(wq_page_pfn);
+ wq_page_pfn_lo = lower_32_bits(wq_page_pfn);
+
+ /* Use 0-level CLA */
+ wq_block_pfn = WQ_BLOCK_PFN(wq_page_addr);
+
+ wq_block_pfn_hi = upper_32_bits(wq_block_pfn);
+ wq_block_pfn_lo = lower_32_bits(wq_block_pfn);
+
+ rq_ctxt->ci_pi = RQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |
+ RQ_CTXT_CI_PI_SET(pi_start, PI_IDX);
+
+ /* RQ doesn't need ceq, msix_entry_idx set 1, but mask not enable */
+ rq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(1, EN) |
+ RQ_CTXT_CEQ_ATTR_SET(0, INTR_ARM) |
+ RQ_CTXT_CEQ_ATTR_SET(1, INTR);
+
+ /* Use 32Byte WQE with SGE for CQE in default */
+ 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;
+ default:
+ IPXE_DRV_LOG(INFO, "Invalid rq wqe type: %d", wqe_type);
+ }
+
+ rq_ctxt->wq_pfn_lo = wq_page_pfn_lo;
+
+ rq_ctxt->pref_cache =
+ RQ_CTXT_PREF_SET(WQ_PREFETCH_MIN, CACHE_MIN) |
+ RQ_CTXT_PREF_SET(WQ_PREFETCH_MAX, CACHE_MAX) |
+ RQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);
+
+ rq_ctxt->pref_ci_owner =
+ RQ_CTXT_PREF_SET(CI_HIGN_IDX(ci_start), CI_HI) |
+ RQ_CTXT_PREF_SET(1, OWNER);
+
+ rq_ctxt->pref_wq_pfn_hi_ci =
+ RQ_CTXT_PREF_SET(wq_page_pfn_hi, WQ_PFN_HI) |
+ RQ_CTXT_PREF_SET(ci_start, CI_LOW);
+
+ rq_ctxt->pref_wq_pfn_lo = wq_page_pfn_lo;
+
+ rq_ctxt->pi_paddr_hi = 0;
+ rq_ctxt->pi_paddr_lo = 0;
+
+ rq_ctxt->wq_block_pfn_hi =
+ RQ_CTXT_WQ_BLOCK_SET(wq_block_pfn_hi, PFN_HI);
+
+ rq_ctxt->wq_block_pfn_lo = wq_block_pfn_lo;
+ mb();
+
+ hinic5_cpu_to_be32(rq_ctxt, sizeof(*rq_ctxt));
+}
+
+static int init_sq_ctxts(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+ u64 out_param = 0;
+ u16 q_id, max_ctxts;
+ int err = 0;
+ u8 cmd;
+
+ cmd_buf = hinic5_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd buf for sq ctx failed");
+ return -ENOMEM;
+ }
+
+ q_id = 0;
+ while (q_id < nic_dev->num_sqs) {
+ max_ctxts = (nic_dev->num_sqs - q_id) > HINIC5_Q_CTXT_MAX ?
+ HINIC5_Q_CTXT_MAX :
+ (nic_dev->num_sqs - q_id);
+
+ cmd = nic_dev->cmdq_ops->prepare_cmd_buf_qp_context_multi_store(
+ nic_dev, cmd_buf, HINIC5_QP_CTXT_TYPE_SQ, q_id,
+ max_ctxts);
+
+ mb();
+
+ err = hinic5_cmdq_direct_resp(nic_dev->hwdev, HINIC5_MOD_L2NIC,
+ cmd, cmd_buf, &out_param, 0);
+ if (err || out_param != 0) {
+ IPXE_DRV_LOG(ERR,
+ "Set SQ ctxts failed, "
+ "err: %d, out_param: %llu",
+ err, out_param);
+
+ err = -EFAULT;
+ break;
+ }
+
+ q_id += max_ctxts;
+ }
+
+ hinic5_free_cmd_buf(cmd_buf);
+ return err;
+}
+
+static int init_rq_ctxts(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+ u64 out_param = 0;
+ u16 q_id, max_ctxts;
+ u8 cmd;
+ int err = 0;
+
+ cmd_buf = hinic5_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd buf for rq ctx failed");
+ return -ENOMEM;
+ }
+
+ q_id = 0;
+ while (q_id < nic_dev->num_rqs) {
+ max_ctxts = (nic_dev->num_rqs - q_id) > HINIC5_Q_CTXT_MAX ?
+ HINIC5_Q_CTXT_MAX :
+ (nic_dev->num_rqs - q_id);
+
+ cmd = nic_dev->cmdq_ops->prepare_cmd_buf_qp_context_multi_store(
+ nic_dev, cmd_buf, HINIC5_QP_CTXT_TYPE_RQ, q_id,
+ max_ctxts);
+ mb();
+ err = hinic5_cmdq_direct_resp(nic_dev->hwdev, HINIC5_MOD_L2NIC,
+ cmd, cmd_buf, &out_param, 0);
+ if (err || out_param != 0) {
+ IPXE_DRV_LOG(ERR,
+ "Set RQ ctxts failed, "
+ "err: %d, out_param: %llu",
+ err, out_param);
+
+ err = -EFAULT;
+ break;
+ }
+
+ q_id += max_ctxts;
+ }
+
+ hinic5_free_cmd_buf(cmd_buf);
+ return err;
+}
+
+static int clean_queue_offload_ctxt(struct hinic5_nic_dev *nic_dev,
+ enum hinic5_qp_ctxt_type ctxt_type)
+{
+ struct hinic5_cmd_buf *cmd_buf;
+ u64 out_param = 0;
+ u8 cmd;
+ int err;
+
+ cmd_buf = hinic5_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ IPXE_DRV_LOG(ERR, "Allocate cmd buf for LRO/TSO space failed");
+ return -ENOMEM;
+ }
+
+ cmd = nic_dev->cmdq_ops->prepare_cmd_buf_clean_tso_lro_space(
+ nic_dev, cmd_buf, ctxt_type);
+
+ err = hinic5_cmdq_direct_resp(nic_dev->hwdev, HINIC5_MOD_L2NIC, cmd,
+ cmd_buf, &out_param, 0);
+ if ((err) || (out_param)) {
+ IPXE_DRV_LOG(ERR,
+ "Clean queue offload ctxts failed, "
+ "err: %d, out_param: %llu",
+ err, out_param);
+
+ err = -EFAULT;
+ }
+
+ hinic5_free_cmd_buf(cmd_buf);
+ return err;
+}
+
+static int clean_qp_offload_ctxt(struct hinic5_nic_dev *nic_dev)
+{
+ /* Clean LRO/TSO context space */
+ return (clean_queue_offload_ctxt(nic_dev, HINIC5_QP_CTXT_TYPE_SQ) ||
+ clean_queue_offload_ctxt(nic_dev, HINIC5_QP_CTXT_TYPE_RQ));
+}
+
+void hinic5_get_func_rx_buf_size(void *dev)
+{
+ struct hinic5_nic_dev *nic_dev = (struct hinic5_nic_dev *)dev;
+ struct hinic5_rxq *rxq = NULL;
+ u16 q_id;
+ u16 buf_size = 0;
+
+ for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) {
+ rxq = &nic_dev->rxqs[q_id];
+
+ if (q_id == 0) {
+ buf_size = rxq->buf_len;
+ }
+
+ buf_size = (buf_size > rxq->buf_len) ? rxq->buf_len : buf_size;
+ }
+
+ nic_dev->rx_buff_len = buf_size;
+}
+
+static int init_qp_ctxts(struct hinic5_nic_dev *nic_dev)
+{
+ int err = 0;
+
+ err = init_sq_ctxts(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init SQ ctxts failed");
+ return err;
+ }
+
+ err = init_rq_ctxts(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init RQ ctxts failed");
+ return err;
+ }
+
+ err = clean_qp_offload_ctxt(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Clean qp offload ctxts failed");
+ return err;
+ }
+
+ return err;
+}
+
+/* Init qps ctxt and set sq ci attr and arm all sq */
+int hinic5_init_qp_ctxts(void *dev)
+{
+ struct hinic5_nic_dev *nic_dev = NULL;
+ struct hinic5_hwdev *hwdev = NULL;
+ struct hinic5_sq_attr sq_attr;
+ u32 rq_depth = 0;
+ u32 sq_depth = 0;
+ u16 q_id;
+ int err;
+
+ if (!dev) {
+ return -EINVAL;
+ }
+
+ nic_dev = (struct hinic5_nic_dev *)dev;
+ hwdev = nic_dev->hwdev;
+
+ err = init_qp_ctxts(nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init qp ctxts failed");
+ return err;
+ }
+
+ if (nic_dev->num_rqs != 0)
+ rq_depth = ((u32)nic_dev->rxqs[0].q_depth)
+ << nic_dev->rxqs[0].wqe_type;
+
+ if (nic_dev->num_sqs != 0)
+ sq_depth = nic_dev->txqs[0].q_depth;
+
+ err = hinic5_set_root_ctxt(hwdev, rq_depth, sq_depth,
+ nic_dev->rx_buff_len);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Set root context failed");
+ return err;
+ }
+
+ for (q_id = 0; q_id < nic_dev->num_sqs; q_id++) {
+ sq_attr.ci_dma_base = nic_dev->txqs[q_id].ci_dma_base >> 0x2;
+ sq_attr.pending_limit = HINIC5_DEAULT_TX_CI_PENDING_LIMIT;
+ sq_attr.coalescing_time = HINIC5_DEAULT_TX_CI_COALESCING_TIME;
+ sq_attr.intr_en = 0;
+ sq_attr.intr_idx = 0; /* Tx doesn't need intr */
+ sq_attr.l2nic_sqn = q_id;
+ sq_attr.dma_attr_off = 0;
+ err = hinic5_set_ci_table(hwdev, &sq_attr);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Set ci table failed");
+ hinic5_clean_root_ctxt(hwdev);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+void hinic5_free_qp_ctxts(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ hinic5_clean_root_ctxt(hwdev);
+}
+
+void hinic5_update_driver_feature(void *dev, u64 s_feature)
+{
+ struct hinic5_nic_dev *nic_dev = NULL;
+
+ if (!dev) {
+ return;
+ }
+
+ nic_dev = (struct hinic5_nic_dev *)dev;
+ nic_dev->feature_cap = s_feature;
+
+ IPXE_DRV_LOG(INFO, "Update nic feature to 0x%llx\n",
+ nic_dev->feature_cap);
+}
+
+u64 hinic5_get_driver_feature(void *dev)
+{
+ struct hinic5_nic_dev *nic_dev = NULL;
+
+ nic_dev = (struct hinic5_nic_dev *)dev;
+
+ return nic_dev->feature_cap;
+}
+
+u8 hinic5_get_driver_feature_bit(void *dev, u64 feature_bit)
+{
+ struct hinic5_nic_dev *nic_dev = (struct hinic5_nic_dev *)dev;
+ return (nic_dev->feature_cap & feature_bit) ? 1 : 0;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.h
new file mode 100644
index 000000000..0a2d2b949
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_nic_io.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_NIC_IO_H_
+#define _HINIC5_NIC_IO_H_
+
+#include "hinic5_cmdq.h"
+#include "hinic5_nic_dev.h"
+
+FILE_LICENCE(GPL2_ONLY);
+
+#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_LEN 32
+#define HINIC5_CQE_SIZE_SHIFT 4
+
+/* Ci addr should CACHE_SIZE(64B) alignment for performance */
+#define HINIC5_CI_Q_ADDR_SIZE 64
+
+#define CI_TABLE_SIZE(num_qps, pg_sz) \
+ (HINIC5_ALIGN((num_qps)*HINIC5_CI_Q_ADDR_SIZE, pg_sz))
+
+#define HINIC5_CI_VADDR(base_addr, q_id) \
+ ((u8 *)(base_addr) + (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_Q_CTXT_MAX (u16)((HINIC5_CMDQ_BUF_SIZE - 8) / 64)
+
+#define SQ_CTXT_SIZE(num_sqs) \
+ ((u16)(sizeof(struct hinic5_qp_ctxt_header) + \
+ (num_sqs) * sizeof(struct hinic5_sq_ctxt)))
+
+#define RQ_CTXT_SIZE(num_rqs) \
+ ((u16)(sizeof(struct hinic5_qp_ctxt_header) + \
+ (num_rqs) * sizeof(struct hinic5_rq_ctxt)))
+
+enum hinic5_qp_ctxt_type {
+ HINIC5_QP_CTXT_TYPE_SQ,
+ HINIC5_QP_CTXT_TYPE_RQ,
+};
+
+/* 临时方案,对72来说HINIC5_NORMAL_RQ_WQE宏为合一式,HINIC5_COMPACT_RQ_WQE为分离式,等25适配合一式之后修改回来 */
+enum hinic5_rq_wqe_type {
+ HINIC5_COMPACT_RQ_WQE,
+ HINIC5_NORMAL_RQ_WQE,
+ HINIC5_EXTEND_RQ_WQE
+};
+
+enum hinic5_queue_type { HINIC5_SQ, HINIC5_RQ, HINIC5_MAX_QUEUE_TYPE };
+
+/* Doorbell info */
+struct hinic5_db {
+ u32 db_info;
+ u32 pi_hi;
+};
+
+struct hinic5_nic_cmdq_ops {
+ u8 (*prepare_cmd_buf_clean_tso_lro_space)(
+ struct hinic5_nic_dev *nic_dev, struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type);
+ u8 (*prepare_cmd_buf_qp_context_multi_store)(
+ struct hinic5_nic_dev *nic_dev, 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)(
+ struct hinic5_nic_dev *nic_dev, struct hinic5_cmd_buf *cmd_buf);
+ u8 (*prepare_cmd_buf_get_rss_indir_table)(
+ struct hinic5_nic_dev *nic_dev, struct hinic5_cmd_buf *cmd_buf);
+};
+
+struct hinic5_nic_tx_rx_ops {
+ void (*tx_set_wqe_offload)(void *wqe_info, void *wqe_combo);
+ void (*rx_get_cqe_info)(volatile void *rx_cqe, void *cqe_info);
+};
+
+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;
+};
+
+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;
+};
+
+#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_INFO_UPPER_32(val) (((u64)(val)) << 32)
+
+#define DB_ADDR(db_addr, pi) ((u64 *)(db_addr) + DB_PI_LOW(pi))
+#define SRC_TYPE 1
+
+/* Cflag data path */
+#define SQ_CFLAG_DP 0
+#define RQ_CFLAG_DP 1
+
+#define MASKED_QUEUE_IDX(queue, idx) ((idx) & (queue)->q_mask)
+
+#define NIC_WQE_ADDR(queue, idx) \
+ ((void *)((intptr_t)((queue)->queue_buf_vaddr) + \
+ ((idx) << (queue)->wqebb_shift)))
+
+/**
+ * Write send queue doorbell
+ *
+ * @param[in] db_addr
+ * Doorbell address
+ * @param[in] q_id
+ * Send queue id
+ * @param[in] cos
+ * Send queue cos
+ * @param[in] cflag
+ * Cflag data path
+ * @param[in] pi
+ * Send queue pi
+ */
+static inline void hinic5_write_db(void *db_addr, u16 q_id, int cos, u8 cflag,
+ u16 pi)
+{
+ u64 db;
+
+ /* Hardware will do endianness coverting */
+ db = DB_PI_HIGH(pi);
+ db = DB_INFO_UPPER_32(db) | DB_INFO_SET(SRC_TYPE, TYPE) |
+ DB_INFO_SET(cflag, CFLAG) | DB_INFO_SET(cos, COS) |
+ DB_INFO_SET(q_id, QID);
+
+ wmb(); /* Write all before the doorbell */
+
+ writeq(*((u64 *)&db), DB_ADDR(db_addr, pi));
+}
+
+void hinic5_get_func_rx_buf_size(void *dev);
+
+/**
+ * Init queue pair context
+ *
+ * @param[in] dev
+ * Device pointer to nic device
+ *
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+int hinic5_init_qp_ctxts(void *dev);
+
+/**
+ * Free queue pair context
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ */
+void hinic5_free_qp_ctxts(void *hwdev);
+
+/**
+ * Update service feature driver supported
+ *
+ * @param[in] dev
+ * Device pointer to nic device
+ * @param[out] s_feature
+ * s_feature driver supported
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+void hinic5_update_driver_feature(void *dev, u64 s_feature);
+
+/**
+ * Get service feature driver supported
+ *
+ * @param[in] dev
+ * Device pointer to nic device
+ * @param[out] s_feature
+ * s_feature driver supported
+ * @retval zero: Success
+ * @retval non-zero: Failure
+ */
+u64 hinic5_get_driver_feature(void *dev);
+
+/**
+ * Prepare sq context
+ *
+ * @param[in] sq
+ * Pointer to sq
+ * @param[in] sq_id
+ * Specific sq id
+ * @param[out] sq_ctxt
+ * Pointer to sq context
+ */
+void hinic5_sq_prepare_ctxt(struct hinic5_txq *sq, u16 sq_id,
+ struct hinic5_sq_ctxt *sq_ctxt);
+
+/**
+ * Prepare rq context
+ *
+ * @param[in] rq
+ * Pointer to rq
+ * @param[out] rq_ctxt
+ * Pointer to rq context
+ */
+void hinic5_rq_prepare_ctxt(struct hinic5_rxq *rq,
+ struct hinic5_rq_ctxt *rq_ctxt);
+
+/**
+ * Get cmdq ops that 182x supported
+ *
+ * @retval Pointer to ops
+ */
+struct hinic5_nic_cmdq_ops *hinic5_nic_cmdq_get_182x_ops(void);
+
+/**
+ * Get cmdq ops that 187x supported
+ *
+ * @retval Pointer to ops
+ */
+struct hinic5_nic_cmdq_ops *hinic5_nic_cmdq_get_187x_ops(void);
+
+/**
+ * Determine whether specific service is set
+ *
+ * @param[in] dev
+ * Device pointer to nic device
+ * @param[in] feature_bit
+ * specific service bit
+ * @retval zero: disabled
+ * @retval non-zero: enabled
+ */
+u8 hinic5_get_driver_feature_bit(void *dev, u64 feature_bit);
+
+#endif /* _HINIC5_NIC_IO_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.c
new file mode 100644
index 000000000..ff53bcaef
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.c
@@ -0,0 +1,444 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipxe/list.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/pci.h>
+#include <ipxe/dma.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/ethernet.h>
+
+#include "securec/securec.h"
+#include "base/hinic5_compat.h"
+#include "base/hinic5_wq.h"
+#include "base/hinic5_hwdev.h"
+#include "base/hinic5_hwif.h"
+#include "hinic5_nic_io.h"
+#include "hinic5_nic_cfg.h"
+#include "hinic5_nic_dev.h"
+#include "hinic5_rx.h"
+
+void hinic5_free_rxqs(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ free(nic_dev->rxqs);
+}
+
+int hinic5_alloc_rxqs(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ struct hinic5_rxq *rxq = NULL;
+ u16 q_id, num_rxqs = nic_dev->max_rqs;
+ u64 rxq_size;
+
+ rxq_size = num_rxqs * sizeof(*nic_dev->rxqs);
+ if (rxq_size == 0) {
+ IPXE_DRV_LOG(ERR, "Cannot allocate zero size rxqs\n");
+ return -EINVAL;
+ }
+
+ nic_dev->rxqs = zalloc(rxq_size);
+ if (!nic_dev->rxqs) {
+ IPXE_DRV_LOG(ERR, "Failed to allocate rxqs\n");
+ return -ENOMEM;
+ }
+
+ for (q_id = 0; q_id < num_rxqs; q_id++) {
+ rxq = &nic_dev->rxqs[q_id];
+ rxq->nic_dev = nic_dev;
+ rxq->q_id = q_id;
+ }
+
+ return 0;
+}
+
+static void hinic5_destroy_rxq(struct hinic5_rxq *rxq)
+{
+ u32 queue_buf_size = rxq->wqebb_size * rxq->q_depth;
+
+ free(rxq->rx_info);
+ rxq->rx_info = NULL;
+ dma_free(&rxq->cqe_map, rxq->cqe_start_vaddr,
+ rxq->q_depth * sizeof(*rxq->rx_cqe));
+ dma_free(&rxq->rq_map, rxq->queue_buf_vaddr, queue_buf_size);
+
+ return;
+}
+
+static int hinic5_init_rxq(struct hinic5_rxq *rxq,
+ struct hinic5_nic_dev *nic_dev, u32 *queue_buf_size)
+{
+ rxq->rxbuf_cnt = 0;
+ rxq->next_to_update = 0;
+ rxq->q_depth = HINIC5_PXE_DEFAULT_QUEUE_DEPTH;
+ rxq->q_mask = HINIC5_PXE_DEFAULT_QUEUE_DEPTH - 1;
+ rxq->delta = HINIC5_PXE_DEFAULT_QUEUE_DEPTH;
+ rxq->cons_idx = 0;
+ rxq->prod_idx = 0;
+ rxq->wqe_type = HINIC5_NORMAL_RQ_WQE;
+ rxq->wqebb_shift = HINIC5_RQ_WQEBB_SHIFT + rxq->wqe_type;
+ rxq->wqebb_size = (u16)BIT(rxq->wqebb_shift);
+
+ rxq->buf_len = nic_dev->rx_buff_len;
+ rxq->rx_buff_shift = ilog2(rxq->buf_len);
+
+ *queue_buf_size = rxq->wqebb_size * rxq->q_depth;
+ rxq->queue_buf_vaddr = dma_alloc(nic_dev->dma, &rxq->rq_map,
+ *queue_buf_size,
+ HINIC5_WQ_PGSIZE_ALIGN);
+ if (rxq->queue_buf_vaddr == NULL) {
+ IPXE_DRV_LOG(ERR, "Alloc rxq queue addr failed");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int hinic5_create_rxq(struct hinic5_rxq *rxq)
+{
+ struct hinic5_nic_dev *nic_dev = rxq->nic_dev;
+ void *db_addr = NULL;
+ u32 queue_buf_size;
+ int err;
+
+ err = hinic5_init_rxq(rxq, nic_dev, &queue_buf_size);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init rxq failed");
+ goto alloc_queue_buf_fail;
+ }
+
+ /* Initialise descriptor ring */
+ (void)memset_s(rxq->queue_buf_vaddr, queue_buf_size, 0, queue_buf_size);
+ rxq->queue_buf_paddr = dma(&rxq->rq_map, rxq->queue_buf_vaddr);
+
+ rxq->cqe_start_vaddr = dma_alloc(nic_dev->dma, &rxq->cqe_map,
+ rxq->q_depth * sizeof(*rxq->rx_cqe),
+ HINIC5_CQE_SIZE_ALIGN);
+ if (rxq->cqe_start_vaddr == NULL) {
+ IPXE_DRV_LOG(ERR, "Alloc rxq cqe addr failed");
+ err = -ENOMEM;
+ goto alloc_cqe_fail;
+ }
+
+ (void)memset_s(rxq->cqe_start_vaddr,
+ rxq->q_depth * sizeof(*rxq->rx_cqe), 0,
+ rxq->q_depth * sizeof(*rxq->rx_cqe));
+ rxq->cqe_start_paddr = dma(&rxq->rq_map, rxq->cqe_start_vaddr);
+ rxq->rx_cqe = (struct hinic5_rq_cqe *)rxq->cqe_start_vaddr;
+
+ rxq->rx_info = zalloc(sizeof(struct hinic5_rx_info) * rxq->q_depth);
+ if (rxq->rx_info == NULL) {
+ IPXE_DRV_LOG(ERR, "Alloc rx info failed");
+ err = -ENOMEM;
+ goto alloc_rx_info_fail;
+ }
+
+ err = hinic5_alloc_db_addr(nic_dev->hwdev, &db_addr, HINIC5_DB_TYPE_RQ);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Alloc rq doorbell addr failed");
+ goto alloc_db_err_fail;
+ }
+ rxq->db_addr = db_addr;
+
+ return 0;
+
+alloc_db_err_fail:
+ free(rxq->rx_info);
+alloc_rx_info_fail:
+ dma_free(&rxq->cqe_map, rxq->cqe_start_vaddr,
+ rxq->q_depth * sizeof(*rxq->rx_cqe));
+alloc_cqe_fail:
+ dma_free(&rxq->rq_map, rxq->queue_buf_vaddr, queue_buf_size);
+alloc_queue_buf_fail:
+ return err;
+}
+
+int hinic5_alloc_rx_resources(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_rxq *rxq = NULL;
+ u16 q_id, i;
+ int err;
+
+ for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) {
+ rxq = &nic_dev->rxqs[q_id];
+ err = hinic5_create_rxq(rxq);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Create rxq %d fail, err: %d\n", q_id,
+ err);
+ goto create_rxq_err;
+ }
+ }
+
+ return 0;
+
+create_rxq_err:
+ for (i = 0; i < q_id; i++) {
+ rxq = &nic_dev->rxqs[i];
+ hinic5_destroy_rxq(rxq);
+ }
+ return err;
+}
+
+void hinic5_free_rx_resources(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_rxq *rxq = NULL;
+ u16 q_id;
+
+ for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) {
+ rxq = &nic_dev->rxqs[q_id];
+ hinic5_destroy_rxq(rxq);
+ }
+}
+
+static inline void *hinic5_get_rq_wqe(struct hinic5_rxq *rxq, u16 *pi)
+{
+ *pi = MASKED_QUEUE_IDX(rxq, rxq->prod_idx);
+
+ /* Get only one rq wqe for once */
+ rxq->prod_idx++;
+ rxq->delta--;
+
+ return NIC_WQE_ADDR(rxq, *pi); /*lint !e701 !e647*/
+}
+
+static inline void hinic5_put_rq_wqe(struct hinic5_rxq *rxq, u16 wqe_cnt)
+{
+ rxq->delta += wqe_cnt;
+ rxq->prod_idx -= wqe_cnt;
+}
+
+u32 hinic5_fill_rx_cqe(struct hinic5_rxq *rxq)
+{
+ struct hinic5_rq_wqe *rq_wqe = NULL;
+ struct hinic5_nic_dev *nic_dev = rxq->nic_dev;
+ u64 cqe_dma;
+ u16 pi = 0;
+ u16 i;
+
+ cqe_dma = (u64)rxq->cqe_start_paddr;
+ for (i = 0; i < rxq->q_depth; i++) {
+ rq_wqe = hinic5_get_rq_wqe(rxq, &pi);
+ if (!rq_wqe) {
+ IPXE_DRV_LOG(
+ ERR,
+ "Get rq wqe failed, rxq id: %d, wqe id: %d",
+ rxq->q_id, i);
+ break;
+ }
+
+ if (rxq->wqe_type == HINIC5_EXTEND_RQ_WQE) {
+ /* Unit of cqe length is 16B */
+ hinic5_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
+ cqe_dma,
+ HINIC5_CQE_LEN >> HINIC5_CQE_SIZE_SHIFT);
+
+ /* Use fixed len */
+ rq_wqe->extend_wqe.buf_desc.sge.len =
+ nic_dev->rx_buff_len;
+ } else {
+ rq_wqe->normal_wqe.cqe_hi_addr = upper_32_bits(cqe_dma);
+ rq_wqe->normal_wqe.cqe_lo_addr = lower_32_bits(cqe_dma);
+ }
+
+ cqe_dma += sizeof(struct hinic5_rq_cqe);
+
+ hinic5_hw_be32_len(rq_wqe, rxq->wqebb_size);
+ }
+
+ hinic5_put_rq_wqe(rxq, (u16)i);
+
+ return i;
+}
+
+void hinic5_free_rx_buffer(struct hinic5_rxq *rxq)
+{
+ struct hinic5_rx_info *rx_info = NULL;
+ volatile struct hinic5_rq_cqe *rx_cqe = NULL;
+ u16 i;
+
+ for (i = 0; i < rxq->q_depth; i++) {
+ rx_cqe = &rxq->rx_cqe[i];
+ /* Clear done bit */
+ rx_cqe->status = 0;
+
+ rx_info = &rxq->rx_info[i];
+ if (rx_info->iobuf) {
+ free_rx_iob(rx_info->iobuf);
+ rx_info->iobuf = NULL;
+ }
+ }
+}
+
+#define RXBUF_CNT 16
+int hinic5_alloc_rx_buffer(struct hinic5_rxq *rxq)
+{
+ struct hinic5_rq_wqe *rq_wqe = NULL;
+ struct hinic5_rx_info *rx_info = NULL;
+ struct io_buffer *iobuf = NULL;
+ physaddr_t dma_addr;
+ u16 i, free_wqebbs;
+
+ free_wqebbs = rxq->delta - 1;
+ for (i = 0; (i < free_wqebbs) && (rxq->rxbuf_cnt < RXBUF_CNT); i++) {
+ rx_info = &rxq->rx_info[rxq->next_to_update];
+
+ iobuf = alloc_rx_iob(rxq->buf_len, rxq->nic_dev->dma);
+ if (iobuf == NULL) {
+ break;
+ }
+
+ rx_info->iobuf = iobuf;
+ dma_addr = iob_dma(iobuf);
+
+ rq_wqe = NIC_WQE_ADDR(rxq,
+ rxq->next_to_update); /*lint !e701 !e647*/
+
+ /* Fill buffer address only */
+ if (rxq->wqe_type == HINIC5_EXTEND_RQ_WQE) {
+ rq_wqe->extend_wqe.buf_desc.sge.hi_addr =
+ hinic5_hw_be32(upper_32_bits(dma_addr));
+ rq_wqe->extend_wqe.buf_desc.sge.lo_addr =
+ hinic5_hw_be32(lower_32_bits(dma_addr));
+ } else {
+ rq_wqe->normal_wqe.buf_hi_addr =
+ hinic5_hw_be32(upper_32_bits(dma_addr));
+ rq_wqe->normal_wqe.buf_lo_addr =
+ hinic5_hw_be32(lower_32_bits(dma_addr));
+ }
+
+ rxq->next_to_update = (rxq->next_to_update + 1) & rxq->q_mask;
+ rxq->rxbuf_cnt++;
+ }
+
+ if (i > 0) {
+ hinic5_write_db(rxq->db_addr, rxq->q_id, 0, RQ_CFLAG_DP,
+ (u16)(rxq->next_to_update
+ << rxq->wqe_type)); /*lint !e701*/
+ /* Init rq contxet used, need to optimization */
+ rxq->prod_idx = rxq->next_to_update;
+ rxq->delta -= i;
+ }
+
+ return (u32)i;
+}
+
+void hinic5_remove_rxqs(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_rxq *rxq = NULL;
+ u16 q_id;
+
+ for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) {
+ rxq = &nic_dev->rxqs[q_id];
+ hinic5_free_rx_buffer(rxq);
+ }
+}
+
+int hinic5_configure_rxqs(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_rxq *rxq = NULL;
+ u16 q_id, i;
+ u32 pkts;
+ int err;
+
+ for (q_id = 0; q_id < nic_dev->num_rqs; q_id++) {
+ rxq = &nic_dev->rxqs[q_id];
+ pkts = hinic5_fill_rx_cqe(rxq);
+ if (pkts != rxq->q_depth) {
+ IPXE_DRV_LOG(ERR, "Fill rx wqe failed, wqe_count: %d",
+ pkts);
+ err = -ENOMEM;
+ goto fill_rx_wqe_fail;
+ }
+
+ pkts = hinic5_alloc_rx_buffer(rxq);
+ if (pkts == 0) {
+ IPXE_DRV_LOG(ERR, "Failed to alloc Rx buffer");
+ err = -ENOMEM;
+ goto fill_rx_buffer_fail;
+ }
+ }
+
+ return 0;
+
+fill_rx_buffer_fail:
+fill_rx_wqe_fail:
+ for (i = 0; i < q_id; i++) {
+ rxq = &nic_dev->rxqs[i];
+ hinic5_free_rx_buffer(rxq);
+ }
+ return err;
+}
+
+static inline u16 hinic5_get_rq_local_ci(struct hinic5_rxq *rxq)
+{
+ return MASKED_QUEUE_IDX(rxq, rxq->cons_idx);
+}
+
+static inline void hinic5_update_rq_local_ci(struct hinic5_rxq *rxq,
+ u16 wqe_cnt)
+{
+ rxq->cons_idx += wqe_cnt;
+ rxq->delta += wqe_cnt;
+}
+
+u32 hinic5_rq_pkt_len(struct hinic5_rq_cqe *cqe, bool compact_cqe)
+{
+ if (compact_cqe) {
+ return RQ_COMPACT_CQE_STATUS_GET(cqe->status, PKT_LEN);
+ }
+
+ return HINIC5_GET_RX_PKT_LEN(cqe->vlan_len);
+}
+
+void hinic5_pxe_rx_poll(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ struct hinic5_rxq *rxq = &nic_dev->rxqs[0];
+ struct hinic5_rq_cqe *rx_cqe = NULL;
+ struct hinic5_rx_info *rx_info = NULL;
+ u32 status, pkt_len;
+ u16 sw_ci;
+ bool compact_cqe = false;
+
+ while (true) {
+ sw_ci = hinic5_get_rq_local_ci(rxq);
+ rx_cqe = &rxq->rx_cqe[sw_ci];
+
+ status = hinic5_hw_cpu32(rx_cqe->status);
+ if (!HINIC5_GET_RX_DONE(status)) {
+ break;
+ }
+
+ /* make sure we read rx_done before packet length */
+ rmb();
+
+ if (HINIC5_SUPPORT_RX_HW_COMPACT_CQE(nic_dev)) {
+ compact_cqe = true;
+ }
+
+ pkt_len = hinic5_rq_pkt_len(rx_cqe, compact_cqe);
+
+ rx_info = &rxq->rx_info[sw_ci];
+
+ if (rx_info->iobuf) {
+ iob_put(rx_info->iobuf, pkt_len);
+ netdev_rx(netdev, rx_info->iobuf);
+ }
+
+ /* rx only used one wqe */
+ hinic5_update_rq_local_ci(rxq, 1);
+
+ rx_info->iobuf = NULL;
+ rx_cqe->status = 0;
+ rxq->rxbuf_cnt--;
+ }
+
+ (void)hinic5_alloc_rx_buffer(rxq);
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.h
new file mode 100644
index 000000000..270391fdf
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_rx.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_RX_H_
+#define _HINIC5_RX_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include "base/hinic5_wq.h"
+
+#define HINIC5_CQE_SIZE_ALIGN 64
+
+#define RQ_CQE_OFFOLAD_TYPE_PKT_TYPE_SHIFT 0
+#define RQ_CQE_OFFOLAD_TYPE_PKT_UMBCAST_SHIFT 19
+#define RQ_CQE_OFFOLAD_TYPE_VLAN_EN_SHIFT 21
+#define RQ_CQE_OFFOLAD_TYPE_RSS_TYPE_SHIFT 24
+
+#define RQ_CQE_OFFOLAD_TYPE_PKT_TYPE_MASK 0xFFFU
+#define RQ_CQE_OFFOLAD_TYPE_PKT_UMBCAST_MASK 0x3U
+#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) \
+ (((val) >> RQ_CQE_OFFOLAD_TYPE_##member##_SHIFT) & \
+ RQ_CQE_OFFOLAD_TYPE_##member##_MASK)
+
+#define HINIC5_GET_RX_PKT_TYPE(offload_type) \
+ RQ_CQE_OFFOLAD_TYPE_GET(offload_type, PKT_TYPE)
+
+#define HINIC5_GET_RX_PKT_UMBCAST(offload_type) \
+ RQ_CQE_OFFOLAD_TYPE_GET(offload_type, PKT_UMBCAST)
+
+#define HINIC5_GET_RX_VLAN_OFFLOAD_EN(offload_type) \
+ RQ_CQE_OFFOLAD_TYPE_GET(offload_type, VLAN_EN)
+
+#define HINIC5_GET_RSS_TYPES(offload_type) \
+ RQ_CQE_OFFOLAD_TYPE_GET(offload_type, RSS_TYPE)
+
+#define RQ_CQE_SGE_VLAN_SHIFT 0
+#define RQ_CQE_SGE_LEN_SHIFT 16
+
+#define RQ_CQE_SGE_VLAN_MASK 0xFFFFU
+#define RQ_CQE_SGE_LEN_MASK 0xFFFFU
+
+#define RQ_CQE_SGE_GET(val, member) \
+ (((val) >> RQ_CQE_SGE_##member##_SHIFT) & RQ_CQE_SGE_##member##_MASK)
+
+#define HINIC5_GET_RX_VLAN_TAG(vlan_len) RQ_CQE_SGE_GET(vlan_len, VLAN)
+
+#define HINIC5_GET_RX_PKT_LEN(vlan_len) RQ_CQE_SGE_GET(vlan_len, LEN)
+
+#define RQ_CQE_STATUS_CSUM_ERR_SHIFT 0
+#define RQ_CQE_STATUS_NUM_LRO_SHIFT 16
+#define RQ_CQE_STATUS_LRO_PUSH_SHIFT 25
+#define RQ_CQE_STATUS_LRO_ENTER_SHIFT 26
+#define RQ_CQE_STATUS_LRO_INTR_SHIFT 27
+#define RQ_CQE_STATUS_FLUSH_SHIFT 28
+#define RQ_CQE_STATUS_DECRY_PKT_SHIFT 29
+#define RQ_CQE_STATUS_BP_EN_SHIFT 30
+#define RQ_CQE_STATUS_RXDONE_SHIFT 31
+
+#define RQ_CQE_STATUS_CSUM_ERR_MASK 0xFFFFU
+#define RQ_CQE_STATUS_NUM_LRO_MASK 0xFFU
+#define RQ_CQE_STATUS_LRO_PUSH_MASK 0x1U
+#define RQ_CQE_STATUS_LRO_ENTER_MASK 0x1U
+#define RQ_CQE_STATUS_LRO_INTR_MASK 0x1U
+#define RQ_CQE_STATUS_BP_EN_MASK 0x1U
+#define RQ_CQE_STATUS_RXDONE_MASK 0x1U
+#define RQ_CQE_STATUS_FLUSH_MASK 0x1U
+#define RQ_CQE_STATUS_DECRY_PKT_MASK 0x1U
+
+#define RQ_CQE_STATUS_GET(val, member) \
+ (((val) >> RQ_CQE_STATUS_##member##_SHIFT) & \
+ RQ_CQE_STATUS_##member##_MASK)
+
+#define HINIC5_GET_RX_CSUM_ERR(status) RQ_CQE_STATUS_GET(status, CSUM_ERR)
+
+#define HINIC5_GET_RX_DONE(status) RQ_CQE_STATUS_GET(status, RXDONE)
+
+#define HINIC5_GET_RX_FLUSH(status) RQ_CQE_STATUS_GET(status, FLUSH)
+
+#define HINIC5_GET_RX_BP_EN(status) RQ_CQE_STATUS_GET(status, BP_EN)
+
+#define HINIC5_GET_RX_NUM_LRO(status) RQ_CQE_STATUS_GET(status, NUM_LRO)
+
+#define HINIC5_RX_IS_DECRY_PKT(status) RQ_CQE_STATUS_GET(status, DECRY_PKT)
+
+#define HINIC5_SUPPORT_FEATURE(dev, feature) \
+ ((hinic5_get_driver_feature(dev) & NIC_F_##feature) != 0)
+
+#define HINIC5_SUPPORT_RX_HW_COMPACT_CQE(dev) \
+ HINIC5_SUPPORT_FEATURE(dev, RX_HW_COMPACT_CQE)
+
+#define NIC_F_RX_HW_COMPACT_CQE NIC_F(RX_HW_COMPACT_CQE)
+
+#define RQ_COMPACT_CQE_STATUS_PKT_LEN_SHIFT 0
+
+#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))
+
+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_CQM = (1 << 16),
+};
+
+struct hinic5_rq_cqe {
+ u32 status;
+ u32 vlan_len;
+
+ u32 offload_type;
+ u32 hash_val;
+ u32 rsv[4];
+};
+
+/*
+ * Attention: please do not add any member in hinic5_rx_info because rxq bulk
+ * rearm mode will write mbuf in rx_info
+ */
+struct hinic5_rx_info {
+ struct io_buffer *iobuf;
+};
+
+struct hinic5_sge_sect {
+ struct hinic5_sge sge;
+ u32 rsvd;
+};
+
+struct hinic5_rq_extend_wqe {
+ struct hinic5_sge_sect buf_desc;
+ struct hinic5_sge_sect cqe_sect;
+};
+
+struct hinic5_rq_normal_wqe {
+ u32 buf_hi_addr;
+ u32 buf_lo_addr;
+ u32 cqe_hi_addr;
+ u32 cqe_lo_addr;
+};
+
+struct hinic5_rq_wqe {
+ union {
+ struct hinic5_rq_normal_wqe normal_wqe;
+ struct hinic5_rq_extend_wqe extend_wqe;
+ };
+};
+
+struct hinic5_rxq {
+ struct hinic5_nic_dev *nic_dev;
+
+ u16 q_id;
+ u16 q_depth;
+ u16 q_mask;
+ u16 buf_len;
+
+ u32 rx_buff_shift;
+
+ u16 wqebb_shift;
+ u16 wqebb_size;
+
+ u16 wqe_type;
+ u16 cons_idx;
+ u16 prod_idx;
+ u16 delta;
+
+ u16 next_to_update;
+
+ struct dma_mapping rq_map;
+ void *queue_buf_vaddr;
+ physaddr_t queue_buf_paddr; /* rq dma info */
+
+ void *db_addr;
+
+ struct hinic5_rx_info *rx_info;
+ struct hinic5_rq_cqe *rx_cqe;
+
+ struct dma_mapping cqe_map;
+ void *cqe_start_vaddr;
+ physaddr_t cqe_start_paddr;
+
+ u32 rxbuf_cnt;
+};
+
+int hinic5_alloc_rxqs(struct net_device *netdev);
+void hinic5_free_rxqs(struct net_device *netdev);
+int hinic5_alloc_rx_resources(struct hinic5_nic_dev *nic_dev);
+void hinic5_free_rx_resources(struct hinic5_nic_dev *nic_dev);
+void hinic5_pxe_rx_poll(struct net_device *netdev);
+void hinic5_remove_rxqs(struct hinic5_nic_dev *nic_dev);
+int hinic5_configure_rxqs(struct hinic5_nic_dev *nic_dev);
+
+#endif /* _HINIC5_RX_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.c
new file mode 100644
index 000000000..f4953e6a2
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.c
@@ -0,0 +1,532 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipxe/list.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/pci.h>
+#include <ipxe/dma.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/ethernet.h>
+
+#include "securec/securec.h"
+#include "hinic5_nic_dev.h"
+#include "base/hinic5_compat.h"
+#include "base/hinic5_hw_comm.h"
+#include "hinic5_nic_cfg.h"
+#include "hinic5_settings.h"
+
+int g_hinic_net_dev_counter = 0;
+struct hinic5_nic_dev *g_hinic_net_dev[MAX_HINIC5_NUM] = { NULL };
+int led_status = 0;
+static const struct settings_scope hinic5_settings_scope;
+static const char *g_sriov_strlist[SRIOV_MAX_STR_SIZE] = {
+ "invalid", // 0 - 无效配置
+ "Y", // 1 - 开启
+ "N" // 2 - 关闭
+};
+static const char *g_vlan_enable_strlist[VLAN_ENABLE_MAX_STR_SIZE] = {
+ "N", // 0 - 关闭
+ "Y" // 1 - 开启
+};
+static const char *g_led_enable_strlist[LED_ENABLE_MAX_STR_SIZE] = {
+ "N", // 0 - 关闭
+ "Y" // 1 - 开启
+};
+
+static int hinic5_sriov_enable_store(const void *data, size_t len)
+{
+ char tmp_setting_str[MAX_SETTING_STR_LEN] = { 0 };
+ int enable = -1;
+ int ret = -1;
+ int i;
+ u32 opcode;
+ struct nic_bios_cfg conf = { 0 };
+
+ if (!data || len >= MAX_SETTING_STR_LEN) {
+ return -EINVAL;
+ }
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ if (memcpy_s(tmp_setting_str, MAX_SETTING_STR_LEN, data, len) != EOK) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < SRIOV_MAX_STR_SIZE; i++) {
+ if (strcmp(tmp_setting_str, g_sriov_strlist[i]) == 0) {
+ enable = i;
+ break;
+ }
+ }
+
+ if ((enable != SRIOV_ENABLE) && (enable != SRIOV_DISABLE)) {
+ return -EINVAL;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ ret = hinic5_get_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ opcode = NIC_NVM_DATA_SRIOV_CONTROL;
+ conf.sriov_en = enable;
+ ret = hinic5_set_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ return EOK;
+}
+
+static int hinic5_vlan_enable_store(const void *data, size_t len)
+{
+ char tmp_setting_str[MAX_SETTING_STR_LEN] = { 0 };
+ int enable = -1;
+ int ret = -1;
+ int i;
+ u32 opcode;
+ struct nic_bios_cfg conf = { 0 };
+
+ if (!data || len >= MAX_SETTING_STR_LEN) {
+ return -EINVAL;
+ }
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ if (memcpy_s(tmp_setting_str, MAX_SETTING_STR_LEN, data, len) != EOK) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < VLAN_ENABLE_MAX_STR_SIZE; i++) {
+ if (strcmp(tmp_setting_str, g_vlan_enable_strlist[i]) == 0) {
+ enable = i;
+ break;
+ }
+ }
+ if (i == VLAN_ENABLE_MAX_STR_SIZE) {
+ return -EINVAL;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ ret = hinic5_get_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ opcode = NIC_NVM_DATA_LEGACY_VLAN;
+ conf.nlvc.pxe_vlan_en = enable;
+ ret = hinic5_set_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ return EOK;
+}
+
+static int hinic5_vlan_store(const void *data, size_t len)
+{
+ int vlan_id = 0;
+ int ret = -1;
+ u32 opcode;
+ struct nic_bios_cfg conf = { 0 };
+
+ if (!data || len != sizeof(int)) {
+ return -EINVAL;
+ }
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ if (memcpy_s(&vlan_id, sizeof(int), data, sizeof(int)) != EOK) {
+ return -ENOMEM;
+ }
+
+ vlan_id = ntohl(vlan_id);
+ if (vlan_id < HINIC5_VLAN_ID_MIN || vlan_id > HINIC5_VLAN_ID_MAX) {
+ return -EINVAL;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ ret = hinic5_get_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ opcode = NIC_NVM_DATA_LEGACY_VLAN_ID;
+ conf.nlvc.pxe_vlan_id = vlan_id;
+ ret = hinic5_set_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ return EOK;
+}
+
+static int hinic5_led_store(const void *data, size_t len)
+{
+ char tmp_setting_str[MAX_SETTING_STR_LEN] = { 0 };
+ int enable = 0;
+ int ret = -1;
+ int i;
+
+ if (!data || len >= MAX_SETTING_STR_LEN) {
+ return -EINVAL;
+ }
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ if (memcpy_s(tmp_setting_str, MAX_SETTING_STR_LEN, data, len) != EOK) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < LED_ENABLE_MAX_STR_SIZE; i++) {
+ if (strcmp(tmp_setting_str, g_led_enable_strlist[i]) == 0) {
+ enable = i;
+ break;
+ }
+ }
+ if (i == LED_ENABLE_MAX_STR_SIZE) {
+ return -EINVAL;
+ }
+
+ if (enable) {
+ ret = hinic5_set_led_status(g_hinic_net_dev[0]->hwdev,
+ MAG_CMD_LED_TYPE_ALARM,
+ MAG_CMD_LED_MODE_FORCE_BLINK_2HZ);
+ if (ret) {
+ return ret;
+ }
+ } else {
+ ret = hinic5_set_led_status(g_hinic_net_dev[0]->hwdev,
+ MAG_CMD_LED_TYPE_ALARM,
+ MAG_CMD_LED_MODE_DEFAULT);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ led_status = enable;
+
+ return EOK;
+}
+
+static int hinic5_sriov_enable_fetch(void *data, size_t len)
+{
+ int ret = 0;
+ const int sriov_not_support_idx = SRIOV_DISABLE;
+ u32 opcode;
+ struct nic_bios_cfg conf = { 0 };
+ size_t src_len = 0;
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ ret = hinic5_get_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ switch (conf.sriov_en) {
+ case SRIOV_ENABLE:
+ case SRIOV_DISABLE:
+ src_len = strlen(g_sriov_strlist[conf.sriov_en]) + 1;
+ if (len != 0 &&
+ memcpy_s(data, len, g_sriov_strlist[conf.sriov_en],
+ src_len) != EOK) {
+ return -EINVAL;
+ }
+ ret = src_len;
+ break;
+ default:
+ src_len = strlen(g_sriov_strlist[sriov_not_support_idx]) + 1;
+ if (len != 0 &&
+ memcpy_s(data, len, g_sriov_strlist[sriov_not_support_idx],
+ src_len) != EOK) {
+ return -EINVAL;
+ }
+ ret = src_len;
+ break;
+ }
+ return ret;
+}
+
+static int hinic5_vlan_enable_fetch(void *data, size_t len)
+{
+ int ret = 0;
+ u32 opcode;
+ struct nic_bios_cfg conf = { 0 };
+ size_t src_len = 0;
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ ret = hinic5_get_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ switch (conf.nlvc.pxe_vlan_en) {
+ case 0:
+ case 1:
+ src_len = strlen(g_vlan_enable_strlist[conf.nlvc.pxe_vlan_en]) +
+ 1;
+ if (len != 0 &&
+ memcpy_s(data, len,
+ g_vlan_enable_strlist[conf.nlvc.pxe_vlan_en],
+ src_len) != EOK) {
+ return -EINVAL;
+ }
+ ret = src_len;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static int hinic5_vlan_fetch(void *data, size_t len)
+{
+ int ret = 0;
+ u32 opcode;
+ struct nic_bios_cfg conf = { 0 };
+ int vlan_id = 0;
+ size_t src_len = 0;
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ ret = hinic5_get_persistent_conf(g_hinic_net_dev[0]->hwdev, opcode,
+ &conf);
+ if (ret) {
+ return ret;
+ }
+
+ vlan_id = (int)conf.nlvc.pxe_vlan_id;
+ vlan_id = htonl(vlan_id);
+ src_len = sizeof(int);
+ if (len != 0 && memcpy_s(data, len, &vlan_id, src_len) != EOK) {
+ return -EINVAL;
+ }
+ ret = src_len;
+
+ return ret;
+}
+
+static int hinic5_led_fetch(void *data, size_t len)
+{
+ int ret = 0;
+ size_t src_len = 0;
+
+ switch (led_status) {
+ case 0:
+ case 1:
+ src_len = strlen(g_led_enable_strlist[led_status]) + 1;
+ if (len != 0 &&
+ memcpy_s(data, len, g_led_enable_strlist[led_status],
+ src_len) != EOK) {
+ return -EINVAL;
+ }
+ ret = src_len;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int hinic5_version_fetch(void *data, size_t len)
+{
+ int ret = 0;
+ size_t src_len = 0;
+ char tmp_setting_str[MAX_SETTING_STR_LEN] = { 0 };
+
+ if (!(g_hinic_net_dev[0])) {
+ return -ENODEV;
+ }
+
+ ret = hinic5_get_mgmt_version(g_hinic_net_dev[0]->hwdev,
+ tmp_setting_str, MAX_SETTING_STR_LEN);
+ if (ret) {
+ return ret;
+ }
+
+ src_len = strlen(tmp_setting_str) + 1;
+ if (len != 0 && memcpy_s(data, len, tmp_setting_str, src_len) != EOK) {
+ return -EINVAL;
+ }
+ ret = src_len;
+ return ret;
+}
+
+struct hinic5_setting_info g_hinic5_setting_infos[HINIC5_CONFIG_MAX] = {
+ { .name = "sriov",
+ .hinic5_setting_store = hinic5_sriov_enable_store,
+ .hinic5_setting_fetch = hinic5_sriov_enable_fetch },
+ { .name = "vlan enable",
+ .hinic5_setting_store = hinic5_vlan_enable_store,
+ .hinic5_setting_fetch = hinic5_vlan_enable_fetch },
+ { .name = "vlan tag",
+ .hinic5_setting_store = hinic5_vlan_store,
+ .hinic5_setting_fetch = hinic5_vlan_fetch },
+ { .name = "blink led",
+ .hinic5_setting_store = hinic5_led_store,
+ .hinic5_setting_fetch = hinic5_led_fetch },
+ { .name = "fw version",
+ .hinic5_setting_store = NULL,
+ .hinic5_setting_fetch = hinic5_version_fetch }
+};
+
+static int hinic5_store(struct settings *settings __unused,
+ const struct setting *setting, const void *data,
+ size_t len)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < HINIC5_CONFIG_MAX; i++) {
+ if (strcmp(setting->name, g_hinic5_setting_infos[i].name) ==
+ 0) {
+ if (g_hinic5_setting_infos[i].hinic5_setting_store ==
+ NULL) {
+ return -EINVAL;
+ }
+ ret = g_hinic5_setting_infos[i].hinic5_setting_store(
+ data, len);
+ break;
+ }
+ }
+
+ if (i >= HINIC5_CONFIG_MAX) {
+ ret = -EINVAL;
+ }
+
+ return ret; /* return store len, or negative error */
+}
+
+static int hinic5_fetch(struct settings *settings __unused,
+ struct setting *setting, void *data, size_t len)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < HINIC5_CONFIG_MAX; i++) {
+ if (strcmp(setting->name, g_hinic5_setting_infos[i].name) ==
+ 0) {
+ if (g_hinic5_setting_infos[i].hinic5_setting_fetch ==
+ NULL) {
+ return -EINVAL;
+ }
+ ret = g_hinic5_setting_infos[i].hinic5_setting_fetch(
+ data, len);
+ break;
+ }
+ }
+
+ if (i >= HINIC5_CONFIG_MAX) {
+ ret = -EINVAL;
+ }
+
+ return ret; /* return fetch len, or negative error */
+}
+
+static struct settings_operations hinic5_settings_operations = {
+ .store = hinic5_store,
+ .fetch = hinic5_fetch,
+};
+
+struct settings hinic5_settings = {
+ .refcnt = NULL,
+ .siblings = LIST_HEAD_INIT(hinic5_settings.siblings),
+ .children = LIST_HEAD_INIT(hinic5_settings.children),
+ .op = &hinic5_settings_operations,
+ .default_scope = &hinic5_settings_scope,
+};
+
+const struct setting hinic5_vlan_enable_setting __setting(SETTING_AUTH_EXTRA,
+ VLANENABLE) = {
+ .name = "vlan enable",
+ .description = "VLAN-ENABLE(Y/N)",
+ .type = &setting_type_string,
+ .scope = &hinic5_settings_scope,
+};
+
+const struct setting hinic5_vlan_setting __setting(SETTING_AUTH_EXTRA, VLAN) = {
+ .name = "vlan tag",
+ .description = "VLAN (range:1-4094)",
+ .type = &setting_type_int32,
+ .scope = &hinic5_settings_scope,
+};
+
+const struct setting hinic5_sriov_setting __setting(SETTING_AUTH_EXTRA,
+ SRIOV) = {
+ .name = "sriov",
+ .description = "SRIOV(Y/N)",
+ .type = &setting_type_string,
+ .scope = &hinic5_settings_scope,
+};
+
+const struct setting hinic5_led_setting __setting(SETTING_AUTH_EXTRA,
+ HINIC5_LED) = {
+ .name = "blink led",
+ .description = "BLINK LED(Y/N)",
+ .type = &setting_type_string,
+ .scope = &hinic5_settings_scope,
+};
+
+const struct setting hinic5_version_setting __setting(SETTING_AUTH_EXTRA,
+ HINIC5_VERSION) = {
+ .name = "fw version",
+ .description = "Firmware version",
+ .type = &setting_type_string,
+ .scope = &hinic5_settings_scope,
+};
+
+int hinic5_settings_register(struct hinic5_nic_dev *nic_dev)
+{
+ if (g_hinic_net_dev_counter >= MAX_HINIC5_NUM) {
+ IPXE_DRV_LOG(
+ ERR,
+ "No space left for device, hinic5_settings_register counter: %d.",
+ g_hinic_net_dev_counter);
+ return -EPERM;
+ }
+ g_hinic_net_dev[g_hinic_net_dev_counter++] = nic_dev;
+ IPXE_DRV_LOG(INFO, "hinic5_settings_register counter: %d.",
+ g_hinic_net_dev_counter);
+
+ if (register_settings(&hinic5_settings, NULL, "hinic5") != EOK) {
+ return -EIO;
+ }
+
+ return EOK;
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.h
new file mode 100644
index 000000000..83f936db2
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_settings.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_SETTINGS_H_
+#define _HINIC5_SETTINGS_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+#define SRIOV_MAX_STR_SIZE 3
+#define SRIOV_ENABLE 1
+#define SRIOV_DISABLE 2
+#define VLAN_ENABLE_MAX_STR_SIZE 2
+#define LED_ENABLE_MAX_STR_SIZE 2
+#define HINIC5_CONFIG_MAX 5
+#define MAX_SETTING_STR_LEN 100
+#define MAX_HINIC5_NUM 4
+
+struct hinic5_setting_info {
+ const char *name;
+ int (*hinic5_setting_store)(const void *data, size_t len);
+ int (*hinic5_setting_fetch)(void *data, size_t len);
+};
+
+int hinic5_settings_register(struct hinic5_nic_dev *nic_dev);
+
+#endif /* _HINIC5_SETTINGS_H_ */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.c
new file mode 100644
index 000000000..49b9dd4bc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.c
@@ -0,0 +1,498 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+FILE_LICENCE(GPL2_ONLY);
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ipxe/list.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/pci.h>
+#include <ipxe/dma.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/ethernet.h>
+
+#include "securec/securec.h"
+#include "base/hinic5_compat.h"
+#include "base/hinic5_wq.h"
+#include "base/hinic5_hwdev.h"
+#include "base/hinic5_hwif.h"
+#include "hinic5_nic_io.h"
+#include "hinic5_nic_cfg.h"
+#include "hinic5_nic_dev.h"
+#include "hinic5_tx.h"
+
+#define WQEBB_CNT_FOR_EXTEND_WQE 2
+void hinic5_free_txqs(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ free(nic_dev->txqs);
+}
+
+int hinic5_alloc_txqs(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ struct hinic5_txq *txq = NULL;
+ u16 q_id, num_txqs = nic_dev->max_sqs;
+ u64 txq_size;
+
+ txq_size = num_txqs * sizeof(*nic_dev->txqs);
+ if (txq_size == 0) {
+ IPXE_DRV_LOG(ERR, "Cannot allocate zero size txqs\n");
+ return -EINVAL;
+ }
+
+ nic_dev->txqs = zalloc(txq_size);
+ if (!nic_dev->txqs) {
+ IPXE_DRV_LOG(ERR, "Failed to allocate txqs\n");
+ return -ENOMEM;
+ }
+
+ for (q_id = 0; q_id < num_txqs; q_id++) {
+ txq = &nic_dev->txqs[q_id];
+ txq->nic_dev = nic_dev;
+ txq->q_id = q_id;
+ txq->cos = nic_dev->default_cos;
+ }
+
+ return 0;
+}
+
+static void hinic5_destory_txq(struct hinic5_txq *txq)
+{
+ u32 queue_buf_size = txq->wqebb_size * txq->q_depth;
+
+ free(txq->tx_info);
+ dma_free(&txq->sq_map, txq->queue_buf_vaddr, queue_buf_size);
+ dma_free(&txq->ci_map, txq->ci_vaddr_base, HINIC5_CI_Q_ADDR_SIZE);
+}
+
+static int hinic5_init_txq(struct hinic5_txq *txq,
+ struct hinic5_nic_dev *nic_dev)
+{
+ txq->q_depth = HINIC5_PXE_DEFAULT_QUEUE_DEPTH;
+ txq->q_mask = HINIC5_PXE_DEFAULT_QUEUE_DEPTH - 1;
+ txq->cons_idx = 0;
+ txq->prod_idx = 0;
+ txq->owner = 1;
+ txq->wqebb_shift = HINIC5_SQ_WQEBB_SHIFT;
+ txq->wqebb_size = (u16)BIT(txq->wqebb_shift);
+
+ /* Allocate descriptor ring. Align ring on its own size to
+ * prevent any possible page-crossing errors due to hardware
+ * errata.
+ */
+ txq->ci_vaddr_base = dma_alloc(nic_dev->dma, &txq->ci_map,
+ HINIC5_CI_Q_ADDR_SIZE,
+ HINIC5_CI_Q_ADDR_SIZE);
+ if (txq->ci_vaddr_base == NULL) {
+ IPXE_DRV_LOG(ERR, "Alloc ci addr failed");
+ return -ENOMEM;
+ }
+
+ (void)memset_s(txq->ci_vaddr_base, HINIC5_CI_Q_ADDR_SIZE, 0,
+ HINIC5_CI_Q_ADDR_SIZE);
+ txq->ci_dma_base = dma(&txq->ci_map, txq->ci_vaddr_base);
+
+ return 0;
+}
+
+static int hinic5_create_txq(struct hinic5_txq *txq)
+{
+ struct hinic5_nic_dev *nic_dev = txq->nic_dev;
+ void *db_addr = NULL;
+ u32 queue_buf_size;
+ int err;
+
+ err = hinic5_init_txq(txq, nic_dev);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Init txq failed");
+ return err;
+ }
+
+ queue_buf_size = txq->wqebb_size * txq->q_depth;
+ txq->queue_buf_vaddr = dma_alloc(nic_dev->dma, &txq->sq_map,
+ queue_buf_size,
+ HINIC5_WQ_PGSIZE_ALIGN);
+ if (txq->queue_buf_vaddr == NULL) {
+ IPXE_DRV_LOG(ERR, "Alloc txq queue addr failed");
+ err = -ENOMEM;
+ goto alloc_queue_buf_fail;
+ }
+
+ /* Initialise descriptor ring */
+ (void)memset_s(txq->queue_buf_vaddr, queue_buf_size, 0, queue_buf_size);
+ txq->queue_buf_paddr = dma(&txq->sq_map, txq->queue_buf_vaddr);
+
+ txq->tx_info = zalloc(sizeof(struct hinic5_tx_info) * txq->q_depth);
+ if (txq->tx_info == NULL) {
+ IPXE_DRV_LOG(ERR, "Alloc tx info failed");
+ err = -ENOMEM;
+ goto alloc_tx_info_fail;
+ }
+
+ err = hinic5_alloc_db_addr(nic_dev->hwdev, &db_addr, HINIC5_DB_TYPE_SQ);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Alloc sq doorbell addr failed");
+ goto alloc_db_err_fail;
+ }
+ txq->db_addr = db_addr;
+
+ return 0;
+
+alloc_db_err_fail:
+ free(txq->tx_info);
+alloc_tx_info_fail:
+ dma_free(&txq->sq_map, txq->queue_buf_vaddr, queue_buf_size);
+alloc_queue_buf_fail:
+ dma_free(&txq->ci_map, txq->ci_vaddr_base, HINIC5_CI_Q_ADDR_SIZE);
+ return err;
+}
+
+void hinic5_free_tx_resources(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_txq *txq = NULL;
+ u16 q_id;
+
+ for (q_id = 0; q_id < nic_dev->num_sqs; q_id++) {
+ txq = &nic_dev->txqs[q_id];
+ hinic5_destory_txq(txq);
+ }
+
+ return;
+}
+
+int hinic5_alloc_tx_resources(struct hinic5_nic_dev *nic_dev)
+{
+ struct hinic5_txq *txq = NULL;
+ u16 q_id, i;
+ int err;
+
+ for (q_id = 0; q_id < nic_dev->num_sqs; q_id++) {
+ txq = &nic_dev->txqs[q_id];
+ err = hinic5_create_txq(txq);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Create txq %d fail, err: %d\n", q_id,
+ err);
+ goto create_txq_err;
+ }
+ }
+
+ return 0;
+
+create_txq_err:
+ for (i = 0; i < q_id; i++) {
+ txq = &nic_dev->txqs[i];
+ hinic5_destory_txq(txq);
+ }
+ return err;
+}
+
+/**
+ * Get send queue free wqebb cnt
+ *
+ * @param[in] sq
+ * Send queue
+ * @return
+ * Number of free wqebb
+ */
+static inline u16 hinic5_get_sq_free_wqebbs(struct hinic5_txq *sq)
+{
+ return ((sq->q_depth -
+ (((sq->prod_idx - sq->cons_idx) + sq->q_depth) & sq->q_mask)) -
+ 1);
+}
+
+/**
+ * Get send queue pi
+ *
+ * @param[in] sq
+ * Send queue
+ * @return
+ * pi
+ */
+static inline u16 hinic5_get_sq_pi(struct hinic5_txq *sq)
+{
+ return MASKED_QUEUE_IDX(sq, sq->prod_idx);
+}
+
+/**
+ * Update send queue local ci
+ *
+ * @param[in] sq
+ * Send queue
+ * @param[in] wqe_cnt
+ * Number of wqebb
+ */
+static inline void hinic5_update_sq_local_ci(struct hinic5_txq *sq, u16 wqe_cnt)
+{
+ sq->cons_idx += wqe_cnt;
+}
+
+/**
+ * Get send queue local ci
+ *
+ * @param[in] sq
+ * Send queue
+ * @return
+ * Local ci
+ */
+static inline u16 hinic5_get_sq_local_ci(struct hinic5_txq *sq)
+{
+ return MASKED_QUEUE_IDX(sq, sq->cons_idx);
+}
+
+static void *hinic5_get_sq_wqe(struct hinic5_txq *sq,
+ struct hinic5_wqe_info *wqe_info)
+{
+ u16 cur_pi = MASKED_QUEUE_IDX(sq, sq->prod_idx);
+ u32 end_pi;
+
+ end_pi = cur_pi + wqe_info->wqebb_cnt;
+ sq->prod_idx += wqe_info->wqebb_cnt;
+
+ wqe_info->owner = (u8)(sq->owner);
+ wqe_info->pi = cur_pi;
+ wqe_info->wrapped = 0;
+
+ if (end_pi >= sq->q_depth) {
+ sq->owner = !sq->owner;
+
+ if (end_pi > sq->q_depth) {
+ wqe_info->wrapped = (u8)(sq->q_depth - cur_pi);
+ }
+ }
+
+ return NIC_WQE_ADDR(sq, cur_pi); /*lint !e701 !e647*/
+}
+
+static inline void hinic5_put_sq_wqe(struct hinic5_txq *sq,
+ struct hinic5_wqe_info *wqe_info)
+{
+ if (wqe_info->owner != sq->owner) {
+ sq->owner = wqe_info->owner;
+ }
+
+ sq->prod_idx -= wqe_info->wqebb_cnt;
+}
+
+static inline u16 hinic5_get_sq_hw_ci(struct hinic5_txq *sq)
+{
+ return MASKED_QUEUE_IDX(sq, hinic5_hw_cpu16(*(sq->ci_vaddr_base)));
+}
+
+static inline void hinic5_set_vlan_tx_offload(struct hinic5_sq_task *task,
+ u16 vlan_tag, u8 vlan_type)
+{
+ task->vlan_offload = SQ_TASK_INFO3_SET(vlan_tag, VLAN_TAG) |
+ SQ_TASK_INFO3_SET(vlan_type, VLAN_TYPE) |
+ SQ_TASK_INFO3_SET(1U, VLAN_TAG_VALID);
+}
+
+void hinic5_tx_set_compact_vlan_tx_offload(struct hinic5_sq_task *task,
+ u16 vlan_tag, u8 vlan_type)
+{
+ task->pkt_info0 = SQ_TASK_INFO_SET(1U, VLAN_VALID) |
+ SQ_TASK_INFO_SET(vlan_type, VLAN_SEL) |
+ SQ_TASK_INFO_SET(vlan_tag, VLAN_TAG);
+}
+
+void hinic5_sq_prepare_wqe(struct hinic5_sq_extend_wqe *sq_wqe,
+ struct hinic5_sge *sge, u16 owner, u8 vlan_en,
+ u8 vlan_pri, u16 vlan_id, u8 wqe_task_type)
+{
+ struct hinic5_sq_wqe_desc *wqe_desc = &sq_wqe->wqe_desc;
+ u16 vlan_tag;
+
+ /* pxe one packet only have one sge */
+ wqe_desc->ctrl_len = SQ_CTRL_SET(sge->len, BD0_LEN) |
+ SQ_CTRL_SET(1, BUFDESC_NUM) |
+ SQ_CTRL_SET(SQ_WQE_EXTENDED_TYPE, TASKSECT_LEN) |
+ SQ_CTRL_SET(SQ_NORMAL_WQE, DATA_FORMAT) |
+ SQ_CTRL_SET(SQ_WQE_EXTENDED_TYPE, EXTENDED) |
+ SQ_CTRL_SET(owner, OWNER);
+
+ wqe_desc->queue_info = SQ_CTRL_QUEUE_INFO_SET(1U, UC);
+
+ wqe_desc->queue_info |= SQ_CTRL_QUEUE_INFO_SET(TX_MSS_DEFAULT, MSS);
+
+ wqe_desc->hi_addr = sge->hi_addr;
+ wqe_desc->lo_addr = sge->lo_addr;
+
+ if (vlan_en) {
+ vlan_tag = MAKE_VLAN_TAG(vlan_id, vlan_pri);
+
+ (void)memset_s(&sq_wqe->task, sizeof(struct hinic5_sq_task), 0,
+ sizeof(struct hinic5_sq_task));
+
+ if (wqe_task_type == HINIC5_TX_WQE_COMPACT_TASK) {
+ hinic5_tx_set_compact_vlan_tx_offload(&sq_wqe->task,
+ vlan_tag, 0);
+ } else {
+ hinic5_set_vlan_tx_offload(&sq_wqe->task, vlan_tag, 0);
+ }
+ }
+}
+
+void hinic5_pxe_tx_poll(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ struct hinic5_txq *txq = &nic_dev->txqs[0];
+ struct hinic5_tx_info *tx_info = NULL;
+ u16 hw_ci, sw_ci, sq_mask;
+ u32 wqebb_cnt = 0;
+
+ hw_ci = hinic5_get_sq_hw_ci(txq);
+ sw_ci = hinic5_get_sq_local_ci(txq);
+ sq_mask = txq->q_mask;
+
+ while (sw_ci != hw_ci) {
+ tx_info = &txq->tx_info[sw_ci];
+
+ if (((hw_ci - sw_ci) & sq_mask) < tx_info->wqebb_cnt) {
+ break;
+ }
+
+ wqebb_cnt += tx_info->wqebb_cnt;
+
+ /*
+ tx_iobuf maybe NULL when HW_CI was modified unexpectedly.
+ in this case, print the queue's dfx information
+ */
+ if (tx_info->tx_iobuf == NULL) {
+ IPXE_DRV_LOG(
+ ERR,
+ "tx_iobuf in txq: %d is NULL, q_depth: %d, PI: %d, CI: %d, hwci: %d \n",
+ txq->q_id, txq->q_depth, txq->prod_idx, sw_ci,
+ hw_ci);
+ break;
+ }
+
+ netdev_tx_complete(netdev, tx_info->tx_iobuf);
+ tx_info->tx_iobuf = NULL;
+
+ sw_ci = (sw_ci + tx_info->wqebb_cnt) & sq_mask;
+ }
+
+ hinic5_update_sq_local_ci(txq, (u16)wqebb_cnt);
+
+ return;
+}
+
+int hinic5_pxe_transmit(struct net_device *netdev, struct io_buffer *iobuf)
+{
+ struct hinic5_nic_dev *nic_dev = netdev->priv;
+ struct hinic5_txq *txq = &nic_dev->txqs[0];
+ struct hinic5_wqe_info wqe_info = { 0 };
+ struct hinic5_sq_wqe *sq_wqe = NULL;
+ struct nic_bios_cfg conf = { 0 };
+ struct hinic5_sge sge;
+ unsigned int vlan_id = 0;
+ u8 wqe_task_type = 0;
+ u8 vlan_pri = 0;
+ u8 vlan_en = 0;
+ u32 opcode;
+ int err;
+
+ if (hinic5_get_sq_free_wqebbs(txq) <= WQEBB_CNT_FOR_EXTEND_WQE) {
+ IPXE_DRV_LOG(INFO, "txq full\n");
+ return -ENOBUFS;
+ }
+
+ /* TX used 32B extend WQE, tx packet only one sge */
+ wqe_info.wqebb_cnt = WQEBB_CNT_FOR_EXTEND_WQE;
+
+ /* Get sq wqe address from wqe_page */
+ sq_wqe = hinic5_get_sq_wqe(txq, &wqe_info);
+
+ txq->tx_info[wqe_info.pi].tx_iobuf = iobuf;
+ txq->tx_info[wqe_info.pi].wqebb_cnt = wqe_info.wqebb_cnt;
+
+ sge.lo_addr = lower_32_bits(iob_dma(iobuf));
+ sge.hi_addr = upper_32_bits(iob_dma(iobuf));
+ sge.len = iob_len(iobuf);
+
+ if (HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev)) {
+ wqe_task_type = HINIC5_TX_WQE_COMPACT_TASK;
+ } else {
+ wqe_task_type = HINIC5_TX_WQE_NORMAL_TASK;
+ }
+
+ opcode = NIC_NVM_DATA_ALL;
+ err = hinic5_get_persistent_conf(nic_dev->hwdev, opcode, &conf);
+ if (err) {
+ IPXE_DRV_LOG(ERR, "Hinic5 get vlan info failed, ret=%d", err);
+ txq->tx_info[wqe_info.pi].tx_iobuf = NULL;
+ txq->tx_info[wqe_info.pi].wqebb_cnt = 0;
+ hinic5_put_sq_wqe(txq, &wqe_info);
+ return err;
+ }
+
+ vlan_en = conf.nlvc.pxe_vlan_en;
+ vlan_id = conf.nlvc.pxe_vlan_id;
+ vlan_pri = conf.nlvc.pxe_vlan_pri;
+ hinic5_sq_prepare_wqe(&sq_wqe->extend_wqe, &sge, wqe_info.owner,
+ vlan_en, vlan_pri, vlan_id, wqe_task_type);
+
+ hinic5_write_db(txq->db_addr, txq->q_id, (int)(txq->cos), SQ_CFLAG_DP,
+ MASKED_QUEUE_IDX(txq, txq->prod_idx));
+
+ return 0;
+}
+
+static bool is_hw_complete_sq_process(struct hinic5_txq *txq)
+{
+ u16 sw_pi, hw_ci;
+
+ sw_pi = hinic5_get_sq_pi(txq);
+ hw_ci = hinic5_get_sq_hw_ci(txq);
+
+ return sw_pi == hw_ci;
+}
+
+#define HINIC5_FLUSH_QUEUE_TIMEOUT 300
+#define HINIC5_FLUSH_QUEUE_SINGLE_WAIT 10
+int hinic5_stop_sq(struct hinic5_txq *txq)
+{
+ u32 timeout = 0;
+ int err = -EFAULT;
+
+ do {
+ if (is_hw_complete_sq_process(txq)) {
+ err = 0;
+ break;
+ }
+
+ usleep(HINIC5_FLUSH_QUEUE_SINGLE_WAIT * HINIC5_MS_TO_US_UNIT);
+ timeout++;
+ } while (timeout < HINIC5_FLUSH_QUEUE_TIMEOUT);
+
+ if (err != 0) {
+ IPXE_DRV_LOG(
+ WARN,
+ "Wait sq empty timeout, queue_idx: %d, sw_ci: %d, "
+ "hw_ci: %d, sw_pi: %d, free_wqebbs: %d, q_depth:%d\n",
+ txq->q_id, hinic5_get_sq_local_ci(txq),
+ hinic5_get_sq_hw_ci(txq),
+ MASKED_QUEUE_IDX(txq, txq->prod_idx),
+ hinic5_get_sq_free_wqebbs(txq), txq->q_depth);
+ }
+ return err;
+}
+
+/* Should stop transmiting any packets before calling this function */
+void hinic5_flush_txqs(struct hinic5_nic_dev *nic_dev)
+{
+ u16 qid;
+ int err;
+
+ for (qid = 0; qid < nic_dev->num_sqs; qid++) {
+ err = hinic5_stop_sq(&nic_dev->txqs[qid]);
+ if (err != 0) {
+ IPXE_DRV_LOG(ERR, "Stop sq%d failed", qid);
+ }
+ }
+}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.h
new file mode 100644
index 000000000..a406a8191
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/hinic5_tx.h
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ */
+
+#ifndef _HINIC5_TX_H_
+#define _HINIC5_TX_H_
+
+FILE_LICENCE(GPL2_ONLY);
+
+/* ************* SQ_CTRL ************** */
+enum sq_wqe_data_format {
+ SQ_NORMAL_WQE = 0,
+};
+
+enum sq_wqe_ec_type {
+ SQ_WQE_COMPACT_TYPE = 0,
+ SQ_WQE_EXTENDED_TYPE = 1,
+};
+
+#define COMPACT_WQE_MAX_CTRL_LEN 0x3FFF
+#define TX_MSS_DEFAULT 0x3E00
+
+enum sq_wqe_tasksect_len_type {
+ SQ_WQE_TASKSECT_46BITS = 0,
+ SQ_WQE_TASKSECT_16BYTES = 1,
+};
+
+#define SQ_CTRL_BD0_LEN_SHIFT 0
+#define SQ_CTRL_RSVD_SHIFT 18
+#define SQ_CTRL_BUFDESC_NUM_SHIFT 19
+#define SQ_CTRL_TASKSECT_LEN_SHIFT 27
+#define SQ_CTRL_DATA_FORMAT_SHIFT 28
+#define SQ_CTRL_DIRECT_SHIFT 29
+#define SQ_CTRL_EXTENDED_SHIFT 30
+#define SQ_CTRL_OWNER_SHIFT 31
+
+#define SQ_CTRL_BD0_LEN_MASK 0x3FFFFU
+#define SQ_CTRL_RSVD_MASK 0x1U
+#define SQ_CTRL_BUFDESC_NUM_MASK 0xFFU
+#define SQ_CTRL_TASKSECT_LEN_MASK 0x1U
+#define SQ_CTRL_DATA_FORMAT_MASK 0x1U
+#define SQ_CTRL_DIRECT_MASK 0x1U
+#define SQ_CTRL_EXTENDED_MASK 0x1U
+#define SQ_CTRL_OWNER_MASK 0x1U
+
+#define SQ_CTRL_SET(val, member) \
+ (((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)
+
+#define SQ_CTRL_CLEAR(val, member) \
+ ((val) & (~(SQ_CTRL_##member##_MASK << SQ_CTRL_##member##_SHIFT)))
+
+#define SQ_CTRL_QUEUE_INFO_PKT_TYPE_SHIFT 0
+#define SQ_CTRL_QUEUE_INFO_PLDOFF_SHIFT 2
+#define SQ_CTRL_QUEUE_INFO_UFO_SHIFT 10
+#define SQ_CTRL_QUEUE_INFO_TSO_SHIFT 11
+#define SQ_CTRL_QUEUE_INFO_TCPUDP_CS_SHIFT 12
+#define SQ_CTRL_QUEUE_INFO_MSS_SHIFT 13
+#define SQ_CTRL_QUEUE_INFO_SCTP_SHIFT 27
+#define SQ_CTRL_QUEUE_INFO_UC_SHIFT 28
+#define SQ_CTRL_QUEUE_INFO_PRI_SHIFT 29
+
+#define SQ_CTRL_QUEUE_INFO_PKT_TYPE_MASK 0x3U
+#define SQ_CTRL_QUEUE_INFO_PLDOFF_MASK 0xFFU
+#define SQ_CTRL_QUEUE_INFO_UFO_MASK 0x1U
+#define SQ_CTRL_QUEUE_INFO_TSO_MASK 0x1U
+#define SQ_CTRL_QUEUE_INFO_TCPUDP_CS_MASK 0x1U
+#define SQ_CTRL_QUEUE_INFO_MSS_MASK 0x3FFFU
+#define SQ_CTRL_QUEUE_INFO_SCTP_MASK 0x1U
+#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_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 HINIC5_TX_WQE_NORMAL_TASK 0
+#define HINIC5_TX_WQE_COMPACT_TASK 1
+
+#define VLANTAG_PRIO_MASK 0xE000 /* Priority Code Point */
+#define VLANTAG_PRIO_SHIFT 13
+#define VLANTAG_VID_MASK 0x0FFF /* VLAN Identifier */
+#define VLANTAG_VID_SHIFT 0
+
+/* Assemble the vlan Tag, note that we set DEI/CFI bit in Vlan Tag to 0 */
+#define MAKE_VLAN_TAG(vid, pri) \
+ ((((u16)(vid) << VLANTAG_VID_SHIFT) & VLANTAG_VID_MASK) | \
+ (((u16)(pri) << VLANTAG_PRIO_SHIFT) & VLANTAG_PRIO_MASK))
+
+#define SQ_TASK_INFO3_VLAN_TAG_SHIFT 0
+#define SQ_TASK_INFO3_VLAN_TYPE_SHIFT 16
+#define SQ_TASK_INFO3_VLAN_TAG_VALID_SHIFT 19
+
+#define SQ_TASK_INFO3_VLAN_TAG_MASK 0xFFFFU
+#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) \
+ (((val) >> SQ_TASK_INFO3_##member##_SHIFT) & \
+ SQ_TASK_INFO3_##member##_MASK)
+
+#define HINIC5_SUPPORT_FEATURE(dev, feature) \
+ ((hinic5_get_driver_feature(dev) & NIC_F_##feature) != 0)
+
+#define HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, TX_WQE_COMPACT_TASK)
+#define NIC_F_TX_WQE_COMPACT_TASK NIC_F(TX_WQE_COMPACT_TASK)
+
+#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_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)
+
+struct hinic5_tx_info {
+ struct io_buffer *tx_iobuf;
+ u32 wqebb_cnt;
+};
+struct hinic5_txq {
+ struct hinic5_nic_dev *nic_dev;
+
+ u16 q_id;
+ u16 q_depth;
+ u16 q_mask;
+ u16 wqebb_size;
+
+ u16 wqebb_shift;
+ u16 cons_idx;
+ u16 prod_idx;
+
+ u16 owner; /* Used for sq */
+
+ void *db_addr;
+
+ struct hinic5_tx_info *tx_info;
+
+ struct dma_mapping sq_map;
+ void *queue_buf_vaddr;
+ physaddr_t queue_buf_paddr; /* Sq dma info */
+
+ struct dma_mapping ci_map;
+ u16 *ci_vaddr_base;
+ physaddr_t ci_dma_base;
+
+ u32 cos;
+};
+
+struct hinic5_wqe_info {
+ u8 wrapped;
+ u8 owner;
+ u16 pi;
+
+ u16 wqebb_cnt;
+ u16 rsvd1;
+};
+
+struct hinic5_sq_wqe_desc {
+ u32 ctrl_len;
+ u32 queue_info;
+ u32 hi_addr;
+ u32 lo_addr;
+};
+
+struct hinic5_sq_task {
+ u32 pkt_info0;
+ u32 ip_identify;
+ u32 pkt_info2; /* ipsec used as spi */
+ u32 vlan_offload;
+};
+struct hinic5_sq_bufdesc {
+ u32 len; /* 31-bits Length, L2NIC only use length[17:0] */
+ u32 rsvd;
+ u32 hi_addr;
+ u32 lo_addr;
+};
+
+struct hinic5_sq_compact_wqe {
+ struct hinic5_sq_wqe_desc wqe_desc;
+};
+
+struct hinic5_sq_extend_wqe {
+ struct hinic5_sq_wqe_desc wqe_desc;
+ struct hinic5_sq_task task;
+ struct hinic5_sq_bufdesc buf_desc[0];
+};
+
+struct hinic5_sq_wqe {
+ union {
+ struct hinic5_sq_compact_wqe compact_wqe;
+ struct hinic5_sq_extend_wqe extend_wqe;
+ };
+};
+
+int hinic5_alloc_txqs(struct net_device *netdev);
+void hinic5_free_txqs(struct net_device *netdev);
+int hinic5_alloc_tx_resources(struct hinic5_nic_dev *nic_dev);
+void hinic5_free_tx_resources(struct hinic5_nic_dev *nic_dev);
+int hinic5_pxe_transmit(struct net_device *netdev, struct io_buffer *iobuf);
+void hinic5_pxe_tx_poll(struct net_device *netdev);
+void hinic5_flush_txqs(struct hinic5_nic_dev *nic_dev);
+
+#endif /* _HINIC5_TX_H_ */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/menu.ipxe b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/menu.ipxe
new file mode 100755
index 000000000..a5aa58d03
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/ipxe/menu.ipxe
@@ -0,0 +1,25 @@
+#!ipxe
+
+set retries:int32 0
+
+#if press Ctrl+B during post will enter pxe config immediately
+#if not will auto boot directly
+prompt --key 0x02 --timeout 1 && goto pxe_config || goto pxe_autoboot
+###################################### config ################################
+:pxe_config
+c1o8n2f3ig && goto config_exit || goto config_shell
+
+:config_shell
+shell
+exit
+
+:config_exit
+exit
+
+######################################### auto boot ###########################
+#auto boot 3 times
+:pxe_autoboot
+iseq ${retries} 3 && exit ||
+inc retries
+#if boot is successful then control will not return to iPXE
+autoboot || goto pxe_autoboot
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/CMakeLists.txt b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/CMakeLists.txt
new file mode 100644
index 000000000..6d0e7e674
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/CMakeLists.txt
@@ -0,0 +1,82 @@
+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(HISDK5_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/sdk/knldk/lld)
+
+# =============================== 使用KCompat自动化工具时临时适配1650的NIC驱动编译(TODO)===============================
+message(STATUS "KDIR = ${KDIR}")
+set(HI1823_TRUNK_DIR ${TOP_DIR}/ChipSolution)
+set(NIC_KCOMPAT_GENERATOR_PATH "${HI1823_TRUNK_DIR}/build/host/linux/nic/nic-kcompat-generator.sh")
+set(NIC_KCOMPAT_PATH "${HI1823_TRUNK_DIR}/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h")
+
+if("${KDIR}" MATCHES "2403_SP2")
+ message(STATUS "KNL_HEADER_TYPE: UB1650")
+ set(KERN_VER "NULL")
+ set(KSRC "${KDIR}/../../../../open_source/2403_SP2")
+ message(STATUS "KSRC = ${KSRC}")
+
+ if(EXISTS ${NIC_KCOMPAT_GENERATOR_PATH})
+ message(STATUS "${NIC_KCOMPAT_GENERATOR_PATH} file is exist!")
+ endif()
+
+ string(RANDOM LENGTH 4 RAND_NUM)
+ set(NIC_KCOMPAT_GENERATOR_PATH_TMP "${HI1823_TRUNK_DIR}/build/host/linux/nic/nic-kcompat-generator_${RAND_NUM}.sh")
+
+ if(EXISTS ${NIC_KCOMPAT_GENERATOR_PATH_TMP})
+ file(REMOVE ${NIC_KCOMPAT_GENERATOR_PATH_TMP})
+ endif()
+
+ file(COPY_FILE "${NIC_KCOMPAT_GENERATOR_PATH}" "${NIC_KCOMPAT_GENERATOR_PATH_TMP}")
+ if(EXISTS ${NIC_KCOMPAT_GENERATOR_PATH_TMP})
+ message(STATUS "${NIC_KCOMPAT_GENERATOR_PATH_TMP} file copy succeed")
+ else()
+ message(STATUS "${NIC_KCOMPAT_GENERATOR_PATH_TMP} file copy failed")
+ endif()
+
+ file(READ ${NIC_KCOMPAT_GENERATOR_PATH_TMP} FILE_CONTENTS)
+ string(REPLACE "KERN_VER=\$(uname -r)" "KERN_VER=${KERN_VER}" FILE_CONTENTS "${FILE_CONTENTS}")
+ string(REPLACE "KSRC=\"\"" "KSRC=\"${KSRC}\"" FILE_CONTENTS "${FILE_CONTENTS}")
+ file(WRITE ${NIC_KCOMPAT_GENERATOR_PATH_TMP} "${FILE_CONTENTS}")
+
+ execute_process(
+ COMMAND bash -c "source ${NIC_KCOMPAT_GENERATOR_PATH_TMP} && gen_nic_kcompat ${NIC_KCOMPAT_PATH}"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ RESULT_VARIABLE RESULT
+ )
+ if(EXISTS ${NIC_KCOMPAT_GENERATOR_PATH_TMP})
+ file(REMOVE ${NIC_KCOMPAT_GENERATOR_PATH_TMP})
+ endif()
+else()
+ message(STATUS "KNL_HEADER_TYPE: DEFAULT")
+ execute_process(
+ COMMAND bash -c "source ${NIC_KCOMPAT_GENERATOR_PATH} && gen_nic_kcompat ${NIC_KCOMPAT_PATH}"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ RESULT_VARIABLE RESULT
+ )
+endif()
+
+if(EXISTS ${NIC_KCOMPAT_PATH})
+ message(STATUS "${NIC_KCOMPAT_PATH} file is exist!")
+else()
+ message(STATUS "${NIC_KCOMPAT_PATH} file is not exist!")
+endif()
+# =====================================================================================================
+
+add_custom_target(hinic5_ko
+ COMMENT echo "build ${CMAKE_CURRENT_SOURCE_DIR} start."
+ COMMAND cd ${TOP_DIR}/ChipSolution && git apply build/host/linux/sdk/patch_code/knl6_6_compile.patch && cd -
+ 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} HI1823_TRUNK_DIR=${TOP_DIR}/ChipSolution HI1823_BUILD_DIR=${TOP_DIR}/ChipSolution HI1823_OS_RELEASE=openEuler24.03 HISDK5_SYMVERS=${HISDK5_BUILD_DIR}/Module.symvers
+ COMMAND cp -f *.ko ${CMAKE_INSTALL_PREFIX}/ko
+ COMMAND cd ${TOP_DIR}/ChipSolution && git apply --reverse build/host/linux/sdk/patch_code/knl6_6_compile.patch && cd -
+ DEPENDS kernel
+)
+
+add_dependencies(hinic5_ko hisdk5_ko)
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/outband_mpu_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/outband_mpu_ncsi_cmd_defs.h
new file mode 100644
index 000000000..4cc9b3dc8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/outband_mpu_ncsi_cmd_defs.h
@@ -0,0 +1,1641 @@
+
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+ * Description : mpu cmd
+ * Creation time : 2026/05/13
+ */
+#ifndef OUTBAND_MPU_NCSI_CMD_DEFS_H
+#define OUTBAND_MPU_NCSI_CMD_DEFS_H
+
+#include "base_type.h"
+#include "mpu_outband_ncsi_cmd_defs.h"
+
+#pragma pack(1)
+/* Clear Initial State Command (0x00) */
+/**
+ * @brief ncsi clear initial state command (0x00) struct defination
+ * @see NCSI_CLEAR_INITIAL_STATE
+ *
+ */
+typedef struct tg_clear_initial_state {
+ u32 check_sum; /**< clear initial state check sum */
+} clear_initial_state_s, *p_clear_initial_state_s;
+
+/* Clear Initial State Response (0x80) */
+/**
+ * @brief ncsi clear initial state response (0x80) struct defination
+ * @see NCSI_CLEAR_INITIAL_STATE_RSP
+ *
+ */
+typedef struct tg_clear_initial_state_rsp {
+ u16 rsp_code; /**< clear initial state response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< clear initial state response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< clear initial state response check sum */
+} clear_initial_state_rsp_s, *p_clear_initial_state_rsp_s;
+
+/* Select Package Command (0x01) */
+/**
+ * @brief ncsi select packag command (0x01) struct defination
+ * @see NCSI_SELECT_PACKAGE
+ *
+ */
+typedef struct tg_select_package {
+ u8 reserved1[3]; /**< select package reserved1 */
+#ifdef BIG_ENDIAN
+ u8 reserved2 : 7; /**< select package reserved2 */
+ u8 hd_arbitration : 1; /**< select package hd arbitration */
+#else
+ u8 hd_arbitration : 1; /**< select package hd arbitration */
+ u8 reserved2 : 7; /**< select package reserved2 */
+#endif
+ u32 check_sum; /**< select package check sum */
+} select_package_s, *p_select_package_s;
+
+/* Select Package Response (0x81) */
+/**
+ * @brief ncsi select packag response (0x81) struct defination
+ * @see NCSI_SELECT_PACKAGE_RSP
+ *
+ */
+typedef struct tg_select_package_rsp {
+ u16 rsp_code; /**< select package response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< select package response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< select package response check sum */
+} select_package_rsp_s, *p_select_package_rsp_s;
+
+/* Deselect Package Command (0x02) */
+/**
+ * @brief ncsi deselect packag command (0x02) struct defination
+ * @see NCSI_DESELECT_PACKAGE
+ *
+ */
+typedef struct tg_deselect_package {
+ u32 check_sum; /**< deselect package check sum */
+} deselect_package_s, *p_deselect_package_s;
+
+/* Deselect Package Response (0x82) */
+/**
+ * @brief ncsi deselect packag response (0x82) struct defination
+ * @see NCSI_DESELECT_PACKAGE_RSP
+ *
+ */
+typedef struct tg_deselect_package_rsp {
+ u16 reason_code; /**< deselect package response reason code */
+ u16 rsp_code; /**< deselect package response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u32 check_sum; /**< deselect package response check sum @see enum NCSI_REASON_CODE_E */
+} deselect_package_rsp_s, *p_deselect_package_rsp_s;
+
+/* Enable Channel Command (0x03) */
+/**
+ * @brief ncsi enable channel command (0x03) struct defination
+ * @see NCSI_ENABLE_CHANNEL
+ *
+ */
+typedef struct tg_enable_channel {
+ u32 check_sum; /**< enable channel response check sum */
+} enable_channel_s, *p_enable_channel_s;
+
+/* Enable Channel Response (0x83) */
+/**
+ * @brief ncsi enable channel response (0x83) struct defination
+ * @see NCSI_ENABLE_CHANNEL_RSP
+ *
+ */
+typedef struct tg_enable_channel_rsp {
+ u16 rsp_code; /**< enable channel response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< enable channel response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< enable channel response check sum */
+} enable_channel_rsp_s, *p_enable_channel_rsp_s;
+
+/* Disable Channel Command (0x04) */
+/**
+ * @brief ncsi disable channel command (0x04) struct defination
+ * @see NCSI_DISABLE_CHANNEL
+ *
+ */
+typedef struct tg_disable_channel {
+ u8 reserved1[3]; /**< disable channel command reserved1 */
+#ifdef BIG_ENDIAN
+ u8 rsvd : 7; /**< disable channel command reserved */
+ u8 ald : 1; /**< disable channel command ald */
+#else
+ u8 ald : 1; /**< disable channel command ald */
+ u8 rsvd : 7; /**< disable channel command reserved */
+#endif
+ u32 check_sum; /**< disable channel command check sum */
+} disable_channel_s, *p_disable_channel_s;
+/* Disable Channel Response (0x84) */
+/**
+ * @brief ncsi disable channel response (0x84) struct defination
+ * @see NCSI_DISABLE_CHANNEL_RSP
+ *
+ */
+typedef struct tg_disable_channel_rsp {
+ u16 rsp_code; /**< disable channel response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< disable channel response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< disable channel response check sum */
+} disable_channel_rsp_s, *p_disable_channel_rsp_s;
+
+/* Reset Channel Command (0x05) */
+/**
+ * @brief ncsi reset channel command (0x05) struct defination
+ * @see NCSI_RESET_CHANNEL
+ *
+ */
+typedef struct tg_reset_channel {
+ u32 rsvd; /**< reset channel command reserved */
+ u32 check_sum; /**< reset channel command check sum */
+} reset_channel_s, *p_reset_channel_s;
+
+/* Reset Channel Response (0x85) */
+/**
+ * @brief ncsi reset channel response (0x85) struct defination
+ * @see NCSI_RESET_CHANNEL_RSP
+ *
+ */
+typedef struct tg_reset_channel_rsp {
+ u16 rsp_code; /**< reset channel response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reset channel response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< reset channel response check sum */
+} reset_channel_rsp_s, *p_reset_channel_rsp_s;
+
+/* Enable Channel Network TX Command (0x06) */
+/**
+ * @brief ncsi enable channel network TX command (0x06) struct defination
+ * @see NCSI_ENABLE_CHANNEL_NETWORK_TX
+ *
+ */
+typedef struct tg_enable_chn_tx {
+ u32 check_sum; /**< enable channel network TX command check sum */
+} enable_chn_tx_s, *p_enable_chn_tx_s;
+/* Enable Channel Network TX Response (0x86) ) */
+/**
+ * @brief ncsi enable channel network TX response (0x86) struct defination
+ * @see NCSI_ENABLE_CHANNEL_NETWORK_TX_RSP
+ *
+ */
+typedef struct tg_enable_chn_tx_rsp {
+ u16 reason_code; /**< enable channel network TX response reason code @see enum NCSI_REASON_CODE_E */
+ u16 rsp_code; /**< enable channel network TX response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u32 check_sum; /**< enable channel network TX response check sum */
+} enable_chn_tx_rsp_s, *p_enable_chn_tx_rsp_s;
+
+/* Disable Channel Network TX Command (0x07) */
+/**
+ * @brief ncsi disable channel network TX command (0x07) struct defination
+ * @see NCSI_DISABLE_CHANNEL_NETWORK_TX
+ *
+ */
+typedef struct tg_disable_chn_tx {
+ u32 check_sum; /**< disable channel network TX command check sum */
+} disable_chn_tx_s, *p_disable_chn_tx_s;
+/* Disable Channel Network TX Response (0x87) ) */
+/**
+ * @brief ncsi disable channel network TX response (0x87) struct defination
+ * @see NCSI_DISABLE_CHANNEL_NETWORK_TX_RSP
+ *
+ */
+typedef struct tg_disable_chn_tx_rsp {
+ u16 rsp_code; /**< disable channel network TX response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< disable channel network TX response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< disable channel network TX response check sum */
+} disable_chn_tx_rsp_s, *p_disable_chn_tx_rsp_s;
+
+/* AEN Enable Command (0x08) */
+#define AEN_CTRL_LINK_STATUS_SHIFT 0
+#define AEN_CTRL_CONFIG_REQ_SHIFT 1
+#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+
+/* AEN Type */
+typedef enum {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+} aen_type_e;
+
+typedef union tg_aen_control {
+ struct {
+ u16 oem_ctl; /**< AEN control oem control */
+ u8 reserved; /**< AEN control reserved */
+#ifdef BD_BIG_ENDIAN
+ u8 reserved2 : 5; /**< AEN control reserved2 */
+ u8 drv_change : 1; /**< AEN control driver change
+ * 1b = Enable Host NC Driver Status Change AEN 0=disable */
+ u8 config_req : 1; /**< AEN control config_req */
+ u8 link_status : 1; /**< AEN control driver change
+ * 1b = Enable Link Status Change AEN 0=disable */
+#else
+ u8 link_status : 1; /**< AEN control driver change
+ * 1b = Enable Link Status Change AEN 0=disable */
+ u8 config_req : 1; /**< AEN control config_req */
+ u8 drv_change : 1; /**< AEN control driver change
+ * 1b = Enable Host NC Driver Status Change AEN 0=disable */
+ u8 reserved2 : 5; /**< AEN control reserved2 */
+#endif
+ } bits;
+
+ u32 aen_ctrl; /**< AEN control check sum */
+} aen_control_s;
+/**
+ * @brief ncsi AEN enable command (0x08) struct defination
+ * @see NCSI_AEN_ENABLE
+ *
+ */
+typedef struct tg_enable_aen {
+ u8 reserved1[3]; /**< AEN enable command reserved2 */
+ u8 mc_id; /**< AEN enable command management control ID */
+ aen_control_s aen_control; /**< AEN control */
+ u32 check_sum; /**< AEN enable command check sum */
+} enable_aen_s, *p_enable_aen_s;
+/* AEN Enable Response (0x88) */
+/**
+ * @brief ncsi AEN enable response (0x88) struct defination
+ * @see NCSI_AEN_ENABLE_RSP
+ *
+ */
+typedef struct tg_enable_aen_rsp {
+ u16 rsp_code; /**< AEN enable response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< AEN enable response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< AEN enable response check sum */
+} enable_aen_rsp_s, *p_enable_aen_rsp_s;
+
+/* set link: 0x09 */
+/**
+ * @brief ncsi set link command (0x09) struct defination
+ * @see NCSI_SET_LINK
+ *
+ */
+typedef struct tg_set_link {
+ u32 link_settings; /**< set link command link settings */
+ u32 OEM_link_settings; /**< set link command OEM link settings */
+ u32 check_sum; /**< set link command check sum */
+} set_link_s, *p_set_link_s;
+/* set link response (0x89) */
+/**
+ * @brief ncsi set link response (0x89) struct defination
+ * @see NCSI_SET_LINK_RSP
+ *
+ */
+typedef struct tg_set_link_rsp {
+ u16 rsp_code; /**< set link response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< set link response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< set link response check sum */
+} set_link_rsp_s, *p_set_link_rsp_s;
+
+/**
+ * @brief ncsi get link status command (0x0A) struct defination
+ * @see NCSI_GET_LINK_STATUS
+ *
+ */
+typedef struct tg_get_link_status {
+ u32 check_sum; /**< get link status command check sum */
+} get_link_status_s, *p_get_link_status_s;
+
+/* get link status response 0x8A */
+/**
+ * @brief link status struct defination
+ *
+ */
+typedef union {
+ struct {
+#ifdef BD_BIG_ENDIAN
+ u32 ex_speed_duplex : 8; /**< link status extended speed and duplex */
+
+ u32 modulation_cheme : 2; /**< link status modulation scheme */
+ u32 oem_link_speed : 1; /**< link status oem link speed @see enum NCSI_CMD_LINK_SPEED_E */
+ u32 serdes_link : 1; /**< link status serdes link */
+ u32 link_partner8 : 2; /**< link status link partner8 */
+ u32 rx_flow_control : 1; /**< link status rx flow control */
+ u32 tx_flow_control : 1; /**< link status tx flow control */
+
+ u32 link_partner7 : 1; /**< link status link partner7 */
+ u32 link_partner6 : 1; /**< link status link partner6 */
+ u32 link_partner5 : 1; /**< link status link partner5 */
+ u32 link_partner4 : 1; /**< link status link partner4 */
+ u32 link_partner3 : 1; /**< link status link partner3 */
+ u32 link_partner2 : 1; /**< link status link partner2 */
+ u32 link_partner1 : 1; /**< link status link partner1 */
+ u32 channel_available : 1; /**< link status channel available */
+
+ u32 parallel_detection : 1; /**< link status parallel detection */
+ u32 negotiate_complete : 1; /**< link status negotiate complete */
+ u32 negotiate_flag : 1; /**< link status negotiate flag */
+ u32 speed_duplex : 4; /**< link status speed duplex */
+ u32 link_flag : 1; /**< link status link flag */
+#else
+ u32 ex_speed_duplex : 8; /**< link status extended speed and duplex */
+
+ u32 tx_flow_control : 1; /**< link status tx flow control */
+ u32 rx_flow_control : 1; /**< link status rx flow control */
+ u32 link_partner8 : 2; /**< link status link partner8 */
+ u32 serdes_link : 1; /**< link status serdes link */
+ u32 oem_link_speed : 1; /**< link status oem link speed @see enum NCSI_CMD_LINK_SPEED_E */
+ u32 modulation_cheme : 2; /**< link status modulation scheme */
+
+ u32 channel_available : 1; /**< link status channel available */
+ u32 link_partner1 : 1; /**< link status link partner1 */
+ u32 link_partner2 : 1; /**< link status link partner2 */
+ u32 link_partner3 : 1; /**< link status link partner3 */
+ u32 link_partner4 : 1; /**< link status link partner4 */
+ u32 link_partner5 : 1; /**< link status link partner5 */
+ u32 link_partner6 : 1; /**< link status link partner6 */
+ u32 link_partner7 : 1; /**< link status link partner7 */
+
+ u32 link_flag : 1; /**< link status link flag */
+ u32 speed_duplex : 4; /**< link status speed duplex */
+ u32 negotiate_flag : 1; /**< link status negotiate flag */
+ u32 negotiate_complete : 1; /**< link status negotiate complete */
+ u32 parallel_detection : 1; /**< link status parallel detection */
+#endif
+ } bits;
+ u32 val32;
+} ncsi_link_status;
+
+/**
+ * @brief ncsi get link status response (0x8A) struct defination
+ * @see NCSI_GET_LINK_STATUS_RSP
+ *
+ */
+typedef struct tg_get_link_status_rsp {
+ u16 rsp_code; /**< get link status response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get link status response reason code @see enum NCSI_REASON_CODE_E */
+ u32 link_status; /**< get link status response link status */
+ u32 other_indications; /**< get link status response other indications */
+ u32 OEM_link_status; /**< get link status response OEM link status */
+ u32 check_sum; /**< get link status response check sum */
+} get_link_status_rsp_s, *p_get_link_status_rsp_s;
+
+/* Set Vlan Filter (0x0B) */
+/* Only VLAN-tagged packets that match the enabled VLAN Filter settings are accepted. */
+#define VLAN_MODE_UNSET 0X00
+#define VLAN_ONLY 0x01
+/* if match the MAC address ,any vlan-tagged and non-vlan-tagged will be
+ accepted */
+#define ANYVLAN_NONVLAN 0x03
+#define VLAN_MODE_SUPPORT 0x05
+
+/* chanel vlan filter enable */
+#define CHNL_VALN_FL_ENABLE 0x01
+#define CHNL_VALN_FL_DISABLE 0x00
+
+/* vlan id invalid */
+#define VLAN_ID_VALID 0x01
+#define VLAN_ID_INVALID 0x00
+
+/* ncsi_get_controller_packet_statistics_config */
+#define NO_INFORMATION_STATISTICS 0xff
+
+/**
+ * @brief ncsi set vlan filter command (0x0B) struct defination
+ * @see NCSI_SET_VLAN_FILTER
+ *
+ */
+typedef struct tg_set_vlan_filter {
+ u8 reserved1[2]; /**< set vlan filter command reserved1 */
+#ifdef BD_BIG_ENDIAN
+ u8 user_priority : 4; /**< set vlan filter command user priority */
+ u8 vlan_id_hi : 4; /**< set vlan filter command vlan id high */
+#else
+ u8 vlan_id_hi : 4; /**< set vlan filter command vlan id high */
+ u8 user_priority : 4; /**< set vlan filter command user priority */
+#endif
+ u8 vlan_id_low; /**< set vlan filter command vlan id low */
+ u8 reserved2[2]; /**< set vlan filter command reserved2 */
+ u8 filter; /**< set vlan filter command filter */
+#ifdef BD_BIG_ENDIAN
+ u8 reserved3 : 7; /**< set vlan filter command reserved3 */
+ u8 enable : 1; /**< set vlan filter command enable */
+#else
+ u8 enable : 1; /**< set vlan filter command enable */
+ u8 reserved3 : 7; /**< set vlan filter command reserved3 */
+#endif
+ u32 check_sum; /**< set vlan filter command check sum */
+} set_vlan_filter_s, *p_set_vlan_filter_s;
+/* Set Vlan Filter Response (0x8B) */
+/**
+ * @brief ncsi set vlan filter response (0x8B) struct defination
+ * @see NCSI_SET_VLAN_FILTER_RSP
+ *
+ */
+typedef struct tg_set_vlan_filter_rsp {
+ u16 rsp_code; /**< set vlan filter response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< set vlan filter response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< set vlan filter response check sum */
+} set_vlan_filter_rsp_s, *p_set_vlan_filter_rsp_s;
+
+/* Enable VLAN Command (0x0C) */
+
+/* channel对应的某个vlan filter的寄存器 */
+#define VLAN_REG_ADDR(chan_id, filter_selector) \
+ (CSR_IPSURX_CSR_IPSURX_NCSI_VLAN7_CTRL_0_REG + (chan_id)*4 + \
+ (VLAN_FL_MAX_ID - (filter_selector)) * 16)
+
+/**
+ * @brief ncsi enable vlan command (0x0C) struct defination
+ * @see NCSI_ENABLE_VLAN
+ *
+ */
+typedef struct tg_enable_vlan {
+ u8 reserved[3]; /**< enable vlan command reserved */
+ u8 vlan_mode; /**< enable vlan command vlan mode */
+ u32 check_sum; /**< enable vlan command check sum */
+} enable_vlan_s, *p_enable_vlan_s;
+/* Enable VLAN Response (0x8C) */
+/**
+ * @brief ncsi enable vlan response (0x8C) struct defination
+ * @see NCSI_ENABLE_VLAN_RSP
+ *
+ */
+typedef struct tg_enable_vlan_rsp {
+ u16 rsp_code; /**< enable vlan response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< enable vlan response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< enable vlan response check sum */
+} enable_vlan_rsp_s, *p_enable_vlan_rsp_s;
+
+/* Disable VLAN Command (0x0D) */
+/**
+ * @brief ncsi disable VLAN command (0x0D) struct defination
+ * @see NCSI_DISABLE_VLAN
+ *
+ */
+typedef struct tg_disable_vlan {
+ u32 check_sum; /**< disable vlan command check sum */
+} disable_vlan_s, *p_disable_vlan_s;
+/* Disable VLAN Response (0x8D) */
+/**
+ * @brief ncsi disable VLAN response (0x8D) struct defination
+ * @see NCSI_DISABLE_VLAN_RSP
+ *
+ */
+typedef struct tg_disable_vlan_rsp {
+ u16 rsp_code; /**< disable vlan response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< disable vlan response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< disable vlan response check sum */
+} disable_vlan_rsp_s, *p_disable_vlan_rsp_s;
+
+/* get MAC Address 0x0E */
+
+#define UNICAST_ADDRESS_TYPE (0x0)
+#define MULTICAST_ADDRESS_TYPE (0x1)
+
+/**
+ * @brief ncsi get MAC Address command (0x0E) struct defination
+ * @see NCSI_SET_MAC_ADDRESS
+ *
+ */
+typedef struct tg_set_mac_address {
+ u8 mac_filter5; /**< set MAC Address command mac filter5 */
+ u8 mac_filter4; /**< set MAC Address command mac filter4 */
+ u8 mac_filter3; /**< set MAC Address command mac filter3 */
+ u8 mac_filter2; /**< set MAC Address command mac filter2 */
+ u8 mac_filter1; /**< set MAC Address command mac filter1 */
+ u8 mac_filter0; /**< set MAC Address command mac filter0 */
+ u8 mac_number; /**< set MAC Address command mac number */
+#ifdef BD_BIG_ENDIAN
+ u8 address_type : 3; /**< set MAC Address command address type */
+ u8 reserved : 4; /**< set MAC Address command reserved */
+ u8 mac_enable : 1; /**< set MAC Address command mac enable */
+#else
+ u8 mac_enable : 1; /**< set MAC Address command mac enable */
+ u8 reserved : 4; /**< set MAC Address command reserved */
+ u8 address_type : 3; /**< set MAC Address command address type */
+#endif
+ u32 check_sum; /**< set MAC Address command check sum */
+} set_mac_address_s, *p_set_mac_address_s;
+/* set MAC Address response (0x8E) */
+/**
+ * @brief ncsi get MAC Address response (0x8E) struct defination
+ * @see NCSI_SET_MAC_ADDRESS_RSP
+ *
+ */
+typedef struct tg_set_mac_address_rsp {
+ u16 rsp_code; /**< set MAC Address response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< set MAC Address response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< set MAC Address response check sum */
+} set_mac_address_rsp_s, *p_set_mac_address_rsp_s;
+
+/* Enable BC Filter Command (0x10) */
+
+typedef union {
+ struct {
+#ifdef BD_BIG_ENDIAN
+ u32 reserved1 : 28; /**< boradcast filter reserved1 */
+ u32 netbios_packet : 1; /**< boradcast filter netbios packet, This field is optional */
+ u32 dhcp_server_packet : 1; /**< boradcast filter dhcp server packet, This field is optional */
+ u32 dhcp_client_packet : 1; /**< boradcast filter dhcp client packet, This field is optional */
+ u32 arp_packet : 1; /**< boradcast filter arp packet, This field is mandatory */
+#else
+ u32 arp_packet : 1; /**< boradcast filter arp packet, This field is mandatory */
+ u32 dhcp_client_packet : 1; /**< boradcast filter dhcp client packet, This field is optional */
+ u32 dhcp_server_packet : 1; /**< boradcast filter dhcp server packet, This field is optional */
+ u32 netbios_packet : 1; /**< boradcast filter netbios packet, This field is optional */
+ u32 reserved1 : 28; /**< boradcast filter reserved1 */
+#endif
+ } bits;
+ u32 val32;
+} boradcast_filter, *p_boradcast_filter;
+
+/**
+ * @brief ncsi enable broadcast filter command (0x10) struct defination
+ * @see NCSI_ENABLE_BROADCAST_FILTERING
+ *
+ */
+typedef struct tg_enable_broadcast {
+ boradcast_filter
+ brd_filter; /**< enable broadcast filter command boradcast filter */
+ u32 check_sum; /**< enable broadcast filter command check sum */
+} enable_broadcast_s, *p_enable_broadcast_s;
+/**
+ * @brief enable broadcast filter response (0x90) struct defination
+ * @see NCSI_ENABLE_BROADCAST_FILTERING_RSP
+ *
+ */
+typedef struct tg_enable_broadcast_rsp {
+ u16 rsp_code; /**< enable broadcast filter response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< enable broadcast filter response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< enable broadcast filter response check sum */
+} enable_broadcast_rsp_s, *p_enable_broadcast_rsp_s;
+
+/* disbale broadcast filter command(0x11) */
+/**
+ * @brief ncsi disbale broadcast filter command(0x11) struct defination
+ * @see NCSI_DISABLE_BROADCAST_FILTERING
+ *
+ */
+typedef struct tg_disable_broadcast {
+ u32 check_sum; /**< disable broadcast filter response check sum */
+} disable_broadcast_s, *p_disable_broadcast_s;
+/**
+ * @brief ncsi disbale broadcast filter response(0x91) struct defination
+ * @see NCSI_DISABLE_BROADCAST_FILTERING_RSP
+ *
+ */
+typedef struct tg_disable_broadcast_rsp {
+ u16 rsp_code; /**< disable broadcast filter response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< disable broadcast filter response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< disable broadcast filter response check sum */
+} disable_broadcast_rsp_s, *p_disable_broadcast_rsp_s;
+
+/* Enable Global Multicast Filter Command (0x12) */
+
+typedef union {
+ struct tg_multicast_packet_filter {
+#ifdef BD_BIG_ENDIAN
+ u8 reserved1[3]; /**< multicast packet filter reserved1 */
+ u8 reserved2 : 2; /**< multicast packet filter reserved2 */
+ u8 IPv6_Neighbor_Solicitation : 1; /**< multicast packet IPv6 Neighbor Solicitation */
+ u8 IPv6_MLD : 1; /**< multicast packet IPv6 MLD */
+ u8 DHCPv6_multicasts_from_server_to_clients : 1; /**< multicast packet DHCPv6 multicasts from server to clients
+ * listening on well-known UDP ports */
+ u8 DHCPv6_relay_and_server_multicast : 1; /**< multicast packet DHCPv6 relay and server multicast */
+ u8 IPv6_router_advertisement : 1; /**< multicast packet IPv6 router advertisement */
+ u8 IPv6_neighbor_advertisement : 1; /**< multicast packet IPv6 neighbor advertisement */
+#else
+ u8 IPv6_neighbor_advertisement : 1; /**< multicast packet IPv6 neighbor advertisement */
+ u8 IPv6_router_advertisement : 1; /**< multicast packet IPv6 router advertisement */
+ u8 DHCPv6_relay_and_server_multicast : 1; /**< multicast packet DHCPv6 relay and server multicast */
+ u8 DHCPv6_multicasts_from_server_to_clients : 1; /**< multicast packet DHCPv6 multicasts from server to clients
+ * listening on well-known UDP ports */
+ u8 IPv6_MLD : 1; /**< multicast packet IPv6 MLD */
+ u8 IPv6_Neighbor_Solicitation : 1; /**< multicast packet IPv6 Neighbor Solicitation */
+ u8 reserved2 : 2; /**< multicast packet filter reserved2 */
+ u8 reserved1[3]; /**< multicast packet filter reserved1 */
+#endif
+ } bits;
+ u32 val32;
+} multicast_packet_filter, *p_multicast_packet_filter;
+
+/**
+ * @brief ncsi enable global multicast filter command(0x12) struct defination
+ * @see NCSI_ENABLE_GLOBAL_MULTICAST_FILTERING
+ *
+ */
+typedef struct tg_enable_multicast {
+ multicast_packet_filter
+ multicast_filter; /**< enable global multicast filter command multicast packet filter */
+ u32 check_sum; /**< enable global multicast filter command check sum */
+} enable_multicast_s, *p_enable_multicast_s;
+
+/**
+ * @brief ncsi enable global multicast filter response(0x92) struct defination
+ * @see NCSI_ENABLE_GLOBAL_MULTICAST_FILTERING_RSP
+ *
+ */
+typedef struct tg_enable_multicast_rsp {
+ u16 rsp_code; /**< enable global multicast filter response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< enable global multicast filter response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< enable global multicast filter response check sum */
+} enable_multicast_rsp_s, *p_enable_multicast_rsp_s;
+
+/* Disable Global Multicast Filter Command (0x13) */
+/**
+ * @brief ncsi disable global multicast filter command(0x13) struct defination
+ * @see NCSI_ENABLE_GLOBAL_MULTICAST_FILTERING
+ *
+ */
+typedef struct tg_disable_multicast {
+ u32 check_sum; /**< disable global multicast filter command check sum */
+} disable_multicast_s, *p_disable_multicast_s;
+/**
+ * @brief ncsi disable global multicast filter response(0x93) struct defination
+ * @see NCSI_DISABLE_GLOBAL_MULTICAST_FILTERING_RSP
+ *
+ */
+typedef struct tg_disable_multicast_rsp {
+ u16 rsp_code; /**< disable global multicast filter response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< disable global multicast filter response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< disable global multicast filter response check sum */
+} disable_multicast_rsp_s, *p_disable_multicast_rsp_s;
+
+/* ncsi flow control (0x14) */
+/**
+ * @brief ncsi set ncsi flow control command(0x14) struct defination
+ * @see NCSI_SET_NCSI_FLOW_CONTROL
+ *
+ */
+typedef struct tg_set_flow_control {
+ u8 reserved[3]; /**< set flow control command reserved */
+ u8 flow_control_enable; /**< set flow control command flow control enable */
+ u32 check_sum; /**< set flow control command check sum */
+} set_flow_control_s, *p_set_flow_control_s;
+/**
+ * @brief ncsi set ncsi flow control response(0x94) struct defination
+ * @see NCSI_SET_NCSI_FLOW_CONTROL_RSP
+ *
+ */
+typedef struct tg_set_flow_control_rsp {
+ u16 rsp_code; /**< set flow control response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< set flow control response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< set flow control response check sum */
+} set_flow_control_rsp_s, *p_set_flow_control_rsp_s;
+
+/* Get Version ID Command (0x15) */
+/* fw_name的最大值 */
+#define FW_NAME_MAX_SIZE (12)
+/**
+ * @brief ncsi get version id command(0x15) struct defination
+ * @see NCSI_GET_VERSION_ID
+ *
+ */
+typedef struct tg_get_version_id {
+ u32 check_sum; /**< get version id command check sum */
+} get_version_id_s, *p_get_version_id_s;
+/**
+ * @brief ncsi get version id response(0x95) struct defination
+ * @see NCSI_GET_VERSION_ID_RSP
+ *
+ */
+typedef struct tg_get_version_id_rsp {
+ u16 rsp_code; /**< get version id response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get version id response reason code */
+ u8 pl_major; /**< get version id response pl major */
+ u8 pl_minor; /**< get version id response pl minor */
+ u8 update; /**< get version id response update */
+ u8 alpha1; /**< get version id response alpha1 */
+ u8 reserved[3]; /**< get version id response reserved */
+ u8 alpha2; /**< get version id response alpha2 */
+ u8 name_string[FW_NAME_MAX_SIZE]; /**< get version id response name_string
+ * BIG_ENDIAN, The first byte received is the first byte of the string. */
+ u8 ms_byte3; /**< get version id response ms byte3 */
+ u8 byte2; /**< get version id response byte2 */
+ u8 byte1; /**< get version id response byte1 */
+ u8 ls_byte0; /**< get version id response ls byte0 */
+ u16 pci_did; /**< get version id response pci did */
+ u16 pci_vid; /**< get version id response pci vid */
+ u16 pci_ssid; /**< get version id response pci ssid */
+ u16 pci_svid; /**< get version id response pci svid */
+ u32 manufacturer_id; /**< get version id response manufacturer id
+ * This field is unused, the value shall be set to 0xFFFFFFFF */
+ u32 check_sum; /**< get version id response check sum */
+} get_version_id_rsp_s, *p_get_version_id_rsp_s;
+
+/* get_capabilities: 0x16 */
+/**
+ * @brief ncsi get capabilities command(0x16) struct defination
+ * @see NCSI_GET_CAPABILITIES
+ *
+ */
+typedef struct tg_get_capabilities {
+ u32 check_sum; /**< get capabilities command check sum */
+} get_capabilities_s, *p_get_capabilities_s;
+
+/* NCSI channel capabilities */
+typedef struct tag_ncsi_chan_capa {
+ u32 capa_flags; /**< NCSI channel capabilities capa flags */
+ u32 bcast_filter; /**< NCSI channel capabilities bcast filter */
+ u32 multicast_filter; /**< NCSI channel capabilities multicast filter */
+ u32 buffering; /**< NCSI channel capabilities buffering */
+ u32 aen_ctrl; /**< NCSI channel capabilities aen ctrl */
+ u8 vlan_count; /**< NCSI channel capabilities vlan count */
+ u8 mixed_count; /**< NCSI channel capabilities mixed count */
+ u8 multicast_count; /**< NCSI channel capabilities multicast count */
+ u8 unicast_count; /**< NCSI channel capabilities unicast count */
+ u16 rsvd; /**< NCSI channel capabilities reserved */
+ u8 vlan_mode; /**< NCSI channel capabilities vlan mode */
+ u8 chan_count; /**< NCSI channel capabilities channel count */
+} ncsi_chan_capa_s;
+/**
+ * @brief ncsi get capabilities response(0x96) struct defination
+ * @see NCSI_GET_CAPABILITIES_RSP
+ *
+ */
+typedef struct tg_get_capabilities_rsp {
+ u16 rsp_code; /**< get capabilities response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get capabilities response reason code @see enum NCSI_REASON_CODE_E */
+ ncsi_chan_capa_s
+ chan_capabilities; /**< get capabilities response channel capabilities */
+ u32 check_sum; /**< get capabilities response check sum */
+} get_capabilities_rsp_s, *p_get_capabilities_rsp_s;
+
+/* get parameters(0x17) */
+/**
+ * @brief ncsi get parameters command(0x17) struct defination
+ * @see NCSI_GET_PARAMETERS
+ *
+ */
+typedef struct tg_get_parameters {
+ u32 check_sum; /**< get parameters command check sum */
+} get_parameters_s, *p_get_parameters_s;
+
+typedef struct ncsi_parameters {
+ u8 mac_address_count;
+ u8 reserved1[2];
+ u8 mac_address_flags;
+ u8 vlan_tag_count;
+ u8 reserved2;
+ u16 vlan_tag_flags;
+ u32 link_settings;
+ u32 broadcast_packet_filter_settings;
+ u8 broadcast_packet_filter_status : 1;
+ u8 channel_enable : 1;
+ u8 channel_network_tx_enable : 1;
+ u8 global_mulicast_packet_filter_status : 1;
+ u8 config_flags_reserved1 : 4; /**< bit0-3:mac_add0——mac_add3 address type:0 unicast,1 multileaving */
+ u8 config_flags_reserved2[3];
+ u8 vlan_mode; /**< current vlan mode */
+ u8 flow_control_enable;
+ u16 reserved3;
+ u32 AEN_control;
+ u8 mac_add[4][6];
+ u16 vlan_tag[8];
+} ncsi_parameters_s;
+
+/**
+ * @brief ncsi get parameters response(0x97) struct defination
+ * @see NCSI_GET_PARAMETERS_RSP
+ *
+ */
+typedef struct tg_get_parameters_rsp {
+ u16 rsp_code; /**< get parameters response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get parameters response reason code @see enum NCSI_REASON_CODE_E */
+ ncsi_parameters_s
+ parameters; /**< get parameters response ncsi parameters */
+ u32 check_sum;
+} get_parameters_rsp_s, *p_get_parameters_rsp_s;
+
+/* get current packet statistics for the Ethernet Controller(0x18) */
+/**
+ * @brief ncsi get controller packet statistics command(0x18) struct defination
+ * @see NCSI_GET_CONTROLLER_PACKET_STATISTICS
+ *
+ */
+typedef struct tg_get_packet_statistics {
+ u32 check_sum;
+} get_packet_statistics_s, *p_get_packet_statistics_s;
+
+typedef struct tg_controller_packet_statistics {
+ u32 counter_cleared_from_last_read_MS;
+ u32 counter_cleared_from_last_read_LS;
+ u64 total_bytes_received;
+ u64 total_bytes_transmitted;
+ u64 total_unicast_packets_received;
+ u64 total_multicast_packets_received;
+ u64 total_broadcast_packets_received;
+ u64 total_unicast_packets_transmitted;
+ u64 total_multicast_packets_transmitted;
+ u64 total_broadcast_packets_transmitted;
+ u32 FCS_receive_errors;
+ u32 alignment_errors;
+ u32 false_carrier_detections;
+ u32 runt_packets_received;
+ u32 jabber_packets_received;
+ u32 pause_XON_frames_received;
+ u32 pause_XOFF_frames_received;
+ u32 pause_XON_frames_transmitted;
+ u32 pause_XOFF_frames_transmitted;
+ u32 single_collision_transmit_frames;
+ u32 multiple_collision_transmit_frames;
+ u32 late_collision_frames;
+ u32 excessive_collision_frames;
+ u32 control_frames_received;
+ u32 B64_frames_received;
+ u32 B65_127_frames_received;
+ u32 B128_255_frames_received;
+ u32 B256_511_frames_received;
+ u32 B512_1023_frames_received;
+ u32 B1024_1522_frames_received;
+ u32 B1523_9022_frames_received;
+ u32 B64_frames_transmitted;
+ u32 B65_127_frames_transmitted;
+ u32 B128_255_frames_transmitted;
+ u32 B256_511_frames_transmitted;
+ u32 B512_1023_frames_transmitted;
+ u32 B1024_1522_frames_transmitted;
+ u32 B1523_9022_frames_transmitted;
+ u64 valid_bytes_received;
+ u32 error_runt_packets_received;
+ u32 error_jabber_packets_received;
+} controller_packet_statistics, *p_controller_packet_statistics;
+/**
+ * @brief ncsi get controller packet statistics response(0x98) struct defination
+ * @see NCSI_GET_CONTROLLER_PACKET_STATISTICS_RSP
+ *
+ */
+typedef struct tg_get_packet_statistics_rsp {
+ u16 rsp_code;
+ u16 reason_code;
+ controller_packet_statistics pkt_statistics;
+ u32 check_sum;
+} get_packet_statistics_rsp_s, *p_get_packet_statistics_rsp_s;
+
+/* request the packet statistics specific to the NC-SI (0x19) */
+/**
+ * @brief request the packet statistics specific to the NC-SI command(0x19) struct defination
+ * @see NCSI_GET_NCSI_STATISTICS
+ *
+ */
+typedef struct tg_get_ncsi_statistics {
+ u32 check_sum;
+} get_ncsi_statistics_s, *p_get_ncsi_statistics_s;
+/**
+ * @brief request the packet statistics specific to the NC-SI response(0x99) struct defination
+ * @see NCSI_GET_NCSI_STATISTICS_RSP
+ *
+ */
+typedef struct tg_get_ncsi_statistics_rsp {
+ u16 rsp_code; /**< get ncsi statistics response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get ncsi statistics response reason code @see enum NCSI_REASON_CODE_E */
+ u32 ncsi_commands_received;
+ u32 ncsi_control_packets_dropped;
+ u32 ncsi_command_type_error;
+ u32 ncsi_command_checksun_errors;
+ u32 ncsi_receive_packets;
+ u32 ncsi_transmit_packets;
+ u32 aens_sent;
+ u32 check_sum;
+} get_ncsi_statistics_rsp_s, *p_get_ncsi_statistics_rsp_s;
+
+/* get inventory info (0x4E) */
+#define NCSI_INVERTORY_INFO_DADA_LEN 512
+#define NUMBER_OF_TLVS_LEN 1
+#define INVENTORY_TYPE_LEN 1
+#define INVENTORY_VALUE_LEN 1
+
+/* Inventory Type */
+typedef enum {
+ NCSI_MANUFACTURER = 0x0,
+ NCSI_PRODUCT_OR_MODEL = 0x1,
+ NCSI_INVENTORY_VERSION = 0x2,
+ NCSI_PART_NUMBER = 0x3,
+ NCSI_SERIAL_NUMBER = 0x4,
+ NCSI_MANUFACTURING_TIMESTAMP = 0x5,
+} inventory_type_e;
+
+/* request the inventory info (0x4E) */
+/**
+ * @brief request the inventory info command(0x4E) struct defination
+ * @see NCSI_GET_INVENTORY_INFO
+ *
+ */
+typedef struct tg_get_inventory_info {
+ u32 check_sum;
+} get_inventory_info_s, *p_get_inventory_info_s;
+/**
+ * @brief request the inventory info response(0xCE) struct defination
+ * @see NCSI_GET_INVENTORY_INFO_RSP
+ *
+ */
+typedef struct tg_get_inventory_info_rsp {
+ u16 rsp_code; /**< get inventory info response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get inventory info response reason code @see enum NCSI_REASON_CODE_E */
+ u8 data[NCSI_INVERTORY_INFO_DADA_LEN];
+ u32 check_sum;
+} get_inventory_info_rsp_s, *p_get_inventory_info_rsp_s;
+
+/* request NC-SI Pass-through packet statistics(0x1A) */
+/**
+ * @brief request NC-SI Pass-through packet statistics command(0x1A) struct defination
+ * @see NCSI_GET_PASSTHOUGH_STATISTICS
+ *
+ */
+typedef struct tg_get_passthrough_statistics {
+ u32 check_sum;
+} get_passthrough_statistics_s, *p_get_passthrough_statistics_s;
+/**
+ * @brief request NC-SI Pass-through packet statistics response(0x9A) struct defination
+ * @see NCSI_GET_PASSTHOUGH_STATISTICS_RSP
+ *
+ */
+typedef struct tg_get_passthrough_statistics_rsp {
+ u16 rsp_code; /**< get passthrough statisticse response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get passthrough statisticse response @see enum NCSI_REASON_CODE_E */
+ u64 pass_through_TX_received;
+ u32 pass_through_TX_dropped;
+ u32 pass_through_TX_channel_state_error;
+ u32 pass_through_TX_packet_undersized_error;
+ u32 pass_through_TX_packet_oversized_error;
+ u32 pass_through_RX_received;
+ u32 pass_through_RX_dropped;
+ u32 pass_through_RX_packet_channel_state_errors;
+ u32 pass_through_RX_packet_undersized_error;
+ u32 pass_through_RX_packet_oversized_error;
+ u32 check_sum;
+} get_passthrough_statistics_rsp_s, *p_get_passthrough_statistics_rsp_s;
+
+/* OEM:get channel state (0X1B) */
+/**
+ * @brief ncsi get channel state command(0X1B) struct defination
+ * @see NCSI_GET_CHANNEL_STATE
+ *
+ */
+typedef struct tg_get_channel_state {
+ u32 check_sum;
+} get_channel_state_s, *p_get_channel_state_s;
+
+/**
+ * @brief ncsi get channel state response(0X9B) struct defination
+ * @see NCSI_GET_CHANNEL_STATE_RSP
+ *
+ */
+typedef struct tg_get_channel_state_rsp {
+ u16 rsp_code; /**< get channel state response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get channel state response reason code @see enum NCSI_REASON_CODE_E */
+ u32 channel_state; /**< get channel state response channel state */
+ u32 check_sum; /**< get channel state response check sum */
+} get_channel_state_rsp_s, *p_get_channel_state_rsp_s;
+
+/* get regiset value (0X1C) */
+/**
+ * @brief ncsi get register value command(0X1C) struct defination
+ * @see NCSI_GET_REGISTER_VALUE
+ *
+ */
+typedef struct tg_get_register_value {
+ u32 base_address;
+ u32 offset_address;
+ u32 module;
+ u32 check_sum;
+} get_register_value_s, *p_get_register_value_s;
+
+/**
+ * @brief ncsi get regiset value response(0X9C) struct defination
+ * @see NCSI_GET_REGISTER_VALUE_RSP
+ *
+ */
+typedef struct tg_get_register_value_rsp {
+ u16 rsp_code; /**< get regiset value response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< get regiset value response reason code @see enum NCSI_REASON_CODE_E */
+ u32 register_value;
+ u32 check_sum;
+} get_register_value_rsp_s, *p_get_register_value_rsp_s;
+
+/* Set Fwd Act Cammand 0x1D */
+/**
+ * @brief ncsi Set Fwd Act command(0x1D) struct defination
+ * @see NCSI_SET_FWD_ACT
+ *
+ */
+typedef struct tg_set_fwd_act {
+ u8 reserved[3];
+ u8 fwd_mode;
+ u32 check_sum; /**< Set Fwd Act command check sum */
+} set_fwd_act_s, *p_set_fwd_act_s;
+/**
+ * @brief ncsi Set Fwd Act response(0x9D) struct defination
+ * @see NCSI_SET_FWD_ACT_RSP
+ *
+ */
+typedef struct tg_set_fwd_act_rsp {
+ u16 rsp_code; /**< Set Fwd Act response rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< Set Fwd Act response reason code @see enum NCSI_REASON_CODE_E */
+ u32 check_sum; /**< Set Fwd Act response check sum */
+} set_fwd_act_rsp_s, *p_set_fwd_act_rsp_s;
+
+/* NCSI OEM命令新增错误原因码 */
+typedef enum {
+ OEM_MANUFAC_ID_ERROR =
+ 0x8001, /**< 内部标识用,不回填reason code到rsp packet */
+ OEM_CMD_HEAD_INFO_INVALID = 0x8002,
+ OEM_GET_INFO_FAILED = 0x8003,
+ OEM_ERR_CODE_NUM_OVER = 0x8004,
+ OEM_ERR_UP_GET_DRIVER_INFO_FAILED = 0x8005,
+ OEM_CABLE_TYPE_NOT_SUPPORT = 0x8006,
+ OEM_CABLE_TYPE_UNDEF = 0x8007,
+ OEM_OPTICAL_MODULE_ABS = 0x8008,
+ OEM_ENABLE_LLDP_CAPTURE_FAILED = 0x8009,
+ /* 0x9000~0xFFFF用作ncsi标准命令新增的oem reason code */
+ OEM_GET_CONTROLLER_STATISTIC_FAILED =
+ 0x9000, /**< 网卡统计信息获取失败reason code */
+ OEM_ENABLE_LLDP_OVER_NCSI_FAILED = 0x9001,
+ OEM_GET_LLDP_OVER_NCSI_STATUS_FAILED = 0x9002
+} NCSI_OEM_REASON_CODE_E;
+
+/* ncsi oem命令相关 */
+/* ncsi oem命令公共头 */
+typedef struct tg_ncsi_oem_cmd_head {
+ u32 manufac_id; /**< 厂商id,huawei(0x07db) */
+ u8 cmd_rev;
+ u8 hw_cmd_id; /**< cmd号 */
+ u8 sub_cmd_id; /**< 子cmd号 */
+ u8 index; /**< index:只针对关注pf_id的命令有效(除了获取日志0x12命令代表获取日志类型),其余情况看做rsv字段 */
+} ncsi_oem_cmd_head_s;
+
+/* ncsi oem命令响应包payload公共部分(包含payload前12Bytes) */
+typedef struct tg_ncsi_oem_rsp_payload_comm {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+} ncsi_oem_rsp_payload_comm_s;
+
+/* ncsi oem命令请求包 */
+/**
+ * @brief ncsi oem command(0x50) struct defination
+ * @see NCSI_OEM_COMMAND
+ *
+ */
+typedef struct tg_ncsi_oem_cmd_req {
+ ncsi_oem_cmd_head_s oem_head; /**< oem command header */
+ u32 check_sum;
+} ncsi_oem_cmd_req_s;
+
+#define OEM_PROC_FAILED_RSP_LEN \
+ (4) /* oem命令内部处理失败后给bmc侧返回包payload大小 */
+/* oem命令内部处理失败后给bmc侧返回包结构 */
+typedef struct tg_oem_proc_failed_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ u32 check_sum; /**< check sum */
+} oem_proc_failed_rsp_s;
+
+/**
+ * @brief oem get network interface bdf response(huawei_id:0x0, sub_id:0x1) struct defination
+ * @see OEM_GET_NETWORK_INTERFACE_BDF
+ *
+ */
+typedef struct tg_oem_get_bdf_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 rsvd;
+ u8 bus; /**< bus id */
+ u8 device; /**< device id */
+ u8 function; /**< function id */
+ u32 check_sum; /**< check sum */
+} oem_get_bdf_rsp_s;
+
+/* get the pcie interface ability(huawei_id:0x0, sub_id:0x5) */
+#define OEM_GET_PCIE_ABILITY_RSP_LEN (16)
+/**
+ * @brief oem get the pcie interface ability response(huawei_id:0x0, sub_id:0x5) struct defination
+ * @see OEM_GET_PCIE_ABILITY
+ *
+ */
+typedef struct tg_oem_get_pcie_ability_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 pcie_link_width; /**< pcie link width */
+ u8 pcie_link_speed; /**< pcie link speed */
+ u8 rsv[2];
+ u32 check_sum; /**< check sum */
+} oem_get_pcie_ability_rsp_s;
+
+/* get the pcie interface status(huawei_id:0x0, sub_id:0x6) */
+#define OEM_GET_PCIE_STATUS_RSP_LEN (16)
+/**
+ * @brief oem get the pcie interface status(huawei_id:0x0, sub_id:0x6) struct defination
+ * @see OEM_GET_PCIE_STATUS
+ *
+ */
+typedef struct tg_oem_get_pcie_status_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 pcie_link_width; /**< pcie link width */
+ u8 pcie_link_speed; /**< pcie link speed */
+ u8 rsv[2];
+ u32 check_sum; /**< check sum */
+} oem_get_pcie_status_rsp_s;
+
+/* get the network interface media type(huawei_id:0x0, sub_id:0x9) */
+#define OEM_GET_NETWORK_INTERFACE_MEDIA_TYPE_SP_LEN (16)
+/**
+ * @brief oem get network interface media type response(huawei_id:0x0, sub_id:0x9) struct defination
+ * @see OEM_GET_NETWORK_INTERFACE_MEDIA_TYPE
+ *
+ */
+typedef struct tag_oem_get_network_interface_media_type_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command heade */
+ u8 media_type; /**< 0x0: Fiber(BASE-SR/LR/ER),0x1:DAC(BASE-CR),0x2:Copper(BASE-T/RJ45),0x3:Backplane(BASE-KR) */
+ u8 rsv[3];
+ u32 check_sum; /**< check sum */
+} oem_get_network_interface_media_type_rsp_s;
+
+/* get the junction temperature(huawei_id:0x0, sub_id:0x0a) */
+#define OEM_GET_JUNCTION_TEMP_RSP_LEN (16)
+/**
+ * @brief oem get the junction temperature response(huawei_id:0x0, sub_id:0x0a) struct defination
+ * @see OEM_GET_JUNCTION_TEMP
+ *
+ */
+typedef struct tag_oem_get_junction_temp_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u16 junction_temp; /**< junction temperature */
+ u8 rsv[2];
+ u32 check_sum; /**< check sum */
+} oem_get_junction_temp_rsp_s;
+
+/* get the optical module temperature(huawei_id:0x0, sub_id:0x0b) */
+/**
+ * @brief oem get the optical module temperature response(huawei_id:0x0, sub_id:0x0b) struct defination
+ * @see OEM_GET_OPTICAL_MODULE_TEMP
+ *
+ */
+#define OEM_GET_OPT_MODU_TEMP_RSP_LEN (16)
+typedef struct tag_oem_get_opt_modu_temp_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u16 opt_modu_temp; /**< optical module temperature */
+ u8 rsv[2];
+ u32 check_sum; /**< check sum */
+} oem_get_opt_modu_temp_rsp_s;
+
+/* get the err code(huawei_id:0x0, sub_id:0x0c) */
+#define NCSI_OEM_ERR_CODE_MAX_NUM (80) /* 上报错误码最大数目,当前定义为80 */
+#define OEM_GET_ERR_CODE_RSP_LEN (36)
+/**
+ * @brief oem get the err code response(huawei_id:0x0, sub_id:0x0c) struct defination
+ * @see OEM_GET_ERR_CODE
+ *
+ */
+typedef struct tag_oem_get_err_code_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 health_status; /**< Health status (0: normal; 1: minor; 2: major; 3: critical) */
+ u8 err_code_count; /**< error code count */
+ u16 err_code[NCSI_OEM_ERR_CODE_MAX_NUM]; /**< Error code array. The size is an odd number and must be 4-byte aligned. */
+ u32 check_sum; /**< check sum */
+} oem_get_err_code_rsp_s;
+
+/* get the transceiver or cable information(huawei_id:0x0, sub_id:0x0d) */
+#define OEM_GET_CABLE_INFO_RSP_LEN (120)
+#define PART_NUM_MAX_LEN (16)
+#define MPU_VENDOR_MAX_LEN (16)
+#define SERIAL_NUM_MAX_LEN (16)
+#define CABLE_INFO_UNSUPPORTED16 (0xFFFF)
+#define CABLE_INFO_UNSUPPORTED8 (0xFF)
+
+#define QSFP_WAVE_LENGTH_DIVIDER (20)
+/**
+ * @brief oem get the transceiver or cable information response(huawei_id:0x0, sub_id:0x0d) struct defination
+ * @see OEM_GET_NETWORK_INTERFACE_TRANS_CABLE_INFO
+ *
+ */
+typedef struct tag_oem_get_trans_or_cable_info_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+
+ u8 device_part_number[PART_NUM_MAX_LEN]; /**< 设备part_number */
+ u8 device_vendor[MPU_VENDOR_MAX_LEN]; /**< 设备厂商 */
+ u8 device_serial_number[SERIAL_NUM_MAX_LEN]; /**< 设备序列号 */
+
+ u8 device_identifier; /**< 设备识别SFP+/QSFP+/SFP28/QSFP28 */
+ u8 device_type; /**< 设备类型(SR/LR/CR_Passive/CR_Active/SR4/LR4/CR4_Passive/CR4_Active) */
+ u8 device_connect_type; /**< 设备连接类型(LC/MPO/DAC/RJ45) */
+ u8 rsv;
+
+ u16 device_trans_distance; /**< 设备传输距离 */
+ u16 device_wavelen; /**< 设备波长 */
+
+ u16 work_para_temp; /**< 工作温度 */
+ u16 work_para_voltage; /**< 工作电压 */
+ u16 work_para_tx_bias_current; /**< tx电流 */
+ u16 work_para_tx_power; /**< tx功率 */
+ u16 work_para_rx_power; /**< rx功率 */
+ u16 warn_threshold_low_temp; /**< 低温告警阈值 */
+ u16 warn_threshold_high_temp; /**< 高温告警阈值 */
+ u16 warn_threshold_tx_power; /**< tx功率告警阈值 */
+ u16 warn_threshold_rx_power; /**< rx功率告警阈值 */
+ u16 alarm_threshold_low_temp; /**< 低温警报阈值 */
+ u16 alarm_threshold_high_temp; /**< 低温警报阈值 */
+ u16 alarm_threshold_tx_power; /**< tx功率警报阈值 */
+ u16 alarm_threshold_rx_power; /**< rx功率警报阈值 */
+ u8 rx_los_state;
+ u8 tx_fult_state;
+
+ u8 rsv1[24];
+
+ u32 check_sum; /**< check sum */
+} oem_get_trans_or_cable_info_rsp_s;
+
+/* enable LLDP capture(huawei_id:0x0, sub_id:0x0e) */
+#define OEM_ENABLE_LLDP_CAPTURE_RSP_LEN (12)
+/**
+ * @brief oem enable LLDP capture response(0xe) struct defination
+ * @see OEM_ENABLE_LLDP_CAPTURE
+ *
+ */
+typedef struct tag_oem_enable_lldp_capture_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+
+ u32 check_sum; /**< check sum */
+} oem_enable_lldp_capture_rsp_s;
+
+/* get lldp capbility(huawei_id:0x0, sub_id:0x0f) */
+#define OEM_GET_LLDP_CAPBILITY_RSP_LEN (16)
+/**
+ * @brief oem get lldp capbility response(huawei_id:0x0, sub_id:0x0f) struct defination
+ * @see OEM_GET_LLDP_CAPBILITY
+ *
+ */
+typedef struct tag_oem_get_lldp_capbility_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 capbility;
+ u8 rsv[3];
+ u32 check_sum; /**< check sum */
+} oem_get_lldp_capbility_rsp_s;
+
+/**
+ * @brief oem get lldp capbility response(huawei_id:0x0, sub_id:0x11) struct defination
+ * @see OEM_GET_HW_OEM_CMD_CAPABILITY (0x11)
+ *
+ */
+typedef struct tag_oem_get_oem_command_cap {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 check_sum; /**< check sum */
+} oem_get_oem_command_cap;
+
+/**
+ * @brief oem get oem command capbility response(huawei_id:0x0, sub_id:0x11) struct defination
+ * @see OEM_GET_HW_OEM_CMD_CAPABILITY (0x11)
+ * @see OEM_ENABLE_LOW_POWER_MODE (0x40C)
+ * @see OEM_GET_LOW_POWER_MODE_STATUS (0x40D)
+ * @see OEM_ENABLE_LLDP_OVER_NCSI (0x40A)
+ * @see OEM_GET_LLDP_OVER_NCSI_STATUS (0x40B)
+ *
+ */
+typedef struct tag_oem_get_oem_command_cap_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+
+ u32 bitmap; /**< Capability Bit Map
+ * bit0: Enable/disable low power consumption mode
+ * bit1: Get low power consumption mode
+ * bit2: Enable/disable LLDP forward over NCSI
+ * bit3: Get LLDP forward over NCSI status
+ * other bit: Reserved
+ */
+ u32 rsvd[13];
+ u32 check_sum; /**< check sum */
+} oem_get_oem_command_cap_resp;
+
+/* get lldp tx capbility(huawei_id:0x0, sub_id:0x13) */
+#define OEM_GET_LLDP_TX_CAPBILITY_RSP_LEN (16)
+/**
+ * @brief oem get lldp tx capbility response(huawei_id:0x0, sub_id:0x13) struct defination
+ * @see OEM_GET_LLDP_TX_CAPBILITY
+ *
+ */
+typedef struct tag_oem_get_lldp_tx_capbility_rsp {
+ u16 rsp_code;
+ u16 reason_code;
+ ncsi_oem_cmd_head_s ncsi_oem_head; /* oem cmd公共头 */
+ u8 capbility;
+ u8 rsv[3];
+ u32 check_sum;
+} oem_get_lldp_tx_capbility_rsp_s;
+
+/* enable LLDP capture(huawei_id:0x0, sub_id:0x14) */
+#define OEM_ENABLE_LLDP_TX_RSP_LEN (12)
+/**
+ * @brief oem enable lldp tx response(huawei_id:0x0, sub_id:0x14) struct defination
+ * @see OEM_ENABLE_LLDP_TX
+ *
+ */
+typedef struct tag_oem_enable_lldp_tx_rsp {
+ u16 rsp_code;
+ u16 reason_code;
+ ncsi_oem_cmd_head_s ncsi_oem_head; /* oem cmd公共头 */
+
+ u32 check_sum;
+} oem_enable_lldp_tx_rsp_s;
+
+typedef struct tag_oem_get_log_info_head {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 offset;
+ u32 len;
+ u32 check_sum; /**< check sum */
+} oem_get_log_head;
+
+#define OEM_GET_LOG_INFO_MAX_LEN (1024) // 一次性传输最大1024B
+#define OEM_GET_LOG_INFO_RSP_LEN (1036)
+/**
+ * @brief oem get log info response(huawei_id:0x0, sub_id:0x12) struct defination
+ * @see OEM_GET_LOG_INFO
+ *
+ */
+typedef struct tag_oem_get_log_info_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 log_data[OEM_GET_LOG_INFO_MAX_LEN];
+ u32 check_sum; /**< check sum */
+} oem_get_log_rsp;
+
+#define OEM_GET_NEW_LOG_CTRL_FRAME 0x5a5a5a5a
+#define OEM_GET_NEW_LOG_DATA_FRAME 0
+
+#define OEM_GET_NEW_LOG_REQ_PAYLD_LEN 20
+
+typedef struct {
+ ncsi_oem_cmd_head_s ncsi_oem_head;
+ u32 frame_type;
+ u32 offset;
+ u32 len;
+ u32 check_sum;
+} oem_get_new_log_req;
+
+typedef struct {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head;
+} oem_get_new_log_rsp_head;
+
+#define OEM_MAX_SUB_LOG_NUM (16)
+
+typedef struct {
+ oem_get_new_log_rsp_head head;
+ u32 total_len;
+ u8 sub_log_num;
+ u8 reserved;
+ u16 sub_log_len[OEM_MAX_SUB_LOG_NUM];
+ u32 check_sum;
+} oem_get_new_log_ctrl_frame_rsp;
+
+typedef struct {
+ oem_get_new_log_rsp_head head;
+ u8 last; // 最后一帧:1 非最后一帧: 0
+ u8 reserved[3];
+ u8 data[OEM_GET_LOG_INFO_MAX_LEN];
+ u32 checksum;
+} oem_get_new_log_data_frame_rsp;
+
+/**
+ * @brief oem enable lldp over ncsi command(0x40A) struct defination
+ * @see OEM_ENABLE_LLDP_OVER_NCSI
+ *
+ */
+typedef struct tag_oem_enable_lldp_over_ncsi {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 enable;
+ u8 rsvd[3];
+ u32 check_sum; /**< check sum */
+} oem_enable_lldp_over_ncsi;
+
+/**
+ * @brief oem enable lldp over ncsi response(0x40A) struct defination
+ * @see OEM_ENABLE_LLDP_OVER_NCSI
+ *
+ */
+typedef struct tag_oem_enable_lldp_over_ncsi_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 check_sum; /**< check sum */
+} oem_enable_lldp_over_ncsi_resp;
+
+/**
+ * @brief oem get lldp over ncsi status command(0x40B) struct defination
+ * @see OEM_GET_LLDP_OVER_NCSI_STATUS
+ *
+ */
+typedef struct tag_oem_get_lldp_over_ncsi_status {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 check_sum; /**< check sum */
+} oem_get_lldp_over_ncsi_status;
+
+/**
+ * @brief oem get lldp over ncsi status response(0x40B) struct defination
+ * @see OEM_GET_LLDP_OVER_NCSI_STATUS
+ *
+ */
+typedef struct tag_oem_get_lldp_over_ncsi_status_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 enable;
+ u8 rsvd[3];
+ u32 check_sum; /**< check sum */
+} oem_get_lldp_over_ncsi_status_resp;
+
+/**
+ * @brief oem enable low power mode command(0x40C) struct defination
+ * @see OEM_ENABLE_LOW_POWER_MODE
+ *
+ */
+typedef struct tag_oem_enable_low_power_mode {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem cmd公共头 */
+ u8 enable;
+ u8 rsvd[3];
+ u32 check_sum; /**< check sum */
+} oem_enable_low_power_mode;
+
+/**
+ * @brief oem oem enable low power mode response(0x40C) struct defination
+ * @see OEM_ENABLE_LOW_POWER_MODE
+ *
+ */
+typedef struct tag_oem_enable_low_power_mode_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 check_sum; /**< check sum */
+} oem_enable_low_power_mode_resp;
+
+/**
+ * @brief oem get low power mode status command(0x40D) struct defination
+ * @see OEM_GET_LOW_POWER_MODE_STATUS
+ *
+ */
+typedef struct tag_oem_get_low_power_mode_status {
+ ncsi_oem_cmd_head_s
+ ncsi_oem_head; /**< oem command header @see struct ncsi_oem_cmd_head_s */
+ u32 check_sum; /**< check sum */
+} oem_get_low_power_mode_status;
+
+/**
+ * @brief oem get low power mode status response(0x40D) struct defination
+ * @see OEM_GET_LOW_POWER_MODE_STATUS
+ *
+ */
+typedef struct tag_oem_get_low_power_mode_status_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 enable;
+ u8 rsvd[3];
+ u32 check_sum; /**< check sum */
+} oem_get_low_power_mode_status_resp;
+
+/* get the network interface mac addr(huawei_id:0x1, sub_id:0x00) */
+#define MAC_ADDRESS_LEN (6)
+#define OEM_GET_NETWORK_INTERFACE_MAC_ADDR_RSP_LEN (64)
+#define OEM_NETWORK_INTERFACE_MAC_ADDR_MAX_NUM \
+ (8) /* 数据结构中最多只呈现8个mac addr */
+/**
+ * @brief oem get netork interface mac addr response(0x100) struct defination
+ * @see OEM_GET_NETWORK_INTERFACE_MAC_ADDR
+ *
+ */
+typedef struct tag_oem_get_netork_interface_mac_addr_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u16 mac_addr_count; /**< mac_addr实际数目(可能不止8个,最多只显示8个) */
+ u8 rsv[2];
+ u8 mac_addr[MAC_ADDRESS_LEN *
+ OEM_NETWORK_INTERFACE_MAC_ADDR_MAX_NUM]; /* mac addr,必须确保4字节对齐 */
+
+ u32 check_sum; /**< check sum */
+} oem_get_netork_interface_mac_addr_rsp_s;
+
+/* get the network interface dcbx(huawei_id:0x1, sub_id:0x02) */
+#define OEM_GET_NETWORK_INTERFACE_DCBX_RSP_LEN (48)
+
+/**
+ * @brief oem get networ interface dcbx response(0x102) struct defination
+ * @see OEM_GET_NETWORK_INTERFACE_DCBX
+ *
+ */
+typedef struct tag_oem_get_network_interface_dcbx_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 up2cos[8]; /**< user_priority优先级到cos的映射关系 */
+ u8 up_pgid[8]; /**< DCB ETS的COS TC映射关系 */
+ u8 pgpct[8]; /**< tc之间的带宽比 */
+ u8 strict[8]; /**< 调度方式为SP还是DWRR */
+ u8 pfcmap; /**< dcb pfc使能和关闭状态 */
+ u8 rsv[3];
+
+ u32 check_sum; /**< check sum */
+} oem_get_network_interface_dcbx_rsp_s;
+
+#define OEM_PGPCT_TC_WGT_INDEX 100
+
+/* get dafault mac address(huawei_id:0x1, sub_id:0x04) */
+#define OEM_GET_DEFAULT_MAC_ADDR_RSP_LEN (64)
+#define OEM_DEFAULT_MAC_ADDRESS_MAX_COUNT (8) /* default mac地址最大数目 */
+#define PORT_DEFAULT_MAC_ADDR_MAX_SIZE \
+ (MAC_ADDRESS_NUM * OEM_DEFAULT_MAC_ADDRESS_MAX_COUNT)
+
+/**
+ * @brief oem get default mac addr response(0x104) struct defination
+ * @see OEM_GET_NETWORK_DEFAULT_MAC_ADDR
+ *
+ */
+typedef struct tag_oem_get_default_mac_addr_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 mac_count; /**< mac地址数目 */
+ u8 rsv[3];
+ u8 mac_addr[PORT_DEFAULT_MAC_ADDR_MAX_SIZE]; /**< default mac addr,必须确保4字节对齐 */
+
+ u32 check_sum; /**< check sum */
+} oem_get_default_mac_addr_rsp_s;
+
+/**
+ * @brief ncsi oem set volatile mac command(0x508) struct defination
+ * @see OEM_SET_VOLATILE_MAC
+ *
+ */
+typedef struct tag_oem_set_volatile_mac {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 mac[MAC_ADDRESS_LEN];
+ u8 rsv[2];
+ u32 check_sum; /**< check sum */
+} oem_set_volatile_mac;
+
+#define OEM_SET_VOLATILE_MAC_REQ_PAYLD_LEN 16
+#define OEM_SET_VOLATILE_MAC_RESP_LEN 12
+#define OEM_GET_VOLATILE_MAC_RESP_LEN 20
+
+/**
+ * @brief ncsi oem set volatile mac response(0x508) struct defination
+ * @see OEM_SET_VOLATILE_MAC
+ *
+ */
+typedef struct tag_oem_set_volatile_mac_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 check_sum; /**< check sum */
+} oem_set_volatile_mac_resp;
+
+/**
+ * @brief ncsi oem get volatile mac command(0x509) struct defination
+ * @see OEM_SET_VOLATILE_MAC
+ *
+ */
+typedef struct tag_oem_get_volatile_mac {
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u32 check_sum; /**< check sum */
+} oem_get_volatile_mac;
+
+/**
+ * @brief ncsi oem get volatile mac response(0x509) struct defination
+ * @see OEM_SET_VOLATILE_MAC
+ *
+ */
+typedef struct tag_oem_get_volatile_mac_resp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_OEM_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 mac[MAC_ADDRESS_LEN];
+ u8 rsv[2];
+ u32 check_sum; /**< check sum */
+} oem_get_volatile_mac_resp;
+
+/* get xsfp present status */
+#define OEM_GET_XSFP_STATUS_RSP_LEN (16)
+/**
+ * @brief oem get get xsfp present status response(huawei_id:0x0, sub_id:0x17) struct defination
+ * @see OEM_GET_XSFP_STATUS
+ *
+ */
+typedef struct tag_oem_get_xsfp_status_rsp {
+ u16 rsp_code; /**< rsp code @see enum NCSI_RESPONSE_CODE_E */
+ u16 reason_code; /**< reason code @see enum NCSI_REASON_CODE_E */
+ ncsi_oem_cmd_head_s ncsi_oem_head; /**< oem command header */
+ u8 rsv[3];
+ u8 present_status; /**< Optical module present status */
+ u32 check_sum; /**< check sum */
+} oem_get_xsfp_status_rsp_s;
+
+#pragma pack()
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd.h
new file mode 100644
index 000000000..c82666f4a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+ * Description : RoCE MPU cmd
+ * Author : /
+ * Create : /
+ * Notes : /
+ * History : /
+ */
+
+#ifndef ROCE_MPU_CMD_H
+#define ROCE_MPU_CMD_H
+
+/* Commands between RoCE driver to MPU */
+enum {
+ /* FUNC CFG */
+ ROCE_MPU_CMD_SET_FUNC_STATE =
+ 0, /**< Set roce_vld in function table @see > roce_set_func_state_cmd_s */
+ ROCE_MPU_CMD_SET_CPU_ENDIAN, /**< Set cpu endian in function table @see > roce_set_cpu_endian_cmd_s */
+ ROCE_MPU_CMD_GET_CFG_INFO, /**< Get roce-related configuration from cfg_data @see > roce_get_cfg_info_cmd_s */
+ ROCE_MPU_CMD_DEL_FUNC_RES, /**< Clear relevant resources when FLR @see > roce_set_func_state_cmd_s */
+ ROCE_MPU_CMD_GET_FUNC_TABLE, /**< Get function table @see > roce_get_func_table_cmd_s */
+ ROCE_MPU_CMD_ADD_MAC =
+ 10, /**< Add MAC to MAC table @see > roce_cfg_mac_cmd_s, Unused in HI1825V100 */
+ ROCE_MPU_CMD_DEL_MAC, /**< Delete MAC from MAC table @see > roce_cfg_mac_cmd_s, Unused in HI1825V100 */
+ ROCE_MPU_CMD_ADD_IPSU_MAC, /**< Add entry to IPSURX VF table MAC mode @see > roce_cfg_ipsu_mac_cmd_s */
+ ROCE_MPU_CMD_DEL_IPSU_MAC, /**< Delete entry from IPSURX VF table MAC mode @see > roce_cfg_ipsu_mac_cmd_s */
+ ROCE_MPU_CMD_GET_MAC_VNI, /**< Get vxlan roce vni and mac @see > vroce_mac_cfg_vni_info_s */
+ ROCE_MPU_CMD_ADD_IPSU_IP, /**< Add entry to IPSURX VF table IP mode @see > roce_cfg_ipsu_ip_cmd_s */
+ ROCE_MPU_CMD_DEL_IPSU_IP, /**< Delete entry from IPSURX VF table IP mode @see > roce_cfg_ipsu_ip_cmd_s */
+ ROCE_MPU_CMD_ADD_IPSU_TCAM, /**< Add entry to IPSURX TCAM table @see > roce_cfg_ipsu_tcam_cmd_s */
+ ROCE_MPU_CMD_DEL_IPSU_TCAM, /**< Delete entry from IPSURX TCAM table @see > roce_cfg_ipsu_tcam_cmd_s */
+
+ /* BOND */
+ ROCE_MPU_CMD_BOND_CHECK_SLAVE_PORT = 20,
+
+ /* INNER ULP */
+ ROCE_MPU_CMD_ULP_VROCE_GET_GROUP_ID =
+ 25, /**< < Get vxlan roce group cos num @see > roce_cmd_get_group_id */
+
+ /* CC */
+ ROCE_MPU_CMD_CC_CFG_CC_PARAM =
+ 40, /**< Config CC param table @see > roce_cc_cfg_param_cmd_s */
+ ROCE_MPU_CMD_CC_CFG_DCQCN_PARAM, /**< Config DCQCN param table @see > roce_cc_cfg_param_cmd_s */
+ ROCE_MPU_CMD_CC_CFG_IPQCN_PARAM, /**< Config IPQCN param table @see > roce_cc_cfg_param_cmd_s */
+ ROCE_MPU_CMD_CC_CFG_LDCP_PARAM, /**< Config LDCP param table @see > roce_cc_cfg_param_cmd_s */
+ ROCE_MPU_CMD_CC_SET_BW_CTRL, /**< Unused */
+ ROCE_MPU_CMD_CC_QUERY_BW_CTRL, /**< Unused */
+ ROCE_MPU_CMD_CC_CFG_UCC_PARAM, /**< Config UCC param table @see > roce_cc_cfg_param_cmd_s */
+ ROCE_MPU_CMD_CC_RTT_TCAM_CTRL, /**< 计算ULP占用该位 */
+ ROCE_MPU_CMD_CC_SET_VNIC_WATERLINE, /**< Config VNIC waterline @see > roce_cc_cfg_vnic_waterline_cmd_s */
+ ROCE_MPU_CMD_CC_GET_VNIC_WATERLINE, /**< READ VNIC waterline @see > roce_cc_cfg_vnic_waterline_cmd_s */
+
+ /* DFX */
+ ROCE_MPU_CMD_DFX_CACHE_OUT = 55, /**< Unused */
+ ROCE_MPU_CMD_DFX_SET_CAP_CFG, /**< Unused */
+ ROCE_MPU_CMD_DFX_GET_CAP_CFG, /**< Unused */
+ ROCE_MPU_CMD_DFX_READ_CAP_CTR, /**< Unused */
+ ROCE_MPU_CMD_DFX_CLEAR_CAP_CTR, /**< Unused */
+ ROCE_MPU_CMD_DFX_SET_ICDQ_SCOREBOARD, /**< 计算ULP占用该位 */
+ ROCE_MPU_CMD_DFX_QUERY_ICDQ_SCOREBOARD, /**< 计算ULP占用该位 */
+ ROCE_MPU_CMD_DFX_PORT_TRAFFIC, /**< Read port traffic counters @see > roce_mpu_port_statics_cmd_inbuf_t */
+ ROCE_MPU_CMD_DFX_ROCE_SET, /**< Set roce configs @see > roce_dfx_set_cmd_s */
+ ROCE_MPU_CMD_DFX_ROCE_SET_DEBUG, /**< Set roce configs in debug version @see > roce_dfx_set_debug_cmd_s */
+ ROCE_MPU_CMD_DFX_QUERY_ADDR_TBL, /**< Query addr table entries @see > roce_mpu_cmd_dfx_addr_query_inbuf_t */
+
+ /* EXTERN ULP, ULP MAILBOX命令字共预留128个, 范围128-255, 基础roce不可使用 */
+ ROCE_MPU_CMD_ULP_AA_SET_DD_CFG = 128, /**< Unused */
+ ROCE_MPU_CMD_ULP_AA_CTRL_READY, /**< Unused */
+ ROCE_MPU_CMD_ULP_AA_SWITCH_IO, /**< Unused */
+ ROCE_MPU_CMD_ULP_AA_FAKE_DATA, /**< Unused */
+ ROCE_MPU_CMD_ULP_AA_CLAER_ACT_CTRL_BMP, /**< Unused */
+ ROCE_MPU_CMD_ULP_START =
+ 133, /**< 提供给产品ulp的mailbox命令字总入口,范围133-255 */
+
+ ROCE_MPU_CMD_MAX = 256
+};
+
+#endif /* ROCE_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd_defs.h
new file mode 100644
index 000000000..36b9d4af9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x/roce_mpu_cmd_defs.h
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+ * Description : RoCE service common API b/w driver and MPU
+ * Author : /
+ * Create : /
+ * Notes : /
+ * History : /
+ */
+
+#ifndef ROCE_MPU_CMD_DEFS_H
+#define ROCE_MPU_CMD_DEFS_H
+
+#include "mpu_cmd_base_defs.h"
+
+/* ********************************** Func cmd between driver and mpu ********************************** */
+typedef struct roce_set_func_state_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 func_en;
+ u8 rsvd;
+} roce_set_func_state_cmd_s;
+
+typedef struct roce_get_func_table_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 rsvd[2];
+} roce_get_func_table_cmd_s;
+
+typedef struct roce_get_func_table_rsp {
+ struct mgmt_msg_head head;
+ u32 func_tbl_value;
+} roce_get_func_table_rsp_s;
+
+typedef struct roce_get_cfg_info_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 rsvd[2];
+} roce_get_cfg_info_cmd_s;
+
+typedef struct roce_get_cfg_info_resp {
+ struct mgmt_msg_head head;
+
+ u8 scence_id;
+ u8 lb_en;
+ u8 lb_mode;
+ u8 container_mode;
+
+ u8 fake_en;
+ u8 pf_start_bit;
+ u8 pf_end_bit;
+ u8 page_bit;
+
+ u8 port_num;
+ u8 host_num;
+ struct {
+ u16 pcie_atomic_en : 1;
+ u16 is_vroce : 1;
+ u16 ip2func : 1;
+ u16 rsvd : 13;
+ };
+
+ u32 max_wqe;
+ u32 max_cqe;
+ u32 max_srq_wqe;
+ u32 max_sq_sge;
+ u32 max_rq_sge;
+ u32 max_srq_sge;
+ u32 max_sq_wqe_len : 12;
+ u32 max_pd : 20;
+ u32 max_rq_wqe_len : 12;
+ u32 max_xrcd : 20;
+ u32 max_sq_inline;
+ u32 max_gid : 12;
+ u32 rsvd0 : 20;
+ u32 rsvd1[5];
+} roce_get_cfg_info_resp_s;
+
+typedef struct roce_get_cfg_info_comp_resp {
+ struct mgmt_msg_head head;
+
+ u8 scence_id;
+ u8 lb_en;
+ u8 lb_mode;
+ u8 container_mode;
+
+ u8 fake_en;
+ u8 pf_start_bit;
+ u8 pf_end_bit;
+ u8 page_bit;
+
+ u8 port_num;
+ u8 host_num;
+ struct {
+ u16 pcie_atomic_en : 1;
+ u16 rsvd : 15;
+ };
+} roce_get_cfg_info_comp_resp_s;
+
+typedef struct roce_set_cpu_endian_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 cpu_endian;
+ u8 rsvd;
+} roce_set_cpu_endian_cmd_s;
+
+typedef struct roce_cfg_mac_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd;
+ u16 er_fwd_id;
+ u8 mac[6];
+ u8 vni_en;
+ u32 vlan_id;
+} roce_cfg_mac_cmd_s;
+
+typedef struct roce_cfg_ipsu_mac_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 er_id;
+ u8 vni_en; /* vni enable */
+ u8 mac[6];
+ u16 src_func_id;
+ u32 vlanid_vni;
+} roce_cfg_ipsu_mac_cmd_s;
+
+/* Keep the same definition with sml_addr_info */
+union roce_addr_info {
+ struct {
+ u64 high;
+ u64 low;
+ } ipv6;
+ struct {
+ u32 rsvd[3];
+ u32 val;
+ } ipv4;
+ struct {
+ u16 vlan_id;
+ u8 addr[6];
+ u8 rsvd2[8];
+ } mac;
+ u32 dw[4];
+};
+
+struct roce_cmd_mpu_addr_info {
+ u8 ip_ver; // 0x0:IPv4; 0x1:IPv6。
+ u8 rsvd[3];
+ union roce_addr_info ip_addr;
+};
+
+typedef struct roce_cfg_ipsu_ip_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 port_id;
+ u8 ip_ver; // 0x0:IPv4; 0x1:IPv6
+ union roce_addr_info ip;
+} roce_cfg_ipsu_ip_cmd_s;
+
+typedef struct roce_cfg_ipsu_tcam_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 ip_ver; // 0x0:IPv4; 0x1:IPv6
+ u8 gid_idx;
+ union roce_addr_info ip;
+} roce_cfg_ipsu_tcam_cmd_s;
+
+struct roce_cmd_get_group_id {
+ struct mgmt_msg_head head;
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+
+ u16 func_id;
+ u8 group_rc_cos;
+ u8 group_ud_cos;
+ u8 group_xrc_cos;
+};
+
+/* ********************************** Bond cmd between driver and mpu ********************************** */
+typedef struct roce_bond_cfg_state_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 bond_en;
+ u8 rsvd;
+} roce_bond_cfg_state_cmd_s;
+
+typedef struct roce_bond_set_ipsu_mac_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 er_fwd_id;
+ u8 mac[6];
+} roce_bond_set_ipsu_mac_cmd_s;
+
+typedef struct roce_bond_cfg_er_fwd_id_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u16 er_fwd_id;
+ u32 bond_tbl_val;
+} roce_bond_cfg_er_fwd_id_cmd_s;
+
+typedef struct roce_bond_combine_er_fwd_id_cmd {
+ struct mgmt_msg_head head;
+ u16 func_id_src;
+ u16 func_id_dst;
+ u16 er_fwd_id;
+ u8 rsvd[2];
+} roce_bond_combine_er_fwd_id_cmd_s;
+
+typedef struct roce_bond_compact_er_fwd_id_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd;
+ u32 value; /* dw14 value */
+} roce_bond_compact_er_fwd_id_cmd_s;
+
+/* ********************************** CC cmd between driver and mpu ********************************** */
+#define ROCE_CC_CFG_PARAM_MAX_DW_NUM \
+ 32 // 自研算法使用4dw,ucc算法使用16dw,另增加16dw用于后续扩展
+typedef struct roce_cc_cfg_param_cmd {
+ struct mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd;
+ u32 param[ROCE_CC_CFG_PARAM_MAX_DW_NUM];
+} roce_cc_cfg_param_cmd_s;
+
+typedef struct roce_ovs_qos_policing_cmd {
+ u32 index;
+ u32 apply_mode;
+ u32 profile_id;
+ u32 cir; /**< 1-100000000kbps */
+ u32 cbs; /**< 1-2560000kbits */
+ u32 pir; /**< 1-100000000kbps */
+ u32 pbs; /**< 1-2560000kbits */
+} roce_ovs_qos_policing_cmd_s;
+
+typedef struct roce_ovs_set_policing_cmd {
+ struct mgmt_msg_head comm_head;
+ u16 sub_cmd;
+ u16 rsvd;
+
+ roce_ovs_qos_policing_cmd_s data; /**< the real message begin */
+} roce_ovs_set_policing_cmd_s;
+
+typedef struct roce_ovs_vport_cmd {
+ u16 func_id;
+ u16 vport_id;
+
+ u16 vport_type;
+ u8 vhd_type;
+ u8 rsvd;
+} roce_ovs_vport_cmd_s;
+
+typedef struct roce_ovs_vport_attr {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 vlan_tag : 16;
+ u32 vlan_mode : 8;
+ u32 vlan_ol : 8;
+
+ u32 vni; /**< vxlan id */
+ u32 vm_id;
+ u32 trunk_port_en;
+ u32 local_lro_en;
+ u32 rsvd0;
+
+ u32 rsvd1 : 6;
+ u32 max_queue_flag : 1;
+ u32 max_queue : 8;
+ u32 clr_vm_id_flag : 1;
+ u32 profile_id : 7;
+ u32 set_vm_id_flag : 1;
+ u32 rsvd2 : 8;
+
+ u32 mirror_src_ip;
+ u32 rsvd3[18];
+
+#else
+ u32 vlan_ol : 8;
+ u32 vlan_mode : 8;
+ u32 vlan_tag : 16;
+
+ u32 vni; /**< vxlan id */
+ u32 vm_id;
+ u32 trunk_port_en;
+ u32 local_lro_en;
+ u32 rsvd0;
+
+ u32 rsvd2 : 8;
+ u32 set_vm_id_flag : 1;
+ u32 profile_id : 7;
+ u32 clr_vm_id_flag : 1;
+ u32 max_queue : 8;
+ u32 max_queue_flag : 1;
+ u32 rsvd1 : 6;
+
+ u32 mirror_src_ip;
+ u32 rsvd3[18];
+#endif
+} roce_ovs_vport_attr_s;
+
+typedef struct roce_hiovs_vport_attr {
+ roce_ovs_vport_cmd_s vport;
+ roce_ovs_vport_attr_s attr;
+} roce_hiovs_vport_attr_s;
+
+typedef struct roce_ovs_map_vport_cmd {
+ struct mgmt_msg_head comm_head;
+ u16 sub_cmd;
+ u16 rsvd;
+
+ roce_hiovs_vport_attr_s data; /**< the real message begin */
+} roce_ovs_map_vport_cmd_s;
+
+typedef struct roce_cc_cfg_bw_ctrl_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 rsvd;
+
+ u8 color_type;
+ u16 ptype;
+ u8 hw_wred_mode;
+
+ u32 cir;
+ u32 pir;
+ u32 cbs;
+ u32 xbs;
+ u32 cnp;
+ u32 enable;
+} roce_cc_cfg_bw_ctrl_cmd_s;
+
+typedef struct roce_mpu_vnic_waterline_info {
+ u16 red_waterline;
+ u16 yellow_waterline;
+} roce_mpu_vnic_waterline_info_s;
+
+typedef struct roce_cfg_ipsu_vnic_waterline_cmd {
+ roce_cfg_ipsu_ip_cmd_s ip_cmd;
+ roce_mpu_vnic_waterline_info_s waterline_info;
+} roce_cfg_ipsu_vnic_waterline_cmd_s;
+
+typedef struct roce_cc_cfg_vnic_waterline_cmd_param {
+ union {
+ struct {
+ u64 high;
+ u64 low;
+ } ipv6;
+ struct {
+ u32 rsvd[3];
+ u32 val;
+ } ipv4;
+ } ip_info;
+ u16 red_waterline;
+ u16 yellow_waterline;
+} roce_cc_cfg_vnic_waterline_cmd_param_s;
+
+typedef struct roce_cc_cfg_vnic_waterline_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id;
+ u8 port_id;
+ u8 ip_ver;
+
+ roce_cc_cfg_vnic_waterline_cmd_param_s param;
+} roce_cc_cfg_vnic_waterline_cmd_s;
+
+/* ********************************** DFX cmd between driver and mpu and tools ********************************** */
+#define ROCE_PORT_NUM_MAX 4
+#define ROCE_COS_NUM_MAX 8
+#define ROCE_PORT_TRAFFIC_CTR_ID(port, cos) \
+ ((((port) << 0x3) + ((cos)&0x7)) << 1)
+#define ROCE_MAX_LATENCY_PROF_NUM 5 // 与L2D的统计大小一致
+#define ROCE_MAX_TILE_NUM 8 // 最大可统计的TILE数量
+#define ROCE_MPU_MAX_ADDR_ENTRY_CNT 100
+
+typedef struct {
+ u64 pkt_bytes;
+ u64 pkt_num;
+} roce_ctr_bytes_t;
+
+typedef struct roce_ctr_array_bytes {
+ roce_ctr_bytes_t tx_cur[ROCE_PORT_NUM_MAX][ROCE_COS_NUM_MAX];
+ roce_ctr_bytes_t rx_cur[ROCE_PORT_NUM_MAX][ROCE_COS_NUM_MAX];
+} roce_ctr_array_bytes_t;
+
+typedef struct {
+ u32 cmd_type;
+ u8 port_id;
+ u8 cos;
+ u8 exec_cos_set;
+ u8 exec_port_set;
+} roce_port_sta_inbuf_t;
+
+typedef struct {
+ struct mgmt_msg_head head;
+ roce_ctr_array_bytes_t ctr_array;
+ u64 cur_time;
+} roce_port_sta_outbuf_t;
+
+typedef struct roce_mpu_set_sub_cmd_param {
+ union {
+ struct {
+ u32 max_tso_len_cnt : 5;
+ u32 port_traffic_enable : 1;
+ u32 ack_pkt_num : 5;
+ u32 pfc_free_en : 1;
+ u32 cc_inject_en : 1;
+ u32 rsvd : 19;
+ } bs;
+ u32 value;
+ } dw0;
+ struct {
+ u32 latency_prof_en : 1;
+ u32 frequency_reduction_ratio : 15;
+ u32 rsvd : 16;
+ u8 latency_prof_num[ROCE_MAX_TILE_NUM];
+ u32 wqe_latency[ROCE_MAX_TILE_NUM][ROCE_MAX_LATENCY_PROF_NUM];
+ } latency_prof;
+} roce_mpu_set_sub_cmd_param_s;
+
+typedef struct roce_mpu_set_debug_sub_cmd_param {
+ union {
+ struct {
+ u32 cc_inject_en : 1;
+ u32 rsvd : 31;
+ } bs;
+ u32 value;
+ } dw0;
+} roce_mpu_set_debug_sub_cmd_param_s;
+
+typedef struct roce_dfx_set_inbuf {
+ u32 cmd_type;
+ u32 sub_cmd_type;
+ u32 func_id;
+ roce_mpu_set_sub_cmd_param_s sub_param;
+ u32 show;
+} roce_dfx_set_inbuf_s;
+
+typedef struct roce_dfx_set_debug_inbuf {
+ u32 cmd_type;
+ u32 sub_cmd_type;
+ u32 func_id;
+ roce_mpu_set_debug_sub_cmd_param_s sub_param;
+ u32 show;
+} roce_dfx_set_debug_inbuf_s;
+
+/* ********************************** DFX cmd between driver and mpu ********************************** */
+typedef struct roce_dfx_cache_out_cmd {
+ struct mgmt_msg_head head;
+ u16 func_idx;
+ u8 cache_index;
+ u8 rsvd;
+} roce_dfx_cache_out_cmd_s;
+
+typedef struct roce_dfx_cfg_cap_param_cmd {
+ struct mgmt_msg_head head;
+ u16 index;
+ u16 rsvd;
+ u32 param[4];
+} roce_dfx_cfg_cap_param_cmd_s;
+
+typedef struct roce_dfx_cap_ctr_cmd {
+ struct mgmt_msg_head head;
+ u16 index;
+ u16 rsvd;
+ u32 value;
+} roce_dfx_cap_ctr_cmd_s;
+
+typedef struct {
+ struct mgmt_msg_head head;
+ roce_port_sta_inbuf_t cmd;
+} roce_mpu_port_statics_cmd_inbuf_t;
+
+typedef struct roce_dfx_set_cmd {
+ struct mgmt_msg_head head;
+ roce_dfx_set_inbuf_s cmd;
+} roce_dfx_set_cmd_s;
+
+typedef struct roce_dfx_set_debug_cmd {
+ struct mgmt_msg_head head;
+ roce_dfx_set_debug_inbuf_s cmd;
+} roce_dfx_set_debug_cmd_s;
+
+typedef struct roce_dfx_set_outbuf {
+ struct mgmt_msg_head head;
+ roce_mpu_set_sub_cmd_param_s sub_param;
+} roce_dfx_set_outbuf_s;
+
+typedef struct roce_dfx_set_debug_outbuf {
+ struct mgmt_msg_head head;
+ roce_mpu_set_debug_sub_cmd_param_s sub_param;
+} roce_dfx_set_debug_outbuf_s;
+
+#define ROCE_BOND_PORT_MAX_NUM 8
+
+typedef struct roce_bond_check_slave_port_req {
+ struct mgmt_msg_head head;
+ u8 slave_ports[ROCE_BOND_PORT_MAX_NUM];
+ u8 slave_ports_num;
+ u8 rsvd[3];
+} roce_bond_check_slave_port_req_s;
+
+typedef struct roce_bond_check_slave_port_rsp {
+ struct mgmt_msg_head head;
+ u8 slave_ports_result[ROCE_BOND_PORT_MAX_NUM];
+} roce_bond_check_slave_port_rsp_s;
+
+/* ********************************** DFX addr table query cmd ********************************** */
+typedef struct roce_mpu_cmd_dfx_addr_query_inbuf {
+ struct mgmt_msg_head head;
+ u8 rsvd[4];
+} roce_mpu_cmd_dfx_addr_query_inbuf_s;
+
+/* DFX addr 查询表项结构 - 只处理 MAC 类型 */
+typedef struct roce_mpu_cmd_dfx_addr_query_entry {
+ u32 index; /* 表项索引 */
+ u8 host_id; /* item 部分:主机 ID */
+ u16 fwd_type; /* item 部分:func 类型 */
+ u16 fwd_id; /* item 部分:func ID */
+ u16 vlan_id; /* key 部分:VLAN ID(MAC 类型) */
+ u8 er_id; /* key 部分:ER ID(MAC 类型) */
+ u8 mac_addr[6]; /* key 部分:MAC 地址(MAC 类型) */
+} roce_mpu_cmd_dfx_addr_query_entry_s;
+
+typedef struct roce_mpu_cmd_dfx_addr_query_outbuf {
+ struct mgmt_msg_head head;
+ u32 entry_count;
+ roce_mpu_cmd_dfx_addr_query_entry_s entries[ROCE_MPU_MAX_ADDR_ENTRY_CNT];
+} roce_mpu_cmd_dfx_addr_query_outbuf_s;
+
+#endif /* ROCE_MPU_CMD_DEFS_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_aeq_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_aeq_format.h
new file mode 100644
index 000000000..468e64dd5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_aeq_format.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA common event queue format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_AEQ_FORMAT_H
+#define ROCE_AEQ_FORMAT_H
+
+#define CQM_AEQ_BASE_T_ROCE 16 // sync with cqm@sdk
+#define ROCE_EVENT_TYPE_NUM 0x20
+#define ROCE_EVENT_TYPE_START CQM_AEQ_BASE_T_ROCE
+#define ROCE_EVENT_TYPE_END (ROCE_EVENT_TYPE_START + ROCE_EVENT_TYPE_NUM - 1)
+
+/* RoCE EVENT */
+enum {
+ ROCE_EVENT_TYPE_OFED_NO_DEF = (ROCE_EVENT_TYPE_START + 0x00),
+ ROCE_EVENT_TYPE_PATH_MIG = (ROCE_EVENT_TYPE_START + 0x01), /* RSVD */
+ ROCE_EVENT_TYPE_COMM_EST = (ROCE_EVENT_TYPE_START + 0x02),
+ ROCE_EVENT_TYPE_SQ_DRAINED = (ROCE_EVENT_TYPE_START + 0x03),
+ ROCE_EVENT_TYPE_SRQ_QP_LAST_WQE = (ROCE_EVENT_TYPE_START + 0x04),
+
+ /* 5 */
+ ROCE_EVENT_TYPE_WQ_CATAS_ERROR = (ROCE_EVENT_TYPE_START + 0x05),
+ ROCE_EVENT_TYPE_PATH_MIG_FAILED = (ROCE_EVENT_TYPE_START + 0x06),
+ ROCE_EVENT_TYPE_WQ_INVAL_REQ_ERROR = (ROCE_EVENT_TYPE_START + 0x07),
+ ROCE_EVENT_TYPE_WQ_ACCESS_ERROR = (ROCE_EVENT_TYPE_START + 0x08),
+ ROCE_EVENT_TYPE_CQ_ERROR = (ROCE_EVENT_TYPE_START + 0x09),
+
+ /* 10 */
+ ROCE_EVENT_TYPE_SRQ_LIMIT = (ROCE_EVENT_TYPE_START + 0x0a),
+ ROCE_EVENT_TYPE_SRQ_CATAS_ERROR = (ROCE_EVENT_TYPE_START + 0x0b),
+ ROCE_EVENT_TYPE_LOCAL_CATAS_ERROR =
+ (ROCE_EVENT_TYPE_START + 0x0c), /* RSVD */
+ ROCE_EVENT_TYPE_MR_SIG_ERR = (ROCE_EVENT_TYPE_START + 0x0e),
+
+ ROCE_EVENT_TYPE_ODP_PAGE_FAULT = (ROCE_EVENT_TYPE_START + 0x0f),
+ /* ROCE NOF AA */
+ ROCE_EVENT_TYPE_SWITCH_HOST = (ROCE_EVENT_TYPE_START + 0x10),
+ ROCE_EVENT_TYPE_HOST_FAILOVER = (ROCE_EVENT_TYPE_START + 0x11),
+ ROCE_EVENT_NOFAA_STUB = (ROCE_EVENT_TYPE_START + 0x12),
+
+ ROCE_EVENT_TYPE_DEBUG = ROCE_EVENT_TYPE_END
+};
+
+/* RoCE v100 Debug event, 仅在V100中使用,与V100驱动兼容 */
+enum {
+ ROCE_EVENT_TYPE_FATAL_WARNING = (CQM_AEQ_BASE_T_ROCE + 0x34),
+ ROCE_EVENT_TYPE_XRC_DOMAIN_VIOLATION_ERROR =
+ (CQM_AEQ_BASE_T_ROCE + 0x37),
+ ROCE_EVENT_TYPE_INVALID_XRCETH_ERROR = (CQM_AEQ_BASE_T_ROCE + 0x38),
+ ROCE_EVENT_TYPE_FLUSH_WQE_ERROR = (CQM_AEQ_BASE_T_ROCE + 0x39),
+};
+
+// 驱动侧通过 ROCE_AEQE_EVENT_DATA 解析
+#define ROCE_AEQE_EVENT(module_type, subtype, type, err_code) \
+ (((u32)(module_type) << 28) | ((subtype) << 20) | ((type) << 8) | \
+ (err_code))
+/* **********************macro define************************ */
+enum ROCE_ERR_STATE_E {
+ ROCE_AEQE_NOERR_STATE = 0,
+ ROCE_AEQE_ERR_STATE,
+};
+
+enum ROCE_QP_ERR_STATE_E {
+ ROCE_QP_NOERR_STATE = 0,
+ ROCE_QP_ERR_STATE,
+};
+
+/* *********ROCE_AEQE_COMMON_SUBTYPE_E******* */
+enum ROCE_AEQE_COMMON_SUBTYPE_E {
+ ROCE_AEQE_SUBTYPE_PATH_MIGRATED = 0, /* * APM */
+ ROCE_AEQE_SUBTYPE_COMM_ESTABLISHED, /* *RQ RTR RCV FIRST PKT */
+ ROCE_AEQE_SUBTYPE_SQ_DRAINED, /* * sq empty and change to SQ DRANNING STATE */
+ ROCE_AEQE_SUBTYPE_SRQ_LIMIT_REACHED, /* *SRQ LIMIT_REACHED from RXDMA api rsp */
+ ROCE_AEQE_SUBTYPE_QP_LAST_WQE_REACHED, /* *srq en & LAST_WQE_REACHED */
+ ROCE_AEQE_SUBTYPE_CQ_ERR, /* *api rsp cq err */
+ ROCE_AEQE_SUBTYPE_QP_FATAL, /* *LOC_WORK_QUEUE_CATASTROPHIC_ERR */
+ ROCE_AEQE_SUBTYPE_QP_REQ_ERR, /* *INVALID_REQ_LOC_WORK_QUEUE_ERR */
+ ROCE_AEQE_SUBTYPE_QP_ACCESS_ERR, /* *LOC_ACCESS_VIOLATION_WORK_QUEUE_ERR */
+ ROCE_AEQE_SUBTYPE_PATH_MIG_ERR,
+ ROCE_AEQE_SUBTYPE_GID_CHANGE_EVENT,
+ ROCE_AEQE_SUBTYPE_CQ_OVERRUN,
+ ROCE_AEQE_SUBTYPE_SRQ_CATASTROPHIC_ERR,
+ ROCE_AEQE_SUBTYPE_CFG_ERR,
+ ROCE_AEQE_SUBTYPE_CHIP_ERR,
+ ROCE_AEQE_SUBTYPE_DIF_ERR,
+ ROCE_AEQE_SUBTYPE_XRC_DOMAIN_VIOLATION_ERR,
+ ROCE_AEQE_SUBTYPE_INVALID_XRCETH_ERR,
+ ROCE_AEQE_SUBTYPE_UCODE_FATAL_ERR,
+ ROCE_AEQE_SUBTYPE_ODP_PAGE_FAULT,
+ ROCE_AEQE_SUBTYPE_RSVD,
+};
+
+/* ******ROCE_AEQE_DEBUG_SUBTYPE_E******* */
+enum ROCE_AEQE_DEBUG_SUBTYPE_E {
+ ROCE_AEQE_DEBUG_SUBTYPE_EEC_CATAS_ERROR,
+ ROCE_AEQE_DEBUG_SUBTYPE_PORT_CHANGE,
+ ROCE_AEQE_DEBUG_SUBTYPE_ECC_DETECT,
+ ROCE_AEQE_DEBUG_SUBTYPE_VEP_UPDATE,
+ ROCE_AEQE_DEBUG_SUBTYPE_FATAL_WARNING,
+ ROCE_AEQE_DEBUG_SUBTYPE_FLR_EVENT,
+ ROCE_AEQE_DEBUG_SUBTYPE_PORT_MNG_CHG_EVENT,
+ ROCE_AEQE_DEBUG_SUBTYPE_XRC_DOMAIN_VIOLATION_ERROR,
+ ROCE_AEQE_DEBUG_SUBTYPE_INVALID_XRCETH_ERROR,
+ ROCE_AEQE_DEBUG_SUBTYPE_FLUSH_WQE_ERROR,
+ ROCE_AEQE_DEBUG_SUBTYPE_EQ_OVERFLOW,
+ ROCE_AEQE_DEBUG_SUBTYPE_CMD,
+ ROCE_AEQE_DEBUG_SUBTYPE_COMM_CHANNEL,
+ ROCE_AEQE_DEBUG_SUBTYPE_OP_REQUIRED
+};
+
+/* *********ROCE SQ ERR type******* */
+enum ROCE_COMPLETION_EVENT_ERR_TYPE_E {
+ ROCE_COMPLETE_EVENT_NO_ERR = 0,
+ ROCE_COMPLETE_EVENT_LOC_LEN_ERR = 0x1,
+ ROCE_COMPLETE_EVENT_LOC_QP_OPERATION_ERR,
+ ROCE_COMPLETE_EVENT_LOC_PROTECTION_ERR = 0x4,
+ ROCE_COMPLETE_EVENT_LOC_MEM_MANAGEMENT_ERR = 0x4,
+ ROCE_COMPLETE_EVENT_WR_FLUSH_ERR,
+ ROCE_COMPLETE_EVENT_MW_BIND_ERR,
+ ROCE_COMPLETE_EVENT_BAD_RESP_ERR = 0x10,
+ ROCE_COMPLETE_EVENT_LOC_ACCESS_ERR,
+ ROCE_COMPLETE_EVENT_REM_INV_REQ_ERR,
+ ROCE_COMPLETE_EVENT_REM_ACCESS_ERR,
+ ROCE_COMPLETE_EVENT_REM_OPERATION_ERR,
+ ROCE_COMPLETE_EVENT_RETRY_CTR_EXCEED_ERR,
+ ROCE_COMPLETE_EVENT_RNR_RETRY_CTR_EXCEED_ERR,
+ ROCE_COMPLETE_EVENT_REM_ABORTED_ERR = 0x22,
+ ROCE_COMPLETE_EVENT_GENERAL_ERR,
+ ROCE_COMPLETE_EVENT_XRC_VIOLATION_ERR,
+ ROCE_COMPLETE_EVENT_MAX = 0x25
+};
+
+enum ROCE_AEQE_EVENT_ERR_TYPE_E {
+ ROCE_AEQE_QP_FATAL_SQ_FETCH_WQE_STATUS_ERR = 0,
+ ROCE_AEQE_QP_FATAL_SQ_DMA_GEN_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_SQ_DMA_GEN_MPT_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_SQ_DMA_GEN_CQ_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_SQ_COMPLETE_WQE_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_SQ_COMPLETE_CQ_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RQ_RXDMA_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RQ_RXDMA_MPT_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RQ_RXDMA_CQ_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RQ_RXDMA_SRQ_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RQ_RDMA_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RQ_RDMA_MPT_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_CQ_CQE_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_CQ_ARM_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_SRQ_ARM_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RDMARC_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_RDMARC_RSP_PSN_ERR = 0x10,
+ ROCE_AEQE_QP_FATAL_MINVLD_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_CQ_RESIZE_STATUS_ERR,
+ ROCE_AEQE_QP_FATAL_CQ_OVERFLOW,
+ ROCE_AEQE_CFG_TYPE_STATELESS_MAC = 0x20,
+ ROCE_AEQE_CFG_TYPE_STATELESS_FUNC,
+ ROCE_AEQE_CFG_TYPE_QPC_PREFETCH_RSP_ERR,
+ ROCE_AEQE_CFG_TYPE_QPC_STATE_ERR,
+ ROCE_AEQE_CFG_TYPE_QPC_STATE_NOT_RTS,
+ ROCE_AEQE_CHIP_TYPE_CPB_BUF_FULL,
+ ROCE_AEQE_CHIP_TYPE_IPSU_RSP_ERR,
+ ROCE_AEQE_CHIP_TYPE_QU_QUERY_RSP_ERR,
+ ROCE_AEQE_LOC_QP_REQ_ERR_TOO_MANY_READ_ATOMIC = 0x30,
+ ROCE_AEQE_LOC_QP_REQ_ERR_OPCODE_MISMATCH,
+ ROCE_AEQE_LOC_QP_REQ_ERR_LEN_ERR,
+ ROCE_AEQE_LOC_QP_OPERATION_ERR,
+ ROCE_AEQE_LOC_QP_NUM_RANGE_ERR,
+ ROCE_AEQE_MPT_NUM_RANGE_ERR,
+ ROCE_AEQE_MASTER_QP_MODIFY_ERR,
+};
+
+#endif /* ROCE_AEQ_FORMAT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cc_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cc_format.h
new file mode 100644
index 000000000..5e9a9dbae
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cc_format.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA CC context.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_CC_FORMAT_H
+#define ROCE_CC_FORMAT_H
+
+#include "base_type.h"
+#include "ccp_algo_format.h"
+
+/* Align each field with 4bytes. */
+#pragma pack(push) // 保存对齐状态
+#pragma pack(4)
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 0x1234
+#endif
+
+enum ROCE_CC_ALGO_E {
+ ROCE_CC_DISABLE = 0,
+ ROCE_CC_DCQCN_ALGO,
+ ROCE_CC_LDCP_ALGO,
+ ROCE_CC_IPQCN_ALGO,
+ ROCE_CC_USER_A_ALGO = 6,
+ ROCE_CC_USER_B_ALGO
+};
+
+#define ROCE_CC_COMMON_PARAM ROCE_CC_DISABLE
+
+/* *************************** EXT TABLE *************************** */
+/* cc common param tbl */
+typedef struct roce_cc_param {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 bypass : 2;
+ u32 rsvd : 1;
+ u32 algo_mode : 1;
+ u32 min_cnp_period : 8;
+ u32 rtt_rsp_prio : 3;
+ u32 rtt_rsp_prio_enable : 1;
+ u32 rtt_version : 2;
+ u32 ecn_cnp_en : 1;
+ u32 flow_ctrl_unit : 2;
+ u32 cnp_prio_enable : 1;
+ u32 slow_path_psn_threshold : 8;
+ u32 rtt_req_event_mode : 1;
+ u32 rsvd1 : 2;
+#else
+ u32 rsvd1 : 2;
+ u32 rtt_req_event_mode : 1;
+ u32 slow_path_psn_threshold : 8;
+ u32 cnp_prio_enable : 1;
+ u32 flow_ctrl_unit : 2;
+ u32 ecn_cnp_en : 1;
+ u32 rtt_version : 2;
+ u32 rtt_rsp_prio_enable : 1;
+ u32 rtt_rsp_prio : 3;
+ u32 min_cnp_period : 8;
+ u32 algo_mode : 1;
+ u32 rsvd : 1;
+ u32 bypass : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cnp_cos : 3;
+ u32 cnp_prio : 3;
+ u32 cc_appid : 8;
+ u32 rsvd : 18;
+#else
+ u32 rsvd : 18;
+ u32 cc_appid : 8;
+ u32 cnp_prio : 3;
+ u32 cnp_cos : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ u32 rsvd[2];
+} roce_cc_param_s;
+
+typedef struct roce_ipqcn_param {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 18;
+ u32 flow_min_rate : 6;
+ u32 token_period : 8;
+#else
+ u32 token_period : 8;
+ u32 flow_min_rate : 6;
+ u32 rsvd : 18;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rate_inc_period : 10;
+ u32 alpha_dec_period : 10;
+ u32 rsvd : 12;
+#else
+ u32 rsvd : 12;
+ u32 alpha_dec_period : 10;
+ u32 rate_inc_period : 10;
+#endif
+ } bs;
+
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rate_inc_period : 16;
+ u32 alpha_dec_period : 16;
+#else
+ u32 alpha_dec_period : 16;
+ u32 rate_inc_period : 16;
+#endif
+ } bs1;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rate_inc_ai : 8;
+ u32 rate_inc_hai : 8;
+ u32 rate_dec_period : 8;
+ u32 min_cnp_period : 8;
+#else
+ u32 min_cnp_period : 8;
+ u32 rate_dec_period : 8;
+ u32 rate_inc_hai : 8;
+ u32 rate_inc_ai : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 factor_gita : 4;
+ u32 rt_clamp : 1;
+ u32 rsvd : 1;
+ u32 initial_alpha : 10;
+ u32 rate_first_set : 16;
+#else
+ u32 rate_first_set : 16;
+ u32 initial_alpha : 10;
+ u32 rsvd : 1;
+ u32 rt_clamp : 1;
+ u32 factor_gita : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+} roce_ipqcn_param_s;
+
+typedef struct roce_ldcp_param {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 alpha : 4;
+ u32 beta : 4;
+ u32 gamma : 4;
+ u32 eta : 4;
+ u32 wnd_min : 4;
+ u32 set_flag : 1;
+ u32 rsvd : 11;
+#else
+ u32 rsvd : 11;
+ u32 set_flag : 1;
+ u32 wnd_min : 4;
+ u32 eta : 4;
+ u32 gamma : 4;
+ u32 beta : 4;
+ u32 alpha : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 16;
+ u32 wnd_default : 16;
+#else
+ u32 wnd_default : 16;
+ u32 rsvd : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ u32 rsvd[2];
+} roce_ldcp_param_s;
+
+typedef union roce_ccp_comm_param {
+ ccp_comm_param_s ccp_comm_param;
+ struct {
+ u32 used_param[2];
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ccp_appid : 3;
+ u32 cpb_wl_en : 1;
+ u32 rsvd : 28;
+#else
+ u32 rsvd : 28;
+ u32 cpb_wl_en : 1;
+ u32 ccp_appid : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ u32 rsvd;
+ } roce_comm_param;
+} roce_ccp_comm_param_s;
+
+#pragma pack(0)
+#pragma pack(pop) // 恢复对齐状态
+
+#endif // ROCE_CC_FORMAT_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cfg_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cfg_format.h
new file mode 100644
index 000000000..6e0bd77c8
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_cfg_format.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA common config format.
+ * Create: 2025-12-11
+ */
+
+#ifndef ROCE_CFG_FORMAT_H
+#define ROCE_CFG_FORMAT_H
+
+#include "base_type.h"
+
+/**
+ * RDMA OFED北向API能力位掩码定义
+ *
+ * 包含标准的InfiniBand架构命令,与ib_uverbs_write_cmds保持同步,用于RDMA内核态与固件之间的基本能力协商。
+ * 每个位对应一个特定的内核态协商消息的支持状态,新增标准IB命令支持时应放在此类。
+ *
+ * 版本约定:
+ * - MSG_V2: 支持1825V100或1825V100、1823V200内核态驱动与固件协商的功能特性;
+ * - MSG_V1: 支持1823V100或1823V200、1823V100内核态驱动与固件协商的功能特性(当前未定义)。
+ */
+
+typedef enum {
+ ROCE_SUPPORT_IB_CMD_GET_CONTEXT_MSG_V2 = BIT(0),
+ ROCE_SUPPORT_IB_CMD_QUERY_DEVICE_MSG_V2 = BIT(1),
+ ROCE_SUPPORT_IB_CMD_QUERY_PORT_MSG_V2 = BIT(2),
+ ROCE_SUPPORT_IB_CMD_ALLOC_PD_MSG_V2 = BIT(3),
+ ROCE_SUPPORT_IB_CMD_DEALLOC_PD_MSG_V2 = BIT(4),
+ ROCE_SUPPORT_IB_CMD_CREATE_AH_MSG_V2 = BIT(5),
+ ROCE_SUPPORT_IB_CMD_MODIFY_AH_MSG_V2 = BIT(6),
+ ROCE_SUPPORT_IB_CMD_QUERY_AH_MSG_V2 = BIT(7),
+ ROCE_SUPPORT_IB_CMD_DESTROY_AH_MSG_V2 = BIT(8),
+ ROCE_SUPPORT_IB_CMD_REG_MR_MSG_V2 = BIT(9),
+ ROCE_SUPPORT_IB_CMD_REG_SMR_MSG_V2 = BIT(10),
+ ROCE_SUPPORT_IB_CMD_REREG_MR_MSG_V2 = BIT(11),
+ ROCE_SUPPORT_IB_CMD_QUERY_MR_MSG_V2 = BIT(12),
+ ROCE_SUPPORT_IB_CMD_DEREG_MR_MSG_V2 = BIT(13),
+ ROCE_SUPPORT_IB_CMD_ALLOC_MW_MSG_V2 = BIT(14),
+ ROCE_SUPPORT_IB_CMD_BIND_MW_MSG_V2 = BIT(15),
+ ROCE_SUPPORT_IB_CMD_DEALLOC_MW_MSG_V2 = BIT(16),
+ ROCE_SUPPORT_IB_CMD_CREATE_COMP_CHANNEL_MSG_V2 = BIT(17),
+ ROCE_SUPPORT_IB_CMD_CREATE_CQ_MSG_V2 = BIT(18),
+ ROCE_SUPPORT_IB_CMD_RESIZE_CQ_MSG_V2 = BIT(19),
+ ROCE_SUPPORT_IB_CMD_DESTROY_CQ_MSG_V2 = BIT(20),
+ ROCE_SUPPORT_IB_CMD_POLL_CQ_MSG_V2 = BIT(21),
+ ROCE_SUPPORT_IB_CMD_PEEK_CQ_MSG_V2 = BIT(22),
+ ROCE_SUPPORT_IB_CMD_REQ_NOTIFY_CQ_MSG_V2 = BIT(23),
+ ROCE_SUPPORT_IB_CMD_CREATE_QP_MSG_V2 = BIT(24),
+ ROCE_SUPPORT_IB_CMD_QUERY_QP_MSG_V2 = BIT(25),
+ ROCE_SUPPORT_IB_CMD_MODIFY_QP_MSG_V2 = BIT(26),
+ ROCE_SUPPORT_IB_CMD_DESTROY_QP_MSG_V2 = BIT(27),
+ ROCE_SUPPORT_IB_CMD_POST_SEND_MSG_V2 = BIT(28),
+ ROCE_SUPPORT_IB_CMD_POST_RECV_MSG_V2 = BIT(29),
+ ROCE_SUPPORT_IB_CMD_ATTACH_MCAST_MSG_V2 = BIT(30),
+ ROCE_SUPPORT_IB_CMD_DETACH_MCAST_MSG_V2 = BIT(31),
+ ROCE_SUPPORT_IB_CMD_CREATE_SRQ_MSG_V2 = BIT(32),
+ ROCE_SUPPORT_IB_CMD_MODIFY_SRQ_MSG_V2 = BIT(33),
+ ROCE_SUPPORT_IB_CMD_QUERY_SRQ_MSG_V2 = BIT(34),
+ ROCE_SUPPORT_IB_CMD_DESTROY_SRQ_MSG_V2 = BIT(35),
+ ROCE_SUPPORT_IB_CMD_POST_SRQ_RECV_MSG_V2 = BIT(36),
+ ROCE_SUPPORT_IB_CMD_OPEN_XRCD_MSG_V2 = BIT(37),
+ ROCE_SUPPORT_IB_CMD_CLOSE_XRCD_MSG_V2 = BIT(38),
+ ROCE_SUPPORT_IB_CMD_CREATE_XSRQ_MSG_V2 = BIT(39),
+ ROCE_SUPPORT_IB_CMD_OPEN_QP_MSG_V2 = BIT(40)
+} roce_ability_kernel_e;
+
+/**
+ * RDMA内核态扩展能力位掩码定义
+ *
+ * 用于内核态驱动与固件之间的增强功能协商,每个位代表一个特定功能;
+ * 新增非IB标准命令的内核专用特性时应放在此类,命名避免使用IB_CMD前缀。
+ */
+typedef enum {
+ ROCE_SUPPORT_COMMON_SCQE_ASSEMBLE_FLUSH_MSG_V2 = BIT(0),
+ ROCE_SUPPORT_STORAGE_NOFAA_SWITCH_MSG_V2 = BIT(1),
+ ROCE_SUPPORT_CQ_MODIFY_MSG_V2 = BIT(2),
+ ROCE_SUPPORT_CQ_CHECK_DATA_STATE_MSG_V2 = BIT(3),
+ ROCE_SUPPORT_CQ_CACHE_OUT_MSG_V2 = BIT(4),
+ ROCE_SUPPORT_QP_SRQN_LB_MSG_V2 = BIT(5),
+ ROCE_SUPPORT_SET_PI_ON_CHIP_MSG_V2 = BIT(6),
+ ROCE_SUPPORT_SQ_DB_TYPE_MSG_V2 = BIT(7),
+ ROCE_SUPPORT_GET_QP_RX_PORT_MSG_V2 = BIT(8),
+ ROCE_SUPPORT_MODIFY_UDP_SRC_PORT_MSG_V2 = BIT(9),
+ ROCE_SUPPORT_GET_QP_UDP_SRC_PORT_MSG_V2 = BIT(10),
+ ROCE_SUPPORT_DFX_CMD_QUERY_MPT_MSG_V2 = BIT(11),
+ ROCE_SUPPORT_DFX_CMD_QUERY_GID_MSG_V2 = BIT(12),
+ ROCE_SUPPORT_DFX_CMD_QUERY_CQ_MSG_V2 = BIT(13),
+ ROCE_SUPPORT_DFX_CMD_QUERY_PI_CI_MSG_V2 = BIT(14),
+ ROCE_SUPPORT_ALLOC_QPC_MSG_FEATURE = BIT(15),
+ ROCE_SUPPORT_GET_OQID_MSG_FEATURE = BIT(16),
+ ROCE_SUPPORT_RETRY_LOAD_CQC_MSG_FEATURE = BIT(17),
+ ROCE_SUPPORT_SET_HASH_VALUE_MSG_V2 = BIT(18),
+ ROCE_SUPPORT_CC_GET_DCQCN_ENABLE = BIT(19),
+ ROCE_SUPPORT_CC_GET_LDCP_ENABLE = BIT(20),
+ ROCE_SUPPORT_CC_GET_IPQCN_ENABLE = BIT(21),
+ ROCE_SUPPORT_CC_GET_USER_ALGO_ENABLE = BIT(22),
+ ROCE_SUPPORT_KERNEL_8K_MTU = BIT(23),
+ ROCE_SUPPORT_SML_MAC_TABLE = BIT(24),
+ ROCE_SUPPORT_SQ_DB_TYPE_21 = BIT(25),
+ ROCE_SUPPORT_CC_PARAM_V1 = BIT(26),
+ ROCE_SUPPORT_CC_PARAM_V2 = BIT(27),
+} roce_ability_kernel_ext_e;
+
+/**
+ * RDMA用户态扩展能力位掩码定义
+ *
+ * 用于用户态驱动与固件之间的增强功能协商,如特定版本的用户态性能优化等扩展功能,每个位代表一个特定功能;
+ * 新增用户态专用特性时应放在此类。
+ */
+typedef enum {
+ ROCE_SUPPORT_USR_SQ_DB_TYPE_23 = BIT(0),
+ ROCE_SUPPORT_AT_CONFIG_MSG_V2 = BIT(1),
+ ROCE_SUPPORT_DWQE_FEATURE = BIT(2),
+ ROCE_SUPPORT_FAST_DWQE_FEATURE = BIT(3),
+ ROCE_SUPPORT_USR_SQ_DB_TYPE_21 = BIT(4),
+ ROCE_SUPPORT_USER_8K_MTU = BIT(23),
+} roce_ability_user_ext_e;
+
+/* RDMA芯片能力定义 */
+#define ROCE_SUPPORT_HI1825_V100_KERNEL \
+ (ROCE_SUPPORT_IB_CMD_RESIZE_CQ_MSG_V2 | \
+ ROCE_SUPPORT_IB_CMD_QUERY_QP_MSG_V2 | \
+ ROCE_SUPPORT_IB_CMD_MODIFY_SRQ_MSG_V2 | \
+ ROCE_SUPPORT_IB_CMD_DESTROY_SRQ_MSG_V2)
+/**< 1825V100 支持的所有内核态基本属性协商消息 */
+#define ROCE_SUPPORT_HI1825_V100_KERNEL_EXT \
+ (ROCE_SUPPORT_CQ_MODIFY_MSG_V2 | ROCE_SUPPORT_CQ_CACHE_OUT_MSG_V2 | \
+ ROCE_SUPPORT_CQ_CHECK_DATA_STATE_MSG_V2 | \
+ ROCE_SUPPORT_QP_SRQN_LB_MSG_V2 | ROCE_SUPPORT_SET_PI_ON_CHIP_MSG_V2 | \
+ ROCE_SUPPORT_SQ_DB_TYPE_21 | ROCE_SUPPORT_GET_QP_RX_PORT_MSG_V2 | \
+ ROCE_SUPPORT_MODIFY_UDP_SRC_PORT_MSG_V2 | \
+ ROCE_SUPPORT_GET_QP_UDP_SRC_PORT_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_MPT_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_CQ_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_GID_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_PI_CI_MSG_V2 | \
+ ROCE_SUPPORT_SET_HASH_VALUE_MSG_V2 | \
+ ROCE_SUPPORT_CC_GET_DCQCN_ENABLE | \
+ ROCE_SUPPORT_CC_GET_USER_ALGO_ENABLE | ROCE_SUPPORT_CC_PARAM_V2)
+/**< 1825V100 支持的所有内核态增强属性协商消息 */
+#define ROCE_SUPPORT_HI1825_V100_USER_EXT \
+ (ROCE_SUPPORT_USR_SQ_DB_TYPE_21 | ROCE_SUPPORT_AT_CONFIG_MSG_V2 | \
+ ROCE_SUPPORT_DWQE_FEATURE | ROCE_SUPPORT_FAST_DWQE_FEATURE)
+/**< 1825V100 支持的所有用户态增强属性协商消息 */
+
+#define ROCE_SUPPORT_HI1823_V200_KERNEL \
+ (ROCE_SUPPORT_IB_CMD_RESIZE_CQ_MSG_V2 | \
+ ROCE_SUPPORT_IB_CMD_QUERY_QP_MSG_V2 | \
+ ROCE_SUPPORT_IB_CMD_MODIFY_SRQ_MSG_V2 | \
+ ROCE_SUPPORT_IB_CMD_DESTROY_SRQ_MSG_V2)
+/**< 1823V200 支持的所有内核态基本属性协商消息 */
+#define ROCE_SUPPORT_HI1823_V200_KERNEL_EXT \
+ (ROCE_SUPPORT_CQ_MODIFY_MSG_V2 | ROCE_SUPPORT_CQ_CACHE_OUT_MSG_V2 | \
+ ROCE_SUPPORT_CQ_CHECK_DATA_STATE_MSG_V2 | \
+ ROCE_SUPPORT_QP_SRQN_LB_MSG_V2 | ROCE_SUPPORT_SET_PI_ON_CHIP_MSG_V2 | \
+ ROCE_SUPPORT_SQ_DB_TYPE_MSG_V2 | ROCE_SUPPORT_GET_QP_RX_PORT_MSG_V2 | \
+ ROCE_SUPPORT_MODIFY_UDP_SRC_PORT_MSG_V2 | \
+ ROCE_SUPPORT_GET_QP_UDP_SRC_PORT_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_MPT_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_CQ_MSG_V2 | \
+ ROCE_SUPPORT_DFX_CMD_QUERY_GID_MSG_V2 | \
+ ROCE_SUPPORT_RETRY_LOAD_CQC_MSG_FEATURE | \
+ ROCE_SUPPORT_SET_HASH_VALUE_MSG_V2 | \
+ ROCE_SUPPORT_CC_GET_LDCP_ENABLE | ROCE_SUPPORT_SML_MAC_TABLE | \
+ ROCE_SUPPORT_CC_PARAM_V1)
+/**< 1823V200 支持的所有内核态增强属性协商消息 */
+#define ROCE_SUPPORT_HI1823_V200_USER_EXT \
+ (ROCE_SUPPORT_USR_SQ_DB_TYPE_23 | ROCE_SUPPORT_DWQE_FEATURE)
+/**< 1823V200 支持的所有用户态增强属性协商消息 */
+
+#define ROCE_SUPPORT_HI1823_V100_KERNEL_EXT \
+ (ROCE_SUPPORT_ALLOC_QPC_MSG_FEATURE | \
+ ROCE_SUPPORT_GET_OQID_MSG_FEATURE | \
+ ROCE_SUPPORT_RETRY_LOAD_CQC_MSG_FEATURE | \
+ ROCE_SUPPORT_SML_MAC_TABLE | ROCE_SUPPORT_CC_PARAM_V1)
+/**< 1823V100 支持的所有内核态增强属性协商消息 */
+
+#endif /* ROCE_CFG_FORMAT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_ctx_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_ctx_format.h
new file mode 100644
index 000000000..ebdf1e2ff
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_ctx_format.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA common context format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_CTX_FORMAT_H
+#define ROCE_CTX_FORMAT_H
+#include "base_type.h"
+/* ********************** sync info ************************ */
+#define ROCE_CACHE_LINE_SIZE (0x100)
+#define ROCE_PAGE_SIZE 4096
+#define ROCE_RC_ENTRY_NUM_PER_CACELINE 8
+
+/**
+ * @brief struct roce_latch_header/roce_latch_header_u
+ * @details roce latch data 4B header
+ */
+typedef union roce_latch_data_header {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 magic_num : 8; // 使用magic number校验是否valid,对于invalid状态需清零
+ u32 first_seq : 4;
+ u32 last_seq : 4;
+ u32 latch_total_len : 16;
+#else
+ u32 latch_total_len : 16;
+ u32 last_seq : 4;
+ u32 first_seq : 4;
+ u32 magic_num : 8; // 使用magic number校验是否valid,对于invalid状态需清零
+#endif
+ } bs;
+ u32 value;
+} roce_latch_data_header_u;
+
+enum {
+ ROCE_QP_ST_RC = 0x0, /* 000 */
+ ROCE_QP_ST_UC = 0x1, /* 001 */
+ ROCE_QP_ST_RD = 0x2, /* 010 */
+ ROCE_QP_ST_UD = 0x3, /* 011 */
+ ROCE_QP_ST_XRC = 0x6, /* 110 */
+ ROCE_QP_ST_PRIV = 0x7 /* 111 */
+};
+
+#endif /* ROCE_CTX_FORMAT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_hyper_npu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_hyper_npu_cmd.h
new file mode 100644
index 000000000..bb8005420
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_hyper_npu_cmd.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: HyperRoCE verbs QP processing.
+ */
+
+#ifndef ROCE_HYPER_NPU_CMD_H
+#define ROCE_HYPER_NPU_CMD_H
+
+#include "roce_npu_cmd_defs.h"
+
+/**< hyperRoCE sub_cmds */
+enum hyper_sub_cmd {
+ RoCE_CMD_ENABLE_HYPER_ROCE_QP,
+ RoCE_CMD_HYPER_ROCE_QUERY_QP_FIRST_512B,
+ RoCE_CMD_HYPER_ROCE_QUERY_QP_LAST_512B,
+ RoCE_CMD_INIT_MSNC_QP,
+ RoCE_CMD_MODIFY_QP_DROP_PERCENT
+};
+
+/**< hyperRoCE ext mask */
+enum qp_attr_extend_mask {
+ QP_ATTR_EXTEND_UDP_SRC_PORT = 1 << 0, /* 源UDP端口号 */
+ QP_ATTR_EXTEND_HYROCE_FEATURE = 1 << 1, /* 高阶RoCE的特性 */
+ QP_ATTR_EXTEND_LB_MODE = 1 << 2, /* 负载均衡模式 */
+ QP_ATTR_EXTEND_MULTI_PATH_CONFIG =
+ 1 << 3, /* MULTI PATH多路径模式参数配置 */
+ QP_ATTR_EXTEND_AR_CONFIG = 1 << 4, /* AR多路径模式参数配置 */
+ QP_ATTR_EXTEND_SACK_CONFIG = 1 << 5, /* 选择性重传参数配置 */
+};
+
+/**< hyperRoCE lb mode */
+enum hyroce_lb_mode {
+ HYROCE_LB_MODE_DEFAULT = 0, /* 基于QP的逐流 */
+ HYROCE_LB_MODE_MULTI_PATH, /* 多路径 */
+ HYROCE_LB_MODE_AR /* AR自适应 */
+};
+
+typedef struct roce_verbs_enable_hyper_qp {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 attr_ext_mask : 6;
+ u32 srp_en : 1;
+ u32 hyper_mode : 2;
+ u32 lb_mode : 2;
+ u32 rsvd : 5;
+ u32 base_src_port : 16;
+#else
+ u32 base_src_port : 16;
+ u32 rsvd : 5;
+ u32 lb_mode : 2;
+ u32 hyper_mode : 2;
+ u32 srp_en : 1;
+ u32 attr_ext_mask : 6;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 path_rr_enable : 1; /* mpath模式下的rr_enable,未使用 */
+ u32 sport_interval : 5;
+ u32 sport_repeat_num : 6;
+ u32 path_num : 6;
+ u32 cc_mode : 2;
+ u32 port_rr_enable : 1; /* AR模式下的rr_enable */
+ u32 rsvd : 11;
+#else
+ u32 rsvd : 11;
+ u32 port_rr_enable : 1;
+ u32 cc_mode : 2;
+ u32 path_num : 6;
+ u32 sport_repeat_num : 6;
+ u32 sport_interval : 5;
+ u32 path_rr_enable : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 srp_range_n : 16;
+ u32 oor_range_m : 16;
+#else
+ u32 oor_range_m : 16;
+ u32 srp_range_n : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+} roce_verbs_enable_hyper_qp_info_s;
+
+typedef struct roce_uni_cmd_enable_hyper_roce_cmd {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_enable_hyper_qp_info_s cmd_info;
+} roce_uni_cmd_enable_hyper_roce_s;
+
+/**< init tx/rxmsnc data struct */
+typedef struct roce_verbs_init_msnc_info {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 txmsn_entry_size : 2;
+ u32 txmsn_table_size : 3;
+ u32 sack_bitmap_size : 3;
+ u32 txmsn_table_gpa_h : 24;
+#else
+ u32 txmsn_table_gpa_h : 24;
+ u32 sack_bitmap_size : 3;
+ u32 txmsn_table_size : 3;
+ u32 txmsn_entry_size : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ u32 txmsn_table_gpa_l;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rxmsn_entry_size0 : 2;
+ u32 rxmsn_table_size0 : 2;
+ u32 rsvd : 4;
+ u32 rxmsn_table_gpa0_h : 24;
+#else
+ u32 rxmsn_table_gpa0_h : 24;
+ u32 rsvd : 4;
+ u32 rxmsn_table_size0 : 2;
+ u32 rxmsn_entry_size0 : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ u32 rxmsn_table_gpa0_l;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sack_bitmap_size : 3;
+ u32 rxmsn_entry_size1 : 2;
+ u32 rxmsn_table_size1 : 2;
+ u32 rsvd : 1;
+ u32 rxmsn_table_gpa1_h : 24;
+#else
+ u32 rxmsn_table_gpa1_h : 24;
+ u32 rsvd : 1;
+ u32 rxmsn_table_size1 : 2;
+ u32 rxmsn_entry_size1 : 2;
+ u32 sack_bitmap_size : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ u32 rxmsn_table_gpa1_l;
+} roce_verbs_init_msnc_info_s;
+
+typedef struct roce_muiti_cmd_init_msnc_cmd {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_init_msnc_info_s cmd_info;
+} roce_uni_cmd_init_msnc_s;
+
+/**< hyperRoCE query qp data construct */
+typedef struct roce_uni_cmd_hyper_roce_query_qp_cmd {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_hyper_roce_query_qp_s;
+
+typedef struct hyper_qp_first_512B {
+ u32 qpc[128]; /* npu can translate it to hyper_roce_qp_context_s */
+} hyper_qp_first_512B_s;
+
+typedef struct hyper_qp_last_512B {
+ u32 ext_sw_seg[80];
+ u32 ext_hw_seg[48];
+} hyper_qp_last_512B_s;
+
+typedef struct roce_hyper_roce_query_512B {
+ union {
+ hyper_qp_first_512B_s first_512B;
+ hyper_qp_last_512B_s last_512B;
+ } hyper_qpc;
+} roce_hyper_roce_query_512B_s;
+
+/**< hyperRoCE modify/query rsp drop percent data struct */
+typedef struct roce_verbs_qp_drop_percent_info {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 drop_precent : 7;
+ u32 rsvd : 25;
+#else
+ u32 rsvd : 25;
+ u32 drop_precent : 7;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+} roce_verbs_qp_drop_percent_info_s;
+
+typedef struct roce_uni_cmd_modify_qp_drop_percent_cmd {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_qp_drop_percent_info_s cmd_info;
+} roce_uni_cmd_modify_qp_drop_percent_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd.h
new file mode 100644
index 000000000..b7133e2b9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA npu commonds.
+ * Create: 2023-10-11
+ */
+
+#ifndef ROCE_NPU_CMD_H
+#define ROCE_NPU_CMD_H
+
+/*
+ * Commands between RoCE driver to NPU
+ */
+enum {
+ /* ULP CMD, ULP共预留16*4个, 范围0x20-0x5f */
+ /* 给计算分配16个, 范围0x20-0x2f */
+ ROCE_ULP_CMD_START = 0x20,
+ ROCE_ULP_CMD_END = 0x5f,
+
+ /* GID CMD */
+ ROCE_CMD_UPDATE_GID =
+ 0x60, /**< Update GID table @see > roce_uni_cmd_update_gid_s */
+ ROCE_CMD_QUERY_GID =
+ 0x61, /**< Query GID table @see > roce_uni_cmd_query_gid_s */
+ ROCE_CMD_CLEAR_GID =
+ 0x62, /**< Clear GID table @see > roce_uni_cmd_clear_gid_s */
+
+ /* TPT CMD */
+ ROCE_CMD_SW2HW_MPT =
+ 0x70, /**< Init MPT context to HW @see > roce_uni_cmd_mpt_sw2hw_s */
+ ROCE_CMD_HW2SW_MPT =
+ 0x71, /**< Deinit MPT context from HW @see > roce_uni_cmd_mpt_hw2sw_s */
+ ROCE_CMD_MODIFY_MPT = 0x72, /**< Unused */
+ ROCE_CMD_QUERY_MPT =
+ 0x73, /**< Query MPT context from HW @see > roce_uni_cmd_mpt_query_s */
+ ROCE_CMD_FLUSH_TPT = 0x74, /**< Unused */
+ ROCE_CMD_SYNC_TPT = 0x75, /**< Unused */
+
+ /* CQ CMD */
+ ROCE_CMD_SW2HW_CQ =
+ 0x80, /**< Init CQ context to HW @see > roce_uni_cmd_create_cq_s */
+ ROCE_CMD_RESIZE_CQ =
+ 0x81, /**< Resize CQ and notify HW @see > roce_uni_cmd_resize_cq_s */
+ ROCE_CMD_MODIFY_CQ =
+ 0x82, /**< Modify CQ context in HW @see > roce_uni_cmd_modify_cq_s */
+ ROCE_CMD_HW2SW_CQ =
+ 0x83, /**< Deinit CQ context from HW @see > roce_uni_cmd_cq_hw2sw_s */
+ ROCE_CMD_QUERY_CQ =
+ 0x84, /**< Query CQ context in HW @see > roce_uni_cmd_cq_query_s */
+
+ /* SRQ CMD */
+ ROCE_CMD_SW2HW_SRQ =
+ 0x90, /**< Init SRQ context to HW @see > roce_uni_cmd_create_srq_s */
+ ROCE_CMD_ARM_SRQ =
+ 0x91, /**< Arm SRQ to HW @see > roce_uni_cmd_srq_arm_s */
+ ROCE_CMD_HW2SW_SRQ =
+ 0x92, /**< Deinit SRQ context from HW @see > roce_uni_cmd_srq_hw2sw_s */
+ ROCE_CMD_QUERY_SRQ =
+ 0x93, /**< Query SRQ context in HW @see > roce_uni_cmd_srq_query_s */
+
+ /* QP CMD */
+ ROCE_CMD_RST2INIT_QP =
+ 0xa0, /**< Modify QP context from reset to init state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_INIT2INIT_QP =
+ 0xa1, /**< Modify QP context from init to init state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_INIT2RTR_QP =
+ 0xa2, /**< Modify QP context from init to rtr state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_RTR2RTS_QP =
+ 0xa3, /**< Modify QP context from rtr to rts state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_RTS2RTS_QP =
+ 0xa4, /**< Modify QP context from rts to rts state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_SQERR2RTS_QP =
+ 0xa5, /**< Modify QP context from sqerr to rts state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_2ERR_QP =
+ 0xa6, /**< Modify QP context from any state to err state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_RTS2SQD_QP =
+ 0xa7, /**< Modify QP context from rts to sqd state @see > roce_uni_cmd_qp_modify_rts2sqd_s */
+ ROCE_CMD_SQD2SQD_QP =
+ 0xa8, /**< Modify QP context from sqd to sqd state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_SQD2RTS_QP =
+ 0xa9, /**< Modify QP context from sqd to rts state @see > roce_uni_cmd_modify_qpc_s */
+ ROCE_CMD_2RST_QP =
+ 0xaa, /**< Modify QP context from any state to reset state @see > roce_uni_cmd_qp_modify2rst_s */
+ ROCE_CMD_QUERY_QP =
+ 0xab, /**< Query QP context from HW @see > roce_uni_cmd_qp_query_s */
+ ROCE_CMD_MIRROR_QP = 0xac, /**< Unused */
+ ROCE_CMD_MODIFY_HASH_VALUE_QP =
+ 0xad, /**< Modify bond hash in QP context @see > roce_uni_cmd_modify_hash_s */
+ ROCE_CMD_GET_RX_PORT_QP =
+ 0xae, /**< Query rx port from QP context @see > roce_uni_cmd_get_port_info_s */
+ ROCE_CMD_MODIFY_UDP_SRC_PORT_QP =
+ 0xaf, /**< Modify src port in QP context @see > roce_uni_cmd_set_udp_src_port_s */
+ ROCE_CMD_GET_UDP_SRC_PORT_QP =
+ 0xb0, /**< Query udp src port from QP context @see > roce_uni_cmd_get_port_info_s */
+ ROCE_CMD_GET_HASH_VALUE_QP =
+ 0xb1, /**< Query hash from QP context @see > roce_uni_cmd_get_hash_s */
+
+ /* HyperRoCE CMD */
+ RoCE_CMD_HYPER_ROCE =
+ 0xbf, /**< HyperRoCE CMD entrance @see > e.g.roce_uni_cmd_enable_hyper_roce_s */
+
+ /* MTT commands */
+ ROCE_CMD_QUERY_MTT = 0xc0, /**< Unused */
+
+ /* DFX commands */
+ ROCE_CMD_MODIFY_CONTEXT = 0xd0, /**< Unused */
+ ROCE_CMD_EN_QP_CAP_PKT = 0xd1, /**< Unused */
+ ROCE_CMD_DIS_QP_CAP_PKT = 0xd2, /**< Unused */
+
+ /* COMM commands */
+ ROCE_CMD_GET_CHIP_ABILITY =
+ 0xd3, /**< Provide cmd for feature negotiate @see > roce_get_chip_ability_s */
+
+ /* LATCH commands */
+ ROCE_CMD_LATCH_DFX = 0xd4, /** 锁存的dfx接口处理 */
+ ROCE_CMD_SET_LATCH_QP =
+ 0xd5, /**< Set RoCE latch RDMARC table attribute to qpc @see > roce_uni_cmd_modify_qpc_s */
+
+ /* CACHE commands */
+ ROCE_CMD_MISC_CACHE_INVLD =
+ 0xe0, /**< Invalid QP context cache from HW @see > roce_uni_cmd_qp_cache_invalid_s */
+ ROCE_CMD_MISC_CQ_CACHE_INVLD =
+ 0xf0, /**< Invalid CQ context cache from HW @see > roce_uni_cmd_cq_cache_invalid_s */
+
+ /* ULP CMD */
+ ROCE_CMD_CREAT_SLAVE_QP = 0xf1, /**< Unused */
+ ROCE_CMD_QUERY_MASTER_QP_BITMAP = 0xf2, /**< Unused */
+ ROCE_CMD_GET_MASTER_QPN = 0xf3, /**< Unused */
+ ROCE_CMD_SET_CONN_STAT = 0xf4, /**< Unused */
+ ROCE_CMD_DISCONNECT_QP = 0xf5, /**< Unused */
+ ROCE_CMD_SET_SHARD_CFG = 0xf6, /**< Unused */
+
+ ROCE_CMD_ULP_EXTEND = 0xff, /* Command word entry provided to ULP */
+};
+
+#define ROCE_VERBS_CMD_TYPE_GET(sub_type) ((sub_type) >> 4)
+enum {
+ ROCE_GID_CMD = 0x6,
+ ROCE_MR_CMD = 0x7,
+ ROCE_CQ_CMD = 0x8,
+ ROCE_SRQ_CMD = 0x9,
+ ROCE_QP_CMD = 0xa,
+ ROCE_MTT_CMD = 0xc,
+ ROCE_DFX_CMD = 0xd,
+ ROCE_CACHE_INLVD_CMD = 0xe
+};
+#endif /* ROCE_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_cq_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_cq_defs.h
new file mode 100644
index 000000000..3164870ec
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_cq_defs.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq cq attribute context.
+ * Create: 2021-04-22
+ */
+
+#ifndef ROCE_VERBS_CQ_ATTR_H
+#define ROCE_VERBS_CQ_ATTR_H
+
+#include "roce_npu_cmd_mr_defs.h"
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#pragma pack(4)
+typedef struct tag_roce_verbs_cq_attr_dfx {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ci : 24;
+ u32 rsvd : 8;
+#else
+ u32 rsvd : 8;
+ u32 ci : 24;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 pi : 24;
+ u32 rsvd : 8;
+#else
+ u32 rsvd : 8;
+ u32 pi : 24;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 load_ci : 1;
+ u32 last_solicited_pi : 24;
+ u32 rsvd : 7;
+#else
+ u32 rsvd : 7;
+ u32 last_solicited_pi : 24;
+ u32 load_ci : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 last_notified_pi : 24;
+ u32 rsvd : 8;
+#else
+ u32 rsvd : 8;
+ u32 last_notified_pi : 24;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+} roce_verbs_cq_attr_dfx_s;
+
+typedef struct roce_verbs_cq_attr {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 signature : 5;
+ u32 ci_on_chip : 1;
+ u32 cnt_clear_en : 1;
+ u32 cnt_adjust_en : 1;
+ u32 rsvd : 3;
+ u32 timer_mode : 1;
+ u32 arm_timer_en : 1;
+ u32 tss_timer_num : 3;
+ u32 mtt_page_size : 4;
+ u32 cqe_size : 3;
+ u32 page_size : 4;
+ u32 size : 5;
+#else
+ u32 size : 5; /* Completion Queue size, equals to (2^cq_size)*CQE.
+ The maximum CQ size is 2^23 CQEs. */
+ u32 page_size : 4; /* Page size of CQ, equals to (2^cq_page_size)*4KB. */
+ u32 cqe_size : 3; /* Completion Queue Entry (CQE) size in bytes is (2^cq_cqe_size)*16B.
+ The minimum size is 32B and the values 0, 3, 4, 5, 6, 7 are reserved. */
+ u32 mtt_page_size : 4;
+ u32 tss_timer_num : 3;
+ u32 arm_timer_en : 1;
+ u32 timer_mode : 1;
+ u32 rsvd : 3;
+ u32 cnt_adjust_en : 1;
+ u32 cnt_clear_en : 1;
+ u32 ci_on_chip : 1; /* If set, the CI of Complete Queue is stored in the chip,
+ the counter is absolute value. */
+ u32 signature : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 state : 4;
+ u32 rsvd : 14;
+ u32 ep : 3;
+ u32 cos : 3;
+ u32 so_ro : 2;
+ u32 dma_attr_idx : 6;
+#else
+ u32 dma_attr_idx : 6; /* It specifies the outbound PCIe TLP header attribute of the DMA operation.
+ * This filed is only valid when processing CQ's CQEs. */
+ u32 so_ro : 2; /* It specifies the ATTR[1:0] bits in the outbound PCIe TLP headers of the DMA operation.
+ * This field is only valid when processing CQ's CQEs.
+ * 2'b00: Strict Ordering;
+ * 2'b01: Relaxed Ordering;
+ * 2'b10: ID Based Ordering;
+ * 2'b11: Both Relaxed Ordering and ID Based Ordering. */
+ u32 cos : 3;
+ u32 ep : 3;
+ u32 rsvd : 14;
+ u32 state : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ceqn : 8;
+ u32 rsvd : 1;
+ u32 arm_ceqe_en : 1;
+ u32 ceqe_en : 1;
+ u32 cqecnt_rctl_en : 1;
+ u32 cqecnt_lth : 4;
+ u32 idle_max_count : 16;
+#else
+ u32 idle_max_count : 16;
+ u32 cqecnt_lth : 4;
+ u32 cqecnt_rctl_en : 1;
+ u32 ceqe_en : 1;
+ u32 arm_ceqe_en : 1;
+ u32 rsvd : 1;
+ u32 ceqn : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 max_cnt : 16;
+ u32 timeout : 16;
+#else
+ u32 timeout : 16; /* Completion Event Moderation timer in microseconds.
+ 0x0: interrupt moderation disabled. */
+ u32 max_cnt : 16; /* Completion Event Moderation counters.
+ 0x0: interrupt moderation disabled. */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4 - DW5 */
+ union {
+ u64 cqc_l0mtt_gpa; /* The GPA of Layer 0 MTT. It may point to the CQ's buffer directly.low 3bits(cq_gpa_sign) */
+ struct {
+ u32 cqc_l0mtt_gpa_hi;
+ u32 cqc_l0mtt_gpa_lo;
+ } dw4_dw5;
+ };
+
+ /* DW6 - DW7 */
+ union {
+ u64 ci_record_gpa_at_hop_num; /* The GPA of stored CI of Complete Queue.
+ * Address translation hop numbers.
+ 0x0: the 'cq_l0mtt_gpa' points to the buffer of CQ directly.
+ 0x1: it need to perform one hop address translation to get the buffer's
+ address of CQ; 0x2: there is two hop address translation to get the buffer's
+ address of CQ; 0x3: reserved. */
+ struct {
+ u32 ci_record_gpa_hi;
+ u32 ci_record_gpa_lo_at_hop_num; /* bit[1:0] Address translation hop numbers */
+ } dw6_dw7;
+ };
+
+ roce_verbs_cq_attr_dfx_s dfx_info;
+} roce_verbs_cq_attr_s;
+
+#define ROCE_VERBS_CQ_ATTR_SIZE (sizeof(roce_verbs_cq_attr_s))
+
+typedef struct tag_roce_verbs_query_cq_info {
+ u32 context[32];
+} roce_verbs_query_cq_info_s;
+
+typedef struct tag_roce_verbs_cq_resize_info {
+ /* DW0~3 */
+ u32 mtt_page_size; /* Size of the mtt page after resize. */
+ 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];
+ };
+
+ /* DW6~10 */
+ roce_verbs_mtt_cacheout_info_s cmtt_cache;
+} roce_verbs_cq_resize_info_s;
+
+typedef struct tag_roce_verbs_modify_cq_info {
+ u32 max_cnt;
+ u32 timeout;
+ u32 rsvd[12];
+} roce_verbs_modify_cq_info_s;
+#pragma pack()
+
+#endif /* ROCE_VERBS_CQ_ATTR_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_defs.h
new file mode 100644
index 000000000..15664b9e7
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_defs.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq command format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_NPU_CMD_DEFS_H
+#define ROCE_NPU_CMD_DEFS_H
+
+#include "roce_npu_cmd_qp_defs.h"
+#include "roce_npu_cmd_cq_defs.h"
+#include "roce_npu_cmd_srq_defs.h"
+#include "roce_npu_cmd_type_defs.h"
+
+enum roce5_cmd_ret_status {
+ ROCE_CMD_RET_SUCCESS = 0x0,
+
+ ROCE_CMD_RET_FLR_ERR = 0x1,
+ ROCE_CMD_RET_FUNC_INVLD,
+ ROCE_CMD_RET_CMDMISC_UNSUPPORT,
+ ROCE_CMD_RET_CMDTYPE_UNSUPPORT,
+ ROCE_CMD_RET_RET_ADDR_INVLD,
+ ROCE_CMD_RET_INDEX_INVLD,
+ ROCE_CMD_RET_LOCAL_UNSUPPORT,
+ ROCE_CMD_RET_XRC_UNSUPPORT,
+ ROCE_CMD_RET_QPC_RSP_ERR = 0x10,
+ ROCE_CMD_RET_QPC_STATE_UNEXPECT,
+ ROCE_CMD_RET_MODIFY_QP_OPT_ERR,
+ ROCE_CMD_RET_MODIFY_QP_EXTEND_OP_API_ERR,
+ ROCE_CMD_RET_SQD_QP_FETCH_WQE_ERR,
+ ROCE_CMD_RET_RDMARC_SYNC_EXTEND_OP_API_ERR,
+ ROCE_CMD_RET_MODIFY_QP_OQID_ERR,
+ ROCE_CMD_RET_CQC_STATE_UNEXPECT = 0x18,
+ ROCE_CMD_RET_CQC_MISC_API_ERR,
+ ROCE_CMD_RET_CQC_CREATE_CACHE_OUT_ERR,
+ ROCE_CMD_RET_CQ_RESIZE_API_ERR,
+ ROCE_CMD_RET_CQ_EXTEND_OP_API_ERR,
+ ROCE_CMD_RET_CQ_TIMER_DEL_ERR,
+ ROCE_CMD_RET_CQ_TIMER_REM_ERR,
+ ROCE_CMD_RET_CQ_TIMER_FLUSH_ERR,
+ ROCE_CMD_RET_SRQC_STATE_UNEXPECT = 0x20,
+ ROCE_CMD_RET_SRQ_ARM_SRQ_CONT_EN_ERR,
+ ROCE_CMD_RET_SRQ_ARM_SRQ_API_ERR,
+ ROCE_CMD_RET_SRQ_EXTEND_OP_API_ERR,
+ ROCE_CMD_RET_MR_STATE_ERR = 0x28,
+ ROCE_CMD_RET_MR_BIND_MW_API_ERR,
+ ROCE_CMD_RET_MR_EXTEND_OP_API_ERR,
+ ROCE_CMD_RET_MR_MISC_LOAD_API_ERR,
+ ROCE_CMD_RET_MR_MPTC_SYNC_ERR,
+ ROCE_CMD_RET_MR_MISC_STORE_API_ERR,
+ ROCE_CMD_RET_MR_CACHE_OUT_MPT_ERR,
+ ROCE_CMD_RET_MR_CACHE_OUT_MTT_ERR,
+ ROCE_CMD_RET_DBG_EXTEND_OP_API_ERR = 0x30,
+ ROCE_CMD_RET_DBG_WQE_UPDATE_PI_ERR,
+ ROCE_CMD_RET_QU_FLUSH_WAIT,
+ ROCE_CMD_RET_QU_FLUSH_API_ERR,
+ ROCE_CMD_RET_CACHE_INVALIED_ERR,
+ ROCE_CMD_RET_CMD_OP_LB_ERR,
+ ROCE_CMD_RET_CMD_OP_SRQN_ERR,
+ ROCE_CMD_RET_QP_EXTEND_OP_ERR,
+ ROCE_CMD_RET_LOAD_ERR,
+ ROCE_CMD_RET_STORE_ERR,
+ ROCE_CMD_RET_LOAD_HOST_GPA_ERR,
+ ROCE_CMD_RET_CACHE_OUT_ERR,
+ ROCE_CMD_RET_CACHE_OUT_MTT_ERR,
+ ROCE_CMD_RET_BANK_GPA_FLUSH_ERR,
+ ROCE_CMD_RET_INVALID_PARAM_ERR,
+ ROCE_CMD_RET_DIF_TASKID_ALLOC_ERR = 0x40,
+ ROCE_CMD_RET_DIF_TASKID_DELETE_ERR,
+ ROCE_CMD_RET_GID_INVALID_ERR,
+ ROCE_CMD_RET_GID_ENTRY_CHECK_ERR,
+ ROCE_CMD_RET_LATCH_CHK_XID_ERR = 0x50,
+ ROCE_CMD_RET_LATCH_API_ERR = 0x51,
+ ROCE_CMD_RET_VROCE_SEC_MEM_CHECK_FAIL = 0xf0,
+ ROCE_CMD_RET_RSVD_ERR = 0xff,
+};
+
+enum roce5_cmd_ret_extend_op_err {
+ ROCE_CMD_RET_EXTEND_OP_NONE = 0x0,
+
+ ROCE_CMD_RET_EXTEND_OP_RCC_RRE = 0x1,
+ ROCE_CMD_RET_EXTEND_OP_RCC_RAE,
+ ROCE_CMD_RET_EXTEND_OP_RRWC_RWE,
+ ROCE_CMD_RET_EXTEND_OP_RRWC_STA,
+ ROCE_CMD_RET_EXTEND_OP_RCC_STA,
+ ROCE_CMD_RET_EXTEND_OP_SQC_STA,
+ ROCE_CMD_RET_EXTEND_OP_SQAC_STA,
+ ROCE_CMD_RET_EXTEND_OP_RQC_STA,
+ ROCE_CMD_RET_EXTEND_OP_CQC_TIMEOUT = 0x10,
+ ROCE_CMD_RET_EXTEND_OP_CQC_STA,
+ ROCE_CMD_RET_EXTEND_OP_SQC_COS,
+ ROCE_CMD_RET_EXTEND_OP_RCC_COS,
+ ROCE_CMD_RET_EXTEND_OP_SRQC_STA = 0x18,
+ ROCE_CMD_RET_EXTEND_OP_MPT_STA = 0x20,
+ ROCE_CMD_RET_EXTEND_OP_QPC_DBG_EDIT = 0x28,
+ ROCE_CMD_RET_EXTEND_OP_CQC_SRQC_DBG_EDIT
+};
+
+/* Mask description of *********ROCE verbs modify qp ******* */
+/* ******************************************************************
+ opt INIT2INIT INIT2RTR RTR2RTS RTS2RTS SQERR2RTS SQD2SQD SQD2RTS
+QP_OPTPAR_ALT_ADDR_PATH 0 √ √ √ √ √
+QP_OPTPAR_RRE 1 √ √ √ √ √ √ √
+QP_OPTPAR_RAE 2 √ √ √ √ √ √ √
+QP_OPTPAR_RWE 3 √ √ √ √ √ √ √
+QP_OPTPAR_PKEY_INDEX 4
+QP_OPTPAR_Q_KEY 5 √ √ √ √ √ √ √
+QP_OPTPAR_RNR_TIMEOUT 6 √ √ √ √ √
+QP_OPTPAR_PRIMARY_ADDR_PATH 7 √ √
+QP_OPTPAR_SRA_MAX 8 √ √
+QP_OPTPAR_RRA_MAX 9 √ √
+QP_OPTPAR_PM_STATE 10 √ √ √ √
+QP_OPTPAR_RETRY_COUNT 11 √ √
+QP_OPTPAR_RNR_RETRY 12 √ √
+QP_OPTPAR_ACK_TIMEOUT 13 √ √
+QP_OPTPAR_SCHED_QUEUE 14
+QP_OPTPAR_COUNTER_INDEX 15
+******************************************************************** */
+enum QP_OPTPAR_E {
+ QP_OPTPAR_ALT_ADDR_PATH = 0,
+ QP_OPTPAR_RRE,
+ QP_OPTPAR_RAE,
+ QP_OPTPAR_RWE,
+ QP_OPTPAR_PKEY_INDEX,
+ QP_OPTPAR_Q_KEY,
+ QP_OPTPAR_RNR_TIMEOUT,
+ QP_OPTPAR_PRIMARY_ADDR_PATH,
+ QP_OPTPAR_SRA_MAX = 8,
+ QP_OPTPAR_RRA_MAX,
+ QP_OPTPAR_PM_STATE,
+ QP_OPTPAR_RETRY_COUNT,
+ QP_OPTPAR_RNR_RETRY,
+ QP_OPTPAR_ACK_TIMEOUT,
+ QP_OPTPAR_SCHED_QUEUE,
+ QP_OPTPAR_COUNTER_INDEX = 15
+};
+
+#define ROCE_QP_ALT_ADDR_PATH_OPT (1u << QP_OPTPAR_ALT_ADDR_PATH)
+#define ROCE_QP_RRE_OPT (1u << QP_OPTPAR_RRE)
+#define ROCE_QP_RAE_OPT (1u << QP_OPTPAR_RAE)
+#define ROCE_QP_RWE_OPT (1u << QP_OPTPAR_RWE)
+#define ROCE_QP_PKEY_INDEX_OPT (1u << QP_OPTPAR_PKEY_INDEX)
+#define ROCE_QP_Q_KEY_OPT (1u << QP_OPTPAR_Q_KEY)
+#define ROCE_QP_RNR_TIMEOUT_OPT (1u << QP_OPTPAR_RNR_TIMEOUT)
+#define ROCE_QP_PRIMARY_ADDR_PATH_OPT (1u << QP_OPTPAR_PRIMARY_ADDR_PATH)
+#define ROCE_QP_SRA_MAX_OPT (1u << QP_OPTPAR_SRA_MAX)
+#define ROCE_QP_RRA_MAX_OPT (1u << QP_OPTPAR_RRA_MAX)
+#define ROCE_QP_PM_STATE_OPT (1u << QP_OPTPAR_PM_STATE)
+#define ROCE_QP_RETRY_COUNT_OPT (1u << QP_OPTPAR_RETRY_COUNT)
+#define ROCE_QP_RNR_RETRY_OPT (1u << QP_OPTPAR_RNR_RETRY)
+#define ROCE_QP_ACK_TIMEOUT_OPT (1u << QP_OPTPAR_ACK_TIMEOUT)
+#define ROCE_QP_SCHED_QUEUE_OPT (1u << QP_OPTPAR_SCHED_QUEUE)
+#define ROCE_QP_COUNTER_INDEX_OPT (1u << QP_OPTPAR_COUNTER_INDEX)
+
+#define ROCE_MODIFY_QP_INIT2INIT_OPT (~0x402e)
+#define ROCE_MODIFY_QP_INIT2RTR_OPT (~0x2ee)
+#define ROCE_MODIFY_QP_RTR2RTS_OPT (~0x3d6e)
+#define ROCE_MODIFY_QP_RTS2RTS_OPT (~0x46e)
+#define ROCE_MODIFY_QP_SQERR2RTS_OPT (~0x2e)
+#define ROCE_MODIFY_QP_SQD2SQD_OPT (~0x7fee)
+#define ROCE_MODIFY_QP_SQD2RTS_OPT (~0x46e)
+#define ROCE_MODIFY_QP_RTS2RTS_EXP_OPT (~0x10000)
+#define ROCE_MODIFY_QP_RTS2SQD_SQD_EVENT_OPT (0x80000000)
+
+#define ROCE_CMDQ_HDR_LEN (sizeof(roce_verbs_cmd_header_s))
+#define ROCE_CMDQ_QP_ATTR_LEN (sizeof(roce_verbs_qp_attr_s))
+#define ROCE_CMDQ_SRQ_ATTR_LEN (sizeof(roce_verbs_srq_attr_s))
+#define ROCE_CMDQ_CQ_ATTR_LEN (sizeof(roce_verbs_cq_attr_s))
+#define ROCE_CMDQ_MR_ATTR_LEN (sizeof(roce_verbs_mr_attr_s))
+
+typedef struct tag_roce_uni_cmd_flush_mpt {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_flush_mpt_s;
+
+typedef struct tag_roce_uni_cmd_mpt_query {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_mpt_query_s;
+
+typedef struct tag_roce_uni_cmd_mpt_query_outbuf {
+ roce_verbs_query_mpt_info_s mpt_info;
+} roce_uni_cmd_mpt_query_outbuf_s;
+
+typedef struct tag_roce_uni_cmd_sw2hw_mpt {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_mr_attr_s mr_attr;
+} roce_uni_cmd_mpt_sw2hw_s;
+
+typedef struct tag_roce_uni_cmd_modify_mpt {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_mr_sge_s mr_sge;
+} roce_uni_cmd_modify_mpt_s;
+
+typedef struct tag_roce_uni_cmd_mpt_hw2sw {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_mtt_cacheout_info_s dmtt_cache;
+} roce_uni_cmd_mpt_hw2sw_s;
+
+typedef struct tag_roce_uni_cmd_query_mtt {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_query_mtt_info_s mtt_query;
+} roce_uni_cmd_query_mtt_s;
+
+typedef struct tag_roce_uni_cmd_creat_cq {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_cq_attr_s cq_attr;
+} roce_uni_cmd_create_cq_s;
+
+typedef struct tag_roce_uni_cmd_resize_cq {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_cq_resize_info_s cq_resize;
+} roce_uni_cmd_resize_cq_s;
+
+typedef struct tag_roce_uni_cmd_modify_cq {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_modify_cq_info_s cq_modify;
+} roce_uni_cmd_modify_cq_s;
+
+typedef struct tag_roce_uni_cmd_cq_hw2sw {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_mtt_cacheout_info_s cmtt_cache;
+} roce_uni_cmd_cq_hw2sw_s;
+
+typedef struct tag_roce_uni_cmd_roce_cq_query {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_cq_query_s;
+
+typedef struct tag_roce_uni_cmd_cq_query_outbuf {
+ roce_verbs_query_cq_info_s cq_info;
+} roce_uni_cmd_cq_query_outbuf_s;
+
+typedef struct tag_roce_uni_cmd_creat_srq {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_srq_attr_s srq_attr;
+} roce_uni_cmd_create_srq_s;
+
+typedef struct tag_roce_uni_cmd_srq_arm {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_arm_srq_info_u srq_arm;
+} roce_uni_cmd_srq_arm_s;
+
+typedef struct tag_roce_uni_cmd_srq_hw2sw {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_srq_hw2sw_info_s srq_cache;
+} roce_uni_cmd_srq_hw2sw_s;
+
+typedef struct tag_roce_uni_cmd_srq_query {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_srq_query_s;
+
+typedef struct tag_roce_uni_cmd_srq_query_outbuf {
+ roce_verbs_query_srq_info_s com;
+} roce_uni_cmd_srq_query_outbuf_s;
+
+typedef struct tag_roce_uni_cmd_modify_qpc {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_qp_attr_s qp_attr;
+} roce_uni_cmd_modify_qpc_s;
+
+typedef struct tag_roce_uni_cmd_qp_modify2rst {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_qp_modify2rst_s;
+
+typedef struct tag_roce_uni_cmd_qp_modify_rts2sqd {
+ roce_verbs_cmd_header_s com;
+ u32 sqd_event_en;
+} roce_uni_cmd_qp_modify_rts2sqd_s;
+
+typedef struct tag_roce_uni_cmd_qp_query {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_qp_query_s;
+
+typedef struct tag_roce_uni_cmd_qp_query_outbuf {
+ roce_verbs_query_qp_info_s qp_info;
+} roce_uni_cmd_qp_query_outbuf_s;
+
+typedef struct tag_roce_uni_cmd_qp_cache_invalid {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_qp_hw2sw_info_s qp_cache;
+} roce_uni_cmd_qp_cache_invalid_s;
+
+typedef struct tag_roce_uni_cmd_cq_cache_invalid {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_xq_mtt_info_s mtt_info;
+} roce_uni_cmd_cq_cache_invalid_s;
+
+typedef struct tag_roce_uni_cmd_modify_ctx {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_modify_ctx_info_s ctx_modify;
+} roce_uni_cmd_modify_ctx_s;
+
+typedef struct tag_roce_uni_cmd_cap_pkt {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_cap_pkt_s;
+
+typedef struct tag_roce_uni_cmd_set_udp_src_port {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_udp_src_port_info_s info;
+} roce_uni_cmd_set_udp_src_port_s;
+
+typedef struct tag_roce_uni_cmd_get_port_info {
+ roce_verbs_cmd_header_s com;
+} roce_uni_cmd_get_port_info_s;
+
+typedef struct tag_roce_uni_cmd_get_port_info_outbuf {
+ roce_verbs_dfx_info_s value;
+} roce_uni_cmd_get_port_info_outbuf_s;
+
+typedef struct tag_roce_uni_cmd_modify_hash {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_qp_hash_info_s info;
+} roce_uni_cmd_modify_hash_s;
+
+typedef struct tag_roce_uni_cmd_get_hash {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_qp_hash_info_s info;
+} roce_uni_cmd_get_hash_s;
+
+#endif /* ROCE_NPU_CMD_DEFS_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_dfx_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_dfx_defs.h
new file mode 100644
index 000000000..5ff6ccc5b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_dfx_defs.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq command format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_NPU_CMD_DFX_DEFS_H
+#define ROCE_NPU_CMD_DFX_DEFS_H
+
+#include "roce_npu_cmd_defs.h"
+
+/* 按照最大entry_size=32,最大深度2k配置 */
+#define ROCE_RDMARC_MAX_ENTRY_SIZE 32
+#define ROCE_LATCH_DATA_MAX_SIZE 2032
+#define ROCE_LATCH_VALID_VERIFY_NUM 0x66
+/**
+ * @brief struct tag_roce_uni_cmd_latch_data/roce_uni_cmd_latch_data_s
+ * @details roce latch data out buffer
+ */
+typedef struct roce_uni_cmd_latch_data {
+ u32 latch_data_len;
+ u32 rsvd[3];
+ u8 latch_data[ROCE_LATCH_DATA_MAX_SIZE];
+} roce_uni_cmd_latch_data_s;
+
+/**
+ * @brief struct tag_roce_uni_cmd_rdma_rc_outbuf/roce_uni_cmd_rdma_rc_outbuf_s
+ * @details rdma rc out buffer
+ */
+typedef struct tag_roce_uni_cmd_rdma_rc_outbuf {
+ u32 rc_table_size;
+ u8 rdmarc[ROCE_RDMARC_MAX_ENTRY_SIZE];
+} roce_uni_cmd_rdma_rc_outbuf_s;
+
+typedef struct tag_roce_latch_info_rc {
+ u8 get_latch_info; // TRUE:获取锁存信息 FALSE:清理锁存信息,后续新增考虑枚举
+ u8 rc_entry_idx;
+ u16 rsvd;
+} roce_latch_info_rc_s;
+
+typedef struct tag_roce_dfx_cmd_latch_info {
+ roce_verbs_cmd_header_s com;
+ roce_latch_info_rc_s latch_info;
+} roce_dfx_cmd_latch_info_s;
+
+#endif /* ROCE_NPU_CMD_DFX_DEFS_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_ext_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_ext_defs.h
new file mode 100644
index 000000000..066801798
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_ext_defs.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq extended attributes.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_VERBS_EXT_ATTR_H
+#define ROCE_VERBS_EXT_ATTR_H
+
+#include "roce_npu_cmd_defs.h"
+#include "roce_npu_cmd_ext_data_defs.h"
+
+#pragma pack(4)
+
+typedef struct roce_vtep_context {
+ u32 dmac_h32;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 dmac_l16 : 16;
+ u32 smac_h16 : 16;
+#else
+ u32 smac_h16 : 16;
+ u32 dmac_l16 : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ u32 smac_l32;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 portid : 8;
+ u32 vni : 24;
+#else
+ u32 vni : 24;
+ u32 portid : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ u32 sip[4]; // dw4 ~ 7
+ u32 dip[4]; // dw8 ~ 11
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 src_port : 16;
+ u32 dst_port : 16;
+#else
+ u32 dst_port : 16;
+ u32 src_port : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw12;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 base_id : 8;
+ u32 cvlan : 12;
+ u32 svlan : 12;
+#else
+ u32 svlan : 12;
+ u32 cvlan : 12;
+ u32 base_id : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw13;
+
+ u32 remote_acl_id; // acl(access list) 减少重复查src vtep表次数以缩短时延,仅在第一次查找时将src vtep值赋给vtep
+
+ /* DW15 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 5;
+ u32 vm_dp_capture_en : 1;
+ u32 vm_dp_chk_en : 1;
+ u32 vm_dp_chk_invld : 1;
+ u32 dscp_rc : 8;
+ u32 dscp_ud : 8;
+ u32 dscp_xrc : 8;
+#else
+ u32 dscp_xrc : 8;
+ u32 dscp_ud : 8;
+ u32 dscp_rc : 8;
+ u32 vm_dp_chk_invld : 1;
+ u32 vm_dp_chk_en : 1;
+ u32 vm_dp_capture_en : 1;
+ u32 rsvd : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw15;
+} roce_vtep_context_s;
+
+/* 该数据结构由微码使用,在驱动侧进行大小端转换 */
+typedef struct tag_roce_get_chip_ability {
+ u64 roce_kernel_ability;
+ u64 roce_kernel_ext_ability;
+ u64 roce_user_ext_ability;
+ roce_uld_feature_s uld_feature;
+ u64 rsvd;
+} roce_get_chip_ability_s;
+
+#pragma pack()
+
+#endif /* ROCE_VERBS_EXT_ATTR_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_gid_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_gid_defs.h
new file mode 100644
index 000000000..16ba0825f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_gid_defs.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq gid attribute context.
+ * Create: 2021-04-22
+ */
+#ifndef ROCE_VERBS_GID_ATTR_H
+#define ROCE_VERBS_GID_ATTR_H
+
+#include "roce_npu_cmd_defs.h"
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#pragma pack(4)
+typedef struct tag_roce_verbs_gid_ipv4_attr {
+ /* DW0 */
+ union {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 udpudp_len_gap : 8;
+ u32 rsvd : 8;
+ u32 bth_addr : 16;
+#else
+ u32 bth_addr : 16;
+ u32 rsvd : 8;
+ u32 udpudp_len_gap : 8;
+#endif
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ip_addr : 16;
+ u32 udp_addr : 16;
+#else
+ u32 udp_addr : 16;
+ u32 ip_addr : 16;
+#endif
+ u32 value;
+ } dw1;
+} roce_verbs_gid_ipv4_attr_s;
+
+typedef struct tag_roce_verbs_gid_attr {
+ /* DW0~3 */
+ u32 gid[4];
+
+ /* DW4 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd0 : 12;
+ u32 cvlan : 12;
+ u32 rsvd : 8;
+#else
+ u32 rsvd : 8;
+ u32 cvlan : 12;
+ u32 rsvd0 : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ /* DW5 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ppersp_pad_len : 8;
+ u32 l2_len : 8;
+ u32 ipv4_hdr_len : 8;
+ u32 pkthdr_len : 8;
+#else
+ u32 pkthdr_len : 8;
+ u32 ipv4_hdr_len : 8;
+ u32 l2_len : 8;
+ u32 ppersp_pad_len : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 5;
+ u32 ppe_ub_rsvd0 : 1;
+ u32 gid_update : 1;
+ u32 stag : 1;
+ u32 outer_tag : 2;
+ u32 outer_ip_type : 1;
+ u32 gid_type : 2;
+ u32 tunnel : 1;
+ u32 tag : 2;
+ u32 smac_hi16 : 16;
+#else
+ u32 smac_hi16 : 16;
+ u32 tag : 2;
+ u32 tunnel : 1;
+ u32 gid_type : 2; /* 0:ROCE V1; 1:ROCE V2 IPV4; 2:ROCE V2 IPV6; other:rsvd */
+ u32 outer_ip_type : 1;
+ u32 outer_tag : 2;
+ u32 stag : 1;
+ u32 gid_update : 1;
+ u32 ppe_ub_rsvd0 : 1; // must be 0 in roce
+ u32 rsvd : 5;
+#endif
+ } bs;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ctrl_val : 16;
+ u32 smac_hi16 : 16;
+#else
+ u32 smac_hi16 : 16;
+ u32 ctrl_val : 16;
+#endif
+ } bs1;
+ u32 value;
+ } dw6;
+
+ u32 smac_lo32;
+
+ roce_verbs_gid_ipv4_attr_s ipv4;
+
+ /* 后续新增结构为1825及后续代次需要,前代次不支持解析 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 16;
+ u32 shadow_vf_num : 16;
+#else
+ u32 shadow_vf_num : 16;
+ u32 rsvd : 16;
+#endif
+ } shadow;
+ u32 value;
+ } dw10;
+ u32 rsvd[3];
+} roce_verbs_gid_attr_s;
+
+typedef struct tag_roce_verbs_clear_gid_info {
+ u32 gid_num;
+
+ /* 后续新增结构为1825及后续代次需要,前代次不支持解析 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 16;
+ u32 shadow_vf_num : 16;
+#else
+ u32 shadow_vf_num : 16;
+ u32 rsvd : 16;
+#endif
+ } shadow;
+ u32 value;
+ } dw1;
+ u32 rsvd[3];
+} roce_verbs_clear_gid_info_s;
+
+typedef struct tag_roce_verbs_query_gid_info {
+ /* 后续新增结构为1825及后续代次需要,前代次不支持解析 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 16;
+ u32 shadow_vf_num : 16;
+#else
+ u32 shadow_vf_num : 16;
+ u32 rsvd : 16;
+#endif
+ } shadow;
+ u32 value;
+ } dw0;
+ u32 rsvd[3];
+} roce_verbs_query_gid_info_s;
+
+#pragma pack()
+
+typedef struct tag_roce_uni_cmd_gid {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_gid_attr_s gid_attr;
+} roce_uni_cmd_update_gid_s;
+
+typedef struct tag_roce_uni_cmd_clear_gid {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_clear_gid_info_s gid_clear;
+} roce_uni_cmd_clear_gid_s;
+
+typedef struct tag_roce_uni_cmd_qurey_gid {
+ roce_verbs_cmd_header_s com;
+ roce_verbs_query_gid_info_s gid_query;
+} roce_uni_cmd_query_gid_s;
+
+#define ROCE_CMDQ_GID_ATTR_LEN (sizeof(roce_verbs_gid_attr_s))
+
+#endif /* ROCE_VERBS_GID_ATTR_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_mr_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_mr_defs.h
new file mode 100644
index 000000000..04f1b6310
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_mr_defs.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq extended MR attributes.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_VERBS_MR_ATTR_H
+#define ROCE_VERBS_MR_ATTR_H
+
+#include "base_type.h"
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#define ROCE_RDMA_USER_DATE_LENGTH 6
+
+#pragma pack(4)
+typedef struct tag_roce_verbs_mr_sge {
+ u32 rsvd;
+ u32 new_key;
+
+ /* DW2~3 */
+ union {
+ u64 length; /* Length of mr or mw */
+
+ struct {
+ u32 length_hi; /* Length of mr or mw */
+ u32 length_lo; /* Length of mr or mw */
+ } dw2;
+ };
+
+ /* DW4~5 */
+ union {
+ u64 iova; /* Start address of mr or mw */
+
+ struct {
+ u32 iova_hi; /* Upper 32 bits of the start address of mr or mw */
+ u32 iova_lo; /* Lower 32 bits of the start address of mr or mw */
+ } dw4;
+ };
+} roce_verbs_mr_sge_s;
+
+typedef struct tag_roce_verbs_query_mpt_info {
+ u32 context[16];
+} roce_verbs_query_mpt_info_s;
+
+typedef struct tag_roce_verbs_mtt_cacheout_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_verbs_mtt_cacheout_info_s;
+
+typedef struct tag_roce_verbs_wqe_cacheout_info {
+ u32 wqe_flags; /* Indicates whether to kick out cache. by queue (0) or VF(1). */
+ u32 wqe_num; /* Number of wqe, which needs to be assigned by the driver when the is kicked out by queue. */
+ u32 wqe_cache_line_start; /* The driver needs to read the driver from the configuration file. */
+ u32 wqe_cache_line_end; /* The driver needs to read the driver from the configuration file. */
+ u32 wqe_cache_line_size; /* 0:256B,1:512B */
+} roce_verbs_wqe_cacheout_info_s;
+
+typedef struct tag_roce_verbs_query_mtt_info {
+ u32 mtt_addr_start_hi32;
+ u32 mtt_addr_start_lo32;
+ u32 mtt_num;
+ u32 rsvd;
+} roce_verbs_query_mtt_info_s;
+
+typedef struct tag_roce_dif_user_data_s {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 smd_tp : 2;
+ u32 app_esc : 1;
+ u32 ref_esc : 1;
+ u32 sct_v_tp : 2;
+ u32 sct_sz : 1;
+ u32 md_sz : 1;
+ u32 hdr_vld : 1;
+ u32 sec_num : 23;
+#else
+ u32 sec_num : 23;
+ u32 hdr_vld : 1; // tx: 0->no nvme hdr, 1: hdr
+ u32 md_sz : 1;
+ u32 sct_sz : 1;
+ u32 sct_v_tp : 2;
+ u32 ref_esc : 1;
+ u32 app_esc : 1;
+ u32 smd_tp : 2;
+#endif
+ } bs;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 smd_tp : 2;
+ u32 app_esc : 1;
+ u32 ref_esc : 1;
+ u32 sct_v_tp : 2;
+ u32 sct_sz : 1;
+ u32 md_sz : 1;
+ u32 hdr_vld : 1;
+ u32 rsvd : 11;
+ u32 fix_hdr_len : 12;
+#else
+ u32 fix_hdr_len : 12;
+ u32 rsvd : 11;
+ u32 hdr_vld : 1;
+ u32 md_sz : 1;
+ u32 sct_sz : 1;
+ u32 sct_v_tp : 2;
+ u32 ref_esc : 1;
+ u32 app_esc : 1;
+ u32 smd_tp : 2;
+#endif
+ } xnet_dif;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rep_app_tag : 16;
+ u32 grd_v_en : 1;
+ u32 grd_rid : 2;
+ u32 grd_v_agm : 1;
+ u32 grd_ri_agm : 1;
+ u32 grd_agm_ini : 1;
+ u32 crc16_ini : 1;
+ u32 ipcs_ini : 1;
+ u32 ref_v_en : 1;
+ u32 ref_rid : 2;
+ u32 ref_v_inc : 1;
+ u32 ref_ri_inc : 1;
+ u32 app_v_en : 1;
+ u32 app_rid : 2;
+#else
+ u32 app_rid : 2;
+ u32 app_v_en : 1;
+ u32 ref_ri_inc : 1;
+ u32 ref_v_inc : 1;
+ u32 ref_rid : 2;
+ u32 ref_v_en : 1;
+ u32 ipcs_ini : 1;
+ u32 crc16_ini : 1;
+ u32 grd_agm_ini : 1;
+ u32 grd_ri_agm : 1;
+ u32 grd_v_agm : 1;
+ u32 grd_rid : 2;
+ u32 grd_v_en : 1;
+ u32 rep_app_tag : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cmp_app_tag : 16;
+ u32 cmp_app_tag_mask : 16;
+#else
+ u32 cmp_app_tag_mask : 16;
+ u32 cmp_app_tag : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ u32 cmp_ref_tag;
+ u32 rep_ref_tag;
+} roce_dif_user_data_s;
+
+typedef struct tag_roce_verbs_mr_attr {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 buf_page_size : 4; /* Page_size of the buffer */
+ u32 mtt_layer_num : 3; /* Mtt level */
+ u32 mtt_page_size : 4; /* Page_size of mtt */
+ u32 rsvd2 : 3;
+ u32 david_en : 1;
+ u32 zbva : 1; /* The value 1 indicates that ZBVA is supported, that is, iova = 0. */
+ u32 access_lr : 1; /* 1: Indicates that the local read permission is supported. */
+ u32 access_lw : 1; /* The value 1 indicates that the local write permission is supported. */
+ u32 access_rr : 1; /* 1: Indicates that the remote read permission is supported. */
+ u32 access_rw : 1; /* 1: The remote write permission is supported. */
+ u32 access_ra : 1; /* The value 1 indicates that the remote Atomic permission is supported. */
+ u32 bpd : 1; /* 1: Bound to pd */
+ u32 bqp : 1; /* 1: Bound to qp */
+ u32 dif_mode : 1;
+ u32 rkey : 1;
+ u32 pa : 1; /* Flag bit of DMA_MR */
+ u32 r_w : 1; /* Mr or mw. The value 1 indicates MR, and the value 0 indicates MW. */
+ u32 remote_invalid_en : 1; /* Indicates whether to support the remote INVALID operation. */
+ u32 invalid_en : 1; /* Indicates whether to support the INVALID operation. */
+ u32 fast_reg_en : 1; /* Indicates whether the FRMR operation is supported. */
+ u32 remote_access_en : 1; /* Indicates whether the FRMR can specify remote rights. */
+ u32 access_bind : 1; /* Whether the mr supports the binding of the mw */
+#else
+ u32 access_bind : 1; /* Whether the mr supports the binding of the mw */
+ u32 remote_access_en : 1; /* Indicates whether the FRMR can specify remote rights. */
+ u32 fast_reg_en : 1; /* Indicates whether the FRMR operation is supported. */
+ u32 invalid_en : 1; /* Indicates whether to support the INVALID operation. */
+ u32 remote_invalid_en : 1; /* Indicates whether to support the remote INVALID operation. */
+ u32 r_w : 1; /* Mr or mw */
+ u32 pa : 1; /* Flag bit of DMA_MR */
+ u32 rkey : 1;
+ u32 dif_mode : 1;
+ u32 bqp : 1; /* 1: Bound to qp */
+ u32 bpd : 1; /* 1: Bound to pd */
+ u32 access_ra : 1; /* The value 1 indicates that the remote Atomic permission is supported. */
+ u32 access_rw : 1; /* 1: The remote write permission is supported. */
+ u32 access_rr : 1; /* 1: Indicates that the remote read permission is supported. */
+ u32 access_lw : 1; /* The value 1 indicates that the local write permission is supported. */
+ u32 access_lr : 1; /* 1: Indicates that the local read permission is supported. */
+ u32 zbva : 1; /* The value 1 indicates that ZBVA is supported, that is, iova = 0. */
+ u32 david_en : 1;
+ u32 rsvd2 : 3;
+ u32 mtt_page_size : 4; /* Page_size of mtt */
+ u32 mtt_layer_num : 3; /* Number of mtt levels */
+ u32 buf_page_size : 4; /* Page_size of the buffer */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 so_ro : 2;
+ u32 dma_attr_idx : 6;
+ u32 sector_size : 1;
+ u32 ep : 3;
+ u32 qpn : 20;
+#else
+ u32 qpn : 20; /* Qp bound to mw */
+ u32 ep : 3;
+ u32 sector_size : 1; /* 0:512B, 1:4KB */
+ u32 dma_attr_idx : 6; /* Dma attribute index */
+ u32 so_ro : 2; /* Dma order-preserving flag */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 status : 4;
+ u32 indirect_mr : 1;
+ u32 cos : 3;
+ u32 block_size : 6;
+ u32 pdn : 18;
+#else
+ u32 pdn : 18; /* Pd bound to mr or mw */
+ u32 block_size : 6; /* 2^(page_size+12) + 8*block_size */
+ u32 cos : 3;
+ u32 indirect_mr : 1;
+ u32 status : 4; /* Mpt status. Valid values are VALID, FREE, and INVALID. */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 mkey : 8;
+ u32 sw_dif_en : 1;
+ u32 page_mode : 1;
+ u32 fbo : 22;
+#else
+ u32 fbo : 22;
+ u32 page_mode : 1;
+ u32 sw_dif_en : 1;
+ u32 mkey : 8; /* The index is not included. */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4~5 */
+ union {
+ u64 iova; /* Start address of mr or mw */
+ struct {
+ u32 iova_hi; /* Upper 32 bits of the start address of mr or mw */
+ u32 iova_lo; /* Lower 32 bits of the start address of mr or mw */
+ } dw4;
+ };
+
+ /* DW6~7 */
+ union {
+ u64 length; /* Length of mr or mw */
+ struct {
+ u32 length_hi; /* Length of mr or mw */
+ u32 length_lo; /* Length of mr or mw */
+ } dw6;
+ };
+
+ /* DW8~9 */
+ union {
+ u64 mtt_base_addr; /* Mtt base address (pa),low 3bits(gpa_sign) */
+ struct {
+ u32 mtt_base_addr_hi; /* Mtt base address (pa) upper 32 bits */
+ u32 mtt_base_addr_lo; /* Lower 32 bits of mtt base address (pa),low 3bits(gpa_sign) */
+ } dw8;
+ };
+
+ /* DW10 */
+ union {
+ u32 mr_mkey; /* This parameter is valid for MW. */
+ u32 mw_cnt; /* This parameter is valid when the MR is used. */
+ };
+
+ /* DW11 */
+ u32 mtt_sz;
+
+ /* DW12~17 */
+ u32 userdata[ROCE_RDMA_USER_DATE_LENGTH];
+} roce_verbs_mr_attr_s;
+#pragma pack()
+
+typedef union roce_userdata {
+ struct {
+ roce_dif_user_data_s dif_info;
+ u32 rsvd1;
+ };
+} roce_userdata_u;
+
+#endif /* ROCE_VERBS_MR_ATTR_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_qp_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_qp_defs.h
new file mode 100644
index 000000000..c9d7190a7
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_qp_defs.h
@@ -0,0 +1,993 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq attribute qp context.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_VERBS_QP_ATTR_H
+#define ROCE_VERBS_QP_ATTR_H
+
+#include "roce_npu_cmd_mr_defs.h"
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#define ROCE_VERBS_SQ_WQEBB_SIZE (2)
+#define ROCE_VERBS_SQ_PI_VLD (1)
+
+#define ROCE_VERBS_QP_HASH_TYPE_BOND (0)
+#define ROCE_VERBS_QP_HASH_TYPE_UBC (1)
+
+#define ROCE_QP_DESTROY_MAGIG_NUM_OFFSET_4B 4
+#define ROCE_QP_DESTROY_CHECK_VALUE_HIGH_4B 0xffffffff
+#define ROCE_QP_DESTROY_CHECK_VALUE_LOW_4B 0xfefefefe
+
+enum roce5_qpc_mtucode {
+ ROCE_MTU_CODE_256 = 0x0,
+ ROCE_MTU_CODE_512 = 0x1,
+ ROCE_MTU_CODE_1K = 0x3,
+ ROCE_MTU_CODE_2K = 0x7,
+ ROCE_MTU_CODE_4K = 0xf
+};
+
+#pragma pack(4)
+/* qpc_attr_com info ,13*4B */
+typedef struct tag_roce_verbs_qpc_attr_com {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 service_type : 3;
+ u32 fre : 1;
+ u32 rwe : 1;
+ u32 rre : 1;
+ u32 rae : 1;
+ u32 rkey_en : 1;
+ u32 dest_qp : 24;
+#else
+ u32 dest_qp : 24; /* Destination QP number, which is extended to 24 bits in consideration of interconnection
+ with commercial devices. */
+ u32 rkey_en : 1;
+ u32 rae : 1;
+ u32 rre : 1;
+ u32 rwe : 1;
+ u32 fre : 1; /* Indicates whether the local FRPMR is enabled. */
+ u32 service_type : 3; /* Transmission Type
+ * 000:RC
+ * 001:UC
+ * 010:RD
+ * 011 UD
+ * 101:XRC
+ * Other:Reserved
+ */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sra_max : 3;
+ u32 rra_max : 3;
+ u32 rnr_retry_limit : 3;
+ u32 to_retry_limit : 3;
+ u32 local_qp : 20;
+#else
+ u32 local_qp : 20; /* Local QP number */
+ u32 to_retry_limit : 3; /* Number of ACK retransmissions. The value 7 indicates unlimited times, and the
+ value 0 indicates no retransmission. */
+ u32 rnr_retry_limit : 3; /* The maximum number of RNR retransmissions is 7. The value 7 indicates that the
+ maximum number of retransmissions is 7, and the value 0 indicates that the
+ retransmission is not performed. */
+ u32 rra_max : 3; /* The maximum value of responser resource is 128. */
+ u32 sra_max : 3; /* The maximum value of initiator depth is 128. */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ack_to : 5;
+ u32 min_rnr_nak : 5;
+ u32 cont_size : 2;
+ u32 cont_en : 1;
+ u32 srq_en : 1;
+ u32 xrc_srq_en : 1;
+ u32 vroce_en : 1;
+ u32 host_oqid : 16;
+#else
+ u32 host_oqid : 16;
+ u32 vroce_en : 1;
+ u32 xrc_srq_en : 1;
+ u32 srq_en : 1;
+ u32 cont_en : 1;
+ u32 cont_size : 2;
+ u32 min_rnr_nak : 5; /* NAK code of RNR. This parameter is mandatory when INIT2RNR and
+ RTR2RTS\SQE2RTS\SQD2SQD\SQD2RTS is optional. */
+ u32 ack_to : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tss_timer_num : 3;
+ u32 xrc_vld : 1;
+ u32 srq_container : 1;
+ u32 invalid_credit : 1;
+ u32 ext_md : 1;
+ u32 ext_mtu : 1;
+ u32 dsgl_en : 1;
+ u32 dif_en : 1;
+ u32 pmtu : 3;
+ u32 base_mtu_n : 1;
+ u32 pd : 18;
+#else
+ u32 pd : 18;
+ u32 base_mtu_n : 1;
+ u32 pmtu : 3;
+ u32 dif_en : 1;
+ u32 dsgl_en : 1;
+ u32 ext_mtu : 1;
+ u32 ext_md : 1;
+ u32 invalid_credit : 1;
+ u32 srq_container : 1;
+ u32 xrc_vld : 1;
+ u32 tss_timer_num : 3;
+#endif
+ } bs;
+
+ u32 value;
+ } dw3;
+
+ /* DW4 */
+ u32 q_key;
+
+ /* DW5 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ulp_type : 8;
+ u32 oor_en : 1;
+ u32 capture_en : 1;
+ u32 rsvd : 1;
+ u32 acx_mark : 1;
+ u32 mtu_code : 4; /* see enum roce5_qpc_mtucode */
+ u32 port : 2;
+ u32 ep : 3;
+ u32 cos : 3;
+ u32 so_ro : 2;
+ u32 dma_attr_idx : 6;
+#else
+ u32 dma_attr_idx : 6;
+ u32 so_ro : 2;
+ u32 cos : 3;
+ u32 ep : 3;
+ u32 port : 2;
+ u32 mtu_code : 4; /* see enum roce5_qpc_mtucode */
+ u32 acx_mark : 1;
+ u32 rsvd : 1;
+ u32 capture_en : 1;
+ u32 oor_en : 1;
+ u32 ulp_type : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sd_mpt_idx : 12;
+ u32 force_local : 1;
+ u32 state : 4;
+ u32 qpc_round : 2;
+ u32 rsvd : 13;
+#else
+ u32 rsvd : 13;
+ u32 qpc_round : 2;
+ u32 state : 4;
+ u32 force_local : 1;
+ u32 sd_mpt_idx : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ /* DW7 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 10;
+ u32 sq_cqn_lb : 1;
+ u32 rq_cqn_lb : 1;
+ u32 rq_cqn : 20;
+#else
+ u32 rq_cqn : 20;
+ u32 rq_cqn_lb : 1;
+ u32 sq_cqn_lb : 1;
+ u32 rsvd : 10;
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 next_send_psn : 24;
+#else
+ u32 next_send_psn : 24;
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw8;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 next_rcv_psn : 24;
+#else
+ u32 next_rcv_psn : 24;
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw9;
+
+ /* DW10 */
+ u32 lsn;
+
+ /* DW11 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 5;
+ u32 shadow_cq_vfid : 12;
+ u32 set_mpt_indx : 1;
+ u32 rsvd0 : 1;
+ u32 shadow : 1;
+ u32 shadow_vfid : 12;
+#else
+ u32 shadow_vfid : 12;
+ u32 shadow : 1;
+ u32 rsvd0 : 1;
+ u32 set_mpt_indx : 1;
+ u32 shadow_cq_vfid : 12;
+ u32 rsvd : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw11;
+
+ /* DW12 */
+ u32 rsvd;
+} roce_verbs_qpc_attr_com_s;
+
+typedef struct tag_roce_verbs_qpc_attr_path {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 udp_src_port_h : 8;
+ u32 ubc_tx_hash_value : 4; // 供ubc侧选口使用
+ u32 bond_tx_hash_value : 4;
+ u32 dmac_h16 : 16;
+#else
+ u32 dmac_h16 : 16;
+ u32 bond_tx_hash_value : 4;
+ u32 ubc_tx_hash_value : 4; // 供ubc侧选口使用
+ u32 udp_src_port_h : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ u32 dmac_l32;
+
+ /* DW2~5 */
+ u8 dgid[16];
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 4;
+ u32 tclass : 8;
+ u32 flow_label : 20;
+#else
+ u32 flow_label : 20; /* GRH flow lable */
+ u32 tclass : 8;
+ u32 rsvd : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ /* DW7 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sl : 3;
+ u32 loop : 1;
+ u32 udp_src_port : 8;
+ u32 rsvd : 4;
+ u32 base_sgid_n : 1;
+ u32 sgid_index : 7;
+ u32 hoplmt : 8;
+#else
+ u32 hoplmt : 8;
+ u32 sgid_index : 7;
+ u32 base_sgid_n : 1;
+ u32 rsvd : 4;
+ u32 udp_src_port : 8;
+ u32 loop : 1;
+ u32 sl : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+} roce_verbs_qpc_attr_path_s;
+
+typedef struct tag_roce_verbs_qpc_attr_chip {
+ /* DW0~1 */
+ union {
+ u64 sq_rq_l0mtt_gpa; /* hi[63:32],lo[31:03],sq_rq_gpa_sign[02:00] */
+ struct {
+ u32 sq_rq_l0mtt_gpa_hi;
+ u32 sq_rq_l0mtt_gpa_lo;
+ } bs;
+ } dw0;
+
+ /* DW2~3 */
+ union {
+ u64 sq_rq_pi_record_gpa_at_hop_num; /* hi[63:32],lo[31:02],sq_rq_at_hop_num[01:00] */
+ struct {
+ u32 sq_rq_pi_record_gpa_hi;
+ u32 sq_rq_pi_record_gpa_lo_at_hop_num; /* at_hop_num: bit[01:00] */
+ } bs;
+ } dw2;
+
+ /* DW4 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 qp_page_size : 4;
+ u32 sq_rq_mtt_page_size : 4;
+ u32 rsvd1 : 3;
+ u32 qp_signature : 5;
+ u32 rsvd0 : 1;
+ u32 dsgl : 1;
+ u32 rrw_mtt_prefetch_maxlen : 2;
+ u32 rc_size : 4;
+ u32 rc_max_size : 3;
+ u32 rq_base_ci : 5;
+#else
+ u32 rq_base_ci : 5;
+ u32 rc_max_size : 3;
+ u32 rc_size : 4;
+ u32 rrw_mtt_prefetch_maxlen : 2;
+ u32 dsgl : 1;
+ u32 rsvd0 : 1;
+ u32 qp_signature : 5;
+ u32 rsvd1 : 3;
+ u32 sq_rq_mtt_page_size : 4;
+ u32 qp_page_size : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ /* DW5 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_wqe_prefetch_maxnum : 3;
+ u32 sq_wqe_prefetch_minnum : 3;
+ u32 sq_wqe_cache_thd_sel : 2;
+ u32 sq_wqecnt_lth : 4;
+ u32 sq_wqecnt_rctl_en : 1;
+ u32 sq_wqecnt_rctl : 1;
+ u32 sq_prefetch_one_wqe : 1;
+ u32 sq_prewqe_mode : 1;
+ u32 sqa_wqe_prefetch_maxnum : 3;
+ u32 sqa_wqe_prefetch_minnum : 3;
+ u32 sqa_wqe_cache_thd_sel : 2;
+ u32 sq_wqe_check_en : 1;
+ u32 sq_pi_on_chip : 1;
+ u32 sq_inline_en : 1;
+ u32 sq_size : 5;
+#else
+ u32 sq_size : 5;
+ u32 sq_inline_en : 1;
+ u32 sq_pi_on_chip : 1;
+ u32 sq_wqe_check_en : 1;
+ u32 sqa_wqe_cache_thd_sel : 2;
+ u32 sqa_wqe_prefetch_minnum : 3;
+ u32 sqa_wqe_prefetch_maxnum : 3;
+ u32 sq_prewqe_mode : 1;
+ u32 sq_prefetch_one_wqe : 1;
+ u32 sq_wqecnt_rctl : 1;
+ u32 sq_wqecnt_rctl_en : 1;
+ u32 sq_wqecnt_lth : 4;
+ u32 sq_wqe_cache_thd_sel : 2;
+ u32 sq_wqe_prefetch_minnum : 3;
+ u32 sq_wqe_prefetch_maxnum : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_wqe_prefetch_mode : 1;
+ u32 sq_mtt_prefetch_maxlen : 3;
+ u32 sqa_mtt_prefetch_maxlen : 3;
+ u32 rsvd : 25;
+#else
+ u32 rsvd : 25;
+ u32 sqa_mtt_prefetch_maxlen : 3;
+ u32 sq_mtt_prefetch_maxlen : 3;
+ u32 sq_wqe_prefetch_mode : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ /* DW7 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rq_wqe_prefetch_maxnum : 3;
+ u32 rq_wqe_prefetch_minnum : 3;
+ u32 rq_wqe_cache_thd_sel : 2;
+ u32 rq_wqecnt_lth : 4;
+ u32 rq_wqecnt_rctl_en : 1;
+ u32 rq_wqecnt_rctl : 1;
+ u32 srqn : 18;
+#else
+ u32 srqn : 18;
+ u32 rq_wqecnt_rctl : 1;
+ u32 rq_wqecnt_rctl_en : 1;
+ u32 rq_wqecnt_lth : 4;
+ u32 rq_wqe_cache_thd_sel : 2;
+ u32 rq_wqe_prefetch_minnum : 3;
+ u32 rq_wqe_prefetch_maxnum : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+
+ /* DW8 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 srq_wqe_rthd_sel : 2;
+ u32 srq_rqecnt_th : 4;
+ u32 rq_pi_on_chip : 1;
+ u32 rq_inline_en : 1;
+ u32 rq_wqebb_size : 3;
+ u32 rq_size : 5;
+ u32 xrcd : 16;
+#else
+ u32 xrcd : 16;
+ u32 rq_size : 5;
+ u32 rq_wqebb_size : 3;
+ u32 rq_inline_en : 1;
+ u32 rq_pi_on_chip : 1;
+ u32 srq_rqecnt_th : 4;
+ u32 srq_wqe_rthd_sel : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw8;
+
+ /* DW9 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 container_en : 1;
+ u32 container_sz : 2;
+ u32 srq_warth_flag : 1;
+ u32 srq_mtt_prefetch_maxlen1 : 2;
+ u32 rq_mtt_prefetch_maxwqe : 3;
+ u32 rq_mtt_prefetch_maxlen0 : 2;
+ u32 rq_mtt_prefetch_maxlen1 : 2;
+ u32 rsvd : 19;
+#else
+ u32 rsvd : 19;
+ u32 rq_mtt_prefetch_maxlen1 : 2;
+ u32 rq_mtt_prefetch_maxlen0 : 2;
+ u32 rq_mtt_prefetch_maxwqe : 3;
+ u32 srq_mtt_prefetch_maxlen1 : 2;
+ u32 srq_warth_flag : 1;
+ u32 container_sz : 2;
+ u32 container_en : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw9;
+
+ /* DW10 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rc_entry_prefetch_maxnum : 3;
+ u32 rc_mtt_prefetch_maxlen : 2;
+ u32 rsvd : 1;
+ u32 rc_entry_size : 2;
+ u32 rc_page_gpa_h : 24;
+#else
+ u32 rc_page_gpa_h : 24; /* bit[63:40] Indicates the start GPA of RDMARC table. The driver needs to allocate
+ * continuous physical address for the RDMARC table.Configured by Driver */
+ u32 rc_entry_size : 2;
+ u32 rsvd : 1;
+ u32 rc_mtt_prefetch_maxlen : 2;
+ u32 rc_entry_prefetch_maxnum : 3; /* Maximum number of prefetch Entries for RDMARC table.000: prefetch
+ * number equals to zero; Others: prefetch number equals to
+ * (2^(rc_entry_prefetch_maxnum-1)). Configured by Driver */
+#endif
+ } bs;
+ u32 value;
+ } dw10;
+
+ /* DW11 */
+ u32 rc_page_gpa_l; /* bit[39:8] */
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 1;
+ u32 srq_pd : 18;
+ u32 srq_wqebb_size : 3;
+ u32 srq_page_size : 4;
+ u32 srq_size : 5;
+ u32 srq_rkey_en : 1;
+#else
+ u32 srq_rkey_en : 1;
+ u32 srq_size : 5;
+ u32 srq_page_size : 4;
+ u32 srq_wqebb_size : 3;
+ u32 srq_pd : 18;
+ u32 rsvd : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw12;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 srq_cqn : 20;
+ u32 srq_state : 4;
+#else
+ u32 srq_state : 4;
+ u32 srq_cqn : 20;
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw13;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 15;
+ u32 qp_rkey_en : 1;
+ u32 srq_xrcd : 16;
+#else
+ u32 srq_xrcd : 16;
+ u32 qp_rkey_en : 1;
+ u32 rsvd : 15;
+#endif
+ } bs;
+ u32 value;
+ } dw14;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 4;
+ u32 rq_page_size : 4;
+ u32 rq_pd : 18;
+ u32 rq_rkey_en : 1;
+ u32 rq_size : 5;
+#else
+ u32 rq_size : 5;
+ u32 rq_rkey_en : 1;
+ u32 rq_pd : 18;
+ u32 rq_page_size : 4;
+ u32 rsvd : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw15;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 6;
+ u32 sq_wqebb_size : 3;
+ u32 sq_pd : 18;
+ u32 sq_page_size : 4;
+ u32 sq_rkey_en : 1;
+#else
+ u32 sq_rkey_en : 1;
+ u32 sq_page_size : 4;
+ u32 sq_pd : 18;
+ u32 sq_wqebb_size : 3;
+ u32 rsvd : 6;
+#endif
+ } bs;
+ u32 value;
+ } dw16;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 12;
+ u32 sqa_cqn : 20;
+#else
+ u32 sqa_cqn : 20;
+ u32 rsvd : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw17;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 14;
+ u32 ud_pd : 18;
+#else
+ u32 ud_pd : 18;
+ u32 rsvd : 14;
+#endif
+ } bs;
+ u32 value;
+ } dw18;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 14;
+ u32 qp_pd : 18;
+#else
+ u32 qp_pd : 18;
+ u32 rsvd : 14;
+#endif
+ } bs;
+ u32 value;
+ } dw19;
+} roce_verbs_qpc_attr_chip_s;
+
+typedef struct roce_verbs_qpc_attr_vbs {
+ u32 sqpc_ci_record_addr_h;
+ u32 sqpc_ci_record_addr_l;
+} roce_verbs_qpc_attr_vbs_s;
+
+typedef struct roce_verbs_qpc_attr_jbof {
+ u32 offload_en;
+ u32 io_qpn;
+ u32 sq_type;
+ u32 sqpc_ci_record_addr_h;
+ u32 sqpc_ci_record_addr_l;
+} roce_verbs_qpc_attr_jbof_s;
+
+typedef struct roce_verbs_qpc_attr_vroce {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 31;
+ u32 vroce_en : 1;
+#else
+ u32 vroce_en : 1;
+ u32 rsvd : 31;
+#endif
+ u32 ulp_type;
+} roce_verbs_qpc_attr_vroce_s;
+
+typedef struct roce_verbs_qpc_attr_dfx {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_pi : 16;
+ u32 sq_ci : 16;
+#else
+ u32 sq_ci : 16;
+ u32 sq_pi : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_load_pi : 1;
+ u32 rq_load_pi : 1;
+ u32 rsvd : 6;
+ u32 rc_prefetch_ci : 8;
+ u32 sq_wqe_prefetch_ci : 16;
+#else
+ u32 sq_wqe_prefetch_ci : 16;
+ u32 rc_prefetch_ci : 8;
+ u32 rsvd : 6;
+ u32 rq_load_pi : 1;
+ u32 sq_load_pi : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sqa_ci : 16;
+ u32 sqa_wqe_prefetch_ci : 16;
+#else
+ u32 sqa_wqe_prefetch_ci : 16;
+ u32 sqa_ci : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_mtt_prefetch_wqe_ci : 16;
+ u32 rq_mtt_prefetch_wqe_ci : 16;
+#else
+ u32 rq_mtt_prefetch_wqe_ci : 16;
+ u32 sq_mtt_prefetch_wqe_ci : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rq_pi : 16;
+ u32 rq_ci : 16;
+#else
+ u32 rq_ci : 16;
+ u32 rq_pi : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ /* DW5 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rq_wqe_prefetch_ci : 16;
+ u32 rc_pi : 8;
+ u32 rc_ci : 8;
+#else
+ u32 rc_ci : 8;
+ u32 rc_pi : 8;
+ u32 rq_wqe_prefetch_ci : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sw_wnd : 11;
+ u32 sw_send_ce_sn : 11;
+ u32 rsvd : 10;
+#else
+ u32 rsvd : 10;
+ u32 sw_send_ce_sn : 11;
+ u32 sw_wnd : 11;
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ /* DW7 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rr_wnd : 11;
+ u32 rr_send_ce_sn : 11;
+ u32 rsvd : 10;
+#else
+ u32 rsvd : 10;
+ u32 rr_send_ce_sn : 11;
+ u32 rr_wnd : 11;
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+
+ /* DW8 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 wnd_ctrl_rtt : 16;
+ u32 rsvd : 16;
+#else
+ u32 rsvd : 16;
+ u32 wnd_ctrl_rtt : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw8;
+
+ u32 dw9; // sw_seg.ucode_seg.sq_ctx.dw8
+
+ u32 dw10; // sw_seg.ucode_seg.sq_ctx.send_left_len
+
+ u32 dw11; // sw_seg.ucode_seg.sq_ctx.dw11
+
+ u32 dw12; // sw_seg.ucode_seg.sq_ctx.ack_ctx.dw14
+
+ u32 dw13; // sw_seg.ucode_seg.sq_ctx.ack_ctx.dw15
+
+ u32 dw14; // sw_seg.ucode_seg.sq_ctx.ack_ctx.dw16
+
+ u32 dw15; // sw_seg.ucode_seg.sq_ctx.ack_ctx.dw18
+} roce_verbs_qpc_attr_dfx_s;
+
+typedef struct roce_verbs_qpc_attr_ssu {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 global_qpn : 20;
+ u32 rsvd : 12;
+#else
+ u32 rsvd : 12;
+ u32 global_qpn : 20;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1-3 */
+ u32 rsvd[3];
+} roce_verbs_qpc_attr_ssu_s;
+
+typedef struct roce_verbs_qpc_attr_ext {
+ /* DW0~1 */
+ roce_verbs_qpc_attr_vbs_s vbs_info;
+ /* DW2~6 */
+ roce_verbs_qpc_attr_jbof_s jbof_info;
+ /* DW7~8 */
+ roce_verbs_qpc_attr_vroce_s vroce_info;
+ /* DW9~24 */
+ roce_verbs_qpc_attr_dfx_s dfx_info;
+ /* DW25~28 */
+ roce_verbs_qpc_attr_ssu_s ssu_info;
+} roce_verbs_qpc_attr_ext_s;
+
+/* QPC Struct */
+typedef struct tag_roce_verbs_qp_attr {
+ /* com seg, DW0 ~ DW12 */
+ roce_verbs_qpc_attr_com_s com_info;
+
+ /* path seg, DW0 ~ DW7 */
+ roce_verbs_qpc_attr_path_s path_info;
+
+ /* chip seg, DW0 ~ DW19 */
+ roce_verbs_qpc_attr_chip_s chip_seg;
+
+ /* ext seg, DW0 ~ DW28 */
+ roce_verbs_qpc_attr_ext_s ext_seg;
+} roce_verbs_qp_attr_s;
+
+#define ROCE_VERBS_QP_ATTR_SIZE 280
+
+typedef struct tag_roce_verbs_qp_hw2sw_info {
+ /* DW0~1 */
+ u32 sq_buf_len; /* Buffer length of the SQ queue */
+ u32 rq_buf_len; /* Buffer length of the RQ queue */
+
+ /* DW2~6 */
+ roce_verbs_mtt_cacheout_info_s cmtt_cache;
+
+ /* DW7~8 */
+ union {
+ u64 wb_gpa; /* Address written back by the ucode after processing */
+
+ struct {
+ u32 syn_gpa_hi32; /* Upper 32 bits of the start address of mr or mw */
+ u32 syn_gpa_lo32; /* Lower 32 bits of the start address of mr or mw */
+ } gpa_dw;
+ };
+ union {
+ struct {
+ u32 rsvd : 16;
+ u32 host_oqid : 16;
+ } bs;
+
+ u32 value;
+ } dw9;
+ roce_verbs_wqe_cacheout_info_s wqe_cache;
+} roce_verbs_qp_hw2sw_info_s;
+
+typedef struct tag_roce_verbs_query_qp_info {
+ roce_verbs_qp_attr_s qp_attr;
+} roce_verbs_query_qp_info_s;
+
+typedef struct tag_roce_verbs_modify_ctx_info {
+ u32 ctx_type;
+ u32 offset;
+ u32 value;
+ u32 mask;
+} roce_verbs_modify_ctx_info_s;
+
+typedef struct tag_roce_verbs_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_verbs_xq_mtt_info_s;
+
+typedef struct tag_roce_verbs_udp_src_port_info {
+ u32 udp_src_port;
+ u32 rsvd[3];
+} roce_verbs_udp_src_port_info_s;
+
+typedef struct tag_roce_verbs_hash_info {
+ u32 type;
+ u32 hash_value;
+ u32 rsvd[2];
+} roce_verbs_qp_hash_info_s;
+
+typedef struct tag_roce_verbs_dfx_info {
+ u32 udp_src_port;
+ u32 rx_port;
+ u32 rsvd[14];
+} roce_verbs_dfx_info_s;
+
+#define ROCE_VERBS_MODIFY_RSP_MAGIC 0x5aa57bb7
+typedef struct tag_roce_verbs_cmd_qp_modify_rsp {
+ u32 magic;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ssn : 24;
+ u32 rsvd : 7;
+ u32 is_ssn_vld : 1;
+#else
+ u32 is_ssn_vld : 1;
+ u32 rsvd : 7;
+ u32 ssn : 24;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+ u32 rsvd[6];
+} roce_verbs_cmd_qp_modify_rsp_s;
+
+#pragma pack()
+
+#endif /* ROCE_VERBS_QP_ATTR_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_srq_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_srq_defs.h
new file mode 100644
index 000000000..917aca317
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_npu_cmd_srq_defs.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA cmdq srq attribute context.
+ * Create: 2021-04-22
+ */
+
+#ifndef ROCE_VERBS_SRQ_ATTR_H
+#define ROCE_VERBS_SRQ_ATTR_H
+
+#include "roce_npu_cmd_mr_defs.h"
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#pragma pack(4)
+typedef struct tag_roce_verbs_srq_cont_attr {
+ /* DW0 */
+ u32 head_gpa_h;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 head_gpa_l : 20;
+ u32 rsvd : 11;
+ u32 head_gpa_vld : 1;
+#else
+ u32 head_gpa_vld : 1;
+ u32 rsvd : 11;
+ u32 head_gpa_l : 20;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cont_size : 2;
+ u32 rsvd : 10;
+ u32 warn_th : 4;
+ u32 head_idx : 16;
+#else
+ u32 head_idx : 16;
+ u32 warn_th : 4;
+ u32 rsvd : 10;
+ u32 cont_size : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+} roce_verbs_srq_cont_attr_s;
+
+typedef struct tag_roce_verbs_srq_attr_dfx {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 pcnt : 16;
+ u32 ccnt : 16;
+#else
+ u32 ccnt : 16;
+ u32 pcnt : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 wqe_prefetch_ccnt : 16;
+ u32 wqe_prefetch_idx : 16;
+#else
+ u32 wqe_prefetch_idx : 16;
+ u32 wqe_prefetch_ccnt : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+} roce_verbs_srq_attr_dfx_s;
+
+typedef struct tag_roce_verbs_srq_attr {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 xrcd : 16;
+ u32 mtt_page_size : 4;
+ u32 wqebb_size : 3;
+ u32 page_size : 4;
+ u32 size : 5;
+#else
+ u32 size : 5; /* Shared Receive Queue size, equals to (2^srq_size)*WQEBB,
+ * the maximum SRQ size is 16K WQEs, so this field doesn't exceed 14. */
+ u32 page_size : 4; /* Page size of SRQ, equals to (2^srq_page_size)*4KB */
+ u32 wqebb_size : 3; /* Shared Receive WQE Basic Block (WQEBB) size in bytes is (2^rq_wqebb_size)*16B.
+ The minimum size is 32B and the values 0, 4, 5, 6, 7 are reserved */
+ u32 mtt_page_size : 4; /* Page size of MTT for SRQ, equals to (2^srq_mtt_page_size)*4KB. */
+ u32 xrcd : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 state : 4;
+ u32 rsvd : 14;
+ u32 ep : 3;
+ u32 cos : 3;
+ u32 so_ro : 2;
+ u32 dma_attr_idx : 6;
+#else
+ u32 dma_attr_idx : 6; /* It specifies the outbound PCIe TLP header attribute of the DMA operation.
+ * This filed is only valid when processing CQ's CQEs. */
+ u32 so_ro : 2; /* It specifies the ATTR[1:0] bits in the outbound PCIe TLP headers of the DMA operation.
+ * This field is only valid when processing CQ's CQEs.
+ * 2'b00: Strict Ordering;
+ * 2'b01: Relaxed Ordering;
+ * 2'b10: ID Based Ordering;
+ * 2'b11: Both Relaxed Ordering and ID Based Ordering. */
+ u32 cos : 3;
+ u32 ep : 3;
+ u32 rsvd : 14;
+ u32 state : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 wqe_prefetch_max_num : 3;
+ u32 wqe_prefetch_min_num : 3;
+ u32 wqe_cache_thd_sel : 2;
+ u32 wqecnt_lth : 4;
+ u32 wqecnt_ctrl_en : 1;
+ u32 wqecnt_rctl : 1;
+ u32 mtt_prefetch_maxlen : 2;
+ u32 next_wqe_idx : 16;
+#else
+ u32 next_wqe_idx : 16; /* The current WQE index; uses this field to get the corresponding WQE from SRQ. */
+ u32 mtt_prefetch_maxlen : 2;
+ u32 wqecnt_rctl : 1; /* The hardware clear it to zero when performing a SRQ PCnt updating, and driver
+ set it to one to indicate the hardware can performing SRQ PCnt updating. */
+ u32 wqecnt_ctrl_en : 1;
+ u32 wqecnt_lth : 4;
+ u32 wqe_cache_thd_sel : 2; /* Maximum length of prefetch MTTs for SRQ.
+ 000: prefetch length equals to zero;
+ Others: prefetch length equals to
+ (2^(srq_mtt_prefetch_maxlen-1)*1KB). */
+ u32 wqe_prefetch_min_num : 3; /* Minimum number of prefetch WQEBBs for SRQ.
+ 000: prefetch number equals to zero;
+ Others: prefetch number equals to (2^(srq_wqe_prefetch_minnum-1)).
+ */
+ u32 wqe_prefetch_max_num : 3; /* Maximum number of prefetch WQEBBs for SRQ.
+ 000: prefetch number equals to zero;
+ Others: prefetch number equals to (2^srq_wqe_prefetch_maxnum). */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 container : 1;
+ u32 pcnt_on_chip : 1;
+ u32 lth_pre_en : 1;
+ u32 rkey_en : 1;
+ u32 wqe_check_en : 1;
+ u32 lth_gap : 4;
+ u32 rsvd : 5;
+ u32 pd : 18;
+#else
+ u32 pd : 18;
+ u32 rsvd : 5;
+ u32 lth_gap : 4;
+ u32 wqe_check_en : 1;
+ u32 rkey_en : 1;
+ u32 lth_pre_en : 1;
+ u32 pcnt_on_chip : 1;
+ u32 container : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4 */
+ u32 srqn;
+
+ /* DW5 */
+ u32 xrc_cqn;
+
+ /* DW6~7 */
+ union {
+ u64 l0mtt_gpa; /* The GPA of Layer 0 MTT. It may point to the CQ's buffer directly.low 3bits(cq_gpa_sign) */
+ struct {
+ u32 l0mtt_gpa_hi;
+ u32 l0mtt_gpa_lo;
+ } dw6_dw7;
+ };
+
+ /* DW8~9 */
+ union {
+ u64 record_gpa_at_hop_num; /* The GPA of stored CI of Complete Queue.
+ * Address translation hop numbers.
+ * 0x0: the 'cq_l0mtt_gpa' points to the buffer of CQ directly.
+ * 0x1: it need to perform one hop address translation to get the buffer's
+ * address of CQ; 0x2: there is two hop address translation to get the buffer's
+ * address of CQ; 0x3: reserved. */
+ struct {
+ u32 record_gpa_hi;
+ u32 record_gpa_lo_at_hop_num; /* bit[1:0] Address translation hop numbers */
+ } dw8_dw9;
+ };
+
+ roce_verbs_srq_cont_attr_s cont;
+ roce_verbs_srq_attr_dfx_s dfx_info;
+} roce_verbs_srq_attr_s;
+
+#define ROCE_VERBS_SRQ_ATTR_SIZE 56
+
+typedef struct tag_roce_verbs_srq_hw2sw_info {
+ /* DW0~3 */
+ u32 srq_buf_len;
+ u32 wqe_cache_line_start;
+ u32 wqe_cache_line_end;
+ u32 wqe_cache_line_size;
+
+ /* DW4~8 */
+ roce_verbs_mtt_cacheout_info_s cmtt_cache;
+} roce_verbs_srq_hw2sw_info_s;
+
+typedef union tag_roce_verbs_arm_srq_info {
+ 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_verbs_arm_srq_info_u;
+
+typedef struct tag_roce_verbs_query_srq_info {
+ roce_verbs_srq_attr_s srq_attr;
+ u32 srq_ctr_vld;
+ u32 srq_empty_ctr;
+ u32 srq_limit;
+ u32 warn_th;
+ u32 rsvd[0x4];
+} roce_verbs_query_srq_info_s;
+#pragma pack()
+
+#endif /* ROCE_VERBS_SRQ_ATTR_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_base_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_base_format.h
new file mode 100644
index 000000000..9f522f2da
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_base_format.h
@@ -0,0 +1,565 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA wqe structure format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_WQE_BASE_FORMAT_H
+#define ROCE_WQE_BASE_FORMAT_H
+#include "base_type.h"
+#include "roce_wqe_ulp_task.h"
+/* **************************************************************** */
+typedef struct roce5_wqe_ctrl_seg {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 owner : 1;
+ u32 ctrlsl : 2;
+ u32 csl : 2;
+ u32 difsl : 3;
+ u32 cr : 1;
+ u32 df : 1;
+ u32 va : 1;
+ u32 tsl : 5;
+ u32 cf : 1;
+ u32 wf : 1;
+ u32 wqe_ssn : 2;
+ u32 fde : 1;
+ u32 fast : 1;
+ u32 drvsl : 2;
+ u32 bdsl : 8;
+#else
+ u32 bdsl : 8; /* Data segment length, in the unit of 1B. When inline is used, the length of inline is
+ described. The total length of the data segment must be aligned to 8B. */
+ u32 drvsl : 2; /* Indicates the length of the driver section. The value is counted by 8B, and the value of
+ RoCE is 0. */
+ u32 fast : 1; /* Fast Path Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA */
+ u32 fde : 1; /* fast direct wqe,指示fast dircet wqe 使能,使用psm进行加速 */
+ u32 wqe_ssn : 2; /* wqe_ssn 表示驱动侧记录的wqe ssn最低2 bit,用于psm fast direct wqe去重 */
+ u32 wf : 1; /* 0-Normal WQE, 1-link WQE */
+ u32 cf : 1; /* Complete segment format flag. The 0-complete segment directly contains the status information.
+ 1: SGL */
+ u32 tsl : 5; /* Length of the task segment. The value ranges from 8 to 48. The value of RoCE ranges from 8
+ to 48. */
+ u32 va : 1; /* SGE address format flag. The 0-SGE contains the physical address and length. The 1-SGE
+ contains the virtual address, length, and key. The value of RoCE is 1. */
+ u32 df : 1; /* Data segment format flag bit. 0-describes data in SGE format. 1: Data is described in inline
+ format. */
+ u32 cr : 1; /* The CQE generates the request flag. The 0-does not generate the CQE. 1: Generate CQE */
+ u32 difsl : 3; /* DIF segment length. The value is counted by 8 bytes. The value of RoCE is 0. */
+ u32 csl : 2; /* Length of the completed segment. The value is counted by 8B. The value of RoCE is 0. */
+ u32 ctrlsl : 2; /* Length of the control segment. The value is 8 bytes and the value of RoCE is 16. */
+ u32 owner : 1; /* Owner bit. The value 1 indicates all hardware, and the value 0 indicates all software. The
+ meaning of the queue owner bit is reversed every time the queue owner is traversed. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cl : 4;
+ u32 signature : 8;
+ u32 rsvd : 4;
+ u32 mask_pi : 16;
+#else
+ u32 mask_pi : 16; /* Pi is the value of the queue depth mask. It is valid when direct wqe. */
+ u32 rsvd : 4;
+ u32 signature : 8;
+ u32 cl : 4; /* The length of CQE is generated in the task segment. */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 type : 2;
+ u32 rsvd1 : 3;
+ u32 cos : 3;
+ u32 cp_flag : 1;
+ u32 rsvd : 1;
+ u32 ctx_size : 2;
+ u32 qpn : 20;
+#else
+ u32 qpn : 20;
+ u32 ctx_size : 2; /* RoCE QPC size, 512B */
+ u32 rsvd : 1;
+ u32 cp_flag : 1; /* control plane flag */
+ u32 cos : 3; /* Scheduling priority. The value source is SL. */
+ u32 rsvd1 : 3;
+ u32 type : 2; /* Set RoCE SQ Doorbell to 2 and RoCE Arm CQ Doorbell to 3. */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sub_type : 4; /* */
+ u32 sgid_index : 7; /* gid index */
+ u32 mtu_shift : 3; /* 256B:0;512B:1;1024B:2;2048B:3;4096B:4 */
+ u32 rsvd : 1;
+ u32 xrc_vld : 1; /* 1:XRC service type */
+ u32 pi : 16; /* host sw write the sq produce index high 8bit to this section; */
+#else
+ u32 pi : 16; /* host sw write the sq produce index high 8bit to this section; */
+ u32 xrc_vld : 1;
+ u32 rsvd : 1;
+ u32 mtu_shift : 3;
+ u32 sgid_index : 7;
+ u32 sub_type : 4;
+#endif
+ } bs;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 queue_id : 4;
+ u32 rsvd : 12;
+ u32 pi : 16;
+#else
+ u32 pi : 16;
+ u32 rsvd : 12;
+ u32 queue_id : 4;
+#endif
+ } bs1;
+ u32 value;
+ } dw3;
+} roce_wqe_ctrl_seg_s;
+
+/* *
+ * Struct name: sq_wqe_task_remote_common_s.
+ * @brief : SQ WQE common.
+ * Description:
+ */
+typedef struct tag_sq_wqe_task_remote_common {
+ roce_wqe_tsk_com_seg_u common;
+
+ u32 data_len; /* SQ WQE DMA LEN */
+
+ u32 immdata_invkey; /* SEND invalidate or immedate */
+
+ roce_wqe_tsk_misc_seg_u dw3;
+} sq_wqe_task_remote_common_s;
+
+/* Send WQE/Send with imme WQE/Send with invalid(inline or not inline) */
+typedef struct roce_wqe_send_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 data_len; /* Length of the data sent by the SQ WQE */
+
+ /* DW2 */
+ u32 immdata_invkey; /* This parameter is valid for the immediate data operation or SEND invalidate. */
+
+ /* DW3 */
+ roce_wqe_tsk_misc_seg_u dw3;
+} roce_wqe_send_tsk_seg_s;
+
+/* RDMA Read WQE/RDMA Write WQE/RDMA Write with imme WQE(inline or non-inline) */
+typedef struct roce_wqe_rdma_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 data_len;
+
+ /* DW2 */
+ u32 imm_data;
+
+ /* DW3 */
+ roce_wqe_tsk_misc_seg_u dw3;
+
+ /* DW4~5 */
+ union {
+ u64 va;
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+#ifndef PLATFORM_MODE_SNP_MACC /* 宏指令不支持匿名结构体 */
+ } dw4;
+ };
+#else
+ } macc_bs;
+ } dw4;
+#endif /* PLATFORM_MODE_SNP_MACC */
+
+ /* DW6 */
+ u32 rkey;
+
+ /* DW7 */
+ u32 ulp; // ulp可使用
+} roce_wqe_rdma_tsk_seg_s;
+
+/* Atomic WQE */
+typedef struct roce_wqe_atomic_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 key;
+
+ /* DW2~3 */
+ union {
+ u64 va;
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+ } bs;
+ } dw2;
+
+ /* DW4~5 */
+ union {
+ u64 swap_add_data;
+ struct {
+ u32 swap_add_data_h32;
+ u32 swap_add_data_l32;
+ } bs;
+ } dw4;
+
+ /* DW6~7 */
+ union {
+ u64 cmp_data;
+ struct {
+ u32 cmp_data_h32;
+ u32 cmp_data_l32;
+ } bs;
+ } dw6;
+} roce_wqe_atomic_tsk_seg_s;
+
+/* ext Atomic WQE */
+#define ROCE_WQE_ATOMIC_DATA_SIZE 32
+#define ROCE_WQE_ATOMIC_DATA_LEN 128
+#define ROCE_WQE_ATOMIC_DATA_SIZE_2B_ALIGN (ROCE_WQE_ATOMIC_DATA_SIZE >> 1)
+typedef struct roce5_wqe_ext_atomic_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 key;
+
+ /* DW2~3 */
+ union {
+ u64 va;
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+ } dw2;
+ };
+ u32 atomic_data[ROCE_WQE_ATOMIC_DATA_SIZE];
+} roce_wqe_ext_atomic_tsk_seg_s;
+
+/* Mask Atomic WQE */
+typedef struct roce_wqe_mask_atomic_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 rkey;
+
+ /* DW2~3 */
+ union {
+ u64 va;
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+ } bs;
+ } dw2;
+
+ /* DW4~5 */
+ union {
+ u64 swap_add_data;
+ struct {
+ u32 swap_add_data_h32;
+ u32 swap_add_data_l32;
+ } bs;
+ } dw4;
+
+ /* DW6~7 */
+ union {
+ u64 cmp_data;
+ struct {
+ u32 cmp_data_h32;
+ u32 cmp_data_l32;
+ } bs;
+ } dw6;
+
+ /* DW8~9 */
+ union {
+ u64 swap_msk;
+ struct {
+ u32 swap_msk_h32;
+ u32 swap_msk_l32;
+ } bs;
+ } dw8;
+
+ /* DW9~10 */
+ union {
+ u64 cmp_msk;
+ struct {
+ u32 cmp_msk_h32;
+ u32 cmp_msk_l32;
+ } bs;
+ } dw10;
+} roce_wqe_mask_atomic_tsk_seg_s;
+
+/* UD send WQE */
+typedef struct roce_wqe_ud_tsk_seg {
+ /* DW0 */
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 data_len;
+
+ /* DW2 */
+ u32 immdata_invkey;
+
+ /* DW3 */
+ roce_wqe_tsk_misc_seg_u dw2;
+
+ /* DW4 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 fl : 1;
+ u32 wqe_cos : 3; /* DB cos or Path cos or MQM cos */
+ u32 stat_rate : 4;
+ u32 rsvd : 6;
+ u32 pd : 18;
+#else
+ u32 pd : 18; /* Used to verify the PD in the QPC. */
+ u32 rsvd : 6;
+ u32 stat_rate : 4; /* Maximum static rate control 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 wqe_cos : 3; /* DB cos or Path cos or MQM cos */
+ u32 fl : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW5 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tc : 8;
+ u32 rsvd : 4;
+ u32 port : 4;
+ u32 vlan_en : 1;
+ u32 sgid_idx : 7;
+ u32 hop_limit : 8;
+#else
+ u32 hop_limit : 8;
+ u32 sgid_idx : 7;
+ u32 vlan_en : 1;
+ u32 port : 4;
+ u32 rsvd : 4;
+ u32 tc : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 2;
+ u32 smac_index : 10;
+ u32 flow_label : 20;
+#else
+ u32 flow_label : 20;
+ u32 smac_index : 10;
+ u32 rsvd : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ /* DW7~10 */
+ u8 dgid[16];
+
+ /* DW11 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 dst_qp : 24;
+#else
+ u32 dst_qp : 24;
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw10;
+
+ /* DW12 */
+ u32 qkey;
+
+ /* DW13 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vlan_pri : 3; /* send pkt pri */
+ u32 cfi : 1;
+ u32 vlan_id : 12;
+ u32 dmac_h16 : 16;
+#else
+ u32 dmac_h16 : 16;
+ u32 vlan_id : 12;
+ u32 cfi : 1;
+ u32 vlan_pri : 3; /* send pkt pri */
+#endif
+ } bs;
+ u32 value;
+ } dw12;
+
+ /* DW14 */
+ u32 dmac_l32;
+
+ /* DW15 */
+ u32 rsvd;
+} roce_wqe_ud_tsk_seg_s;
+
+/* DRC send WQE */
+typedef struct roce_wqe_drc_rdma_tsk_seg {
+ /* DW0~2 */
+ u32 rsvd[3];
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 fl : 1;
+ u32 wqe_cos : 3; /* DB cos or Path cos or MQM cos */
+ u32 stat_rate : 4;
+ u32 rsvd : 6;
+ u32 pd : 18;
+#else
+ u32 pd : 18; /* Used to verify the PD in the QPC. */
+ u32 rsvd : 6;
+ u32 stat_rate : 4; /* Maximum static rate control 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 wqe_cos : 3; /* DB cos or Path cos or MQM cos */
+ u32 fl : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tc : 8;
+ u32 rsvd : 4;
+ u32 port : 4;
+ u32 vlan_en : 1;
+ u32 sgid_idx : 7;
+ u32 hop_limit : 8;
+#else
+ u32 hop_limit : 8;
+ u32 sgid_idx : 7;
+ u32 vlan_en : 1;
+ u32 port : 4;
+ u32 rsvd : 4;
+ u32 tc : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 2;
+ u32 smac_index : 10;
+ u32 flow_label : 20;
+#else
+ u32 flow_label : 20;
+ u32 smac_index : 10;
+ u32 rsvd : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ u8 dgid[16];
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 drctn : 24;
+#else
+ u32 drctn : 24;
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw10;
+
+ /* DW11 */
+ u32 drct_key_l;
+
+ /* DW12 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vlan_pri : 3; /* send pkt pri */
+ u32 cfi : 1;
+ u32 vlan_id : 12;
+ u32 dmac_h16 : 16;
+#else
+ u32 dmac_h16 : 16;
+ u32 vlan_id : 12;
+ u32 cfi : 1;
+ u32 vlan_pri : 3; /* send pkt pri */
+#endif
+ } bs;
+ u32 value;
+ } dw12;
+
+ /* DW13 */
+ u32 rsvd1;
+
+ /* DW14 */
+ u32 dmac_l32;
+
+ /* DW15 */
+ u32 drct_key_h;
+} roce_wqe_drc_tsk_seg_s;
+
+typedef struct roce_wqe_data_seg {
+ /* DW0~1 */
+ union {
+ u64 addr;
+ struct {
+ u32 addr_h32;
+ u32 addr_l32;
+ } bs;
+ };
+
+ /* DW2~3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 1;
+ u32 len : 31;
+#else
+ u32 len : 31;
+ u32 rsvd : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW4 */
+ u32 key;
+} roce_wqe_data_seg_s;
+
+#endif // ROCE_WQE_BASE_FORMAT_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_format.h
new file mode 100644
index 000000000..1852b87c5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_wqe_format.h
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA wqe structure format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_WQE_FORMAT_H
+#define ROCE_WQE_FORMAT_H
+
+#include "roce_wqe_base_format.h"
+#include "roce_npu_cmd_mr_defs.h" // For DIF reg mr WQE
+#include "roce_wqe_ulp_task.h"
+#include "roce_wqe_opt_types.h"
+
+/* Type1/2 MW Bind WQE */
+typedef struct roce_wqe_bind_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW0~2 */
+ u32 rsvd0[3];
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rae : 1;
+ u32 rwe : 1;
+ u32 rre : 1;
+ u32 type : 1;
+ u32 rsvd : 28;
+#else
+ u32 rsvd : 28;
+ u32 type : 1; /* MW type: 0-Type1 Window 1-Type2B Window */
+ u32 rre : 1; /* Remote read enable */
+ u32 rwe : 1; /* Remote write enable */
+ u32 rae : 1; /* Indicates whether remote Atomic is enabled. */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4 */
+ u32 new_rkey; /* The MW corresponds to the MPT key and is indexed to the MPT through the New_Rkey. For the type1 MW,
+ * This parameter is valid only when the value of New_Rkey is the same as the value of mem_key in the
+ * MPT. For type 2 MW, it is valid only when New_Rkey is equal to mem_key+1 in MPT.
+ * If this parameter is valid, the corresponding field in the MPT is replaced with the entire
+ * section. */
+
+ /* DW5 */
+ u32 lkey; /* Indicates the mem_key of the MR bound to the MW. */
+
+ /* DW6 */
+ u32 rsvd1;
+
+ /* DW7~8 */
+ union {
+ u64 va; /* Indicates the start virtual IP address of the MW. */
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+ } bs;
+ } dw7;
+
+ /* DW9~10 */
+ union {
+ u64 len; /* Indicates the length of the data corresponding to the MW. */
+ struct {
+ u32 len_h32;
+ u32 len_l32;
+ } bs;
+ } dw9;
+} roce_wqe_bind_tsk_seg_s;
+
+/* Fast Register PMR WQE */
+typedef struct roce_wqe_frmr_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW0~1 */
+ u32 rsvd[2];
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 fbo : 22;
+ u32 rsvd : 10;
+#else
+ u32 rsvd : 10;
+ u32 fbo : 22; /* This parameter is valid when ZERO_BASE is set to 1. */
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rae : 1;
+ u32 rwe : 1;
+ u32 rre : 1;
+ u32 lwe : 1;
+ u32 lre : 1;
+ u32 be : 1;
+ u32 zbva : 1;
+ u32 block : 1;
+ u32 rsvd : 2;
+ u32 page_size : 6;
+ u32 pa_num : 16;
+#else
+ u32 pa_num : 16; /* Number of registered PAs, which is calculated by the length/page_size. */
+ u32 page_size : 6; /* Memory Region page size */
+ u32 rsvd : 2;
+ u32 block : 1;
+ u32 zbva : 1; /* ZERO_BASED Permission */
+ u32 be : 1; /* Indicates whether the binding operation is enabled. */
+ u32 lre : 1; /* Local read enable */
+ u32 lwe : 1; /* Local write enable */
+ u32 rre : 1; /* Remote read enable */
+ u32 rwe : 1; /* Remote write enable */
+ u32 rae : 1; /* Indicates whether remote Atomic is enabled. */
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4 */
+ u32 m_key; /* Key of the Memory Region. */
+
+ /* DW5~6 */
+ union {
+ u64 va; /* Start virtual address of Memory Region. This parameter is valid only when ZBVA is not set to 1. */
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+ } bs;
+ } dw5;
+
+ /* DW7~8 */
+ union {
+ u64 len; /* Length of Memory Region */
+ struct {
+ u32 len_h32;
+ u32 len_l32;
+ } bs;
+ } dw7;
+
+ /* DW9~10 */
+ union {
+ u64 pbl_addr; /* Physical address for storing the cache of the PA table. */
+ struct {
+ u32 pbl_addr_h32;
+ u32 pbl_addr_l32;
+ } bs;
+ } dw9;
+} roce_wqe_frmr_tsk_seg_s;
+
+/* Local Invalidate WQE */
+typedef struct roce_wqe_local_inv_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW0 */
+ u32 rsvd;
+
+ /* DW1 */
+ u32 inv_key; /* Mem_Key for invalidate */
+
+ /* DW2 */
+ u32 rsvd1;
+} roce_wqe_local_inv_tsk_seg_s;
+
+typedef struct tag_roce_dif_wqe_rdma_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW1 */
+ u32 data_len;
+
+ /* DW2 */
+ u32 imm_data;
+
+ /* DW3 */
+ u32 rsvd1;
+
+ /* DW4~5 */
+ union {
+ u64 va;
+ struct {
+ u32 va_h32;
+ u32 va_l32;
+ } dw4;
+ };
+
+ /* DW6 */
+ u32 rkey;
+ roce_dif_user_data_s dif_data;
+ /* DW7 */
+ // u32 sig_key;
+} roce_dif_wqe_rdma_tsk_seg_s;
+
+typedef struct tag_roce_dif_wqe_snd_tsk_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW0 */
+ u32 data_len; /* Length of the data sent by the SQ WQE */
+
+ /* DW1 */
+ u32 immdata_invkey; /* This parameter is valid for the immediate data operation or SEND invalidate. */
+
+ roce_dif_user_data_s dif_data;
+} roce_dif_wqe_snd_tsk_seg_s;
+
+/* REG SIG MR Local WQE */
+typedef struct roce_wqe_reg_sig_mr_seg {
+ roce_wqe_tsk_com_seg_u common;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rre : 1; /* Remote read enable */
+ u32 rwe : 1; /* Remote write enable */
+ u32 lwe : 1; /* Local write enable */
+ u32 sgl_mode : 1; /* 0: Single SGL, 1: Dual SGL */
+ u32 sector_size : 1; /* 0 : 512B, 1: 4096B */
+ u32 rsvd1 : 3;
+ u32 block_size : 6; /* Block size, which is the same as the MPT data definition. */
+ u32 rsvd2 : 18;
+#else
+ u32 rsvd2 : 18;
+ u32 block_size : 6; /* Block size, which is the same as the MPT data definition. */
+ u32 rsvd1 : 3;
+ u32 sector_size : 1; /* 0 : 512B, 1: 4096B */
+ u32 sgl_mode : 1; /* 0: Single SGL, 1: Dual SGL */
+ u32 lwe : 1; /* Local write enable */
+ u32 rwe : 1; /* Remote write enable */
+ u32 rre : 1; /* Remote read enable */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ u32 sig_mr_mkey;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 10;
+ u32 mtt_offset : 22;
+#else
+ u32 mtt_offset : 22;
+ u32 rsvd : 10;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+ roce_dif_user_data_s dif_data;
+ u32 data_mr_key;
+ u32 metadata_mr_key;
+ u32 rsvd1;
+} roce_wqe_reg_sig_mr_seg_s;
+
+/* * SRQ Data Format start */
+typedef struct roce_wqe_srq_data_seg {
+ /* DW0~1 */
+ union {
+ u64 addr;
+
+ struct {
+ u32 addr_h32;
+ u32 addr_l32;
+ } bs;
+ };
+
+ /* DW2 */
+ union {
+ struct {
+ u32 rsv : 1; /* Reserved field */
+ u32 len : 31; /* Data length. The value can be [0 or 2G-1]. */
+ } bs;
+ u32 length;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+ u32 last : 1; /* Last flag. The 0-also has the next SGE. 1: The current SGE is the last one. */
+ u32 ext : 1; /* Extended flag. The value 0-is normal and does not need to be extended. 1: Extended mode. The
+ address of the current SGE points to SGL. The key and len are invalid. For RoCE, the value
+ is fixed to 0. */
+ u32 key : 30; /* Local_key. The least significant eight bits are keys, and the most significant 22 bits are
+ indexes. The most significant two bits are reserved and only 20 bits are used. */
+ } bs;
+ u32 lkey;
+ } dw3;
+} roce_wqe_srq_data_seg_s;
+/* * SRQ Data Format end */
+
+typedef union tag_roce_wqe_task_seg {
+ sq_wqe_task_remote_common_s remote_common;
+ roce_wqe_send_tsk_seg_s send;
+ roce_wqe_rdma_tsk_seg_s rdma;
+ roce_wqe_atomic_tsk_seg_s atomic;
+ roce_wqe_ext_atomic_tsk_seg_s ext_atomic;
+ roce_wqe_mask_atomic_tsk_seg_s masked_atomic;
+ roce_wqe_ud_tsk_seg_s ud;
+ roce_wqe_drc_tsk_seg_s drc_rdma;
+
+ roce_wqe_bind_tsk_seg_s bind_mw;
+ roce_wqe_frmr_tsk_seg_s frmr;
+ roce_wqe_local_inv_tsk_seg_s local_inv;
+ roce_wqe_ulp_rdma_tsk_seg_s ulp;
+#ifdef ROCE_DIF_EN
+ roce_wqe_reg_sig_mr_seg_s reg_sig_mr;
+ roce_dif_wqe_rdma_tsk_seg_s dif_rdma;
+#endif
+} roce_wqe_task_seg_u;
+
+#endif // ROCE_WQE_FORMAT_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_xqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_xqe_format.h
new file mode 100644
index 000000000..5d20ed911
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/roce/roce_xqe_format.h
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: RDMA XQE format.
+ * Create: 2021-12-30
+ */
+
+#ifndef ROCE_XQE_FORMAT_H
+#define ROCE_XQE_FORMAT_H
+
+#include "roce_cqe_format.h"
+
+/* * SQ DB Format start */
+typedef struct roce_sq_db_seg {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 type : 5;
+ u32 cos : 3;
+ u32 cp_flag : 1;
+ u32 rsvd : 1;
+ u32 ctx_size : 2;
+ u32 qpn : 20;
+#else
+ u32 qpn : 20;
+ u32 ctx_size : 2; /* RoCE QPC size, 512B */
+ u32 rsvd : 1;
+ u32 cp_flag : 1; /* control plane flag */
+ u32 cos : 3; /* Scheduling priority. The value source is SL. */
+ u32 type : 5; /* Set RoCE SQ Doorbell to 2 and RoCE Arm CQ Doorbell to 3. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sub_type : 4; /* */
+ u32 sgid_index : 7; /* gid index */
+ u32 mtu_shift : 3; /* 256B:0;512B:1;1024B:2;2048B:3;4096B:4 */
+ u32 rsvd : 1;
+ u32 xrc_vld : 1; /* 1:XRC service type */
+ u32 resv : 8;
+ u32 pi : 8; /* host sw write the sq produce index high 8bit to this section; */
+#else
+ u32 pi : 8; /* host sw write the sq produce index high 8bit to this section; */
+ u32 resv : 8;
+ u32 xrc_vld : 1;
+ u32 rsvd : 1;
+ u32 mtu_shift : 3;
+ u32 sgid_index : 7;
+ u32 sub_type : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+} roce_sq_db_seg_s;
+
+union roce_sq_db {
+ roce_sq_db_seg_s sq_db_seg;
+ union {
+ u64 sq_db_val;
+ struct {
+ u32 sq_db_val_h32;
+ u32 sq_db_val_l32;
+ } dw2;
+ };
+};
+
+/* *SQ DB Format end */
+
+/* DWQE DB Format start */
+typedef struct roce_sq_dwqe_ctrl {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 type : 2; /* indicate it is sq doorbell; */
+ u32 cos : 3; /* hardware priority */
+ u32 c : 1; /* control plane flag;we should indicate sq cmd through data plane; */
+ u32 pi_h4 : 4; /* high 4bit of pi; */
+ u32 cntx_si : 2; /* indicate the qpc size;cntx size: 0:256B/01:512B/10:1024B/11:reserved; */
+ u32 qpn : 20; /* indicate the sq qpn; */
+#else
+ u32 qpn : 20;
+ u32 cntx_si : 2;
+ u32 pi_h4 : 4;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 type : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sgid_index : 7; /* gid index */
+ u32 mtu_shift : 3; /* 256B:0;512B:1;1024B oo2;2048B oo3;4096B oo4 */
+ u32 r : 1; /* reserved bit; */
+ u32 xrc_vld : 1; /* 1:XRC service type */
+ u32 rsvd : 8;
+ u32 pi_l12 : 12; /* low 12bit of pi; */
+#else
+ u32 pi_l12 : 12;
+ u32 rsvd : 8;
+ u32 xrc_vld : 1;
+ u32 r : 1;
+ u32 mtu_shift : 3;
+ u32 sgid_index : 7;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+} roce_sq_dwqe_ctrl_s;
+
+union roce_sq_dwqe {
+ roce_sq_dwqe_ctrl_s dwqe_db; /* sq dwqe ctrl section structure; */
+ u64 dwqe_db_value; /* sq dwqe wqe ctrl section doorbell value; */
+};
+/* DWQE DB Format end */
+
+/* * ARM CQ DB Format start */
+typedef struct roce_db_cq_arm {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 type : 5; /* dB type. The value of RoCE ARM CQ DB is 3. */
+ u32 cos : 3; /* ARM CQ DB Not required */
+ u32 cp : 1; /* the control plane flag of a DB */
+ u32 non_filter : 1;
+ u32 cqc_type : 2; /* Cq type, 0: RDMA/1:T/IFOE/2.3: Rsv */
+ u32 cqn : 20;
+#else
+ u32 cqn : 20;
+ u32 cqc_type : 2; /* Cq type, 0: RDMA/1:T/IFOE/2.3: Rsv */
+ u32 non_filter : 1;
+ u32 cp : 1; /* the control plane flag of a DB */
+ u32 cos : 3; /* ARM CQ DB Not required */
+ u32 type : 5; /* dB type. The value of RoCE ARM CQ DB is 3. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cmd_sn : 2; /* The ArmCQ DB carries the CmdSn, which is compared with the CmdSn in the chip. If the is
+ * different from the in the chip, the is valid. If the is the same, the needs to be
+ * checked. --
+ * Each time a CEQE is generated, the CmdSn of the chip is updated to the CmdSn of the
+ * latest ArmCq DB. */
+ u32 cmd : 2; /* Run the Arm command. 0-non-Arm After receiving the next CQE with the SE, the 1-ARM SOLICITED
+ generates the CEQE. The * 2-ARM NEXT generates the CEQE after receiving the next CQE. */
+ u32 rsv1 : 4;
+ u32 ci : 24; /* Consumer pointer */
+#else
+ u32 ci : 24; /* Consumer pointer */
+ u32 rsv1 : 4;
+ u32 cmd : 2; /* Run the Arm command. 0-non-Arm After receiving the next CQE with the SE, the 1-ARM SOLICITED
+ generates the CEQE. The * 2-ARM NEXT generates the CEQE after receiving the next CQE. */
+
+ u32 cmd_sn : 2; /* The ArmCQ DB carries the CmdSn, which is compared with the CmdSn in the chip. If the
+ * values are different, the is valid. If the values are the same, the needs to be checked.
+ * -- Each time a CEQE is generated, the CmdSn of the chip is updated to the CmdSn of the
+ * latest ArmCq DB. */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+} roce_db_cq_arm_s;
+/* * ARM CQ DB Format end */
+
+typedef struct roce_resize_cqe {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 owner : 1; /* Owner bit. During initialization, 0 indicates all hardware, and 1 indicates all software.
+ * This bit is overwritten when the hardware writes the CQE. The meaning of the queue owner
+ * bit is reversed every time the queue owner is traversed. */
+ u32 rsvd : 31;
+#else
+ u32 rsvd : 31;
+ u32 owner : 1; /* Owner bit. During initialization, 0 indicates all hardware, and 1 indicates all software.
+ * This bit is modified when the hardware writes the CQE. The meaning of the queue owner bit
+ * is reversed every time the queue owner is traversed. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 op_type : 5; /* The operation type is the same as that of SQ WQE. For details, see the enumeration
+ roce_cqe_opcode. */
+ u32 s_r : 1; /* Indicates whether SQ CQE or RQ CQE is used. 1-Send Completion; 0-Receive Completion */
+ u32 rsvd : 26;
+#else
+ u32 rsvd : 26;
+ u32 s_r : 1; /* Indicates whether SQ CQE or RQ CQE is used. 1-Send Completion; 0-Receive Completion */
+ u32 op_type : 5; /* The operation type is the same as that of SQ WQE. For details, see the enumeration
+ roce_cqe_opcode. */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2~7 */
+ u32 rsvd[6];
+
+ u32 common_rsvd[8];
+} roce_resize_cqe_s;
+
+typedef struct roce_err_cqe {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 owner : 1; /* Owner bit. During initialization, 0 indicates all hardware, and 1 indicates all software.
+ * This bit is overwritten when the hardware writes the CQE. The meaning of the queue owner
+ * bit is reversed every time the queue owner is traversed. */
+ u32 rsvd : 11; /* For RoCE, this field is reserved. */
+ u32 qpn : 20; /* Local QPN, which is used in all cases. The driver finds the software QPC based on the QPN. */
+#else
+ u32 qpn : 20; /* Local QPN, which is used in all cases. The driver finds the software QPC based on the QPN. */
+ u32 rsvd : 11; /* For roce, this field is reserved. */
+ u32 owner : 1; /* Owner bit. During initialization, 0 indicates all hardware, and 1 indicates all software.
+ * This bit is overwritten when the hardware writes the CQE. The meaning of the queue owner
+ * bit is reversed every time the queue owner is traversed. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 op_type : 5; /* The operation type is the same as that of SQ WQE. For details, see roce_cqe_opcode. */
+ u32 s_r : 1; /* Indicates the SQ CQE or RQ CQE. 1-Send Completion; 0-Receive Completion */
+ u32 inline_r : 1;
+ u32 flush_op : 1;
+ u32 fake : 1;
+ u32 rsvd : 3;
+ u32 wqebb_cnt : 20; /* The WQEBB index and SQ/RQ/SRQ are valid. */
+#else
+ u32 wqebb_cnt : 20; /* The WQEBB index and SQ/RQ/SRQ are valid. */
+ u32 rsvd : 3;
+ u32 fake : 1; /* Indicates whether this CQE is a fake cqe or not.when fake = 1, optype & syndronme should be
+ 0 */
+ u32 flush_op : 1;
+ u32 inline_r : 1;
+ u32 s_r : 1; /* Indicates the SQ CQE or RQ CQE. 1-Send Completion; 0-Receive Completion */
+ u32 op_type : 5; /* The operation type is the same as that of SQ WQE. For details, see roce_cqe_opcode. */
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2~5 */
+ u32 rsvd[3];
+
+ u32 wqe_num;
+
+ /* DW6 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 srqn : 24; /* The XRC at the receive end is valid, which is XRCSRQ. */
+#else
+ u32 srqn : 24; /* The XRC at the receive end is valid, which is the XRCSRQ number. */
+ u32 rsvd : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ /* DW7 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 wqe_cnt : 16; /* WQE index: Indicates that the SQ is valid. */
+ u32 vendor_err : 8;
+ u32 syndrome : 8; /* 0 indicates that the operation is successful. The value is valid when Op_type is
+ ROCE_OPCODE_ERR. For details, see the enumeration roce_cqe_syndrome. */
+#else
+ u32 syndrome : 8; /* 0 indicates that the operation is complete. This parameter is valid when Op_type is set
+ to ROCE_OPCODE_ERR. For details about the definition, see the enumeration
+ roce_cqe_syndrome. */
+ u32 vendor_err : 8;
+ u32 wqe_cnt : 16; /* WQE index, valid SQ */
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd0 : 12;
+ u32 global_qpn : 20; /* 偏移需要联动1815E的HBU配置,当前固定只支持一个qpn_mode */
+#else
+ u32 global_qpn : 20;
+ u32 rsvd0 : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw8;
+
+ u32 common_rsvd[7];
+} roce_err_cqe_s;
+
+#endif // RDMA_XQE_FORMAT_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_aeqe.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_aeqe.h
new file mode 100644
index 000000000..c86323d04
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_aeqe.h
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: ub aeq define .
+ * Create: 2023-8-14
+ */
+
+#ifndef UB_AEQ_H
+#define UB_AEQ_H
+
+#define UB_AEQN_DEFAULT AEQ0
+#define UB_AEQN_CREDIT_TP AEQ3
+
+/**
+ * @brief union ub_aeqe_t - 异步事件队列事件信息
+ * @details 记录异步事件的详细信息
+ */
+typedef union ub_aeqe_t {
+ struct {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 queue_type : 4;
+ u32 credit_vld : 1;
+ u32 sub_type : 7;
+ u32 xid : 20;
+#else
+ u32 xid : 20; /**< xid */
+ u32 sub_type : 7; /**< 事件类型 @see > enum UB_AEQE_CREDIT_STATE_E */
+ u32 credit_vld : 1; /**< 信用启用标志 @see > enum UB_AEQE_CREDIT_VLD_E */
+ u32 queue_type : 4; /**< 队列类型 4'b0:TP, 4'b1:JFS, 4'b2:JFR, 4'b3:Jetty, 4'b4:JFC @see > enum UB_AEQE_QUEUE_TYPE_E */
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 api_type : 8;
+ u32 api_err_code : 4;
+ u32 udf_dfx : 20;
+#else
+ u32 udf_dfx : 20; /**< dfx信息,自定义 */
+ u32 api_err_code : 4; /**< api错误码 */
+ u32 api_type : 8; /**< api编号 */
+#endif
+ };
+ u32 dw1_value;
+ };
+ };
+
+ u64 qword_value;
+} ub_aeqe_u;
+
+/**
+ * @brief 将api信息转化为dfx u32信息
+ *
+ * @param api_type - dfx信息,自定义
+ * @param api_err_code - api错误码
+ * @param udf_dfx - api编号
+ *
+ * @details 将api信息赋值给结构体变量,返回该结构所在联合体中的u32值
+ *
+ * @return dfx u32信息
+ */
+static inline u32 ub_aeqe_api_dfx_info(u8 api_type, u8 api_err_code,
+ u32 udf_dfx)
+{
+ ub_aeqe_u ub_aeqe = { 0 };
+ ub_aeqe.api_type = api_type;
+ ub_aeqe.api_err_code = api_err_code;
+ ub_aeqe.udf_dfx = udf_dfx;
+ return ub_aeqe.dw1_value;
+}
+
+static inline void ub_aeqe_init(ub_aeqe_u *ub_aeqe, u8 sub_type,
+ u32 api_dfx_info, u32 xid, u16 queue_type,
+ u8 credit_vld)
+{
+ ub_aeqe->xid = xid;
+ ub_aeqe->queue_type = queue_type;
+ ub_aeqe->sub_type = sub_type;
+ ub_aeqe->credit_vld = credit_vld;
+ ub_aeqe->dw1_value = api_dfx_info;
+ return;
+}
+
+/**
+ * @brief enum UB_AEQE_CREDIT_STATE_E - 信用状态
+ * @details 信用状态
+ */
+enum UB_AEQE_CREDIT_STATE_E {
+ UB_AEQE_CREDIT_STATE_DONE = 0, /**< 信用状态完成 */
+ UB_AEQE_CREDIT_STATE_PUSH = 1, /**< 信用状态推送 */
+};
+
+/**
+ * @brief enum UB_AEQE_CREDIT_VLD_E - 信用启用标志
+ * @details 信用启用标志
+ */
+enum UB_AEQE_CREDIT_VLD_E {
+ UB_AEQE_CREDIT_DISABLE = 0, /**< 禁用信用 */
+ UB_AEQE_CREDIT_ENABLE = 1, /**< 启用信用 */
+};
+
+#define UB_CQM_AEQ_BASE_T_UB 80 /**< defined in "hinic5_cqm_defs.h" */
+#define UB_EVENT_TYPE_NUM 0x10 /**< defined in "hinic5_cqm_defs.h" */
+#define UB_CQM_AEQ_MAX \
+ (UB_CQM_AEQ_BASE_T_UB + UB_EVENT_TYPE_NUM) /**< aepe类型最大值 */
+
+/**
+ * @brief enum UB_CQM_AEQE_TYPE_E - 异步事件类型
+ * @details 异步事件类型
+ */
+enum UB_CQM_AEQE_TYPE_E {
+ UB_CQM_AEQE_TYPE_NOT_DEFINED = UB_CQM_AEQ_BASE_T_UB, /**< 未定义事件 */
+ UB_CQM_AEQE_TYPE_DEVICE_ERR = 81, /**< 设备错误事件 */
+ UB_CQM_AEQE_TYPE_TP_INFO = 82, /**< TP侧消息事件 */
+ UB_CQM_AEQE_TYPE_TP_WARN = 83, /**< TP侧告警事件 */
+ UB_CQM_AEQE_TYPE_TP_ERR = 84, /**< TP侧错误事件 */
+ UB_CQM_AEQE_TYPE_TA_INFO = 85, /**< TA侧消息事件 */
+ UB_CQM_AEQE_TYPE_TA_WARN = 86, /**< TA侧告警事件 */
+ UB_CQM_AEQE_TYPE_TA_ERR = 87, /**< TA侧错误事件 */
+ UB_CQM_AEQE_TYPE_PORT_ERR = 88, /**< 端口错误事件 */
+ UB_CQM_AEQE_TYPE_DEBUG = 89, /**< DEBUG事件 */
+ UB_CQM_AEQE_TYPE_VTP_INFO = 90, /**< 设备消息事件 */
+ UB_CQM_AEQE_TYPE_VTP_WARN = 91, /**< 设备告警事件 */
+ UB_CQM_AEQE_TYPE_VTP_ERR = 92, /**< 设备错误事件 */
+};
+
+/**
+ * @brief enum UB_AEQE_QUEUE_TYPE_E - 队列类型
+ * @details 队列类型
+ */
+enum UB_AEQE_QUEUE_TYPE_E {
+ UB_AEQE_TYPE_DEVICE = 0, /**< 设备 */
+ UB_AEQE_TYPE_PORT = 1, /**< 端口 */
+ UB_AEQE_TYPE_FLR = 2, /**< FLR */
+ UB_AEQE_TYPE_TP = 3, /**< TP */
+ UB_AEQE_TYPE_JFS = 4, /**< JFS */
+ UB_AEQE_TYPE_JFR = 5, /**< JFR */
+ UB_AEQE_TYPE_JETTY = 6, /**< JETTY */
+ UB_AEQE_TYPE_JFC = 7, /**< JFC */
+ UB_AEQE_TYPE_VTP = 8, /**< VTP */
+ UB_AEQE_TYPE_UTP = 9, /**< UTP */
+ UB_AEQE_TYPE_SIP = 10, /**< SIP */
+ UB_AEQE_TYPE_JFRC = 11, /**< JFRC */
+ UB_AEQE_TYPE_TPG = 12, /**< TPG */
+ UB_AEQE_TYPE_JETTY_GROUP = 13, /**< JETTY GROUP */
+ UB_AEQE_TYPE_TA_DFX = 14, /**< TA DFX */
+ UB_AEQE_TYPE_TP_DFX = 15, /**< TP DFX */
+ UB_AEQE_TYPE_TA_DEFAULT = 16, /**< TA 默认 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_DEVICE_E - 设备子类型
+ * @details 设备子类型
+ */
+enum UB_AEQE_SUBTYPE_DEVICE_E {
+ UB_AEQ_TYPE_DEVICE_NO_ERR = 0, /**< 设备正常 */
+ UB_AEQ_TYPE_DEVICE_ERR = 1, /**< 设备异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_FLR_E - FLR子类型
+ * @details FLR子类型
+ */
+enum UB_AEQE_SUBTYPE_FLR_E {
+ UB_AEQ_TYPE_FLR_NO_ERR = 0, /**< FLR正常 */
+ UB_AEQ_TYPE_FLR_ERR = 1, /**< FLR异常 */
+ UB_AEQ_TYPE_FLR_DONE = 2, /**< FLR完成 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_PORT_E - 端口子类型
+ * @details 端口子类型
+ */
+enum UB_AEQE_SUBTYPE_PORT_E {
+ UB_AEQ_TYPE_PORT_NO_ERR = 0, /**< 端口正常 */
+ UB_AEQ_TYPE_PORT_ACTIVE_ERR = 1, /**< 主端口异常 */
+ UB_AEQ_TYPE_PORT_ERR = 2, /**< 端口异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_TP_E - TP子类型
+ * @details TP子类型
+ */
+enum UB_AEQE_SUBTYPE_TP_E {
+ UB_AEQ_TYPE_TP_NO_ERR = 0, /**< TP正常 */
+ UB_AEQ_TYPE_TP_RETRY_EXCEED = 1, /**< TP重试超时 */
+ UB_AEQ_TYPE_TP_FATAL_ERR = 2, /**< TP致命异常 */
+ UB_AEQ_TYPE_TP_SUBHEALTH = 3, /**< TP亚健康 */
+ UB_AEQ_TYPE_TP_ERR_FLUSH_EMPTY = 4, /**< TP异常排空 */
+ UB_AEQ_TYPE_TP_MIGRATE = 5, /**< TP迁移 */
+ UB_AEQ_TYPE_TP_COMM_EST = 6, /**< tp comm est */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_TA_DEFAULT_E - TA 默认子类型
+ * @details TA 默认子类型
+ */
+enum UB_AEQE_SUBTYPE_TA_DEFAULT_E {
+ UB_NO_AEQ_TYPE_TA_ERR = 0, /**< TA ERR, but no AEQE */
+ UB_AEQ_TYPE_TA_ERR = 1, /**< TA异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_JFS_E - JFS子类型
+ * @details JFS子类型
+ */
+enum UB_AEQE_SUBTYPE_JFS_E {
+ UB_AEQ_TYPE_JFS_NO_ERR = 0, /**< JFS正常 */
+ UB_AEQ_TYPE_JFS_ERR = 1, /**< JFS异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_JFR_E - JFR子类型
+ * @details JFR子类型
+ */
+enum UB_AEQE_SUBTYPE_JFR_E {
+ UB_AEQ_TYPE_JFR_NO_ERR = 0, /**< JFR正常 */
+ UB_AEQ_TYPE_JFR_ERR = 1, /**< JFR异常 */
+ UB_AEQ_TYPE_JFR_ACCESS_ERR = 2, /**< JFR访问异常 */
+ UB_AEQ_TYPE_JFR_LIMIT_REACHED = 3, /**< JFR达到限制 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_JETTY_E - JETTY子类型
+ * @details JETTY子类型
+ */
+enum UB_AEQE_SUBTYPE_JETTY_E {
+ UB_AEQ_TYPE_JETTY_NO_ERR = 0, /**< JETTY正常 */
+ UB_AEQ_TYPE_JETTY_ERR = 1, /**< JETTY异常 */
+ UB_AEQ_TYPE_JETTY_ACESS_ERR = 2, /**< JETTY访问异常 */
+ UB_AEQ_TYPE_JETTY_LIMIT_REACHED = 3, /**< JETTY达到限制 */
+ UB_AEQ_TYPE_JETTY_GRP_ERR = 4, /**< JETTY组异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_JFC_E - JFC子类型
+ * @details JFC子类型
+ */
+enum UB_AEQE_SUBTYPE_JFC_E {
+ UB_AEQ_TYPE_JFC_NO_ERR = 0, /**< JFC正常 */
+ UB_AEQ_TYPE_JFC_ERR = 1, /**< JFC异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_VTP_E - VTP子类型
+ * @details VTP子类型
+ */
+enum UB_AEQE_SUBTYPE_VTP_E {
+ UB_AEQ_TYPE_VTP_NO_ERR = 0, /**< VTP正常 */
+ UB_AEQ_TYPE_VTP_ERR = 1, /**< VTP异常 */
+ UB_AEQ_TYPE_VTP_MIG_ING_ERR = 2, /**< VTP迁移中异常 */
+ UB_AEQ_TYPE_VTP_MIG_BACK_ERR = 3, /**< VTP迁移回退异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_UTP_E - UTP子类型
+ * @details UTP子类型
+ */
+enum UB_AEQE_SUBTYPE_UTP_E {
+ UB_AEQ_TYPE_UTP_NO_ERR = 0, /**< UTP正常 */
+ UB_AEQ_TYPE_UTP_ERR = 1, /**< UTP异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_SIP_E - SIP子类型
+ * @details SIP子类型
+ */
+enum UB_AEQE_SUBTYPE_SIP_E {
+ UB_AEQ_TYPE_SIP_NO_ERR = 0, /**< SIP正常 */
+ UB_AEQ_TYPE_SIP_ERR = 1, /**< SIP异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_JFRC_E - JFRC子类型
+ * @details JFRC子类型
+ */
+enum UB_AEQE_SUBTYPE_JFRC_E {
+ UB_AEQ_TYPE_JFRC_NO_ERR = 0, /**< JFRC正常 */
+ UB_AEQ_TYPE_JFRC_ERR = 1, /**< JFRC异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_TPG_E - TPG子类型
+ * @details TPG子类型
+ */
+enum UB_AEQE_SUBTYPE_TPG_E {
+ UB_AEQ_TYPE_TPG_NO_ERR = 0, /**< TPG正常 */
+ UB_AEQ_TYPE_TPG_NO_VALID_TP_ERR = 1, /**< TPG TP无效异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_JETTY_GROUP_E - JETTY GROUP子类型
+ * @details JETTY GROUP子类型
+ */
+enum UB_AEQE_SUBTYPE_JETTY_GROUP_E {
+ UB_AEQ_TYPE_JETTY_GROUP_NO_ERR = 0, /**< JETTY GROUP正常 */
+ UB_AEQ_TYPE_JETTY_GROUP_ERR = 1, /**< JETTY GROUP异常 */
+ UB_AEQ_TYPE_JETTY_GROUP_EMPTY = 2, /**< JETTY GROUP空 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_TA_DFX_E - TA DFX子类型
+ * @details TA DFX子类型
+ */
+enum UB_AEQE_SUBTYPE_TA_DFX_E {
+ UB_AEQ_TYPE_TA_DFX_NO_ERR = 0, /**< TA DFX正常 */
+ UB_AEQ_TYPE_TA_HOSTID_CHECK_ERR = 1, /**< TA DFX host_id 检查异常 */
+};
+
+/**
+ * @brief enum UB_AEQE_SUBTYPE_TP_DFX_E - TP DFX子类型
+ * @details TP DFX子类型
+ */
+enum UB_AEQE_SUBTYPE_TP_DFX_E {
+ UB_AEQ_TYPE_TP_DFX_NO_ERR = 0, /**< TP DFX正常 */
+};
+
+/**
+ * @brief enum UB_AEQE_API_TYPE_E - API 类型
+ * @details API 类型
+ */
+enum UB_AEQE_API_TYPE_E {
+ NOT_API_ERR = 0, /**< 没有异常api */
+ SQ_FETCH_WQE_ERR = 1, /**< sq获取wqe异常 */
+ RQ_FETCH_WQE_ERR = 2, /**< rq获取wqe异常 */
+ RQ_DMA_GEN_ERR = 3, /**< rq dma gen err */
+ SQ_DMA_GEN_ERR = 4, /**< sq dma gen err */
+ SQ_CPLT_WQE_ERR = 5, /**< sq完成wqe异常 */
+ SQ_RC_OP_ERR = 6, /**< sq rc操作异常 */
+ SQ_PCQ_GEN_ERR = 7, /**< sq pcq gen err异常 */
+ SQ_EXTEND_OP_ERR = 8, /**< sq扩展操作异常 */
+ MINVALID_OP_ERR = 9, /**< minvalid op err */
+ RQ_RDMA_OP_ERR = 10, /**< rq rdma操作异常 */
+ RQ_CQE_GEN_ERR = 11, /**< rq cqe gen err */
+ NOT_Q_DMA_GEN_ERR = 12, /**< not q dma gen err */
+ NOT_Q_READ_OP_ERR = 13, /**< not q read op err */
+ NOT_Q_WRITE_OP_ERR = 14, /**< not q write op err */
+ CTX_EXTEND_OP_ERR = 15, /**< 上下文扩展操作异常 */
+ CTX_CACHE_LOAD_ERR = 16, /**< 上下文缓存读取异常 */
+ PKT_CHECK_ERR = 17, /**< 包检查异常 */
+ EXT_OP_ERR = 18, /**< 扩展操作异常 */
+ SQA_FETCH_WQE_ERR = 19, /**< sqa获取wqe异常 */
+ SQ_TAMSN_OP_ERR = 20, /**< sq tamsn操作异常 */
+ SQ_CQE_GEN_ERR = 21, /**< sq cqe gen err */
+ CPB_PREALLOC_ERR = 22, /**< cpb预扣失败 */
+ JFR_ALLOC_ERR = 23, /**< rqe分配异常 */
+ TA_FUNC_LOAD_ERR = 24, /**< ta func的ub_en未使能 */
+ TP_SIP_INVLD = 25, /**< tp sip校验异常 */
+ TAMSN_ROUND_ERR = 26, /**< tamsn round校验错误 */
+};
+
+#endif /**< UB_AEQ_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_dw_index.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_dw_index.h
new file mode 100644
index 000000000..f3d9688fd
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_dw_index.h
@@ -0,0 +1,42 @@
+/*
+ * 版权所有 (c) 华为技术有限公司 2024.
+ * 注意:本头文件由工具自动生成,请勿手动修改
+ */
+
+#ifndef _UB_DW_INDEX_H_
+#define _UB_DW_INDEX_H_
+
+#define DW_IDX0 0
+#define DW_IDX1 1
+#define DW_IDX2 2
+#define DW_IDX3 3
+#define DW_IDX4 4
+#define DW_IDX5 5
+#define DW_IDX6 6
+#define DW_IDX7 7
+#define DW_IDX8 8
+#define DW_IDX9 9
+#define DW_IDX10 10
+#define DW_IDX11 11
+#define DW_IDX12 12
+#define DW_IDX13 13
+#define DW_IDX14 14
+#define DW_IDX15 15
+#define DW_IDX16 16
+#define DW_IDX17 17
+#define DW_IDX18 18
+#define DW_IDX19 19
+#define DW_IDX20 20
+#define DW_IDX21 21
+#define DW_IDX22 22
+#define DW_IDX23 23
+#define DW_IDX24 24
+#define DW_IDX25 25
+#define DW_IDX26 26
+#define DW_IDX27 27
+#define DW_IDX28 28
+#define DW_IDX29 29
+#define DW_IDX30 30
+#define DW_IDX31 31
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd.h
new file mode 100644
index 000000000..1e8ca8d7e
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB mpu cmd define.
+ * Create: 2023-11-1
+ */
+
+#ifndef UB_MPU_CMD_H
+#define UB_MPU_CMD_H
+
+/**
+ * @brief enum - ub mpu opcode enum define
+ * @details ub mpu opcode enum define
+ */
+enum {
+ UB_MPU_CMD_SET_FUNC_ATTR =
+ 0x0, /**< set function attribute @see > ub_cmd_func_attr */
+ UB_MPU_CMD_SET_CPU_ENDIAN =
+ 0x01, /**< set cpu endian @see > ub_cmd_func_set_cpu_endian */
+ UB_MPU_CMD_ADD_IP_ENTRY =
+ 0x02, /**< add ip entry @see > ub_cmd_ipsu_ip_entry */
+ UB_MPU_CMD_DEL_IP_ENTRY =
+ 0x03, /**< del ip entry @see > ub_cmd_ipsu_ip_entry */
+ UB_MPU_CMD_GET_CFG_INFO =
+ 0x04, /**< get_config info @see > ub_cmd_get_cfg_info */
+ UB_MPU_CMD_RSVD2 = 0x05,
+ UB_MPU_CMD_DEL_FUNC_RES =
+ 0x06, /**< delete function attribute @see > ub_cmd_func_attr */
+ UB_MPU_CMD_GET_FUNC_ATTR =
+ 0x07, /**< get function attribute @see > ub_cmd_get_cfg_info */
+ UB_MPU_CMD_CLEAR_IP_ENTRY =
+ 0x08, /**< clear ip entry @see > ub_cmd_ipsu_ip_entry */
+ UB_MPU_CMD_DFX_GET_FUNC_FILTER =
+ 0x09, /**< get g_ub_filter info @see > ub_cmd_get_ub_filter_info_resp */
+ UB_MPU_CMD_FEAT_NEGO_GET =
+ 0x0a, /**< get support feature @see > ub_feat_nego_s */
+ UB_MPU_CMD_FEAT_NEGO_SET =
+ 0x0b, /**< set support feature @see > ub_feat_nego_s */
+
+ UB_MPU_CMD_GET_CFG_CAP =
+ 0x10, /**< get config capability @see > ub_get_cfg_cap_cmd */
+ UB_MPU_CMD_SET_CC_PARA =
+ 0x11, /**< set cc parameter @see > ub_cc_para_cmd_s */
+ UB_MPU_CMD_GET_CC_PARA =
+ 0x12, /**< get cc parameter @see > ub_cc_para_cmd_s */
+ UB_MPU_CMD_SET_VM_XID_CFG =
+ 0x13, /**< set VM XID @see > ub_vm_global_xid_cfg_cmd_s */
+ UB_MPU_CMD_DFX_SET_CAP_CFG =
+ 0x14, /**< set capability config @see > ub_dfx_cfg_cap_param_cmd */
+ UB_MPU_CMD_DFX_GET_CAP_CFG =
+ 0x15, /**< get capability config @see > ub_dfx_cfg_cap_param_cmd */
+ UB_MPU_CMD_DFX_READ_CAP_CTR =
+ 0x16, /**< read capability counter @see > ub_dfx_cap_ctr_cmd */
+ UB_MPU_CMD_DFX_CLEAR_CAP_CTR =
+ 0x17, /**< clear capability counter @see > ub_dfx_cap_ctr_cmd */
+ UB_MPU_CMD_DFX_SET_DROP =
+ 0x18, /**< Configuring Packet Discarding @see > ub_dfx_drop_cmd */
+ UB_MPU_CMD_DFX_READ_PORT_STA =
+ 0x19, /**< read port statistics @see > ub_dfx_port_statistics_cmd_inbuf_s */
+ UB_MPU_CMD_DFX_READ_VF_STA =
+ 0x1a, /**< read vf statistics @see > ub_dfx_vf_statistics_cmd_inbuf_s */
+ UB_MPU_CMD_DFX_READ_PERF_CTR =
+ 0x1b, /**< read perf counter @see > ub_dfx_port_statistics_cmd_inbuf_s */
+ UB_MPU_CMD_CFG_RRLT_ACC_PARA =
+ 0x1c, /**< set rx rate limit acc parameter @see > ub_rx_rate_limit_acc_cmd_s */
+ UB_MPU_CMD_CFG_RRLT_WRED =
+ 0x1d, /**< get rx rate limit wred parameter @see > ub_rx_rate_limit_wred_cmd_s */
+
+ UB_MPU_CMD_MIGRATE_SET_DRAIN_FLAG =
+ 0x30, /**< migrate set drain flag @see > ub_migrate_set_drain_cmd */
+ UB_MPU_CMD_MIGRATE_GET_CACHE_LINE =
+ 0x31, /**< migrate get cache line @see > ub_migrate_get_cache_line */
+ UB_MPU_CMD_MIGRATE_GET_FUNC_CAP =
+ 0x32, /**< migrate get func cap @see > ub_migrate_get_func_cap */
+ UB_MPU_CMD_MIGRATE_WAIT_THREAD_SWITCH =
+ 0x33, /**< migrate wait npu thread switch @see > ub_migrate_wait_thread_wait */
+ UB_MPU_CMD_QOS_FUNC_MAPPING_SET =
+ 0x34, /**< qos func mapping to vnic set @see > ub_qos_cmd */
+ UB_MPU_CMD_QOS_BPS_SET = 0x35, /**< qos bps set @see > ub_qos_cmd */
+ UB_MPU_CMD_QOS_PPS_SET = 0x36, /**< qos pps set @see > ub_qos_cmd */
+
+ UB_MPU_CMD_RSVD0 = 0x40,
+ UB_MPU_CMD_RSVD1 = 0x41,
+ UB_MPU_CMD_GET_BDF_INFO =
+ 0x42, /**< get bdf info @see > udma_cmd_get_bdf_info */
+ UB_MPU_CMD_SET_MULTI_PATH_MODE =
+ 0x43, /**< 设置多路径模式 @see > ub_set_multi_mode_cmd_s */
+ UB_MPU_CMD_DFX_SET_FUNC_TABLE =
+ 0x44, /**< set func table @see > ub_dfx_modify_func_table_cmd_s */
+ UB_MPU_CMD_GET_FUNC_ID =
+ 0x45, /**< 获取func id @see > ub_cmd_get_func_id */
+ UB_MPU_CMD_MIGRATE_QUERY_DRAIN =
+ 0x46, /**< 迁移查询排空 @see > ub_migrate_cfg_thread_param_cmd_s */
+ UB_MPU_CMD_MIGRATE_DISABLE_LWB =
+ 0x47, /**< 迁移禁用快路径 @see > ub_migrate_cfg_thread_param_cmd_s */
+ UB_MPU_CMD_MIGRATE_STATE_NOTIFY =
+ 0x48, /**< 通知迁移状态 @see > ub_migrate_state_notify_cmd_s */
+ UB_MPU_CMD_MIGRATE_QUERY_TPG_DRAIN =
+ 0x49, /**< 迁移查询TP排空 @see > ub_migrate_cfg_thread_param_cmd_s */
+ /* cmd 0x4a~0x4f rsvd for migrate */
+
+ /* cmd 0x50~0x55 rsvd for fast path */
+ UB_MPU_CMD_CFG_FAST_PATH_CTRL =
+ 0x50, /**< fast path switch cmd @see > mpu_ub_cmd_set_fast_path_ctrl */
+
+ UB_MPU_CMD_DFX_TOOLS = 0xf0, /**< dfx tools @see > ub_dfx_tools_cmd */
+ UB_MPU_CMD_ADD_TA_IP_ENTRY =
+ 0xf1, /**< add ip entry to ta vf table@see > ub_cmd_ipsu_ta_ip_entry */
+ UB_MPU_CMD_DEL_TA_IP_ENTRY =
+ 0xf2, /**< del ip entry to ta vf table@see > ub_cmd_ipsu_ta_ip_entry */
+ /* 待新功能测试稳定后替换 */
+ UB_MPU_CMD_DFX_L2D = 0xf3, /**< ub l2d dfx @see > cmd_ub_l2d_dfx_init */
+ UB_MPU_CMD_CFG_L2D_TBL =
+ 0xf4, /**< ub l2d mem cmd @see > mpu_ub_cmd_config_l2d_tbl */
+
+ UB_MPU_CMD_MAX
+};
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd_defs.h
new file mode 100644
index 000000000..17df7a4e1
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_cmd_defs.h
@@ -0,0 +1,937 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB mpu cmd def define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_MPU_CMD_DEFS_H
+#define UB_MPU_CMD_DEFS_H
+
+#include "base_type.h"
+#include "mpu_cmd_base_defs.h"
+
+#define UB_ALGO_INDEX_SHIFT 3 /**< setting ub algo index shift position */
+
+#define UB_CC_LDCP_PARA_WND_MIN_SHIFT \
+ 3 /**< setting parameter values in cc algorithm window for LDCP */
+#define UB_CC_LDCP_PARA_WND_MIN_MAX \
+ 255 /**< setting parameter values in cc algorithm window for LDCP */
+
+#define UB_CC_LDCP_PARA_INIT_WND_SHIFT \
+ 2 /**< setting parameter values of the LDCP CC algorithm initialization window */
+#define UB_CC_LDCP_PARA_INIT_WND_MAX \
+ 255 /**< setting parameter values of the LDCP CC algorithm initialization window */
+
+#define UB_CC_LDCP_PARA_ALPHA_UNIT_SHIFT \
+ 4 /**< setting alpha unit parameters in LDCP cc algorithms */
+#define UB_CC_LDCP_PARA_ALPHA_MAX \
+ 64 /**< setting alpha parameters in LDCP cc algorithms */
+
+#define UB_CC_LDCP_PARA_BETA_UNIT_SHIFT \
+ 5 /**< setting beta unit parameters in LDCP cc algorithms */
+#define UB_CC_LDCP_PARA_BETA_MAX \
+ 64 /**< setting beta parameters in LDCP cc algorithms */
+
+#define UB_CC_LDCP_PARA_GAMMA_SHIFT \
+ 2 /**< setting gamma parameters in LDCP cc algorithms */
+#define UB_CC_LDCP_PARA_GAMMA_MAX \
+ 64 /**< setting gamma parameters in LDCP cc algorithms */
+
+#define UB_CC_LDCP_PARA_ETA_UNIT_SHIFT \
+ 8 /**< setting eta unit parameters in LDCP cc algorithms */
+#define UB_CC_LDCP_PARA_ETA_MAX \
+ 255 /**< setting eta parameters in LDCP cc algorithms */
+
+#define CC_PARA_PATTERN_NUM 8 /**< cc algorithms parameters pattern num */
+
+#ifdef HI1825V100
+#define UB_PORT_NUM_MAX 8 /**< setting max ub port num */
+#else
+#define UB_PORT_NUM_MAX 4 /**< setting max ub port num */
+#endif
+
+#define UB_COS_NUM_MAX 8 /**< setting max ub cos num */
+#define UB_PORT_CTR_MAX \
+ (UB_PORT_NUM_MAX * \
+ UB_COS_NUM_MAX) /**< setting max ub port counter num */
+#define UB_BASE_VF_ID 64 /**< setting ub base vf id */
+#define UB_VF_NUM_MAX 96 /**< setting max ub vf num */
+#define UB_PCIE_MODE_PF_NUM 32 /**< setting ub pcie mode pf num */
+#define UB_MTT_MAP_BHEAP_BIT_SHIFT 14 /**< bitmap size 16K bit per vf */
+#define UB_MTT_MAP_BHEAP_BYTE_NUM \
+ ((1 << UB_MTT_MAP_BHEAP_BIT_SHIFT) >> 3) /**< 3->bit转换为byte */
+#define UB_MTT_MAP_BHEAP_LT_ENTRY_SIZE 16 /**< bheap线性表访问按16byte粒度 */
+#define UB_MTT_MAP_BHEAP_LT_GET_INDEX(func_id) \
+ (((func_id)-UB_BASE_VF_ID) * UB_MTT_MAP_BHEAP_BYTE_NUM / \
+ UB_MTT_MAP_BHEAP_LT_ENTRY_SIZE) /**< lt start idx */
+#define UB_MTT_MAP_BHEAP_LT_ENTRY_NUM \
+ (UB_MTT_MAP_BHEAP_BYTE_NUM / \
+ UB_MTT_MAP_BHEAP_LT_ENTRY_SIZE) /**< lt entry num */
+
+#define UB_UEID_SIZE 16 /**< ub ueid size in pattern3 */
+
+/**
+ * @brief enum ub_cc_algo_e - 设备拥塞信息查询 cc 算法
+ * @details ub mpu 通过命令查询设备拥塞信息cc算法
+ */
+typedef enum {
+ UB_CC_ALGO_DCQCN = 0, /**< DCQCN算法 基于速率的端到端拥塞协议 */
+ UB_CC_ALGO_LDCP = 1, /**< LDCP拥塞控制算法 */
+ UB_CC_ALGO_IPQCN = 2, /**< IPQCN CC算法 */
+ UB_CC_ALGO_MIBO = 3, /**< MIBO CC算法 */
+ UB_CC_ALGO_CAQM = 4, /**< CAQM CC算法 */
+ UB_CC_ALGO_LDCP_L2H = 5, /**< LDCP拥塞控制算法,seq计算包含l2 header */
+ UB_CC_ALGO_LDCP_TPH = 6, /**< LDCP拥塞控制算法,seq计算包含tp header */
+ UB_CC_ALGO_USER_1 = 7, /**< 用户自定义cc算法 1 */
+ UB_CC_ALGO_USER_2 = 8, /**< 用户自定义cc算法 2 */
+ UB_CC_ALGO_MAX = 16 /**< 4bit最大支持16种 */
+} ub_cc_algo_e;
+
+/**
+ * @brief struct ub_cmd_func_set_cpu_endian - 设置function表cpu 端序
+ * @details ub mpu 通过命令设置function表cpu 端序
+ */
+struct ub_cmd_func_set_cpu_endian {
+ struct mgmt_msg_head head;
+
+ u16 func_id; /**< func_id */
+ u8 cpu_endian; /**< 具体端序 */
+ u8 rsvd1;
+};
+
+/**
+ * @brief struct ub_cmd_func_attr - 设置function表属性
+ * @details ub mpu 通过命令动态function表属性
+ */
+struct ub_cmd_func_attr {
+ struct mgmt_msg_head head;
+
+ /* body dw0 */
+ u16 func_id; /**< function func_id */
+ u16 resv;
+
+ /* body dw1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ /* 为适配大端环境25驱动+TR5MPU场景,增加大端编译宏 */
+ u32 resv : 24;
+ u32 drv_support_mtt_pro : 1;
+ u32 resv1 : 1;
+ u32 fast_path_timer_disable : 1;
+ u32 rcq_cnt : 1;
+ u32 slice : 1;
+ u32 pattern_type : 1;
+ u32 virtualization : 1;
+ u32 func_en : 1;
+#else
+ u32 func_en : 1;
+ u32 virtualization : 1;
+ u32 pattern_type : 1;
+ u32 slice : 1;
+ u32 rcq_cnt : 1;
+ u32 fast_path_timer_disable : 1;
+ u32 resv1 : 1;
+ u32 drv_support_mtt_pro : 1;
+ u32 resv : 24;
+#endif
+ } bs;
+ u32 value;
+ } attr1_mask; /**< function attr1 掩码 */
+
+ /* body dw2 */
+ struct {
+ u32 func_en : 1; /**< func是否使能[0,1] */
+ u32 virtualization : 1; /**< 是否虚拟化[0,1] */
+ u32 pattern_type : 2; /**< 2'b0:Pattern1,2'b1:Pattern2, 2'b2: Pattern3, 2'b3: rsvd */
+ u32 slice : 2; /**< 切片数量 */
+ u32 rcq_cnt : 4; /**< 该值为rcq_cnt的对数,1:rcq_cnt=2, 2:rcq_cnt=4, ... */
+ u32 fast_path_timer_disable : 1; /**< 快路径是否自动退出[0,1]*/
+ u32 resv1 : 1;
+ u32 drv_support_mtt_pro : 1; /** 1:表示此function上的udma驱动支持mtt防攻击, 0:表示不支持 */
+ u32 resv : 19;
+ } attr1;
+
+ /* body dw3 */
+ union {
+ struct {
+ u32 ta2tp_type : 1;
+ u32 hbm_en : 1;
+ u32 reduce_en : 1;
+ u32 taack_flush_en : 1;
+ u32 func_cos : 1;
+ u32 bus_multi_path_en : 1;
+ u32 fake_dma_pa_en : 1; /** 是否分配bank gpa */
+ u32 resv : 25;
+ } bs;
+ u32 value;
+ } attr2_mask; /**< function attr2 掩码 */
+
+ /* body dw4 */
+ struct {
+ u32 ta2tp_type : 4; /** TA2TP调度算法类型 */
+ u32 hbm_en : 1; /** david直通能力使能 */
+ u32 reduce_en : 1; /** inline reduce能力使能 */
+ u32 taack_flush_en : 1; /** taack flush开启 */
+ u32 func_cos : 3; /** 记录func表cos */
+ u32 bus_multi_path_en : 1; /** 主机侧总线多路径能力使能 */
+ u32 resv1 : 21;
+ } attr2;
+
+ u64 fake_dma_pa;
+};
+
+/**
+ * @brief struct ub_cmd_func_resp - ub function cmd response
+ * @details ub mpu 通过命令动态获取function表属性
+ * ub mpu 通过命令获取tpfid
+ */
+struct ub_cmd_func_resp {
+ struct mgmt_msg_head head;
+
+ u16 func_id; /**< function func_id */
+ u16 tpf_id; /**< tpf_id index */
+ u32 v : 1; /**< virtualization from urma */
+ u32 bond_en : 1; /**< bond enable for ub */
+ u32 npi_perm : 1; /**< npi perm */
+ u32 ub_link_en : 1; /**< UB_link enable头模式[0,1] */
+ u32 pattern_type : 2; /**< 2'b0:Pattern1,2'b1:Pattern2, 2'b2: Pattern3, 2'b3: rsvd */
+ u32 round_byte : 8; /**< for jetty vf flr */
+ u32 mig_draining : 1; /**< ub migrate draining flag */
+ u32 slice_sz : 2; /**< 2'b0:32K, 2'b1:64K, 2'b2:128K, 2'b3:256K */
+ u32 func_en : 1; /**< func是否使能[0,1] */
+ u32 virtualization : 1; /**< 是否虚拟化[0,1] */
+ u32 attach_en : 1; /**< attach_en: 0:offload, 1:onload */
+ u32 rsvd : 12;
+};
+
+/**
+ * @brief struct ub_cmd_get_cfg_info - get function attribute
+ * @details ub mpu 通过命令动态function表属性
+ */
+struct ub_cmd_get_cfg_info {
+ struct mgmt_msg_head head;
+
+ u16 func_id; /**< function func_id */
+ u8 rsvd[2];
+};
+
+/**
+ * @brief struct ub_cmd_get_cfg_info_resp - get function attribute response
+ * @details ub mpu 通过命令动态获取function表属性响应
+ */
+struct ub_cmd_get_cfg_info_resp {
+ struct mgmt_msg_head head;
+
+ u8 scenes_id; /**> 获取场景ID信息. */
+ u8 lb_en; /**> 是否使能了LoadBalance. */
+ u8 lb_mode; /**> 获取当前LoadBalance是模式. */
+ u8 container_mode; /**> 获取UB SRQ container mode. */
+
+ u8 fake_en; /**> 判断当前Func是否使能Fake VF, 是则返回其所属的PF. */
+ u8 pf_start_bit; /**> pf start bit. */
+ u8 pf_end_bit; /**> pf end bit. */
+ u8 page_bit; /**> page bit. */
+ u32 rsvd;
+};
+
+/**
+ * @brief struct ub_cmd_get_func_id - 根据func_id查询function属性
+ * @details ub mpu 通过命令动态获取function表属性
+ */
+struct ub_cmd_get_func_id {
+ struct mgmt_msg_head head;
+
+ u32 rsvd[2];
+};
+
+/**
+ * @brief struct ub_cmd_get_func_id_resp - 根据func_id查询function表响应
+ * @details ub mpu 通过命令动态获取function表属性响应
+ */
+struct ub_cmd_get_func_id_resp {
+ struct mgmt_msg_head head;
+
+ u32 func_id; /**< vf func_id of resp */
+ u32 tpf_id; /**< tpf_id of resp */
+ u32 rsvd[2];
+};
+
+/**
+ * @brief union ub_ip_info - 具体ip模式
+ * @details ip 两种模式ipv4、ipv6,使用于ub mpu初始化、卸载驱动时ipsu 设置ip;
+ * 使用于ub mpu 动态修改ipsu ip
+ */
+union ub_ip_info {
+ struct {
+ u64 high;
+ u64 low;
+ } ipv6;
+ struct {
+ u32 rsvd0[1];
+ u32 val;
+ u32 rsvd1[2];
+ } ipv4;
+ struct {
+ u8 id[UB_UEID_SIZE];
+ } eid;
+ u32 dw[4];
+};
+
+/**
+ * @brief struct ub_cmd_ipsu_ip_entry - ub设置ip
+ * @details ip 两种模式ipv4、ipv6,使用于ub mpu初始化、卸载驱动时ipsu 设置ip;
+ * 使用于ub mpu 动态修改ipsu ip
+ */
+struct ub_cmd_ipsu_ip_entry {
+ struct mgmt_msg_head head;
+
+ u16 func_id; /**< vf func_id */
+ u8 port_id; /**< port id */
+ u8 ip_ver; /**< 0x0:IPv4; 0x1:IPv6。*/
+ union ub_ip_info ip; /**< ub_cmd_ipsu_ip_entry @see > ub_ip_info */
+};
+
+struct ub_cmd_ipsu_ta_ip_entry {
+ struct mgmt_msg_head head;
+
+ u16 func_id; /**< vf func_id */
+ u8 ip_ver; /**< 0x0:IPv4; 0x1:IPv6。*/
+ u8 nlp;
+ union ub_ip_info ip; /**< ub_cmd_ipsu_ip_entry @see > ub_ip_info */
+ u32 upi;
+};
+
+/**
+ * @brief union ub_device_feat - ub 设备feature能力配置
+ * @details udma注册ub设备/udma 设备初始化/urma调用查询设备属性
+ */
+union ub_device_feat {
+ struct {
+ u32 oor : 1; /**< URMA_OUT_OF_ORDER_RECEIVING. */
+ u32 jfc_per_wr : 1; /**< URMA_JFC_PER_WR. */
+ u32 stride_op : 1; /**< URMA_STRIDE_OP. */
+ u32 load_store_op : 1; /**< URMA_LOAD_STORE_OP. */
+ u32 non_pin : 1; /**< URMA_NON_PIN. */
+ u32 pmem : 1; /**< URMA_PERSISTENCE_MEM. */
+ u32 jfc_inline : 1; /**< URMA_JFC_INLINE. */
+ u32 spray_en : 1; /**< URMA_SPRAY_ENABLE for UDP port.*/
+ u32 selective_retrans : 1; /**< URMA_SELECTIVE_RETRANS. */
+ u32 live_migrate : 1; /**< support live migration. */
+ u32 dca_tx : 1; /**< for user tp tx */
+ u32 dca_rx : 1; /**< for user tp rx */
+ u32 jetty_grp : 1; /**< support jetty group. */
+ u32 error_suspend : 1; /**< support suspend jetty or jfs on error. */
+ u32 outorder_comp : 1; /**< support out-of-order completion. */
+ u32 bond_en : 1; /**< bond enable for ub */
+ u32 pi_on_chip_en : 1; /**< pi on chip enable[0,1] */
+ u32 reserved : 15;
+ } bs;
+ u32 value;
+};
+
+/**
+ * @brief struct ub_dev_cap - ub 设备能力配置
+ * @details udma注册ub设备/udma 设备初始化/urma调用查询设备属性
+ */
+struct ub_dev_cap {
+ union ub_device_feat feature;
+ u32 max_jfc; /**< max number of jfc supported by the device. */
+ u32 max_jfs; /**< max number of jfs supported by the device. */
+ u32 max_jfr; /**< max number of jfr supported by the device. */
+ u32 max_jetty; /**< max number of jetty supported by the device. */
+ u32 max_jetty_grp; /**< max number of jetty group supported by the device. */
+ u32 max_jetty_in_jetty_grp; /** max number of jetty per jetty group supported by the device. */
+ u16 max_jfc_depth; /**< max depth of jfc supported by the device. */
+ u16 max_jfs_depth; /**< max depth of jfs supported by the device. */
+ u16 max_jfr_depth; /**< max depth of jfr supported by the device. */
+ u16 max_jfs_inline_size; /**< max inline size(byte) supported by the jfs. */
+ u16 max_jfc_inline_size; /**< max inline size(byte) supported by the jfc. */
+ u16 max_jfs_sge; /**< max number of sge supported by the jfs. */
+ u16 max_jfs_rsge; /**< max number of rsge supported by the jfs. */
+ u16 max_jfr_sge; /**< max number of sge supported by the jfr. */
+ u64 max_msg_size; /**< max message size supported by the device. */
+ u32 max_vtp; /**< max number of vtp supported by the device. */
+ u32 max_tpg; /**< max number of tpg supported by the device. */
+ u32 max_tp; /**< max number of tp supported by the device. */
+ u32 max_tp_in_tpg; /**< max number of tp in tpg supported by the device. */
+ u64 max_rc_outstd_cnt; /**< max read command outstanding count in the function entity */
+ u32 max_sip_cnt_per_vf; /**< max number of sip count in per vf supported by the device. */
+ u32 max_dip_cnt_per_vf; /**< max number of dip count in per vf supported by the device. */
+ u32 max_seid_cnt_per_vf; /**< max number of seid count in per vf supported by the device. */
+ u32 max_oor_cnt; /**< max number of oor count supported by the device. */
+ u32 max_utp_cnt; /**< max number of utp count supported by the device. */
+ u32 max_eid_cnt; /**< max number of eid count supported by the device. */
+ u32 max_upi_cnt; /**< max number of upi count supported by the device. */
+ u32 seid_idx_start; /**< seid idx start supported by the device. */
+ u32 min_slice; /** min number of slice supported by the device. */
+ u32 max_slice; /** max number of slice supported by the device. */
+ u32 max_pi_on_chip_num; /**< max pi chip number supported by the device. */
+
+ u32 virtualization : 1; /**< whether virtualization is supported by the device[0,1]. */
+ u32 pattern_type : 2; /**< 2'b0:Pattern1,2'b1:Pattern2, 2'b2: Pattern3, 2'b3: rsvd */
+ u32 slice : 2; /**< number of slice supported by the device. */
+ u32 vf_default_cos : 3; /**< 支持用户配置cos值, 默认值:5 */
+ u32 pf_default_cos : 3; /**< 支持用户配置cos值, 默认值:4 */
+ u32 dwqe_dis : 1; /**< direct wqe disable */
+ u32 mtt_pro_en : 1;
+ u32 jfrc_cos : 3; /**< jfrc cos, 默认值:2 */
+ u32 hbm_en : 1; /**< david hbm enable */
+ u32 default_jetty_cos : 3; /**< 配置文件func粒度默认cos */
+ u32 func_cos : 3; /**< 创建vport配置给func表cos */
+ u32 dcs_en : 1; /**< 数控分离开关状态 */
+ u32 resvd : 8;
+};
+
+/**@struct ub_dev_cap_udma_res
+* @brief udma自己申请相关资源信息
+*/
+struct ub_dev_cap_udma_res {
+ u32 num_ceq_vectors;
+ u32 direct_wqe_size;
+ u8 log_mtt; /**< 1. the number of MTT PA must be integer power of 2 <p>
+ * 2. represented by logarithm. Each MTT table can <p>
+ * contain 1, 2, 4, 8, and 16 PA)
+ */
+ u8 rsvd[3];
+ u32 num_mtts; /**< Number of MTT table (4M) */
+ u32 log_mtt_seg; /**< segmet of log mtt */
+ u32 mtt_entry_sz; /**< MTT table size 8B, including 1 PA(64bits) */
+
+ u32 log_ubrc_seg; /**< segmet of log ubrc */
+ u32 ubrc_depth; /**< ubrc depth */
+ u32 ubrc_entry_size; /**< ubrc entry size */
+
+ u32 max_jfrc_num; /**< max jfrc num */
+ u32 jfrc_depth; /**< jfrc depth */
+ u32 rsvd_u32[5];
+};
+
+/**
+ * @brief struct ub_get_cfg_cap_cmd - 获取ub设备能力
+ * @details udma 设备初始化/mpu ub 初始化根据func_id获取设备能力
+ */
+struct ub_get_cfg_cap_cmd {
+ struct mgmt_msg_head head;
+
+ u16 func_id; /**> function func_id */
+ u8 rsvd[2];
+};
+
+/**
+ * @brief struct ub_get_cfg_cap_resp - 获取ub设备能力response
+ * @details udma 设备初始化/mpu ub 初始化根据func_id获取设备能力
+ */
+struct ub_get_cfg_cap_resp {
+ struct mgmt_msg_head head;
+ struct ub_dev_cap_udma_res
+ udma_res; /**> ub_get_cfg_cap_resp @see > ub_dev_cap_udma_res*/
+ struct ub_dev_cap dev_cap; /**> ub_get_cfg_cap_resp @see > ub_dev_cap*/
+ u32 ub_cmd_ext[0];
+};
+
+/**
+ * @brief struct ub_qos_cmd - ub设备qos限速能力
+ * @details udma dfx 设置qos限速的bps、vnic、pps能力
+ */
+typedef struct ub_qos_cmd {
+ struct mgmt_msg_head head;
+ u16 func_id; /**< func_id */
+ u16 vnic_id; /**< 指定vnic的id */
+ u16 xir_type; /**< 0: 保证速率 cir, 1: 峰值速率 pir */
+ u16 rsvd;
+ u32 bps; /**< 修改指定vnic的bps限速 */
+ u32 pps; /**< 修改指定vnic的pps限速 */
+} ub_qos_cmd_s;
+
+/**
+ * @brief struct ub_dfx_cfg_cap_param_cmd - ub dfx set/get cfg cap
+ * @details udma dfx set/get cfg
+ */
+typedef struct ub_dfx_cfg_cap_param_cmd {
+ struct mgmt_msg_head head;
+ u16 index;
+ u16 rsvd;
+ u32 param[4];
+} ub_dfx_cfg_cap_param_cmd_s;
+
+/**
+ * @brief struct ub_cc_para - ub dfx 获取cc配置
+ * @details udma ioctl阶段 dfx 获取cc配置
+ */
+typedef struct ub_cc_para {
+ struct {
+ u32 dw[2]; /** < 算法无关的公共参数,预留8B */
+ } common;
+ union {
+ struct {
+ u8 wnd_min; /**< (wnd_min+1)*8代表实际窗口 */
+ u8 init_wnd; /**< 初始窗口 */
+ u8 alpha; /**< LDCP算法的4个参数,扩大64倍 */
+ u8 beta; /**< cc算法beta参数 */
+ u8 gamma; /**< cc算法gamma参数 */
+ u8 eta; /**< cc算法eta参数 */
+ } ldcp;
+ struct {
+ u8 alpha;
+ u8 beta;
+ u8 eta;
+ u8 wnd_min;
+ u8 init_wnd;
+ u8 cc_unit;
+ } caqm;
+ u32 dw[6]; ///< 算法相关参数,预留24B
+ };
+} ub_cc_para_s;
+
+/**
+ * @brief struct ub_cc_para_cmd - ub dfx 设置cc配置
+ * @details udma ioctl阶段 dfx 设置cc配置
+ */
+typedef struct ub_cc_para_cmd {
+ struct mgmt_msg_head head;
+ u8 algo;
+ u8 index;
+ u8 rsvd[2];
+ ub_cc_para_s para;
+} ub_cc_para_cmd_s;
+
+/**
+ * @brief struct ub_rx_rate_limit_para - 整机限速
+ * @details ub整机限速ACC算法默认参数调整
+ */
+typedef struct ub_rx_rate_limit_para {
+ struct {
+ u16 down_period;
+ u16 up_period;
+ u16 alpha1;
+ u16 n1;
+ u16 alpha2;
+ u16 alpha3;
+ u16 min_rate;
+ u16 init_rate;
+ u8 n2;
+ u8 beta;
+ u16 resv;
+ } pattern;
+} ub_rx_rate_limit_s;
+
+/**
+ * @brief struct ub_rx_rate_limit_acc_cmd - 整机限速
+ * @details ub整机限速ACC算法默认参数调整
+ */
+typedef struct ub_rx_rate_limit_acc_cmd {
+ struct mgmt_msg_head head;
+ ub_rx_rate_limit_s
+ para; /**< ub_rx_rate_limit_acc_cmd @see > ub_rx_rate_limit_para */
+} ub_rx_rate_limit_acc_cmd_s;
+
+/**@struct ub_rx_rate_limit_wred_cmd
+* @brief ub dfx config rx rate limit wred
+*/
+typedef struct ub_rx_rate_limit_wred_cmd {
+ struct mgmt_msg_head head;
+ u32 cmd;
+ u32 wred_idx;
+ u32 start_val;
+ u32 end_val;
+} ub_rx_rate_limit_wred_cmd_s;
+
+/**
+ * @brief struct ub_set_multi_mode_cmd - 设置多路径模式
+ * @details ub dfx 动态设置多路径模式
+ */
+typedef struct ub_set_multi_mode_cmd {
+ struct mgmt_msg_head head;
+ u32 multi_path_mode;
+ u32 func_id;
+} ub_set_multi_mode_cmd_s;
+
+/**@struct ub_dfx_cap_ctr_cmd
+* @brief ub dfx capture counter command
+*/
+typedef struct ub_dfx_cap_ctr_cmd {
+ struct mgmt_msg_head head;
+ u16 index;
+ u16 rsvd;
+ u32 value;
+} ub_dfx_cap_ctr_cmd_s;
+
+/**@struct ub_dfx_drop_cmd
+* @brief ub dfx drop cfg info
+*/
+struct ub_dfx_drop_cmd {
+ struct mgmt_msg_head head;
+ u32 func_port;
+ u32 drop_level;
+ u32 rsvd[2];
+};
+
+typedef struct ub_vm_glb_xid_cfg_data {
+ u32 min_jetty_num; /**< min jetty num */
+ u32 max_jetty_num; /**< max jetty num */
+ u32 min_jfr_num; /**< min jfr num */
+ u32 max_jfr_num; /**< max jfr num */
+
+ union {
+ struct {
+ u32 min_jetty_num : 1; /**< min jetty num */
+ u32 max_jetty_num : 1; /**< max jetty num */
+ u32 min_jfr_num : 1; /**< min jfr num */
+ u32 max_jfr_num : 1; /**< max jfr num */
+ u32 rsvd : 28;
+ } bs; /**< 1表示对应字段有效,0表示无效 */
+ u32 value;
+ } mask;
+
+ u32 rsvd[3];
+} ub_vm_glb_xid_cfg_data_s;
+
+/**
+ * @brief struct ub_vm_global_xid_cfg_cmd - 设置vm xid
+ * @details urma 调用ub设置vm xid
+ */
+typedef struct ub_vm_global_xid_cfg_cmd {
+ struct mgmt_msg_head head;
+
+ u16 vfid; /**< vm vfid */
+ u16 rsvd;
+
+ ub_vm_glb_xid_cfg_data_s xid_cfg;
+} ub_vm_global_xid_cfg_cmd_s;
+
+/**
+ * @brief struct ub_migrate_set_drain_cmd - ub migrate 设置迁移引流
+ * @details ub reset/mpu ub 初始化时设置迁移引流
+ */
+struct ub_migrate_set_drain_cmd {
+ struct mgmt_msg_head head;
+ u16 func_id; /**< vf func_id */
+ u8 drain_en; /**< 引流使能开关[0,1] */
+ u8 rsvd[3];
+};
+
+/**
+ * @brief struct ub_migrate_wait_thread_wait - ub migrate 设置io线程
+ * @details mpu 初始化设置io线程
+ */
+struct ub_migrate_wait_thread_wait {
+ struct mgmt_msg_head head;
+ u16 func_id; /**< vf func_id */
+ u8 vf_index; /**< vf index */
+ u8 rsvd[5];
+};
+
+/**
+ * @brief struct ub_mpu_cache_line_s - sm表数据查询
+ * @details ub mpu 初始化,查询ub_mpu_cache_line sm表数据
+ */
+typedef struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 9;
+ u32 valid : 1; /**< 是否有效 */
+ u32 cl_size : 2; /**< 查询buff 大小 */
+ u32 cl_end : 10; /**< 结束位置 */
+ u32 cl_start : 10; /**< 查询起始位置 */
+#else
+ u32 cl_start : 10; /**< 查询起始位置 */
+ u32 cl_end : 10; /**< 结束位置 */
+ u32 cl_size : 2; /**< 查询buff 大小 */
+ u32 valid : 1; /**< 是否有效 */
+ u32 rsvd : 9;
+#endif
+} ub_mpu_cache_line_s;
+
+#define UB_MPU_CACHE_LINE_NUM 8
+
+/**
+ * @brief struct ub_migrate_get_cache_line - sm cache数据查询
+ * @details ub mpu 初始化,从smf 表中获取ub cache line
+ */
+struct ub_migrate_get_cache_line {
+ struct mgmt_msg_head head;
+ u16 func_id; /**< ub vf func_id */
+ u16 cache_line_num; /**< get cache num ,ub default 8 */
+ ub_mpu_cache_line_s cache_line[UB_MPU_CACHE_LINE_NUM];
+ u32 rsvd[5];
+};
+
+/**
+ * @brief struct ub_migrate_get_func_cap - ub migrate get function capabilities
+ * @details ub mpu init,get ub function capabilities
+ */
+struct ub_migrate_get_func_cap {
+ struct mgmt_msg_head head;
+ u16 func_id; /**< function func_id */
+ u16 rsvd1;
+ u32 jetty_xid_start; /**< jetty xid 起始位置 */
+ u32 jetty_xid_end; /**< jetty xid 结束位置 */
+ u32 jfc_xid_start; /**< jfc xid 起始位置 */
+ u32 jfc_xid_end; /**< jetty xid 结束位置 */
+ u32 tpgn_start; /**< tpgn 起始位置 */
+ u32 tpgn_end; /**< tpgn 结束位置 */
+ u32 rsvd[3];
+};
+
+/**
+ * @brief struct ub_ctr_bytes - ub counter size
+ * @details ub counter size
+ */
+struct ub_ctr_bytes {
+ u64 pkt_bytes; /**< 单个包大小 */
+ u64 pkt_num; /**< 包数量 */
+};
+
+/**
+ * @brief struct ub_ctr_rx_tx_bytes - 微码rxtx 的counter
+ * @details ub_port_traffic 命令获取微码rxtx 的counter
+ */
+struct ub_ctr_rx_tx_bytes {
+ struct ub_ctr_bytes dp_rx; /**< dp rx @see > ub_ctr_bytes */
+ struct ub_ctr_bytes dp_tx; /**< dp tx @see > ub_ctr_bytes */
+ struct ub_ctr_bytes local_rx; /**< local rx @see > ub_ctr_bytes */
+ struct ub_ctr_bytes local_tx; /**< local rx @see > ub_ctr_bytes */
+};
+
+/**
+ * @brief struct ub_ctr_array_bytes - 微码rxtx 的counter
+ * @details ub_port_traffic 命令获取微码rxtx 的counter
+ */
+struct ub_ctr_array_bytes {
+ struct ub_ctr_rx_tx_bytes
+ cur[UB_VF_NUM_MAX]; /**< current ub rx tx counter @see > ub_ctr_rx_tx_bytes */
+ struct ub_ctr_rx_tx_bytes back
+ [UB_VF_NUM_MAX]; /**< back ub rx tx counter @see > ub_ctr_rx_tx_bytes */
+};
+
+/**
+ * @brief struct ub_dfx_port_statistics_cmd - 端口粒度流量统计
+ * @details udma ioctl ub_port_traffic 端口粒度流量统计
+ */
+typedef struct ub_dfx_port_statistics_cmd {
+ struct mgmt_msg_head head;
+ struct ub_ctr_rx_tx_bytes
+ ctr_array_cur; /**< ub rx tx counter @see > ub_ctr_rx_tx_bytes */
+ u64 cur_time; /**< current time */
+ u32 rsvd[2];
+} ub_dfx_port_statistics_cmd_s;
+
+/**
+ * @brief struct ub_dfx_port_statistics_cmd_inbuf - 端口粒度流量统计inbuf
+ * @details udma ioctl ub_port_traffic 端口粒度流量统计
+ */
+typedef struct ub_dfx_port_statistics_cmd_inbuf {
+ struct mgmt_msg_head head;
+ u8 port_id; /**< port of cmd */
+ u8 cos; /**< cos of cmd */
+ u16 rsvd;
+} ub_dfx_port_statistics_cmd_inbuf_s;
+
+/**
+ * @brief struct ub_dfx_vf_statistics_cmd_inbuf - vf粒度流量统计inbuf
+ * @details udma ioctl ub_port_traffic vf粒度流量统计
+ */
+typedef struct ub_dfx_vf_statistics_cmd_inbuf {
+ struct mgmt_msg_head head;
+ u8 vf_id; /**< vf_id of cmd */
+ u16 rsvd;
+} ub_dfx_vf_statistics_cmd_inbuf_s;
+
+/**
+ * @brief struct udma_pf_bdf_info - 查询function的bdf信息
+ * @details dfx bdf_info命令查询所有function的BDF信息
+ */
+typedef struct udma_pf_bdf_info {
+ u8 itf_idx; /**< itf_idx of bdf_info cmd */
+ u16 bdf; /**< bdf of bdf_info cmd */
+ u8 pf_bdf_info_vld; /**< pf_bdf_info_vld of bdf_info cmd 是否有效[0,1]*/
+} udma_pf_bdf_info_s;
+
+/**
+ * @brief struct udma_vf_bdf_info - 查询指定vf的信息
+ * @details dfx bdf_info命令查询所有vf的bdf信息
+ */
+typedef struct udma_vf_bdf_info {
+ u16 glb_pf_vf_offset; /**< global_func_id offset of 1st vf in pf */
+ u16 max_vfs; /**< vf number */
+ u16 vf_stride; /**< VF_RID_SETTING.vf_stride */
+ u16 vf_offset; /**< VF_RID_SETTING.vf_offset */
+ u8 bus_num; /**< tl_cfg_bus_num */
+ u8 rsv[3];
+} udma_vf_bdf_info_s;
+
+/**
+ * @brief struct udma_cmd_get_bdf_info - 查询function的bdf信息
+ * @details dfx bdf_info命令查询所有function的bdf信息
+ */
+typedef struct udma_cmd_get_bdf_info {
+ struct mgmt_msg_head head;
+ struct udma_pf_bdf_info pf_bdf_info[UB_PCIE_MODE_PF_NUM];
+ struct udma_vf_bdf_info vf_bdf_info[UB_PCIE_MODE_PF_NUM];
+ u32 vf_num; /**< vf num */
+} udma_cmd_get_bdf_info_s;
+
+/**
+ * @brief struct ub_dfx_modify_func_table_cmd - dfx 更新func_table
+ * @details dfx动态更新func_table
+ */
+typedef struct ub_dfx_modify_func_table_cmd {
+ struct mgmt_msg_head head;
+ struct {
+ struct {
+ u32 rsvd : 26;
+ u32 ub_en : 1; /**< ub_en enable[0,1] */
+ u32 mtt_pro_en : 1; /**< mtt_pro_en[0,1] */
+ u32 ub_link_en : 1; /**< ub link enable[0,1] */
+ u32 traffic_en : 1; /**< traffic enable[0,1] */
+ u32 debug_en : 1; /**< debug enable[0,1] */
+ u32 lwb_en : 1; /**< lwb enable[0,1] */
+ } bs;
+ struct {
+ u32 rsvd : 26;
+ u32 ub_en : 1; /**< ub_en enable[0,1] */
+ u32 mtt_pro_en : 1; /**< mtt_pro_en[0,1] */
+ u32 ub_link_en : 1; /**< ub link enable[0,1] */
+ u32 traffic_en : 1; /**< traffic enable[0,1] */
+ u32 debug_en : 1; /**< debug enable[0,1] */
+ u32 lwb_en : 1; /**< lwb enable[0,1] */
+ } bs_flag; /**< 是否修改的标记*/
+ } func_table_modify_attr;
+ u16 func_id; /**< func table func_id */
+ u8 rsvd[2];
+} ub_dfx_modify_func_table_cmd_s;
+
+/**
+ * @brief struct filter_node - filter node
+ * @details ub 初始化、udma ioctl获取ub filter 信息
+ */
+struct filter_node {
+ u32 start; /**< 起始位置 */
+ u32 size; /**< 取值大小 */
+ u16 in_use; /**< 是否使用[0,1] */
+ u16 vf_id; /**< vf vf_id */
+};
+
+/**
+ * @brief struct ub_cmd_get_ub_filter_info_resp - dfx get ub_filter_info
+ * @details ub 初始化、udma ioctl获取ub filter 信息
+ */
+struct ub_cmd_get_ub_filter_info_resp {
+ struct mgmt_msg_head head;
+ struct filter_node
+ filter_list[UB_VF_NUM_MAX +
+ 1]; /**< ub filter resp @see > filter_node */
+ u32 size; /**< size of ub filter resp */
+};
+
+/**
+ * @brief struct ub_cmd_common_resp - ub common response
+ * @details ub 初始化获取ub common response信息
+ */
+struct ub_cmd_common_resp {
+ struct mgmt_msg_head head;
+};
+
+/**
+ * @brief struct ub_migrate_thread_cfg_param - setting ub migrate thread
+ * @details mpu ub 初始化查询ub migrate io 线程
+ */
+typedef struct {
+ u8 index; /**< 资源索引 */
+ u8 thread_num; /**< 拉起STL TIMER线程数 */
+ u16 vfid;
+ u32 xid1; /**< jfrc结束编号,从0开始编号[0,jfrc_end);TPG排空时tpgn_start复用该字段 */
+ u32 xid2; /**< jetty/jfs结束编号,从jfrc_end开始编号[jfrc_end,jetty_end);TPG排空时tpgn_end复用该字段 */
+ u32 addr_h; /**< dma内存地址高32bit */
+ u32 addr_l; /**< dma内存地址低32bit */
+ u32 remain_query_cnt; /**< 剩余查询排空的次数 */
+} ub_migrate_thread_cfg_param;
+
+/**
+ * @brief struct ub_migrate_cfg_thread_param_cmd_s - setting ub_migrate_thread
+ * @details mpu ub 初始化查询ub migrate io 线程
+ */
+typedef struct {
+ struct mgmt_msg_head head;
+ ub_migrate_thread_cfg_param
+ param; /**> setting ub_migrate_thread @see ub_migrate_thread_cfg_param*/
+} ub_migrate_cfg_thread_param_cmd_s;
+
+#define UB_FEAT_BITMAP_U64_MAX 4 /**< setting ub feat bitmap max size */
+/**
+ * @brief struct ub_feat_nego_s - get support ub feature of nego
+ * @details udma probe/mpu ub init get support ub feature of nego
+ */
+typedef struct {
+ struct mgmt_msg_head head;
+ u64 feat_bitmap[UB_FEAT_BITMAP_U64_MAX];
+} ub_feat_nego_s;
+
+#define UB_MIGRATE_STATE_LOG_START 0 /**< log start */
+#define UB_MIGRATE_STATE_PRE_DEACTIVATE 1 /**< pre deactivate */
+#define UB_MIGRATE_STATE_DEACITVATE 2 /**< deactivate */
+#define UB_MIGRATE_STATE_SAVE 3 /**< save */
+#define UB_MIGRATE_STATE_LOG_STOP 4 /**< log stop */
+#define UB_MIGRATE_STATE_RESET 5 /**< reset */
+#define UB_MIGRATE_STATE_CANCEL 6 /**< cancel */
+#define UB_MIGRATE_STATE_PRE_ACTIVATE 7 /**< pre activate */
+#define UB_MIGRATE_STATE_RESTORE 8 /**< restore */
+#define UB_MIGRATE_STATE_ACTIVATE 9 /**< activate */
+#define UB_MIGRATE_STATE_POST_ACTIVATE 10 /**< post activate */
+
+/**
+ * @brief struct ub_migrate_state_notify - ub_migrate_state_notify
+ * @details mpu ub 迁移状态
+ */
+typedef struct {
+ u8 index; /**< 资源索引,[0,1]有效 */
+ u8 state; /**< 迁移状态 */
+ u16 vfid;
+} ub_migrate_state_notify;
+
+/**
+ * @brief struct ub_migrate_state_notify_cmd_s - ub_migrate_state_notify
+ * @details mpu ub 迁移状态通知
+ */
+typedef struct {
+ struct mgmt_msg_head head;
+ ub_migrate_state_notify
+ param; /**> notify ub_migrate_state @see ub_migrate_state_notify */
+} ub_migrate_state_notify_cmd_s;
+
+/**
+ * @brief struct ub_fast_path_ctrl_cmd_s
+ * @details 配置快路径开关控制命令消息体
+ */
+typedef struct {
+ struct mgmt_msg_head msg_head;
+
+ u16 chan_id; /* channel 0~6 */
+ u16 smf_id; /* SMF0~SMF7 */
+ u16 func_id;
+ u16 op_type; /* 1:set 2:get */
+
+ union {
+ struct {
+ u32 rsvd : 30;
+ u32 sm_fde_en : 1;
+ u32 ipsurx_ctrl_en : 1;
+ } bs;
+ u32 value;
+ } attr;
+
+ union {
+ struct {
+ u32 rsvd : 30;
+ u32 sm_fde_en : 1;
+ u32 ipsurx_ctrl_en : 1;
+ } bs;
+ u32 value;
+ } mask;
+
+ u16 lwb_en; /* func ucode fastpath enable flag */
+ u16 rsvd1;
+ u32 rsvd2;
+} ub_fast_path_ctrl_cmd_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_dfx_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_dfx_cmd_defs.h
new file mode 100644
index 000000000..63ce0a0c9
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_mpu_dfx_cmd_defs.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
+ * Description: UB mpu cmd def define.
+ */
+
+#ifndef UB_MPU_DFX_CMD_DEFS_H
+#define UB_MPU_DFX_CMD_DEFS_H
+
+#include "base_type.h"
+#include "mpu_cmd_base_defs.h"
+
+#define UB_LAT_TIME_GAP_NUM 8 /**< setting ub lat time of gap num */
+
+/**
+ * @brief struct ub_ctr_perf - 查询ub counter 性能具体指标
+ * @details 具体查询当前counter数量
+ */
+typedef struct ub_ctr_perf {
+ u64 ctr_cur; /**< 当前时间的counter数量 */
+ u64 cur_time; /**< 当前时间 */
+} ub_ctr_perf_s;
+
+/**
+ * @brief struct ub_ctr_performance - dfx 工具查询微码ub counter 性能
+ * @details ub mpu 通过命令查询微码tatx、tptx、tarx、taackrx、taacktx相关阶段counter
+ */
+typedef struct ub_ctr_performance {
+ struct ub_ctr_perf tareq_tatx; /**< tatx number of current req counter */
+ struct ub_ctr_perf taack_tatx; /**< tatx number of current ack counter */
+ struct ub_ctr_perf tarsp_tatx; /**< tatx number of current rsp counter */
+ struct ub_ctr_perf tareq_tptx; /**< tptx number of current req counter */
+ struct ub_ctr_perf taack_tptx; /**< tptx number of current ack counter */
+ struct ub_ctr_perf tarsp_tptx; /**< tptx number of current rsp counter */
+ struct ub_ctr_perf tareq_rx; /**< tarx number of current req counter */
+ struct ub_ctr_perf tarsp_rx; /**< tarx number of current rsp counter */
+ struct ub_ctr_perf taack_rx; /**< tarx number of current ack counter */
+ struct ub_ctr_perf tpacktx; /**< tp ack tx number of current counter */
+ struct ub_ctr_perf tpackrx; /**< tp ack rx number of current counter */
+ struct ub_ctr_perf
+ lwb_req_tx; /**< lwb req tx number of current counter */
+ struct ub_ctr_perf
+ lwb_req_rx; /**< lwb req rx number of current counter */
+} ub_ctr_performance_s;
+
+/**
+ * @brief struct ub_ctr_array_ctrs - 一段时间ub counter performance查询
+ * @details ub mpu 通过命令查询当前时间和back 时间端counter
+ */
+typedef struct ub_ctr_array_ctrs {
+ struct ub_ctr_performance cur[UB_LAT_TIME_GAP_NUM];
+ struct ub_ctr_performance back[UB_LAT_TIME_GAP_NUM];
+} ub_ctr_array_ctrs_s;
+
+/**
+ * @brief struct ub_perf_ctr_outbuf - ub counter performance outbuf
+ * @details ub mpu 通过命令查询counter outbuf
+ */
+typedef struct ub_perf_ctr_outbuf {
+ struct mgmt_msg_head head;
+ struct ub_ctr_performance
+ ctr_cur; /**< ub_perf_ctr_outbuf @see > ub_ctr_performance */
+ u64 cur_time; /**< current time */
+} ub_perf_ctr_outbuf_s;
+
+/**
+ * @brief struct ub_dfx_perf_ctr_cmd_inbuf - dfx query ub performance counter inbuf
+ * @details ub mpu 通过命令性能 counter输入inbuf
+ */
+typedef struct ub_dfx_perf_ctr_cmd_inbuf {
+ struct mgmt_msg_head head;
+ u8 gap_index; /**> gap_index of dfx */
+ u8 rsvd2[3]; /**< 保留字段 */
+} ub_dfx_perf_ctr_cmd_inbuf_s;
+
+/**
+ * @brief enum ub_dfx_tools_feature - ub dfx设置feature
+ * @details ub mpu feature 具体取值范围 ["invalid_feature", "migrate1", "migrate2"]
+ */
+typedef enum {
+ UB_DFX_FEATURE_INVALID = 0, /**> invalid_feature mode*/
+ UB_DFX_FEATURE_MIGRATE1 = 1, /**> migrate1 mode*/
+ UB_DFX_FEATURE_MIGRATE2 = 2, /**> migrate2 mode*/
+ UB_DFX_FEATURE_MAX
+} ub_dfx_tools_feature;
+
+/**
+ * @brief struct ub_dfx_tools_cfg - ub dfx设置工具配置
+ * @details ub mpu 初始化和通过命令设置tools配置
+ */
+typedef struct {
+ u32 tool_en; /**< tools enable [0,1] */
+ u32 feature; /**< ub_dfx_tools_feature @see > ub_dfx_tools_feature */
+ u32 p1; /**< param1 */
+ u32 p2; /**< param2 */
+ u32 p3; /**< param3 */
+ u32 p4; /**< param4 */
+} ub_dfx_tools_cfg;
+
+/**
+ * @brief struct ub_dfx_tools_cfg - ub dfx设置工具配置
+ * @details ub mpu 初始化和通过命令设置tools配置
+ */
+typedef struct {
+ struct mgmt_msg_head msg_head;
+ ub_dfx_tools_cfg cfg; /**< ub_dfx_tools_cmd @see > ub_dfx_tools_cfg */
+} ub_dfx_tools_cmd;
+
+#define UB_DFX_TOOLS_CMD_RESP_DATA_LEN 8 /**< ub dfx reponse data length */
+/**
+ * @brief struct ub_dfx_tools_cmd_resp - ub dfx设置tools response
+ * @details ub mpu 初始化和通过命令设置tools配置response
+ */
+typedef struct {
+ struct mgmt_msg_head msg_head;
+ u32 data[UB_DFX_TOOLS_CMD_RESP_DATA_LEN];
+} ub_dfx_tools_cmd_resp;
+
+/**
+ * @brief enum ub_l2d_dfx tile_id command
+ */
+typedef enum {
+ UB_L2D_DFX_TILE_ID_INVALID = 0, /**< tile_id command invalid */
+ UB_L2D_DFX_TILE_ID_TILE0, /**< tile_id command, tile 0 */
+ UB_L2D_DFX_TILE_ID_TILE1, /**< tile_id command, tile 1 */
+ UB_L2D_DFX_TILE_ID_TILE2, /**< tile_id command, tile 2 */
+ UB_L2D_DFX_TILE_ID_TILE3, /**< tile_id command, tile 3 */
+ UB_L2D_DFX_TILE_ID_TILE4, /**< tile_id command, tile 4 */
+ UB_L2D_DFX_TILE_ID_TILE5, /**< tile_id command, tile 5 */
+ UB_L2D_DFX_TILE_ID_TILE6, /**< tile_id command, tile 6 */
+ UB_L2D_DFX_TILE_ID_TILE7, /**< tile_id command, tile 7 */
+ UB_L2D_DFX_TILE_ID_TILE_ALL, /**< tile_id command, tile ALL */
+} ub_l2d_dfx_tile_id;
+
+/**
+ * @brief enum ub_l2d_dfx module command
+ */
+typedef enum {
+ UB_L2D_DFX_MODULE_INVALID = 0, /**< module command invalid */
+ UB_L2D_DFX_MODULE_DFX_TBL /**< module command dfx_table */
+} ub_l2d_dfx_module;
+
+/**
+ * @brief enum ub_l2d_dfx sub_type command
+ */
+typedef enum {
+ UB_L2D_DFX_SUB_TYPE_INVALID = 0, /**< sub_type command invalid */
+ UB_L2D_DFX_SUB_TYPE_SHOW, /**< sub_type command show */
+ UB_L2D_DFX_SUB_TYPE_CONFIG /**< sub_type command config */
+} ub_l2d_dfx_sub_type;
+
+/**
+ * @brief enum ub_l2d_dfx parm command
+ */
+typedef enum {
+ UB_L2D_DFX_PARM_INVALID = 0, /**< parm command invalid */
+ UB_L2D_DFX_PARM_TA_MAX_LOOP_CNT, /**< parm command ta_max_loop_cnt */
+ UB_L2D_DFX_PARM_TA_JETTY_TO_TP_RATIO, /**< parm command ta_jetty_to_tp_ratio */
+ UB_L2D_DFX_PARM_TA_TO_TP_DB_CNT, /**< parm command ta_to_tp_db_cnt */
+ UB_L2D_DFX_PARM_CACHE_THRESHOL, /**< parm command cache_threshold */
+ UB_L2D_DFX_PARM_TA_MAX_OUTSTANDING_SSN, /**< parm command ta_max_outstanding_ssn */
+ UB_L2D_DFX_PARM_TP_ACK_AGG_THRESHOLD, /**< parm command tp_ack_agg_threshold */
+ UB_L2D_DFX_PARM_TP_ACK_AGG_TIME, /**< parm command tp_ack_agg_time */
+ UB_L2D_DFX_PARM_TA_ACK_AGG_THRESHOLD, /**< parm command ta_ack_agg_threshold */
+ UB_L2D_DFX_PARM_TA_ACK_AGG_TIME, /**< parm command ta_ack_agg_time */
+ UB_L2D_DFX_PARM_TSO_NUM_MAX, /**< parm command tso_num_max */
+ UB_L2D_DFX_PARM_TSO_LEN_MAX, /**< parm command tso_len_max */
+ UB_L2D_DFX_PARM_PORT_SELECT_MODE, /**< parm command port_select_mode */
+ UB_L2D_DFX_PARM_LAT_MODE, /**< parm command lat_mode */
+ UB_L2D_DFX_PARM_RES_TAMSN_EN, /**< parm command res_tamsn_en */
+ UB_L2D_DFX_PARM_CPB_ALLOC_RETRY_NUM, /**< parm command cpb_alloc_retry_num */
+ UB_L2D_DFX_PARM_REQ_TP_CREDIKT, /**< parm command req_tp_credit */
+ UB_L2D_DFX_PARM_RSP_TP_CREDIKT, /**< parm command rsp_tp_credit */
+} ub_l2d_dfx_parm;
+
+/**
+ * @brief struct ub_l2d_dfx_cmd_resp_s - ub l2d dfx, mpu返回resp
+ * @details ub mpu 初始化和通过命令设置ub l2d dfx配置response
+ */
+#define UB_L2D_DFX_CMD_RESP_DATA_LEN 16 /**< @see l2d_ub_dfx_s */
+typedef struct {
+ struct mgmt_msg_head msg_head; /**< ub_l2d_dfx_cmd_resp, msg_head */
+ u32 data[UB_L2D_DFX_CMD_RESP_DATA_LEN]; /**< ub_l2d_dfx_cmd_resp, data section */
+} ub_l2d_dfx_cmd_resp_s;
+
+typedef enum { UB_L2D_TBL_MOD_INVALID = 0, UB_L2D_TBL_MOD_DFX } ub_l2d_tbl_mod;
+
+typedef enum {
+ UB_L2D_TBL_OP_INVALID = 0,
+ UB_L2D_TBL_OP_SET,
+ UB_L2D_TBL_OP_GET
+} ub_l2d_tbl_op_type;
+
+typedef struct tag_l2d_ub_dfx_tbl_attr {
+ union {
+ struct {
+ u32 ta_max_outstanding_ssn : 4;
+ u32 cache_threshold : 16;
+ u32 ta_to_tp_db_cnt : 4;
+ u32 ta_jetty_to_tp_ratio : 4;
+ u32 ta_max_loop_cnt : 4;
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+ u32 port_select_mode : 2;
+ u32 tso_len_max : 8;
+ u32 tso_num_max : 6;
+ u32 ta_ack_agg_time : 4;
+ u32 ta_ack_agg_threshold : 4;
+ u32 tp_ack_agg_time : 4;
+ u32 tp_ack_agg_threshold : 4;
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+ u32 cpb_alloc_retry_num : 8;
+ u32 rsvd : 7;
+ u32 res_tamsn_en : 1;
+ u32 lat_mode : 16;
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+ u32 rsp_tp_credit : 16;
+ u32 req_tp_credit : 16;
+ } bs;
+ u32 value;
+ } dw3;
+
+ u32 rsvd[11];
+
+ union {
+ struct {
+ u32 rsvd : 18;
+ u32 tx_rx : 2;
+ u32 drop_pkt_type : 3;
+ u32 drop_opcode : 6;
+ u32 drop_pkt_ratio : 3;
+ } bs;
+ u32 value;
+ } dw15;
+} l2d_ub_dfx_tbl_attr_s;
+
+typedef struct tag_l2d_ub_dfx_tbl_mask {
+ union {
+ struct {
+ u32 rsvd : 11;
+
+ /* TP PCQ深度域段mask */
+ u32 rsp_tp_credit : 1;
+ u32 req_tp_credit : 1;
+
+ /* 丢包配置域段mask */
+ u32 drop_pkt_ratio : 1;
+ u32 drop_opcode : 1;
+ u32 drop_pkt_type : 1;
+ u32 tx_rx : 1;
+
+ /* 包率性能域段mask */
+ u32 tp_ack_agg_threshold : 1;
+ u32 tp_ack_agg_time : 1;
+ u32 ta_ack_agg_threshold : 1;
+ u32 ta_ack_agg_time : 1;
+ u32 tso_num_max : 1;
+ u32 tso_len_max : 1;
+
+ /* TA2TP调度性能域段mask */
+ u32 ta_max_loop_cnt : 1;
+ u32 ta_jetty_to_tp_ratio : 1;
+ u32 ta_to_tp_db_cnt : 1;
+ u32 ta_max_outstanding_ssn : 1;
+ u32 res_tamsn_en : 1;
+
+ /* tptx场景预扣cpb失败原地重试次数 */
+ u32 cpb_alloc_retry_num : 1;
+ u32 port_select_mode : 1;
+ u32 cache_threshold : 1;
+ u32 lat_mode : 1;
+ } bs;
+ u32 value;
+ } dw0;
+
+ u32 dw_rsvd[15];
+} l2d_ub_dfx_tbl_mask_s;
+
+#define L2D_UB_TBL_SIZE 64
+/**
+ * @brief struct ub_l2d_mem_cmd_rsp_s
+ * @details UB L2D MEM表项内容返回
+ */
+typedef struct {
+ struct mgmt_msg_head msg_head;
+ u32 data[L2D_UB_TBL_SIZE]; /* ub_l2d_mem_cmd_rsp_s, data section */
+} ub_l2d_mem_cmd_rsp_s;
+
+/**
+ * @brief struct ub_l2d_mem_cfg_s
+ * @details 配置UB L2D MEM资源空间各个表项cmd消息
+ */
+typedef struct {
+ u16 func_id;
+ u16 tile_id; /* tile id从0开始 */
+
+ u16 tbl_mod; /* ub_l2d_tbl_mod */
+ u16 op_type; /* ub_l2d_tbl_op_type */
+ u32 rsvd0;
+ u32 rsvd1;
+
+ union {
+ struct {
+ l2d_ub_dfx_tbl_attr_s attr; /* ub l2d dfx_tbl_attr */
+ l2d_ub_dfx_tbl_mask_s mask; /* ub l2d dfx_tbl_mask */
+ } dfx_tbl;
+
+ struct {
+ u8 attr_tbl[L2D_UB_TBL_SIZE]; /* tbl size default 64B */
+ u8 mask_tbl[L2D_UB_TBL_SIZE];
+ } tbl;
+ } l2d_tbl;
+} ub_l2d_mem_cfg_s;
+
+/**
+ * @brief struct ub_l2d_mem_cfg_cmd_s
+ * @details 配置L2D MEM资源空间表项命令消息体
+ */
+typedef struct {
+ struct mgmt_msg_head msg_head;
+ ub_l2d_mem_cfg_s cfg;
+} ub_l2d_mem_cfg_cmd_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_base_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_base_cmd.h
new file mode 100644
index 000000000..f2a18db97
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_base_cmd.h
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu base cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_BASE_CMD_H
+#define UB_NPU_BASE_CMD_H
+
+#include "base_type.h"
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321 /**< big endian */
+#endif
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 0x1234 /**< little endian */
+#endif
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN /**< board byte order */
+#endif
+
+#define UB_CMD_TYPE_JFS 1 /**< ub cmd process type jfs */
+#define UB_CMD_TYPE_JFR 2 /**< ub cmd process type jfr */
+#define UB_CMD_TYPE_JFC 3 /**< ub cmd process type jfc */
+#define UB_CMD_TYPE_JETTY 4 /**< ub cmd process type jetty */
+#define UB_CMD_TYPE_JETTY_GROUP 5 /**< ub cmd process type jetty group */
+#define UB_CMD_TYPE_SEGMENT 6 /**< ub cmd process type segment */
+#define UB_CMD_TYPE_JFRC 7 /**< ub cmd process type jfrc */
+#define UB_CMD_TYPE_TP 8 /**< ub cmd process type tp */
+#define UB_CMD_TYPE_TP_GROUP 9 /**< ub cmd process type tp group */
+#define UB_CMD_TYPE_VTP 10 /**< ub cmd process type vtp */
+#define UB_CMD_TYPE_UPI 11 /**< ub cmd process type upi */
+#define UB_CMD_TYPE_SIP 12 /**< ub cmd process type sip */
+#define UB_CMD_TYPE_UTP 13 /**< ub cmd process type utp */
+#define UB_CMD_TYPE_MIGRATE 14 /**< ub cmd process type migrate */
+#define UB_CMD_TYPE_DFX 15 /**< ub cmd process type dfx */
+#define UB_CMD_TYPE_EID 16 /**< ub cmd process type eid */
+#define UB_CMD_TYPE_SRQ 17 /**< ub cmd process type srq */
+#define UB_CMD_TYPE_ASYNC_EVENT 18 /**< ub cmd process type async event */
+#define UB_CMD_TYPE_USERCTL 19 /**< ub cmd process type userctl */
+#define UB_CMD_TYPE_MAX 20
+
+enum ub_cmd_ret_status {
+ UB_CMD_RET_SUCCESS = 0x0,
+
+ UB_CMD_RET_COM_FLR_ERR = 0x1, /**< flr error */
+ UB_CMD_RET_COM_FUNC_INVLD = 0x2, /**< func invalid */
+ UB_CMD_RET_COM_QU_RSP_ERR = 0x3, /**< qu rsp error */
+ UB_CMD_RET_COM_UNSUPPORT_TYPE = 0x4, /**< unsupport type */
+ UB_CMD_RET_COM_UNSUPPORT_SUBTYPE = 0x5, /**< unsupport sub type */
+ UB_CMD_RET_COM_RET_ADDR_INVLD = 0x6, /**< addr invalid */
+ UB_CMD_RET_COM_VF_INVALID_ERR = 0x7, /**< vf invalid */
+ UB_CMD_RET_COM_FUNC_PERM_LIMIT = 0x8, /**< func Permissions limit */
+ UB_CMD_RET_COM_PARAM_INVALID = 0x9, /**< param invlid */
+ UB_CMD_RET_COM_API_ERR = 0xA, /**< API error */
+ UB_CMD_RET_COM_IO_ERR = 0xB, /**< IO error */
+ UB_CMD_RET_COM_HOSTID_ERR = 0xC, /**< host id error */
+ UB_CMD_RET_COM_SUBTYPE_ERR = 0xD, /**< subtype error */
+
+ UB_CMD_RET_JFC_STATE_ERR = 0x10, /**< jfc state error */
+ UB_CMD_RET_JFC_STORE_CQC_ERR = 0x11, /**< jfc store cqc error */
+ UB_CMD_RET_JFC_LOAD_CQC_ERR = 0x12, /**< jf load cqc err */
+ UB_CMD_RET_JFC_EXTEND_OP_API_ERR = 0x13, /**< jfc extend op api error */
+ UB_CMD_RET_JFC_CACHE_OUT_ERR = 0x14, /**< jfc cache out error */
+ UB_CMD_RET_JFC_TIMER_DEL_ERR = 0x15, /**< jfc timer del error */
+
+ UB_CMD_RET_SRQ_MISC_STORE_API_ERR =
+ 0x18, /**< srq misc store api error */
+ UB_CMD_RET_SRQ_MISC_LOAD_API_ERR = 0x19, /**< srq misc load api error */
+ UB_CMD_RET_SRQ_STATE_ERR = 0x1A, /**< srq state error */
+ UB_CMD_RET_SRQ_EXTEND_OP_API_ERR = 0x1B, /**< srq extend op api error */
+ UB_CMD_RET_SRQ_CACHE_OUT_ERR = 0x1C, /**< srq cache out error */
+ UB_CMD_RET_SRQ_CACHE_OUT_MTT_ERR = 0x1D, /**< srq cache out mtt error */
+ UB_CMD_RET_SRQ_MODIFY_ERR = 0x1E, /**< srq modify error */
+ UB_CMD_RET_SRQ_LOAD_HOST_GPA_ERR = 0x1F, /**< srq load host gpa error */
+
+ UB_CMD_RET_JFRC_QPC_RSP_ERR = 0x20, /**< jfrc qpc response error */
+
+ UB_CMD_RET_JETTY_GROUP_STORE_CQC_ERR =
+ 0x28, /**< jetty group store cqc error */
+ UB_CMD_RET_JETTY_GROUP_LOAD_CQC_ERR =
+ 0x29, /**< jetty group load cqc error */
+ UB_CMD_RET_JETTY_GROUP_CACHE_OUT_ERR =
+ 0x2A, /**< jetty group cache out error */
+ UB_CMD_RET_JETTY_GROUP_BANK_GPA_FLUSH_ERR =
+ 0x2B, /**< jetty group bank gpa flush error */
+
+ UB_CMD_RET_JETTY_QPC_RSP_ERR = 0x30, /**< jetty qpc response error */
+ UB_CMD_RET_JETTY_BIND_QPC_RSP_ERR =
+ 0x31, /**< jetty bind qpc response error */
+ UB_CMD_RET_JETTY_UNBIND_QPC_RSP_ERR =
+ 0x32, /**< jetty unbind qpc response error */
+ UB_CMD_RET_JETTY_SEID_LOAD_ERR = 0x33, /**< jetty seid load error */
+ UB_CMD_RET_JETTY_PREPARE_CHECK_ERR =
+ 0x34, /**< jetty prepare or check error */
+ UB_CMD_RET_JETTY_STAGE_CHANGE_ERR =
+ 0x35, /**< jetty stage change error */
+ UB_CMD_RET_JETTY_CACHE_OUT_ERR = 0x36, /**< jetty cache out error */
+ UB_CMD_RET_JETTY_PREFETCHING_ERR = 0x37, /**< jetty prefetching error */
+
+ UB_CMD_RET_MR_STATE_ERR = 0x40, /**< mr state error */
+ UB_CMD_RET_MR_STORE_MPT_ERR = 0x41, /**< mr store mpt error */
+ UB_CMD_RET_MR_LOAD_MPT_ERR = 0x42, /**< mr load mpt error */
+ UB_CMD_RET_MR_EXTEND_OP_API_ERR = 0x43, /**< mr extend op api error */
+ UB_CMD_RET_MR_CACHE_OUT_MTT_ERR = 0x44, /**< mr cache out mtt error */
+ UB_CMD_RET_MR_CACHE_OUT_MPT_ERR = 0x45, /**< mr cache out mpt error */
+ UB_CMD_RET_MR_DMTT_BHEAP_NO_FREE_BIT_ERR =
+ 0x46, /**< mr create safe_mem bheap no free bit error */
+
+ UB_CMD_RET_SEID_STORE_API_ERR = 0x48, /**< seid store api error */
+
+ UB_CMD_RET_VTP_STORE_CQC_ERR = 0x50, /**< vtp store cqc error */
+ UB_CMD_RET_VTP_LOAD_CQC_ERR = 0x51, /**< vtp load cqc error */
+ UB_CMD_RET_VTP_EXTEND_OP_API_ERR = 0x52, /**< vtp extend op api error */
+
+ UB_CMD_RET_TPG_STORE_CHILD_CTX_ERR =
+ 0x58, /**< tpg store child ctx error */
+ UB_CMD_RET_TPG_EXTEND_OP_API_ERR = 0x59, /**< tpg extend op api error */
+ UB_CMD_RET_TPG_SIZE_ERR = 0x5A, /**< tpg size invalid> */
+
+ UB_CMD_RET_UTP_STORE_CQC_ERR = 0x60, /**< utp store cqc error */
+ UB_CMD_RET_UTP_LOAD_SIP_API_ERR = 0x61, /**< utp load sip api error */
+ UB_CMD_RET_UTP_EXTEND_OP_API_ERR = 0x62, /**< utp extend op api error */
+
+ UB_CMD_RET_TP_EXTEND_OP_ERR = 0x70, /**< tp extend op api error */
+ UB_CMD_RET_TP_PREFETCHING_STATE_ERR =
+ 0x71, /**< tp extend prefetching state error */
+ UB_CMD_RET_CLEAR_TP_LATCH_LOCK_ERR =
+ 0x72, /**< tp clear latch lock error */
+
+ UB_CMD_RET_MIG_INVALID_QUEUE = 0x80, /**< mig invalid queue */
+ UB_CMD_RET_MIG_SAVE_EID_ERR = 0x81, /**< mig save eid error */
+ UB_CMD_RET_MIG_RESTORE_EID_ERR = 0x82, /**< mig restore eid error */
+
+ UB_CMD_RET_TA_MNGR_ERR = 0x90, /**< ta mngr error */
+
+ UB_CMD_RET_DFX_FETCH_WQE_API_ERR = 0xA0, /**< dfx fetch wqe api error */
+ UB_CMD_RET_DFX_CQC_LOAD_API_ERR = 0xA1, /**< dfx cqc load api error */
+ UB_CMD_RET_DFX_TPGC_LOAD_API_ERR = 0xA2, /**< dfx tpgc load api error */
+ UB_CMD_RET_DFX_SEID_LOAD_API_ERR = 0xA3, /**< dfx seid load api error */
+ UB_CMD_RET_DFX_TPC_LOAD_API_ERR = 0xA4, /**< dfx tpc load api error */
+ UB_CMD_RET_DFX_BATCH_MODIFY_API_OUTBOUND_ERR =
+ 0xA5, /**< dfx batch modify api outbound error */
+ UB_CMD_RET_DFX_MODIFY_CC_CTX_FETCH_TPC_ERR =
+ 0xA6, /**< dfx cc inject fetch tpc error */
+
+ UB_CMD_RET_JFR_PSM_ALLOC_API_ERR =
+ 0xB0, /**< psm_srq modify api error */
+
+ UB_CMD_RET_NAL_LATCH_INIT_API_ERR = 0xE0, /**< latch init error */
+ UB_CMD_RET_NAL_LATCH_RELEASE_API_ERR = 0xE1, /**< latch release error */
+
+ UB_CMD_RET_RSVD_ERR = 0xFF,
+};
+
+enum ub_cmd_ret_extend_op_err {
+ UB_CMD_RET_EXTEND_OP_NONE = 0x0, /**< cmd ret extend op error : none */
+ UB_CMD_RET_EXTEND_OP_RCC_RRE =
+ 0x1, /**< cmd ret extend op error : rcc rre */
+ UB_CMD_RET_EXTEND_OP_RCC_RAE =
+ 0x2, /**< cmd ret extend op error : rcc rae */
+ UB_CMD_RET_EXTEND_OP_RRWC_RWE =
+ 0x3, /**< cmd ret extend op error : rrwc rwe */
+ UB_CMD_RET_EXTEND_OP_RRWC_STA =
+ 0x4, /**< cmd ret extend op error : rrwc sta */
+ UB_CMD_RET_EXTEND_OP_RCC_STA =
+ 0x5, /**< cmd ret extend op error : rcc sta */
+ UB_CMD_RET_EXTEND_OP_SQC_STA =
+ 0x6, /**< cmd ret extend op error : sqc sta */
+ UB_CMD_RET_EXTEND_OP_SQAC_STA =
+ 0x7, /**< cmd ret extend op error : sqac sta */
+ UB_CMD_RET_EXTEND_OP_RQC_STA =
+ 0x8, /**< cmd ret extend op error : rqc sta */
+
+ UB_CMD_RET_EXTEND_OP_CQC_TIMEOUT =
+ 0x10, /**< cmd ret extend op error : cqc timeout */
+ UB_CMD_RET_EXTEND_OP_CQC_STA =
+ 0x11, /**< cmd ret extend op error : cqc sta */
+
+ UB_CMD_RET_EXTEND_OP_SRQC_STA =
+ 0x18, /**< cmd ret extend op error : srqc sta */
+
+ UB_CMD_RET_EXTEND_OP_MPT_STA =
+ 0x20, /**< cmd ret extend op error : mpt sta */
+
+ UB_CMD_RET_EXTEND_OP_QPC_DBG_EDIT =
+ 0x28, /**< cmd ret extend op error : qpc dbg edit */
+ UB_CMD_RET_EXTEND_OP_CQC_SRQC_DBG_EDIT =
+ 0x29, /**< cmd ret extend op error : cqc srqc dbg edit */
+};
+
+/**
+ * @brief struct ub_cmd_com_header/ub_cmd_com_header_s
+ * @details command common header
+ */
+typedef struct ub_cmd_com_header {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 major_version : 8;
+ u32 minor_version : 8;
+ u32 cmd_type : 8;
+ u32 cmd_subtype : 8;
+#else
+ u32 cmd_subtype : 8;
+ u32 cmd_type : 8;
+ u32 minor_version : 8;
+ u32 major_version : 8;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cmd_len : 16;
+ u32 rsvd : 16;
+#else
+ u32 rsvd : 16;
+ u32 cmd_len : 16;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ u32 idx;
+ u32 opt;
+} ub_cmd_com_header_s;
+
+/**
+ * @brief struct ub_mtt_attr/ub_mtt_attr_s
+ * @details mtt attribute
+ */
+typedef struct ub_mtt_attr {
+ u32 mtt_paddr_h;
+ u32 mtt_paddr_l;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 mtt_layers : 8;
+ u32 mtt_page_shift : 8;
+ u32 mtt_layers_ext : 8;
+ u32 mtt_page_shift_ext : 8;
+#else
+ u32 mtt_page_shift_ext : 8;
+ u32 mtt_layers_ext : 8;
+ u32 mtt_page_shift : 8;
+ u32 mtt_layers : 8;
+#endif
+ };
+ u32 dw2_value;
+ };
+ u32 mtt_paddr_ext_h;
+ u32 mtt_paddr_ext_l;
+} ub_mtt_attr_s;
+
+/**
+ * @brief struct ub_sq_attr/ub_sq_attr_s
+ * @details sq attribute
+ */
+typedef struct ub_sq_attr {
+ u32 sq_size; /**< unit: wqebb */
+ u32 sq_wqebb_size;
+ u32 sq_page_size;
+ u32 cqn;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_inline_en : 8;
+ u32 sq_pi_on_chip : 8;
+ u32 rsvd1 : 16;
+#else
+ u32 rsvd1 : 16;
+ u32 sq_pi_on_chip : 8;
+ u32 sq_inline_en : 8;
+#endif
+ };
+ u32 dw4_value;
+ };
+ u32 rsvd[2];
+} ub_sq_attr_s;
+
+/**
+ * @brief struct ub_rq_attr/ub_rq_attr_s
+ * @details rq attribute
+ */
+typedef struct ub_rq_attr {
+ u32 rq_size; /**< unit: wqebb */
+ u32 rq_wqebb_size;
+ u32 rq_page_size;
+ u32 rq_offset;
+ u32 cqn;
+ u32 rsvd[2];
+} ub_rq_attr_s;
+
+/**
+ * @brief struct ub_srq_attr/ub_srq_attr_s
+ * @details srq attribute
+ */
+typedef struct ub_srq_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 container_en : 8;
+ u32 container_mode : 8;
+ u32 rsvd1 : 16;
+#else
+ u32 rsvd1 : 16;
+ u32 container_mode : 8;
+ u32 container_en : 8;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 srqn;
+ u32 srq_cqn;
+ u32 srq_size;
+ u32 srq_page_size;
+ u32 srq_wqebb_size;
+ u32 srq_db_paddr_h;
+ u32 srq_db_paddr_l;
+ u32 rsvd2[2];
+} ub_srq_attr_s;
+
+/**
+ * @brief struct ub_rc_attr/ub_rc_attr_s
+ * @details rc attribute
+ */
+typedef struct ub_rc_attr {
+ u32 rc_paddr_h;
+ u32 rc_paddr_l;
+ u32 rc_size;
+ u32 offset;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 order : 8;
+ u32 ext_order : 8;
+ u32 rsvd1 : 16;
+#else
+ u32 rsvd1 : 16;
+ u32 ext_order : 8;
+ u32 order : 8;
+#endif
+ };
+ u32 value;
+ };
+ u32 rsvd[2];
+} ub_rc_attr_s;
+
+/**
+ * @brief struct ub_index_q_attr/ub_index_q_attr_s
+ * @details index queue attribute
+ */
+typedef struct ub_index_q_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 idx_queue_size : 8;
+ u32 idx_queue_pi_on_chip : 8;
+ u32 idx_queue_lth_pre_en : 1;
+ u32 idx_queue_lth_gap : 4;
+ u32 rsvd1 : 11;
+#else
+ u32 rsvd1 : 11;
+ u32 idx_queue_lth_gap : 4;
+ u32 idx_queue_lth_pre_en : 1;
+ u32 idx_queue_pi_on_chip : 8;
+ u32 idx_queue_size : 8;
+#endif
+ };
+ u32 dw_value;
+ };
+ u32 first_page_addr_h; /* index queue的物理地址 */
+ u32 first_page_addr_l; /* index queue的物理地址 */
+ u32 user_data0;
+ u32 user_data1;
+} ub_index_q_attr_s;
+
+/**
+ * @brief struct ub_chip_attr/ub_chip_attr_s
+ * @details chip attribute
+ */
+typedef struct ub_chip_attr {
+ ub_sq_attr_s sq_attr;
+ union {
+ ub_rq_attr_s rq_attr;
+ ub_srq_attr_s srq_attr;
+ };
+ ub_mtt_attr_s sq_mtt_attr;
+ ub_rc_attr_s rc_attr;
+ u32 db_paddr_h;
+ u32 db_paddr_l;
+ u32 access_flags;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 srq_en : 8;
+ u32 rsvd1 : 24;
+#else
+ u32 rsvd1 : 24;
+ u32 srq_en : 8;
+#endif
+ };
+ u32 value;
+ };
+
+ ub_index_q_attr_s index_q_attr;
+ u32 rsvd;
+} ub_chip_attr_s;
+
+/**
+ * @brief struct ub_cmdq_cqe_udata/ub_cmdq_cqe_udata
+ * @details uboe defined cqe user data
+ */
+typedef union ub_cmdq_cqe_udata {
+ struct {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 exec_time : 16;
+ u32 err_value : 16;
+#else
+ u32 err_value : 16;
+ u32 exec_time : 16;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 err_status : 14;
+ u32 cmd_type : 5;
+ u32 sub_type : 5;
+ u32 dpath_oq_num : 8;
+#else
+ u32 dpath_oq_num : 8;
+ u32 sub_type : 5;
+ u32 cmd_type : 5;
+ u32 err_status : 14;
+#endif
+ };
+ u32 dw1_value;
+ };
+ } bs;
+
+ u64 value;
+} ub_cmdq_cqe_udata_s;
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd.h
new file mode 100644
index 000000000..66a9a1015
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu eid cmd define.
+ * Create: 2023-10-20
+ */
+
+#ifndef UB_NPU_EID_CMD_H
+#define UB_NPU_EID_CMD_H
+
+enum UB_CMD_SEID_TYPE {
+ UB_CMD_SEID_ADD = 0x1, /**< Add SEID @see > ub_cmd_seid_add_s */
+ UB_CMD_SEID_QUERY = 0x2, /**< Query SEID @see > ub_cmd_seid_query_s */
+ UB_CMD_SEID_DEL = 0x3, /**< Del SEID @see > ub_cmd_seid_del_s */
+
+ UB_CMD_SEID_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd_defs.h
new file mode 100644
index 000000000..7b6324b0f
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_eid_cmd_defs.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu eid cmd define.
+ * Create: 2023-10-20
+ */
+
+#ifndef UB_NPU_EID_CMD_DEFS_H
+#define UB_NPU_EID_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_EID_LEN 4 /**< eid len */
+
+/**
+ * @brief struct ub_cmd_body_seid_add/ub_cmd_body_seid_add_s
+ * @details seid add command body struct
+ */
+typedef struct ub_cmd_body_seid_add {
+ u32 idx;
+ u32 upi;
+ u32 vfid;
+ u32 eid[UB_EID_LEN];
+ u32 resv[3];
+} ub_cmd_body_seid_add_s;
+
+/**
+ * @brief struct ub_cmd_seid_add/ub_cmd_seid_add_s
+ * @details seid add command struct
+ */
+typedef struct ub_cmd_seid_add {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_seid_add_s body;
+} ub_cmd_seid_add_s;
+
+/**
+ * @brief struct ub_cmd_body_seid_del/ub_cmd_body_seid_del_s
+ * @details seid del command body struct
+ */
+typedef struct ub_cmd_body_seid_del {
+ u32 idx;
+ u32 vfid;
+ u32 resv[3];
+} ub_cmd_body_seid_del_s;
+
+/**
+ * @brief struct ub_cmd_seid_del/ub_cmd_seid_del_s
+ * @details seid del command struct
+ */
+typedef struct ub_cmd_seid_del {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_seid_del_s body;
+} ub_cmd_seid_del_s;
+
+/**
+ * @brief struct ub_cmd_body_seid_query/ub_cmd_body_seid_query_s
+ * @details seid query command body struct
+ */
+typedef struct ub_cmd_body_seid_query {
+ u32 vfid;
+ u32 idx;
+ u32 ignore_ub_disable_err; // 1:表示当ub_en为0时,不返回错误,返回成功给上层
+ u32 resv[2];
+} ub_cmd_body_seid_query_s;
+
+/**
+ * @brief struct ub_cmd_seid_query/ub_cmd_seid_query_s
+ * @details seid query command struct
+ */
+typedef struct ub_cmd_seid_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_seid_query_s body;
+} ub_cmd_seid_query_s;
+
+/**
+ * @brief struct ub_seid_ctx_info_s
+ * @details used to query the seid ctx information, contains context fields.
+ */
+typedef struct {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 vld : 1;
+ u32 dw0_rsvd : 31;
+#else
+ u32 dw0_rsvd : 31;
+ u32 vld : 1;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 upi;
+ u32 seid[UB_EID_LEN];
+ u32 rsvd[2];
+} ub_seid_ctx_info_s;
+
+#define UB_EID_CTX_SIZE 128
+/**
+ * @brief struct ub_seid_ctx_query
+ * @details used to query the eid context.
+ */
+struct ub_seid_ctx_query {
+ u8 ctx[UB_EID_CTX_SIZE];
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd.h
new file mode 100644
index 000000000..24c5a6512
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu event cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_EVENT_CMD_H
+#define UB_NPU_EVENT_CMD_H
+
+enum UB_CMD_ASYNC_EVENT_TYPE {
+ UB_CMD_ASYNC_EVENT_CREDIT_INIT =
+ 0x1, /**< Init Async Event Credit Context @see > ub_cmd_async_event_info_s */
+ UB_CMD_ASYNC_EVENT_CREDIT_RETURN =
+ 0x2, /**< Return Async Event Credit @see > ub_cmd_async_event_info_s */
+ UB_CMD_ASYNC_EVENT_CREDIT_QUERY =
+ 0x3, /**< Query Async Event Credit @see > ub_cmd_async_event_info_s */
+ UB_CMD_ASYNC_EVENT_DFX_INJECT =
+ 0x4, /**< Async Event DFX Inject @see > ub_cmd_async_event_inject_info_s */
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd_defs.h
new file mode 100644
index 000000000..98e1399b6
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_event_cmd_defs.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu event cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_EVENT_CMD_DEFS_H
+#define UB_NPU_EVENT_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+/**
+ * @brief struct ub_cmd_body_async_event_info/ub_cmd_body_async_event_info_s
+ * @details async event info command body struct
+ */
+typedef struct ub_cmd_body_async_event_info {
+ u32 credit;
+ u32 rsvd[3];
+} ub_cmd_body_async_event_info_s;
+
+/**
+ * @brief struct ub_cmd_async_event_info/ub_cmd_async_event_info_s
+ * @details async event info command struct
+ */
+typedef struct ub_cmd_async_event_info {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_async_event_info_s body;
+} ub_cmd_async_event_info_s;
+
+/**
+ * @brief struct ub_cmd_body_async_event_inject_info/ub_cmd_body_async_event_inject_info_s
+ * @details async event inject command body struct
+ */
+typedef struct ub_cmd_body_async_event_inject_info {
+ u32 xid;
+ u32 event_type;
+ u32 queue_type;
+ u32 event_sub_type;
+ u32 vfid;
+ u32 rsvd;
+} ub_cmd_body_async_event_inject_info_s;
+
+/**
+ * @brief struct ub_cmd_async_event_inject_info/ub_cmd_async_event_inject_info_s
+ * @details async event inject info command struct
+ */
+typedef struct ub_cmd_async_event_inject_info {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_async_event_inject_info_s body;
+} ub_cmd_async_event_inject_info_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd.h
new file mode 100644
index 000000000..4068389e5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu jetty cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_JETTY_CMD_H
+#define UB_NPU_JETTY_CMD_H
+
+/* 驱动、微码 cmdq subtype 命令字,涉及前后版本兼容性,不允许随意插入修改;只能在后面进行追加修改 */
+enum UB_CMD_JETTY_TYPE {
+ UB_CMD_JETTY_CREATE_CTX =
+ 0x1, /**< Create Jetty Context @see > ub_cmd_jetty_create_s */
+ UB_CMD_JETTY_MODIFY_CTX =
+ 0x2, /**< Modify Jetty Context @see > ub_cmd_jetty_modify_s */
+ UB_CMD_JETTY_DELETE_CTX =
+ 0x3, /**< Delete Jetty Context @see > ub_cmd_jetty_delete_s */
+ UB_CMD_JETTY_CACHE_INVLD_CTX =
+ 0x4, /**< Invld Jetty cache @see > ub_cmd_jetty_cache_invld_s */
+ UB_CMD_JETTY_QUERY_CTX =
+ 0x5, /**< Query Jetty Context @see > ub_cmd_jetty_query_s */
+ UB_CMD_JETTY_QUERY_RDMA_RC =
+ 0x6, /**< Query Jetty Rdma rc @see > ub_cmd_jetty_query_rdma_rc_s */
+ UB_CMD_JETTY_GRP_CREATE_CTX =
+ 0x7, /**< Create Jetty Group Context @see > ub_cmd_jetty_grp_create_s */
+ UB_CMD_JETTY_GRP_UPDATE_CTX =
+ 0x8, /**< Update Jetty Group Context @see > ub_cmd_jetty_grp_update_s */
+ UB_CMD_JETTY_GRP_DELETE_CTX =
+ 0x9, /**< Delete Jetty Group Context @see > ub_cmd_jetty_grp_delete_s */
+ UB_CMD_JETTY_GRP_QUERY_CTX =
+ 0xA, /**< Query Jetty Group Context @see > ub_cmd_jetty_grp_query_s */
+ UB_CMD_JETTY_BATCH_MODIFY =
+ 0xB, /**< Batch modify Jetty Rdma rc @see > ub_cmd_jetty_batch_modify_s */
+ UB_CMD_JETTY_QUERY_RDMA_RC_EXT =
+ 0xC, /**< Query Jetty Rdma rc ext table @see > ub_cmd_jetty_query_rdma_rc_s */
+ UB_CMD_JETTY_BIND_CTX =
+ 0xD, /**< Bind Jetty Context @see > ub_cmd_jetty_bind_s */
+ UB_CMD_JETTY_UNBIND_CTX =
+ 0xE, /**< Unbind Jetty Context @see > ub_cmd_jetty_unbind_s */
+ UB_CMD_JETTY_CLEAR_DFX_LOCK_CTX =
+ 0xF, /**< Clear Jetty dfx lock info Context @see > ub_cmd_jetty_clear_dfx_lock_s */
+ UB_CMD_JETTY_QUERY_TA_OOR_INFO =
+ 0x10, /**< Query Jetty TA oor info @see > ub_cmd_jetty_query_rdma_rc_s */
+ UB_CMD_JETTY_QUERY_TAMSN_ENTRY =
+ 0x11, /**< Query Jetty TAMSNE entry @see > ub_cmd_jetty_query_tamsn_s */
+ UB_CMD_JETTY_MAX
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd_defs.h
new file mode 100644
index 000000000..e18ea7afc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jetty_cmd_defs.h
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu jetty cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_JETTY_CMD_DEFS_H
+#define UB_NPU_JETTY_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#ifdef HI1825V100
+#define UB_JETTY_CONTEXT_SIZE 512 /**< jetty context size 512B*/
+#define UB_TA_RDMARC_TABLE_SIZE 64 /**< ta rdmarc table size 64B*/
+#else
+#define UB_JETTY_CONTEXT_SIZE 512 /**< jetty context size 512B*/
+#define UB_TA_RDMARC_TABLE_SIZE 32 /**< ta rdmarc table size 32B*/
+#endif
+#define UB_TA_RDMARC_TABLE_MAX_SIZE 128 /**< ta rdmarc table max size 128B*/
+#define UB_TA_RDMARC_EXT_TABLE_SIZE_HI1823 \
+ 16 /**< ta rdmarc ext table size 16B for Hi1823V200 */
+#define UB_TA_RDMARC_EXT_TABLE_SIZE_HI1825 \
+ 128 /**< ta rdmarc ext table max size 128B for Hi1825V100 */
+#define UB_MSN_ENTRY_MAX_SIZE 128 /**< msn entry max size 128B */
+
+enum jetty_context_type {
+ JFS, /**< jetty context type : jfs */
+ JETTY, /**< jetty context type : jetty */
+ JFR, /**< jetty context type : jfr */
+ JFRC, /**< jetty context type : jfrc */
+};
+
+enum ub_task_jfs_type {
+ UB_TASK_JFS_TYPE_NORMAL = 0, /**< task jfs type : normal */
+ UB_TASK_JFS_TYPE_NODE = 1, /**< task jfs type : node */
+ UB_TASK_JFS_TYPE_MASTER = 2 /**< task jfs type : master */
+};
+
+enum UB_JETTY_GRP_UPDATE_TYPE_E {
+ UB_JETTY_GRP_ADD_JETTY = 0, /**< jetty grp update type : add jetty */
+ UB_JETTY_GRP_DEL_JETTY = 1 /**< jetty grp update type : del jetty */
+};
+
+enum UB_JETTY_STATE_E {
+ UB_JETTY_STATE_RESET = 0, /**< jetty state : reset */
+ UB_JETTY_STATE_READY = 1, /**< jetty state : ready */
+ UB_JETTY_STATE_SUSPENDED = 2, /**< jetty state : suspend */
+ UB_JETTY_STATE_ERROR = 3, /**< jetty state : error */
+ UB_JETTY_STATE_RESERVED = 4
+};
+
+/**
+ * @brief struct ub_jetty_com_attr/ub_jetty_com_attr_s
+ * @details jetty common attribute
+ */
+typedef struct ub_jetty_com_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 jetty_type : 8;
+ u32 jetty_state : 8;
+ u32 slice_en : 1;
+ u32 max_fly_ssn_num : 4;
+ u32 dw0_rsvd : 3;
+ u32 transport_mode : 8;
+#else
+ u32 transport_mode : 8;
+ u32 dw0_rsvd : 3;
+ u32 max_fly_ssn_num : 4;
+ u32 slice_en : 1;
+ u32 jetty_state : 8;
+ u32 jetty_type : 8;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 jetty_id;
+ u32 eid_index;
+ u32 seid[4];
+ u32 upi;
+ u32 tpn;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 priority : 8;
+ u32 db_cos : 8;
+ u32 slice_size_shift : 8;
+ u32 hash : 5;
+ u32 rsvd1 : 3;
+#else
+ u32 rsvd1 : 3;
+ u32 hash : 5;
+ u32 slice_size_shift : 8;
+ u32 db_cos : 8;
+ u32 priority : 8;
+#endif
+ };
+ u32 dw9_value;
+ };
+ u32 rsvd[4];
+} ub_jetty_com_attr_s;
+
+/**
+ * @brief struct ub_jetty_sq_attr/ub_jetty_sq_attr_s
+ * @details jetty sq attribute
+ */
+typedef struct ub_jetty_sq_attr {
+ u32 tx_jfcn;
+ u32 sqe_token_id;
+ u32 ta_timeout;
+ u32 rnr_max_retry_num;
+ u32 next_send_tassn;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 err_mode : 8;
+ u32 rsvd1 : 24;
+#else
+ u32 rsvd1 : 24;
+ u32 err_mode : 8;
+#endif
+ };
+ u32 dw5_value;
+ };
+ u32 rsvd[8];
+} ub_jetty_sq_attr_s;
+
+/**
+ * @brief struct ub_jetty_rq_attr/ub_jetty_rq_attr_s
+ * @details jetty rq attribute
+ */
+typedef struct ub_jetty_rq_attr {
+ u32 rx_jfcn;
+ u32 rqe_token_id;
+ u32 rnr_timer;
+ u32 next_rcv_tassn;
+ u32 token_value;
+ u32 jfrn;
+ u32 jfr_round;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 jfc_inline : 1;
+ u32 rsvd1 : 31;
+#else
+ u32 rsvd1 : 31;
+ u32 jfc_inline : 1;
+#endif
+ };
+ u32 dw7_value;
+ };
+ u32 rsvd[7];
+} ub_jetty_rq_attr_s;
+
+/**
+ * @brief struct ub_jetty_sw_attr/ub_jetty_sw_attr_s
+ * @details jetty software attribute
+ */
+typedef struct ub_jetty_sw_attr {
+ ub_jetty_com_attr_s jetty_com_attr;
+ ub_jetty_sq_attr_s jetty_sq_attr;
+ ub_jetty_rq_attr_s jetty_rq_attr;
+} ub_jetty_sw_attr_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_create/ub_cmd_body_jetty_create_s
+ * @details create jetty command body
+ */
+typedef struct ub_cmd_body_jetty_create {
+ ub_chip_attr_s chip_attr;
+ ub_jetty_sw_attr_s sw_attr;
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_create_s;
+
+/**
+ * @brief struct ub_cmd_jetty_create/ub_cmd_jetty_create_s
+ * @details create jetty command
+ */
+typedef struct ub_cmd_jetty_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_create_s body;
+} ub_cmd_jetty_create_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_modify/ub_cmd_body_jetty_modify_s
+ * @details modify jetty command body
+ */
+typedef struct ub_cmd_body_jetty_modify {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 jetty_type : 2;
+ u32 old_state : 3;
+ u32 new_state : 3;
+ u32 sq_pi : 16;
+ u32 dw1_rsvd : 8;
+#else
+ u32 dw1_rsvd : 8;
+ u32 sq_pi : 16;
+ u32 new_state : 3;
+ u32 old_state : 3;
+ u32 jetty_type : 2;
+#endif
+ };
+ u32 dw0_value;
+ };
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 idx_queue_lth : 16; /* JFR index queue limit threshold: idx_wqe_cnt_lth. */
+ u32 idx_queue_lth_gap : 4; /* JFR index queue limit threshold gap: idx_wqe_cnt_lth_gap. */
+ u32 idx_queue_lth_pre_en : 1; /* Engine should perform Pi prefetch processing */
+ u32 dw_rsvd : 11;
+#else
+ u32 dw_rsvd : 11;
+ u32 idx_queue_lth_pre_en : 1;
+ u32 idx_queue_lth_gap : 4;
+ u32 idx_queue_lth : 16;
+#endif
+ };
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 next_send_tassn : 16;
+ u32 next_ack_tassn : 16;
+#else
+ u32 next_ack_tassn : 16;
+ u32 next_send_tassn : 16;
+#endif
+ };
+ u32 dw1_value;
+ };
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 state : 1;
+ u32 idx_queue_lth : 1; /* JFR Limit Threshold mask. */
+ u32 next_send_tassn_flg : 1;
+ u32 next_ack_tassn_flg : 1;
+ u32 mask_rsvd : 28;
+#else
+ u32 mask_rsvd : 28;
+ u32 next_ack_tassn_flg : 1;
+ u32 next_send_tassn_flg : 1;
+ u32 idx_queue_lth : 1;
+ u32 state : 1;
+#endif
+ } mask;
+ u32 rsvd[2];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_modify_s;
+
+/**
+ * @brief struct ub_cmd_jetty_modify/ub_cmd_jetty_modify_s
+ * @details modify jetty command
+ */
+typedef struct ub_cmd_jetty_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_modify_s body;
+} ub_cmd_jetty_modify_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_delete/ub_cmd_body_jetty_delete_s
+ * @details delete jetty command body
+ */
+typedef struct ub_cmd_body_jetty_delete {
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_delete_s;
+
+/**
+ * @brief struct ub_cmd_jetty_delete/ub_cmd_jetty_delete_s
+ * @details delete jetty command
+ */
+typedef struct ub_cmd_jetty_delete {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_delete_s body;
+} ub_cmd_jetty_delete_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_cache_invld/ub_cmd_body_jetty_cache_invld_s
+ * @details jetty cache invalid command body
+ */
+typedef struct ub_cmd_body_jetty_cache_invld {
+ /** DW0~1 */
+ u32 sq_buf_len; /**< Buffer length of the SQ queue */
+ u32 rq_buf_len; /**< Buffer length of the RQ queue */
+
+ /** DW2~6 */
+ 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 */
+
+ /** DW7~8 */
+ u32 syn_gpa_hi32; /**< Upper 32 bits of the start address of mr or mw */
+ u32 syn_gpa_lo32; /**< Lower 32 bits of the start address of mr or mw */
+ u32 wqe_flags; /**< Indicates whether to kick out cache. by queue (0) or VF(1). */
+ u32 wqe_num; /**< Number of wqe, which needs to be assigned by the driver when the is kicked out by queue. */
+ u32 wqe_cache_line_start; /**< The driver needs to read the driver from the configuration file. */
+ u32 wqe_cache_line_end; /**< The driver needs to read the driver from the configuration file. */
+ u32 wqe_cache_line_size; /**< 0:256B,1:512B */
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_cache_invld_s;
+
+/**
+ * @brief struct ub_cmd_jetty_cache_invld/ub_cmd_jetty_cache_invld_s
+ * @details jetty cache invalid command
+ */
+typedef struct ub_cmd_jetty_cache_invld {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_cache_invld_s body;
+} ub_cmd_jetty_cache_invld_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_query/ub_cmd_body_jetty_query_s
+ * @details jetty query command body
+ */
+typedef struct ub_cmd_body_jetty_query {
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_query_s;
+
+/**
+ * @brief struct ub_cmd_jetty_query/ub_cmd_jetty_query_s
+ * @details jetty query command
+ */
+typedef struct ub_cmd_jetty_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_query_s body;
+} ub_cmd_jetty_query_s;
+
+/* 按照entry_size=64B, 最大深度128进行计算锁存空间 */
+#define UB_TA_RDMARC_MAX_SIZE 64
+#define UB_TA_LATCH_DATA_MAX_SIZE (UB_TA_RDMARC_MAX_SIZE << 7)
+/**
+ * @brief struct ub_ta_latch_data_outbuf/ub_ta_latch_data_outbuf_s
+ * @details ta latch data out buffer
+ */
+typedef struct ub_ta_latch_data_outbuf {
+ u8 ta_latch[UB_TA_LATCH_DATA_MAX_SIZE];
+ u32 ta_latch_size;
+} ub_ta_latch_data_outbuf_s;
+
+/**
+ * @brief struct ub_latch_common_header/ub_latch_common_header_s
+ * @details ta/tp latch data 4B cmmon header
+ */
+typedef union ub_latch_data_common_header {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 7;
+ u32 first_seq : 4;
+ u32 last_seq : 4;
+ u32 valid : 1;
+ u32 latch_total_len : 16;
+#else
+ u32 latch_total_len : 16;
+ u32 valid : 1;
+ u32 last_seq : 4;
+ u32 first_seq : 4;
+ u32 rsvd : 7;
+#endif
+ };
+ u32 dw0;
+} ub_latch_data_common_header_u;
+
+/**
+ * @brief struct ub_ta_rdma_rc_outbuf/ub_ta_rdma_rc_outbuf_s
+ * @details ta rdma rc out buffer
+ */
+typedef struct ub_ta_rdma_rc_outbuf {
+ u8 rdmarc[UB_TA_RDMARC_TABLE_MAX_SIZE];
+ u32 rc_table_size;
+} ub_ta_rdma_rc_outbuf_s;
+
+/**
+ * @brief struct ub_ta_rdma_rc_ext_outbuf/ub_ta_rdma_rc_ext_outbuf_s
+ * @details ta rdma rc extend out buffer
+ */
+typedef struct ub_ta_rdma_rc_ext_outbuf {
+ u8 rdmarc_ext[UB_TA_RDMARC_EXT_TABLE_SIZE_HI1825];
+ u32 rc_ext_table_size;
+} ub_ta_rdma_rc_ext_outbuf_s;
+
+/**
+ * @brief struct ub_oor_ta_info/ub_oor_ta_info_s
+ * @details ta oor info out buffer
+ */
+typedef struct ub_oor_ta_info {
+ u32 next_ack_tassn;
+ u32 next_send_tassn;
+ u32 start_tassn;
+ u32 tamsnc_pi;
+ u32 tamsnc_ci;
+ u32 start_bit;
+ u32 end_bit;
+ u32 total_bit_num;
+ u32 acked_bit;
+ ub_ta_rdma_rc_ext_outbuf_s bitmap;
+} ub_oor_ta_info_s;
+
+/**
+ * @brief enum UB_CMD_QUERTY_JETTY_TAMSN_TYPE_E
+ * @details jetty query tamsn type
+ */
+typedef enum {
+ UB_CMD_JETTY_TAMSN_BY_ID, // 通过entry id查询tamsn表项
+ UB_CMD_JETTY_TAMSN_BY_SSN // 通过tassn查询tamsn表项
+} UB_CMD_QUERTY_JETTY_TAMSN_TYPE_E;
+
+/**
+ * @brief struct ub_cmd_body_jetty_query_tamsn/ub_cmd_body_jetty_query_tamsn_s
+ * @details jetty query tamsn command body
+ */
+typedef struct ub_cmd_body_jetty_query_tamsn {
+ u32 index;
+ UB_CMD_QUERTY_JETTY_TAMSN_TYPE_E type;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_query_tamsn_s;
+
+/**
+ * @brief struct ub_cmd_jetty_query_tamsn/ub_cmd_jetty_query_tamsn_s
+ * @details jetty query tamsn command
+ */
+typedef struct ub_cmd_jetty_query_tamsn {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_query_tamsn_s body;
+} ub_cmd_jetty_query_tamsn_s;
+
+/**
+ * @brief struct ub_msn_entry_outbuf/ub_msn_entry_outbuf_s
+ * @details ta rdma rc out buffer
+ */
+typedef struct ub_msn_entry_outbuf {
+ u8 msn_entry[UB_MSN_ENTRY_MAX_SIZE];
+ u32 msn_entry_size;
+} ub_msn_entry_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_query_rdma_rc/ub_cmd_body_jetty_query_rdma_rc_s
+ * @details jetty query rdma rc command body
+ */
+typedef struct ub_cmd_body_jetty_query_rdma_rc {
+ u32 entry_index;
+ u32 idx;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_query_rdma_rc_s;
+
+/**
+ * @brief struct ub_cmd_jetty_query_rdma_rc/ub_cmd_jetty_query_rdma_rc_s
+ * @details jetty query rdma rc command
+ */
+typedef struct ub_cmd_jetty_query_rdma_rc {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_query_rdma_rc_s body;
+} ub_cmd_jetty_query_rdma_rc_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_clear_dfx_lock/ub_cmd_body_jetty_clear_dfx_lock_s
+ * @details jetty clear dfx lock command body
+ */
+typedef struct ub_cmd_body_jetty_clear_dfx_lock {
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_clear_dfx_lock_s;
+
+/**
+ * @brief struct ub_cmd_jetty_clear_dfx_lock/uub_cmd_jetty_clear_dfx_lock_s
+ * @details jetty query rdma rc command
+ */
+typedef struct ub_cmd_jetty_clear_dfx_lock {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_clear_dfx_lock_s body;
+} ub_cmd_jetty_clear_dfx_lock_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_batch_modify/ub_cmd_body_jetty_batch_modify_s
+ * @details jetty batch modify command body
+ */
+typedef struct ub_cmd_body_jetty_batch_modify {
+ u32 offset;
+ u32 length;
+ u8 ctx[UB_JETTY_CONTEXT_SIZE];
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_batch_modify_s;
+
+/**
+ * @brief struct ub_cmd_jetty_batch_modify/ub_cmd_jetty_batch_modify_s
+ * @details jetty batch modify command
+ */
+typedef struct ub_cmd_jetty_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_batch_modify_s body;
+} ub_cmd_jetty_batch_modify_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_grp_create/ub_cmd_body_jetty_grp_create_s
+ * @details jetty grp create command body
+ */
+typedef struct ub_cmd_body_jetty_grp_create {
+ u32 policy;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_grp_create_s;
+
+/**
+ * @brief struct ub_cmd_jetty_grp_create/ub_cmd_jetty_grp_create_s
+ * @details jetty grp create command
+ */
+typedef struct ub_cmd_jetty_grp_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_grp_create_s body;
+} ub_cmd_jetty_grp_create_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_grp_update/ub_cmd_body_jetty_grp_update_s
+ * @details jetty grp update command body
+ */
+typedef struct ub_cmd_body_jetty_grp_update {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 update_type : 2;
+ u32 jetty_id : 20;
+ u32 dw0_rsvd : 10;
+#else
+ u32 dw0_rsvd : 10;
+ u32 jetty_id : 20;
+ u32 update_type : 2;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_grp_update_s;
+
+/**
+ * @brief struct ub_cmd_jetty_grp_update/ub_cmd_jetty_grp_update_s
+ * @details jetty grp update command
+ */
+typedef struct ub_cmd_jetty_grp_update {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_grp_update_s body;
+} ub_cmd_jetty_grp_update_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_grp_delete/ub_cmd_body_jetty_grp_delete_s
+ * @details jetty grp delete command body
+ */
+typedef struct ub_cmd_body_jetty_grp_delete {
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_grp_delete_s;
+
+/**
+ * @brief struct ub_cmd_jetty_grp_delete/ub_cmd_jetty_grp_delete_s
+ * @details jetty grp delete command
+ */
+typedef struct ub_cmd_jetty_grp_delete {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_grp_delete_s body;
+} ub_cmd_jetty_grp_delete_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_grp_query/ub_cmd_body_jetty_grp_query_s
+ * @details jetty grp query command body
+ */
+typedef struct ub_cmd_body_jetty_grp_query {
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_grp_query_s;
+
+/**
+ * @brief struct ub_cmd_jetty_grp_query/ub_cmd_jetty_grp_query_s
+ * @details jetty grp query command
+ */
+typedef struct ub_cmd_jetty_grp_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_grp_query_s body;
+} ub_cmd_jetty_grp_query_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_bind/ub_cmd_body_jetty_bind_s
+ * @details jetty bind command body
+ */
+typedef struct ub_cmd_body_jetty_bind {
+ u32 peer_jetty_id;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_bind_s;
+
+/**
+ * @brief struct ub_cmd_jetty_bind/ub_cmd_jetty_bind_s
+ * @details jetty bind command
+ */
+typedef struct ub_cmd_jetty_bind {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_bind_s body;
+} ub_cmd_jetty_bind_s;
+
+/**
+ * @brief struct ub_cmd_body_jetty_unbind/ub_cmd_body_jetty_unbind_s
+ * @details jetty unbind command body
+ */
+typedef struct ub_cmd_body_jetty_unbind {
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jetty_unbind_s;
+
+/**
+ * @brief struct ub_cmd_jetty_unbind/ub_cmd_jetty_unbind_s
+ * @details jetty unbind command
+ */
+typedef struct ub_cmd_jetty_unbind {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jetty_unbind_s body;
+} ub_cmd_jetty_unbind_s;
+
+#define UB_JETTY_CONTEXT_QUERY_SIZE (UB_JETTY_CONTEXT_SIZE >> 2)
+/**
+ * @brief struct ub_ta_context_query/ub_ta_context_query_s
+ * @details used to query the context.
+ */
+typedef struct ub_ta_context_query {
+ u32 ctx[UB_JETTY_CONTEXT_QUERY_SIZE];
+} ub_ta_context_query_s;
+
+/**
+ * @brief union ub_jetty_info_u
+ * @details jetty informain in jetty group, contains jetty information fields.
+ */
+typedef union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 vld : 1;
+ u32 rsvd : 11;
+ u32 jetty_id : 20;
+#else
+ u32 jetty_id : 20;
+ u32 rsvd : 11;
+ u32 vld : 1;
+#endif
+ };
+ u32 value;
+} ub_jetty_info_u;
+
+/**
+ * @brief struct ub_jetty_grp_ctx_info_s
+ * @details used to query the jetty group information, contains jetty group ctx fields.
+ */
+typedef struct {
+ u32 rsvd0[5];
+ ub_jetty_info_u jetty[16];
+ u32 rsvd1[11];
+} ub_jetty_grp_ctx_info_s;
+
+#define UB_JETTY_GRP_CTX_SIZE 128
+/**
+ * @brief struct ub_jetty_grp_ctx_query
+ * @details used to query the jetty group.
+ */
+struct ub_jetty_grp_ctx_query {
+ u8 ctx[UB_JETTY_GRP_CTX_SIZE];
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd.h
new file mode 100644
index 000000000..63648aa1b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu jfc cmd define.
+ * Create: 2023-10-18
+ */
+
+#ifndef UB_NPU_JFC_CMD_H
+#define UB_NPU_JFC_CMD_H
+
+enum UB_CMD_JFC_TYPE {
+ UB_CMD_JFC_CREATE_CTX =
+ 0x1, /**< Create JFC Context @see > ub_cmd_jfc_create_s */
+ UB_CMD_JFC_MODIFY_CTX =
+ 0x2, /**< Modify JFC Context @see > ub_cmd_jfc_modify_s */
+ UB_CMD_JFC_DELETE_CTX =
+ 0x3, /**< Delete JFC Context @see > ub_cmd_jfc_delete_s */
+ UB_CMD_JFC_CACHE_INVLD_CTX =
+ 0x4, /**< Cache invalid JFC Context @see > ub_cmd_jfc_invld_s */
+ UB_CMD_JFC_QUERY_CTX =
+ 0x5, /**< Query JFC Context @see > ub_cmd_jfc_query_s */
+ UB_CMD_JFC_BATCH_MODIFY_CTX =
+ 0x6, /**< DFX batch modify JFC Context @see > ub_cmd_jfc_batch_modify_s */
+ UB_CMD_JFC_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd_defs.h
new file mode 100644
index 000000000..9c597e878
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfc_cmd_defs.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu jfc cmd define.
+ * Create: 2023-10-18
+ */
+
+#ifndef UB_NPU_JFC_CMD_DEFS_H
+#define UB_NPU_JFC_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_JFC_CTX_SIZE 128 /** JFC Context大小为128字节 */
+
+/**
+ * @brief struct ub_jfc_chip_attr/ub_jfc_chip_attr_s
+ * @details jfc chip attribute
+ */
+typedef struct ub_jfc_chip_attr {
+ ub_mtt_attr_s cq_mtt_attr;
+ u32 db_paddr_h;
+ u32 db_paddr_l;
+ u32 cq_size;
+ u32 cqe_size;
+ u32 cq_page_size;
+ u32 ceqn;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cnt_adjust_en : 8;
+ u32 cnt_clear_en : 8;
+ u32 ci_on_chip : 8;
+ u32 ceqe_en : 8;
+#else
+ u32 ceqe_en : 8;
+ u32 ci_on_chip : 8;
+ u32 cnt_clear_en : 8;
+ u32 cnt_adjust_en : 8;
+#endif
+ };
+ u32 value;
+ };
+
+ u32 rsvd[4];
+} ub_jfc_chip_attr_s;
+
+/**
+ * @brief struct ub_jfc_sw_attr/ub_jfc_sw_attr_s
+ * @details jfc software attribute
+ */
+typedef struct ub_jfc_sw_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 jfc_inline_en : 8;
+ u32 rsvd1 : 24;
+#else
+ u32 rsvd1 : 24;
+ u32 jfc_inline_en : 8;
+#endif
+ };
+ u32 value;
+ };
+
+ u32 rsvd[4];
+} ub_jfc_sw_attr_s;
+
+/**
+ * @brief struct ub_cmd_body_jfc_create/ub_cmd_body_jfc_create_s
+ * @details create jfc command body struct
+ */
+typedef struct ub_cmd_body_jfc_create {
+ ub_jfc_chip_attr_s chip_attr;
+ ub_jfc_sw_attr_s sw_attr;
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jfc_create_s;
+
+/**
+ * @brief struct ub_cmd_body_jfc_modify/ub_cmd_body_jfc_modify_s
+ * @details modify jfc command body struct
+ */
+typedef struct ub_cmd_body_jfc_modify {
+ u32 mask;
+ u32 timeout;
+ u32 max_cnt;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jfc_modify_s;
+
+/**
+ * @brief struct ub_cmd_body_jfc_invld/ub_cmd_body_jfc_invld_s
+ * @details invalid jfc command body struct
+ */
+typedef struct ub_cmd_body_jfc_invld {
+ u32 cmtt_flags;
+ u32 cmtt_num;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jfc_invld_s;
+
+/**
+ * @brief struct ub_cmd_body_jfc_batch_modify/ub_cmd_body_jfc_batch_modify_s
+ * @details batch modify jfc command body struct
+ */
+typedef struct ub_cmd_body_jfc_batch_modify {
+ u32 offset;
+ u32 length;
+ u8 ctx[UB_JFC_CTX_SIZE];
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_jfc_batch_modify_s;
+
+/**
+ * @brief struct ub_cmd_jfc_create/ub_cmd_jfc_create_s
+ * @details create jfc command struct
+ */
+typedef struct ub_cmd_jfc_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jfc_create_s body;
+} ub_cmd_jfc_create_s;
+
+/**
+ * @brief struct ub_cmd_jfc_modify/ub_cmd_jfc_modify_s
+ * @details modify jfc command struct
+ */
+typedef struct ub_cmd_jfc_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jfc_modify_s body;
+} ub_cmd_jfc_modify_s;
+
+/**
+ * @brief struct ub_cmd_jfc_delete/ub_cmd_jfc_delete_s
+ * @details delete jfc command struct
+ */
+typedef struct ub_cmd_jfc_delete {
+ ub_cmd_com_header_s header;
+ u32 rsvd[4];
+} ub_cmd_jfc_delete_s;
+
+/**
+ * @brief struct ub_cmd_jfc_invld/ub_cmd_jfc_invld_s
+ * @details invalid jfc command struct
+ */
+typedef struct ub_cmd_jfc_invld {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jfc_invld_s body;
+} ub_cmd_jfc_invld_s;
+
+/**
+ * @brief struct ub_cmd_jfc_query/ub_cmd_jfc_query_s
+ * @details query jfc command struct
+ */
+typedef struct ub_cmd_jfc_query {
+ ub_cmd_com_header_s header;
+ u32 rsvd[4];
+} ub_cmd_jfc_query_s;
+
+/**
+ * @brief struct ub_cmd_jfc_batch_modify/ub_cmd_jfc_batch_modify_s
+ * @details batch modify jfc command struct
+ */
+typedef struct ub_cmd_jfc_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_jfc_batch_modify_s body;
+} ub_cmd_jfc_batch_modify_s;
+
+/**
+ * @brief struct ub_jfc_ctx_query_info_s
+ * @details used to query the jfc information, contains context fields.
+ */
+typedef struct {
+ u32 dw0;
+ u32 dw1;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 state : 4;
+ u32 rsvd0 : 28;
+#else
+ u32 rsvd0 : 28;
+ u32 state : 4;
+#endif
+ };
+ u32 dw2;
+ };
+ u32 rsvd[29];
+} ub_jfc_ctx_query_info_s;
+
+/**
+ * @brief struct ub_jfc_ctx_query
+ * @details used to query the jfc context.
+ */
+struct ub_jfc_ctx_query {
+ u8 ctx[UB_JFC_CTX_SIZE];
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfr_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfr_cmd.h
new file mode 100644
index 000000000..1ba7bde86
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfr_cmd.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+ * Description: UB npu jfr cmd define.
+ * Create: 2024-11-14
+ */
+
+#ifndef UB_NPU_JFR_CMD_H
+#define UB_NPU_JFR_CMD_H
+
+enum UB_CMD_JFR_TYPE {
+ UB_CMD_JFR_CREATE_CTX =
+ 0x1, /**< Create JFR Context @see > ub_cmd_jetty_create_s */
+ UB_CMD_JFR_MODIFY_CTX =
+ 0x2, /**< Modify JFR Context @see > ub_cmd_jetty_modify_s */
+ UB_CMD_JFR_DELETE_CTX =
+ 0x3, /**< Delete JFR Context @see > ub_cmd_jetty_delete_s */
+ UB_CMD_JFR_CACHE_INVLD_CTX =
+ 0x4, /**< Invld JFR cache @see > ub_cmd_jetty_cache_invld_s */
+ UB_CMD_JFR_QUERY_CTX =
+ 0x5, /**< Query JFR Context @see > ub_cmd_jetty_query_s */
+ UB_CMD_JFR_MAX
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd.h
new file mode 100644
index 000000000..953e25c4c
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu jfrc cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_JFRC_CMD_H
+#define UB_NPU_JFRC_CMD_H
+
+enum UB_CMD_JFRC_TYPE {
+ UB_CMD_JFRC_CREATE_CTX =
+ 0x1, /**< Create JFRC Context @see > ub_cmd_jetty_create_s */
+ UB_CMD_JFRC_DESTROY_CTX =
+ 0x2, /**< Destroy JFRC Context @see > ub_cmd_jfrc_delete_s */
+ UB_CMD_JFRC_QUERY_QPC_CTX =
+ 0x3, /**< Query JFRC Context @see > ub_cmd_jfrc_query_s */
+ UB_CMD_JFRC_QUERY_PCQC_CTX =
+ 0x4, /**< Query JFRC Context @see > ub_cmd_jfrc_query_s */
+ UB_CMD_JFRC_QUERY_WQE =
+ 0x5, /**< Query JFRC Context @see > ub_cmd_jfrc_query_s */
+ UB_CMD_JFRC_MODIFY_PCQC =
+ 0x6, /**< Modify JFRC PCQC @see > ub_cmd_jfrc_modify_pcqc_s */
+ UB_CMD_JFRC_MAX
+};
+
+#endif // UB_NPU_JFRC_CMD_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd_defs.h
new file mode 100644
index 000000000..3a1d09996
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_jfrc_cmd_defs.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description : UB JFRC common API
+ * Author : /
+ * Create : /
+ * Notes : /
+ * History : /
+ */
+
+#ifndef UB_NPU_JFRC_CMD_DEFS_H
+#define UB_NPU_JFRC_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_MAX_RC_NUM 64 /** 一个TA func支持的RC个数为64 */
+#define UB_PCQ_CTX_SIZE 128 /** PCQ SEG Context大小为64字节 */
+#define UB_RC_QUEUE_WQEBB_SIZE (64) /** wqebb大小为64字节 */
+#define UB_PER_RCQE_WQEBB_NUM (2) /** 一个RCQE(RC queue element)占两个WQEBB */
+#define UB_RCQE_SIZE \
+ (UB_RC_QUEUE_WQEBB_SIZE * UB_PER_RCQE_WQEBB_NUM) /** 一个RCQE大小 */
+
+#define UB_RC_QUEUE_WQE_SHIFT \
+ (6) /** 2 ^ UB_RC_QUEUE_WQE_SHIFT(6) = WQEBB_SIZE(64B) */
+#define UB_RC_QUEUE_WQEBB_SIZE_SHIFT \
+ (4) /**< 2 ^ UB_RC_QUEUE_WQEBB_SIZE_SHIFT(4) = 16B */
+#define UB_RC_QUEUE_DEPTH_MASK (0x0f) /** RC队列深度不超过2^15 = 32k */
+
+/**@struct ub_cmd_jfrc_delete_body
+* @brief delete jfrc body
+*/
+typedef struct ub_cmd_jfrc_delete_body {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 dpath_flag : 1; /**< 排空标志 */
+ u32 rsvd0 : 31; /**< 预留 */
+#else
+ u32 rsvd0 : 31; /**< 预留 */
+ u32 dpath_flag : 1; /**< 排空标志 */
+#endif
+ } bs;
+ u32 ub_cmd_ext[0]; /**< 扩展命令 */
+} ub_cmd_jfrc_delete_body_s;
+
+/**@struct ub_cmd_jfrc_delete
+* @brief rc queue delete cmd
+*/
+typedef struct ub_cmd_jfrc_delete {
+ struct ub_cmd_com_header header;
+ struct ub_cmd_jfrc_delete_body body;
+} ub_cmd_jfrc_delete_s;
+
+/**@struct ub_cmd_jfrc_query_body
+* @brief query jfrc body
+*/
+typedef struct ub_cmd_jfrc_query_body {
+ u32 ci; /**< 查询RCQE时的目标ci */
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_jfrc_query_body_s;
+
+/**@struct ub_cmd_jfrc_query
+* @brief query jfrc
+*/
+typedef struct ub_cmd_jfrc_query {
+ struct ub_cmd_com_header header;
+ struct ub_cmd_jfrc_query_body body;
+} ub_cmd_jfrc_query_s;
+
+/**@struct ub_rc_queue_wqe
+* @brief query rc queue wqe
+*/
+typedef struct ub_rc_queue_wqe {
+ u8 rcqe[UB_RCQE_SIZE]; /**< 一个rcqe占UB_RCQE_SIZE字节 */
+} ub_rcqe_t;
+
+/**@struct ub_pcqc_query_rsp
+* @brief query pcqc response
+*/
+typedef struct ub_pcqc_query_rsp {
+ u8 ctx[UB_PCQ_CTX_SIZE];
+} ub_pcqc_query_rsp_s;
+
+/**
+ * @brief struct ub_cmd_jfrc_modify_pcqc_body/ub_cmd_jfrc_modify_pcqc_body_s
+ * @details jfrc_modify_pcqc command body
+ */
+typedef struct ub_cmd_jfrc_modify_pcqc_body {
+ u32 offset;
+ u32 length;
+ u8 ctx[UB_PCQ_CTX_SIZE];
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_jfrc_modify_pcqc_body_s;
+
+/**
+ * @brief struct ub_cmd_jfrc_modify_pcqc/ub_cmd_jfrc_modify_pcqc_s
+ * @details jfrc modify pcqc command
+ */
+typedef struct ub_cmd_jfrc_modify_pcqc {
+ ub_cmd_com_header_s header;
+ ub_cmd_jfrc_modify_pcqc_body_s body;
+} ub_cmd_jfrc_modify_pcqc_s;
+
+#endif // UB_NPU_JFRC_CMD_DEFS_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd.h
new file mode 100644
index 000000000..e5c710e2a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu mapt cmd define.
+ * Create: 2023-10-23
+ */
+
+#ifndef UB_NPU_MAPT_CMD_H
+#define UB_NPU_MAPT_CMD_H
+
+enum UB_CMD_MAPT_TYPE {
+ UB_CMD_MAPT_CREATE_CTX =
+ 0x1, /**< Create MAPT Context @see > ub_cmd_mapt_create_s */
+ UB_CMD_MAPT_DELETE_CTX =
+ 0x2, /**< Delete MAPT Context @see > ub_cmd_mapt_delete_s */
+ UB_CMD_MAPT_QUERY_CTX =
+ 0x3, /**< Query MAPT Context @see > ub_cmd_mapt_query_s */
+ UB_CMD_MAPT_BATCH_MODIFY_CTX =
+ 0x4, /**< DFX batch modify MAPT Context @see > ub_cmd_mapt_batch_modify_s */
+ UB_CMD_MAPT_QUERY_SAFE_DMTT_BITMAP =
+ 0X5, /**< QUERY SAFE DMTT BITMAP @see > ub_cmd_safe_dmtt_bitmap_outbuf_s */
+ UB_CMD_MAPT_QUERY_SAFE_DMTT_CTX =
+ 0X6, /**< QUERY SAFE DMTT CTX @see > ub_cmd_safe_dmtt_ctx_outbuf_s */
+ UB_CMD_MAPT_CREATE_DAVID_CTX =
+ 0X7, /**< Create david MAPT Context @see > ub_cmd_mapt_create_s */
+ UB_CMD_MAPT_DELETE_DAVID_CTX =
+ 0X8, /**< Delete david MAPT Context @see > ub_cmd_mapt_delete_s */
+ UB_CMD_MAPT_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd_defs.h
new file mode 100644
index 000000000..1fb455733
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mapt_cmd_defs.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu mapt cmd define.
+ * Create: 2023-10-18
+ */
+
+#ifndef UB_NPU_MAPT_CMD_DEFS_H
+#define UB_NPU_MAPT_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_MAPT_CTX_SIZE 64
+
+/**@struct ub_mapt_chip_attr
+* @brief mapt chip attr
+*/
+typedef struct ub_mapt_chip_attr {
+ ub_mtt_attr_s mtt_attr;
+
+ u32 iova_hi;
+ u32 iova_lo;
+ u32 length_hi;
+ u32 length_lo;
+
+ u32 buf_page_size;
+ u32 block_size;
+
+ u32 so_ro;
+ u32 mkey;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 local_write : 1;
+ u32 remote_read : 1;
+ u32 remote_write : 1;
+ u32 remote_atomic : 1;
+ u32 remote_invld : 1;
+ u32 rsvd1 : 27;
+#else
+ u32 rsvd1 : 27;
+ u32 remote_invld : 1;
+ u32 remote_atomic : 1;
+ u32 remote_write : 1;
+ u32 remote_read : 1;
+ u32 local_write : 1;
+#endif
+ };
+ u32 value;
+ };
+
+ u32 rsvd[4];
+} ub_mapt_chip_attr_s;
+
+/**@struct ub_mapt_sw_attr
+* @brief mapt sw attr
+*/
+typedef struct ub_mapt_sw_attr {
+ u32 token_value;
+ u32 key_type;
+ u32 eid_d; /* david instance EID */
+ u32 tid_d; /* david tid */
+ u32 rsvd[2];
+} ub_mapt_sw_attr_s;
+
+/**@struct ub_cmd_body_mapt_create
+* @brief mapt cmd body for create
+*/
+typedef struct ub_cmd_body_mapt_create {
+ ub_mapt_chip_attr_s chip_attr;
+ ub_mapt_sw_attr_s sw_attr;
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mapt_create_s;
+
+/**@struct ub_cmd_body_mapt_delete
+* @brief mapt cmd body for delete
+*/
+typedef struct ub_cmd_body_mapt_delete {
+ u32 mtt_flags;
+ u32 mtt_num;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mapt_delete_s;
+
+/**@struct ub_cmd_body_mapt_batch_modify
+* @brief mapt cmd body for modify
+*/
+typedef struct ub_cmd_body_mapt_batch_modify {
+ u32 offset;
+ u32 length;
+ u8 ctx[UB_MAPT_CTX_SIZE];
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mapt_batch_modify_s;
+
+/**@struct ub_cmd_mapt_create
+* @brief mapt create
+*/
+typedef struct ub_cmd_mapt_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mapt_create_s body;
+} ub_cmd_mapt_create_s;
+
+/**@struct ub_cmd_mapt_delete
+* @brief mapt delete
+*/
+typedef struct ub_cmd_mapt_delete {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mapt_delete_s body;
+} ub_cmd_mapt_delete_s;
+
+/**@struct ub_cmd_mapt_query
+* @brief mapt query
+*/
+typedef struct ub_cmd_mapt_query {
+ ub_cmd_com_header_s header;
+ u32 rsvd[4];
+} ub_cmd_mapt_query_s;
+
+/**@struct ub_cmd_mapt_batch_modify
+* @brief mapt modify
+*/
+typedef struct ub_cmd_mapt_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mapt_batch_modify_s body;
+} ub_cmd_mapt_batch_modify_s;
+
+/**
+ * @brief struct ub_mapt_ctx_info_s
+ * @details used to query the mapt information, contains context fields.
+ */
+typedef struct {
+ u32 rsvd0[2];
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 status : 4; /* Mpt status. Valid values are VALID, FREE, and INVALID. */
+ u32 dw2_rsvd : 28;
+#else
+ u32 dw2_rsvd : 28;
+ u32 status : 4;
+#endif
+ };
+ u32 dw2;
+ };
+ u32 rsvd1[12];
+} ub_mapt_ctx_info_s;
+
+/**
+ * @brief struct ub_vtp_ctx_query
+ * @details used to query the mapt context.
+ */
+struct ub_mapt_ctx_query {
+ u8 ctx[UB_MAPT_CTX_SIZE];
+};
+
+/**@struct ub_cmd_safe_dmtt_bitmap
+* @brief safe_dmtt_bitmap query
+*/
+typedef struct ub_cmd_safe_dmtt_bitmap {
+ ub_cmd_com_header_s header;
+ u32 func_id;
+} ub_cmd_safe_dmtt_bitmap_s;
+
+/**@struct ub_cmd_safe_dmtt_ctx
+* @brief safe_dmtt_ctx query
+*/
+typedef struct ub_cmd_safe_dmtt_ctx {
+ ub_cmd_com_header_s header;
+ u32 func_id;
+ u32 gpa_hi; /* Mtt gpa upper 32 bits */
+ u32 gpa_lo; /* Mtt gpa lower 32 bits */
+} ub_cmd_safe_dmtt_ctx_s;
+
+#define UB_SAFE_DMTT_BITMAP_SIZE 2048
+#define UB_SAFE_DMTT_CTX_SIZE 4096
+typedef struct ub_cmd_safe_dmtt_bitmap_outbuf {
+ u32 ub_safe_dmtt_valid_num;
+ u32 ub_safe_dmtt_remain_num;
+ u8 ub_safe_dmtt_bitmap[UB_SAFE_DMTT_BITMAP_SIZE];
+} ub_cmd_safe_dmtt_bitmap_outbuf_s;
+
+typedef struct ub_cmd_safe_dmtt_ctx_outbuf {
+ u8 ub_safe_dmtt_ctx[UB_SAFE_DMTT_CTX_SIZE];
+} ub_cmd_safe_dmtt_ctx_outbuf_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd.h
new file mode 100644
index 000000000..9621b9b76
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu migrate cmd define.
+ * Create: 2023-10-31
+ */
+
+#ifndef UB_NPU_MIG_CMD_H
+#define UB_NPU_MIG_CMD_H
+
+enum UB_CMD_MIG_TYPE {
+ UB_CMD_MIG_QUERY_DRAIN_NUM =
+ 0x1, /**< Query drain number for ub live migration @see > ub_cmd_mig_comm_proc_s */
+ UB_CMD_MIG_DIRTY_DRAIN =
+ 0x2, /**< Dirty drain for ub live migration @see > ub_cmd_mig_dirty_drain_s */
+ UB_CMD_MIG_QUERY_DRAIN_STATUS =
+ 0x3, /**< Query drain status for ub live migration @see > ub_cmd_mig_query_drain_status_s */
+ UB_CMD_MIG_CACHE_OUT =
+ 0x4, /**< Cache out for ub live migration @see > ub_cmd_mig_cache_out_s */
+ UB_CMD_MIG_SAVE_JFRC_PCQC =
+ 0x5, /**< Save jfrc pcqc for ub live migration @see > ub_cmd_mig_move_jfrc_pcqc_s */
+ UB_CMD_MIG_RESTORE_JFRC_PCQC =
+ 0x6, /**< Restore jfrc pcqc for ub live migration @see > ub_cmd_mig_move_jfrc_pcqc_s */
+ UB_CMD_MIG_RESTORE_DB_TIMER =
+ 0x7, /**< Restore db timer for ub live migration @see > ub_cmd_mig_restore_db_timer_s */
+ UB_CMD_MIG_SAVE_EID =
+ 0x8, /**< Save eid for ub live migration @see > ub_cmd_mig_move_eid_s */
+ UB_CMD_MIG_RESTORE_EID =
+ 0x9, /**< Restore eid for ub live migration @see > ub_cmd_mig_move_eid_s */
+ UB_CMD_MIG_STATE_NOTIFY =
+ 0xA, /**< State notify for ub live migration @see > ub_cmd_mig_state_notify_s */
+ UB_CMD_MIG_QUERY_ROLLBACK =
+ 0xB, /**< Query rollback status for ub live migration @see > ub_cmd_mig_query_rollback_s */
+ UB_CMD_MIG_FLUSH_VTP_DMA =
+ 0xC, /**< flush dma after dst vtp dma @see > ub_cmd_mig_comm_proc_s */
+ UB_CMD_MIG_QEURY_RDMARC =
+ 0xD, /**< query rdmarc addr to log dirty @see > ub_cmd_mig_query_rdmarc_s */
+ UB_CMD_MIG_SAVE_MTT_MAP_BHEAP =
+ 0xE, /**< Save mtt map bheap for ub live migration @see > ub_cmd_mig_move_mtt_map_bheap_s */
+ UB_CMD_MIG_RESTORE_MTT_MAP_BHEAP =
+ 0xF, /**< Restore mtt map bheap for ub live migration @see > ub_cmd_mig_move_mtt_map_bheap_s */
+ UB_CMD_MIG_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd_defs.h
new file mode 100644
index 000000000..bdf5fc762
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_mig_cmd_defs.h
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu migrate cmd define.
+ * Create: 2023-10-31
+ */
+
+#ifndef UB_NPU_MIG_CMD_DEFS_H
+#define UB_NPU_MIG_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+#include "ub_mpu_cmd_defs.h"
+
+#define UB_MIG_CACHE_LINE_NUM 8 /**< mig cache line number */
+#define UB_MIG_JFRC_PCQC_MAX_PROC_CNT 4 /**< jfrc pcqc max procedure count */
+#define UB_MIG_JFRC_PCQC_BUF_SIZE 512 /**< jfrc pcqc buffer size */
+#define UB_MIG_JFRC_PCQC_BUF_OFST 16 /**< jfrc pcqc buffer offset*/
+#define UB_MIG_JFRC_PCQC_READ_CPB_OFFSET \
+ (UB_CMD_READ_CPB_BUF_OFFSET + \
+ UB_MIG_JFRC_PCQC_BUF_OFST) /**< jfrc pcqc read cpb offset */
+
+#define UB_EID_LEN 4 /**< eid len */
+#define UB_MIG_EID_BUF_SIZE 32 /**< eid buffer size */
+
+#define UB_MIG_MTT_MAP_BHEAP_BUF_SIZE 512 /**< mtt map beap buffer size */
+#define UB_MIG_MTT_MAP_BHEAP_PROC_LOOP \
+ (UB_MTT_MAP_BHEAP_BYTE_NUM / UB_MIG_MTT_MAP_BHEAP_BUF_SIZE)
+#define UB_MIG_MTT_MAP_BHEAP_CNT_PER_LOOP \
+ (UB_MIG_MTT_MAP_BHEAP_BUF_SIZE / \
+ UB_MTT_MAP_BHEAP_LT_ENTRY_SIZE) /**< mtt beap max procedure count */
+
+/**
+ * @brief struct ub_cmd_body_mig_comm_proc/ub_cmd_body_mig_comm_proc_s
+ * @details migrate common procedure command struct body
+ */
+typedef struct ub_cmd_body_mig_comm_proc {
+ u32 func_id;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_comm_proc_s;
+
+/**
+ * @brief struct ub_cmd_mig_comm_proc/ub_cmd_mig_comm_proc_s
+ * @details migrate common procedure command struct
+ */
+typedef struct ub_cmd_mig_comm_proc {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_comm_proc_s body;
+} ub_cmd_mig_comm_proc_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_dirty_drain/ub_cmd_body_mig_dirty_drain_s
+ * @details migrate dirty drain command struct body
+ */
+typedef struct ub_cmd_body_mig_dirty_drain {
+ u32 func_id;
+ u32 queue_idx;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_dirty_drain_s;
+
+/**
+ * @brief struct ub_cmd_mig_dirty_drain/ub_cmd_mig_dirty_drain_s
+ * @details migrate dirty drain command struct
+ */
+typedef struct ub_cmd_mig_dirty_drain {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_dirty_drain_s body;
+} ub_cmd_mig_dirty_drain_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_query_drain_status/ub_cmd_body_mig_query_drain_status_s
+ * @details migrate query drain status command struct body
+ */
+typedef struct ub_cmd_body_mig_query_drain_status {
+ u32 func_id;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_query_drain_status_s;
+
+/**
+ * @brief struct ub_cmd_mig_query_drain_status/ub_cmd_mig_query_drain_status_s
+ * @details migrate query drain status command struct
+ */
+typedef struct ub_cmd_mig_query_drain_status {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_query_drain_status_s body;
+} ub_cmd_mig_query_drain_status_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_query_dirty_status/ub_cmd_body_mig_query_dirty_status_s
+ * @details migrate query dirty status command struct body
+ */
+typedef struct ub_cmd_body_mig_query_dirty_status {
+ u32 func_id;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_query_dirty_status_s;
+
+/**
+ * @brief struct ub_cmd_mig_query_dirty_status/ub_cmd_mig_query_dirty_status_s
+ * @details migrate query dirty status command struct
+ */
+typedef struct ub_cmd_mig_query_dirty_status {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_query_dirty_status_s body;
+} ub_cmd_mig_query_dirty_status_s;
+
+/**
+ * @brief struct ub_mig_cache_line/ub_mig_cache_line_s
+ * @details migrate cache line
+ */
+typedef struct ub_mig_cache_line {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 9;
+ u32 valid : 1;
+ u32 cl_size : 2;
+ u32 cl_end : 10;
+ u32 cl_start : 10;
+#else
+ u32 cl_start : 10;
+ u32 cl_end : 10;
+ u32 cl_size : 2;
+ u32 valid : 1;
+ u32 rsvd : 9;
+#endif
+} ub_mig_cache_line_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_cache_out/ub_cmd_body_mig_cache_out_s
+ * @details migrate cache out command struct body
+ */
+typedef struct ub_cmd_body_mig_cache_out {
+ u32 func_id;
+ ub_mig_cache_line_s cache_line[UB_MIG_CACHE_LINE_NUM];
+ u32 mode; // mode_0:为无流量时的cacheout,需要等待cacheout成功;mode_1:为有流量时的cacheout,尽力而为
+ u32 rsvd[3];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_cache_out_s;
+
+/**
+ * @brief struct ub_cmd_mig_cache_out/ub_cmd_mig_cache_out_s
+ * @details migrate cache out command struct
+ */
+typedef struct ub_cmd_mig_cache_out {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_cache_out_s body;
+} ub_cmd_mig_cache_out_s;
+
+#define RDMARC_QUERY_MAX_CNT 40 /**< rdmarc max query count */
+
+/**
+ * @brief struct ub_cmd_body_mig_comm_dfx/ub_cmd_body_mig_query_rdmarc_s
+ * @details migrate query rdmarc command struct body
+ */
+typedef struct ub_cmd_body_mig_comm_dfx {
+ u32 func_id;
+ u32 xid_start;
+ u32 xid_end;
+ u32 send_times;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_query_rdmarc_s;
+
+/**
+ * @brief struct ub_cmd_mig_query_rdmarc/ub_cmd_mig_query_rdmarc_s
+ * @details migrate rdmarc query command struct
+ */
+typedef struct ub_cmd_mig_query_rdmarc {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_query_rdmarc_s body;
+} ub_cmd_mig_query_rdmarc_s;
+
+/**
+ * @brief struct ub_mig_rdmarc_addr/ub_mig_rdmarc_addr_s
+ * @details migrate rdmarc address
+ */
+typedef struct ub_mig_rdmarc_addr {
+ u32 rc_gpa_hi;
+ u32 rc_gpa_lo;
+ u32 rc_len;
+} ub_mig_rdmarc_addr_s;
+
+/**
+ * @brief struct ub_cmd_mig_query_rdmarc_outbuf/ub_cmd_mig_query_rdmarc_outbuf_s
+ * @details migrate query rdmarc outbuffer command
+ */
+typedef struct ub_cmd_mig_query_rdmarc_outbuf {
+ u32 rsp_status;
+ u32 cur_xid;
+ u32 valid_cnt;
+ ub_mig_rdmarc_addr_s data[RDMARC_QUERY_MAX_CNT];
+} ub_cmd_mig_query_rdmarc_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_move_jfrc_pcqc/ub_cmd_body_mig_move_jfrc_pcqc_s
+ * @details migrate move jfrc pcqc command struct body
+ */
+typedef struct ub_cmd_body_mig_move_jfrc_pcqc {
+ u32 func_id;
+ u32 jfrc_idx;
+ u32 jfrc_num;
+ u32 rsvd;
+ u8 data[UB_MIG_JFRC_PCQC_BUF_SIZE];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_move_jfrc_pcqc_s;
+
+/**
+ * @brief struct ub_cmd_mig_move_jfrc_pcqc/ub_cmd_mig_move_jfrc_pcqc_s
+ * @details migrate move jfrc pcqc command struct
+ */
+typedef struct ub_cmd_mig_move_jfrc_pcqc {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_move_jfrc_pcqc_s body;
+} ub_cmd_mig_move_jfrc_pcqc_s;
+
+/**
+ * @brief struct ub_cmd_mig_move_jfrc_pcqc_outbuf/ub_cmd_mig_move_jfrc_pcqc_outbuf_s
+ * @details migrate move jfrc pcqc outbuffer
+ */
+typedef struct ub_cmd_mig_move_jfrc_pcqc_outbuf {
+ u8 data[UB_MIG_JFRC_PCQC_BUF_SIZE];
+} ub_cmd_mig_move_jfrc_pcqc_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_move_eid/ub_cmd_body_mig_move_eid_s
+ * @details migrate move eid command struct body
+ */
+typedef struct ub_cmd_body_mig_move_eid {
+ u32 idx;
+ u32 upi;
+ u32 vfid;
+ u32 eid[UB_EID_LEN];
+ u32 resv[3];
+ u8 data[UB_MIG_EID_BUF_SIZE];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_move_eid_s;
+
+/**
+ * @brief struct ub_cmd_mig_move_eid/ub_cmd_mig_move_eid_s
+ * @details migrate move eid command struct
+ */
+typedef struct ub_cmd_mig_move_eid {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_move_eid_s body;
+} ub_cmd_mig_move_eid_s;
+
+/**
+ * @brief struct ub_cmd_mig_move_eid_outbuf/ub_cmd_mig_move_eid_outbuf_s
+ * @details migrate move eid outbuffer
+ */
+typedef struct ub_cmd_mig_move_eid_outbuf {
+ u8 data[UB_MIG_EID_BUF_SIZE];
+} ub_cmd_mig_move_eid_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_move_mtt_map_bheap/ub_cmd_body_mig_move_mtt_map_bheap_s
+ * @details migrate move mtt map bheap command struct body
+ */
+typedef struct ub_cmd_body_mig_move_mtt_map_bheap {
+ u32 func_id;
+ u32 bheap_idx;
+ u32 bheap_num;
+ u32 rsvd;
+ u8 data[UB_MIG_MTT_MAP_BHEAP_BUF_SIZE];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_move_mtt_map_bheap_s;
+
+/**
+ * @brief struct ub_cmd_mig_move_mtt_map_bheap/ub_cmd_mig_move_mtt_map_bheap_s
+ * @details migrate move mtt map bheap command struct
+ */
+typedef struct ub_cmd_mig_move_mtt_map_bheap {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_move_mtt_map_bheap_s body;
+} ub_cmd_mig_move_mtt_map_bheap_s;
+
+/**
+ * @brief struct ub_cmd_mig_move_mtt_map_bheap_outbuf/ub_cmd_mig_move_mtt_map_bheap_outbuf_s
+ * @details migrate move mtt map bheap outbuffer
+ */
+typedef struct ub_cmd_mig_move_mtt_map_bheap_outbuf {
+ u8 data[UB_MIG_MTT_MAP_BHEAP_BUF_SIZE];
+} ub_cmd_mig_move_mtt_map_bheap_outbuf_s;
+
+// mtt map beap read cpb offset
+#define UB_MIG_MTT_MAP_BHEAP_READ_CPB_OFFSET \
+ (UB_CMD_READ_CPB_BUF_OFFSET + \
+ OFFSET_OF(struct ub_cmd_body_mig_move_mtt_map_bheap, data))
+
+typedef enum {
+ UB_MIG_JETTY_TIMER_CLEAR = 0x0, /**< jetty timer clear */
+ UB_MIG_JFC_TIMER_CLEAR = 0x1, /**< jfc timer clear */
+ UB_MIG_JETTY_DB_TIMER_RESTORE = 0x2, /**< jetty db timer restore */
+ UB_MIG_JFC_TIMER_RESTORE = 0x3, /**< dfr timer restore */
+ UB_MIG_JETTY_PI_ON_CHIP_CLEAR = 0x4, /**< jetty pi on chip clear */
+ UB_MIG_DB_TIMER_RECOVER_TYPE_BUTT =
+ 0x5 /**< db timer recober type butt */
+} ub_mig_db_timer_recovert_t;
+
+/**
+ * @brief struct ub_cmd_body_mig_restore_db_timer/ub_cmd_body_mig_restore_db_timer_s
+ * @details migrate restore db timer command struct body
+ */
+typedef struct ub_cmd_body_mig_restore_db_timer {
+ u32 func_id;
+ u32 type;
+ u32 loop_idx;
+ u32 loop_max;
+ u32 xid_start;
+ u32 xid_end;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_restore_db_timer_s;
+
+/**
+ * @brief struct ub_cmd_mig_restore_db_timer/ub_cmd_mig_restore_db_timer_s
+ * @details migrate restore db timer command struct
+ */
+typedef struct ub_cmd_mig_restore_db_timer {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_restore_db_timer_s body;
+} ub_cmd_mig_restore_db_timer_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_state_notify/ub_cmd_body_mig_state_notify_s
+ * @details migrate state notify command struct body
+ */
+typedef struct ub_cmd_body_mig_state_notify {
+ u32 func_id;
+ u32 state;
+ u32 rsvd[3];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_state_notify_s;
+
+/**
+ * @brief struct ub_cmd_mig_state_notify/ub_cmd_mig_state_notify_s
+ * @details migrate state notify command struct
+ */
+typedef struct ub_cmd_mig_state_notify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_state_notify_s body;
+} ub_cmd_mig_state_notify_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_query_rollback/ub_cmd_body_mig_query_rollback_s
+ * @details migrate query rollback command struct body
+ */
+typedef struct ub_cmd_body_mig_query_rollback {
+ u32 func_id;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_mig_query_rollback_s;
+
+/**
+ * @brief struct ub_cmd_body_mig_query_rollback/ub_cmd_body_mig_query_rollback_s
+ * @details migrate query rollback command struct
+ */
+typedef struct ub_cmd_mig_query_rollback {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_mig_query_rollback_s body;
+} ub_cmd_mig_query_rollback_s;
+
+/**
+ * @brief struct ub_cmd_mig_query_num_outbuf/ub_cmd_mig_query_num_outbuf_s
+ * @details migrate query num outbuffer
+ */
+typedef struct ub_cmd_mig_query_num_outbuf {
+ union {
+ u32 value;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 status : 8;
+ u32 rsvd : 8;
+ u32 queue_num : 16;
+#else
+ u32 queue_num : 16;
+ u32 rsvd : 8;
+ u32 status : 8;
+#endif
+ } bs;
+ };
+} ub_cmd_mig_query_num_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_mig_drain_status_outbuf/ub_cmd_mig_drain_status_outbuf_s
+ * @details migrate drain status outbuffer
+ */
+typedef struct ub_cmd_mig_drain_status_outbuf {
+ u32 dirty_ctr;
+ u32 tx_ctr;
+ u32 rx_ctr;
+ u32 fast_ctr;
+} ub_cmd_mig_drain_status_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_mig_query_dirty_drain_outbuf/ub_cmd_mig_query_dirty_drain_outbuf_s
+ * @details migrate query dirty drain outbuffer
+ */
+typedef struct ub_cmd_mig_query_dirty_drain_outbuf {
+ u32 status;
+ u32 rsvd[4];
+} ub_cmd_mig_query_dirty_drain_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_mig_rollback_status_outbuf/ub_cmd_mig_rollback_status_outbuf_s
+ * @details migrate rollback status outbuffer
+ */
+typedef struct ub_cmd_mig_rollback_status_outbuf {
+ union {
+ u32 value;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rollback_status : 1;
+ u32 rsvd : 31;
+#else
+ u32 rsvd : 31;
+ u32 rollback_status : 1;
+#endif
+ } bs;
+ };
+} ub_cmd_mig_rollback_status_outbuf_s;
+
+enum ub_mig_rsp_status {
+ UB_MIG_RSP_WAIT = 0x0, /**< migrate response wait */
+ UB_MIG_RSP_DONE = 0x1, /**< migrate response done */
+ UB_MIG_RSP_RETRY = 0x2, /**< migrate response retry */
+ UB_MIG_RSP_FAIL = 0x3 /**< migrate response fail */
+};
+
+/**
+ * @brief struct ub_cmd_mig_common_outbuf/ub_cmd_mig_common_outbuf_s
+ * @details migrate common outbuffer
+ */
+typedef struct ub_cmd_mig_common_outbuf {
+ u32 rsp_status;
+} ub_cmd_mig_common_outbuf_s;
+
+#define DRAIN_QUERY_WAIT (0) /**< drain query wait */
+#define DRAIN_QUERY_FINISH (1) /**< drain query finish */
+#define DRAIN_QUERY_ERR (2) /**< drain query error */
+
+/**
+ * @brief struct ub_migrate_drain_thread_result
+ * @details migrate drain thread result
+ */
+typedef struct {
+ u32 status; // 0 正在查询, 1 完成,查询成功, 2 完成,查询失败
+ u32 io_number; // status为1时有效,表示未排空的io个数
+} ub_migrate_drain_thread_result;
+
+#define DRAIN_LWB_DISABLE_WAIT (0) /**< darin lower buffer disable wait */
+#define DRAIN_LWB_DISABLE_FINISH (1) /**< darin lower buffer disable finish */
+#define DRAIN_LWB_DISABLE_ERR (2) /**< darin lower buffer disable error */
+
+/**
+ * @brief struct ub_migrate_lwb_disable_thread_result
+ * @details migrate lower buffer disable thread result
+ */
+typedef struct {
+ u32 status; // 0 正在处理, 1 完成,处理成功, 2 完成,处理失败
+} ub_migrate_lwb_disable_thread_result;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd.h
new file mode 100644
index 000000000..2aa834354
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu sip cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_SIP_CMD_H
+#define UB_NPU_SIP_CMD_H
+
+enum UB_CMD_SIP_TYPE {
+ UB_CMD_ADD_SIP =
+ 0x1, /**< Create sip Context @see > ub_cmd_sip_info_s */
+ UB_CMD_DEL_SIP =
+ 0x2, /**< Delete sip Context @see > ub_cmd_sip_info_s */
+ UB_CMD_QUERY_SIP =
+ 0x3, /**< Query sip Context @see > ub_cmd_sip_info_s */
+ UB_CMD_MODIFY_SIP =
+ 0x4, /**< Query sip Context @see > ub_cmd_sip_info_s */
+ UB_CMD_SIP_MAX
+};
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd_defs.h
new file mode 100644
index 000000000..978231075
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_sip_cmd_defs.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu sip cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_SIP_CMD_DEFS_H
+#define UB_NPU_SIP_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+/**@struct ub_sip_attr
+* @brief sip attr
+*/
+typedef struct ub_sip_attr {
+ u32 sip0;
+
+ u32 sip1;
+
+ u32 sip2;
+
+ u32 sip3;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vlan_cfi : 1;
+ u32 vlan_pri : 3;
+ u32 rsvd0 : 8;
+ u32 cvlan : 12;
+ u32 permission : 1;
+ u32 rsvd1 : 7;
+#else
+ u32 rsvd1 : 7;
+ u32 permission : 1;
+ u32 cvlan : 12;
+ u32 rsvd0 : 8;
+ u32 vlan_pri : 3;
+ u32 vlan_cfi : 1;
+#endif
+ };
+ u32 dw4_value;
+ } dw4;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ppersp_pad_len : 8;
+ u32 l2_len : 8;
+ u32 ip_hdr_len : 8;
+ u32 pkthdr_len : 8;
+#else
+ u32 pkthdr_len : 8;
+ u32 ip_hdr_len : 8;
+ u32 l2_len : 8;
+ u32 ppersp_pad_len : 8;
+#endif
+ };
+ u32 dw5_value;
+ } dw5;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd2 : 1;
+ u32 port_id : 4;
+ u32 ublink_en : 1;
+ u32 sip_update : 1;
+ u32 stag : 1;
+ u32 otag : 2;
+ u32 oiptype : 1;
+ u32 sip_type : 2;
+ u32 tunnel : 1;
+ u32 tag : 2;
+ u32 smac_h16 : 16;
+#else
+ u32 smac_h16 : 16;
+ u32 tag : 2;
+ u32 tunnel : 1;
+ u32 sip_type : 2;
+ u32 oiptype : 1;
+ u32 otag : 2;
+ u32 stag : 1;
+ u32 sip_update : 1;
+ u32 ublink_en : 1;
+ u32 port_id : 4;
+ u32 rsvd2 : 1;
+#endif
+ };
+ u32 dw6_value;
+ } dw6;
+
+ u32 smac_l32;
+} ub_sip_attr_s;
+
+/**@struct ub_cmd_body_sip_info
+* @brief sip cmd body
+*/
+typedef struct ub_cmd_body_sip_info {
+ ub_sip_attr_s sip_attr;
+ u32 offset;
+ u32 length;
+ u32 func_id;
+ u32 rsvd[2]; /* 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_sip_info_s;
+
+/**@struct ub_cmd_sip_info
+* @brief sip cmd info
+*/
+typedef struct ub_cmd_sip_info {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_sip_info_s body;
+} ub_cmd_sip_info_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd.h
new file mode 100644
index 000000000..2f07a7522
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu srq cmd define.
+ * Create: 2023-10-16
+ */
+
+#ifndef UB_NPU_SRQ_CMD_H
+#define UB_NPU_SRQ_CMD_H
+
+enum UB_CMD_SRQ_TYPE {
+ UB_CMD_SRQ_CREATE_CTX =
+ 0x1, /**< Create SRQ Context @see > ub_cmd_srq_create_s */
+ UB_CMD_SRQ_DELETE_CTX =
+ 0x2, /**< Delete SRQ Context @see > ub_cmd_srq_delete_s */
+ UB_CMD_SRQ_MODIFY_CTX =
+ 0x3, /**< Modify SRQ Context @see > ub_cmd_srq_modify_s */
+ UB_CMD_SRQ_QUERY_CTX =
+ 0x4, /**< Query SRQ Context @see > ub_cmd_srq_query_s */
+ UB_CMD_SRQ_BATCH_MODIFY_CTX =
+ 0x5, /**< DFX Batch Modify SRQ Context @see > ub_cmd_srq_batch_modify_s */
+ UB_CMD_SRQ_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd_defs.h
new file mode 100644
index 000000000..08a0528d5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_srq_cmd_defs.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu srq cmd define.
+ * Create: 2023-10-16
+ */
+
+#ifndef UB_NPU_SRQ_CMD_DEFS_H
+#define UB_NPU_SRQ_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_SRQ_CTX_SIZE 64 // srq context size is 64B
+
+/**@struct ub_srq_container_attr
+* @brief srq container attr
+*/
+typedef struct ub_srq_container_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 cont_size : 2;
+ u32 rsvd : 10;
+ u32 warn_th : 4;
+ u32 head_idx : 16;
+#else
+ u32 head_idx : 16;
+ u32 warn_th : 4;
+ u32 rsvd : 10;
+ u32 cont_size : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+} ub_srq_container_attr_s;
+
+/**@struct ub_srq_sw_attr
+* @brief srq sw attr
+*/
+typedef struct ub_srq_sw_attr {
+ /* DW0 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 mtt_page_size : 4;
+ u32 wqebb_size : 3;
+ u32 page_size : 4;
+ u32 size : 5;
+ u32 rsvd : 16;
+#else
+ u32 rsvd : 16;
+ u32 size : 5; /**< Shared Receive Queue size, equals to (2^srq_size)*WQEBB,
+ * the maximum SRQ size is 16K WQEs, so this field doesn't exceed 14. */
+ u32 page_size : 4; /**< Page size of SRQ, equals to (2^srq_page_size)*4KB */
+ u32 wqebb_size : 3; /**< Shared Receive WQE Basic Block (WQEBB) size in bytes is (2^rq_wqebb_size)*16B.
+ The minimum size is 32B and the values 0, 4, 5, 6, 7 are reserved */
+ u32 mtt_page_size : 4; /**< Page size of MTT for SRQ, equals to (2^srq_mtt_page_size)*4KB. */
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 container : 1;
+ u32 state : 4;
+ u32 so_ro : 2;
+ u32 dma_attr_idx : 6;
+ u32 pcnt_on_chip : 1;
+ u32 lth_pre_en : 1;
+ u32 rkey_en : 1;
+ u32 rsvd : 16;
+#else
+ u32 rsvd : 16;
+ u32 rkey_en : 1;
+ u32 lth_pre_en : 1;
+ u32 pcnt_on_chip : 1;
+ u32 dma_attr_idx : 6; /**< It specifies the outbound PCIe TLP header attribute of the DMA operation.
+ * This filed is only valid when processing CQ's CQEs. */
+ u32 so_ro : 2; /**< It specifies the ATTR[1:0] bits in the outbound PCIe TLP headers of the DMA operation.
+ * This field is only valid when processing CQ's CQEs.
+ * 2'b00: Strict Ordering;
+ * 2'b01: Relaxed Ordering;
+ * 2'b10: ID Based Ordering;
+ * 2'b11: Both Relaxed Ordering and ID Based Ordering. */
+ u32 state : 4;
+ u32 container : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ u32 srqn;
+
+ /* DW3~4 */
+ u32 mtt_paddr_h;
+ u32 mtt_paddr_l;
+
+ /* DW5~6 */
+ u32 db_paddr_h;
+ u32 db_paddr_l_at_hop_num; /**< bit[1:0] Address translation hop numbers */
+ ub_srq_container_attr_s cont;
+} ub_srq_sw_attr_s;
+
+/**@struct ub_cmd_body_srq_create
+* @brief srq cmd body for create
+*/
+typedef struct ub_cmd_body_srq_create {
+ ub_srq_sw_attr_s sw_attr;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_srq_create_s;
+
+/**@struct ub_cmd_srq_create
+* @brief srq cmd create
+*/
+typedef struct ub_cmd_srq_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_srq_create_s body;
+} ub_cmd_srq_create_s;
+
+/**@struct ub_cmd_body_srq_delete
+* @brief srq cmd body for delete
+*/
+typedef struct ub_cmd_body_srq_delete {
+ u32 srq_buf_len;
+ u32 wqe_cache_line_start;
+ u32 wqe_cache_line_end;
+ u32 wqe_cache_line_size;
+
+ 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 */
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_srq_delete_s;
+
+/**@struct ub_cmd_srq_delete
+* @brief srq cmd delete
+*/
+typedef struct ub_cmd_srq_delete {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_srq_delete_s body;
+} ub_cmd_srq_delete_s;
+
+/**@struct ub_cmd_body_srq_modify
+* @brief srq cmd body for modify
+*/
+typedef struct ub_cmd_body_srq_modify {
+ union {
+ 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;
+ u32 value;
+ } dw0;
+
+ u32 jfr_id;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_srq_modify_s;
+
+/**@struct ub_cmd_srq_modify
+* @brief srq cmd modify
+*/
+typedef struct ub_cmd_srq_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_srq_modify_s body;
+} ub_cmd_srq_modify_s;
+
+/**@struct ub_cmd_srq_query
+* @brief srq cmd query
+*/
+typedef struct ub_cmd_srq_query {
+ ub_cmd_com_header_s header;
+} ub_cmd_srq_query_s;
+
+/**@struct ub_cmd_srq_query_rsp
+* @brief srq cmd query response body
+*/
+typedef struct ub_cmd_srq_query_rsp {
+ union {
+ u8 ctx[UB_SRQ_CTX_SIZE];
+ struct {
+ u32 dw0;
+ u32 dw1;
+ /* DW2 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsv0 : 10;
+ u32 warn_th : 4; /* warn thresthod */
+ u32 rsv1 : 18;
+#else
+ u32 rsv1 : 18;
+ u32 warn_th : 4;
+ u32 rsv0 : 10;
+#endif
+ } bs_warn_th;
+
+ u32 value;
+ } dw2;
+ u8 rsvd[UB_SRQ_CTX_SIZE - 12];
+ };
+ };
+} ub_cmd_srq_query_rsp_s;
+
+/**@struct ub_cmd_body_srq_batch_modify
+* @brief srq cmd batch modify body
+*/
+typedef struct ub_cmd_body_srq_batch_modify {
+ u32 offset;
+ u32 length;
+ ub_cmd_srq_query_rsp_s srq_ctx;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_srq_batch_modify_s;
+
+/**@struct ub_cmd_srq_batch_modify
+* @brief srq cmd batch modify
+*/
+typedef struct ub_cmd_srq_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_srq_batch_modify_s body;
+} ub_cmd_srq_batch_modify_s;
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd.h
new file mode 100644
index 000000000..14936c4e5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef UB_NPU_TP_CMD_H
+#define UB_NPU_TP_CMD_H
+
+enum UB_CMD_TP_TYPE {
+ UB_CMD_TP_CREATE_CTX =
+ 0x1, /**< TP Create Context @see > ub_cmd_tp_create_s */
+ UB_CMD_TP_MODIFY_CTX =
+ 0x2, /**< TP Modify Context @see > ub_cmd_tp_modify_s */
+ UB_CMD_TP_DESTROY_CTX =
+ 0x3, /**< TP Destroy Context @see > ub_cmd_tp_destroy_s */
+ UB_CMD_TP_QUERY_CTX =
+ 0x4, /**< TP Query Context @see > ub_cmd_tp_query_ctx_s */
+
+ UB_CMD_DCA_CREATE_POOL =
+ 0x5, /**< Create DCA pool @see > ub_cmd_dca_create_s */
+ UB_CMD_DCA_DELETE_POOL =
+ 0x6, /**< Delete DCA pool @see > ub_cmd_dca_delete_s */
+
+ UB_CMD_TP_MODIFY_TP_CC =
+ 0x7, /**< TP cc modify attr @see > ub_cmd_tp_cc_modify_s */
+ UB_CMD_TP_MODIFY_SRP_BITMAP =
+ 0x8, /**< TP srp modify attr @see > ub_cmd_tp_srp_modify_s */
+ UB_CMD_TP_MODIFY_SRP_CTR_BITMAP =
+ 0x9, /**< TP srp ctr modify attr @see > ub_cmd_tp_srp_modify_s */
+ UB_CMD_TP_QUERY_CC_INFO =
+ 0xA, /**< TP cc query info @see > ub_cmd_tp_cc_query_s */
+ UB_CMD_TP_BATCH_MODIFY_CONTEXT =
+ 0xB, /**< TP ctx batch modify @see > ub_cmd_tp_batch_modify_s */
+ UB_CMD_TP_CREATE_UBRC =
+ 0xC, /**< TP create ubrc @see > ub_cmd_create_tp_ubrc_s */
+
+ UB_CMD_TP_QUERY_SRP_BITMAP =
+ 0xD, /**< TP Query SRP Bitmap @see > ub_cmd_tp_query_srp_bitmap_s */
+ UB_CMD_TP_QUERY_SRP_CTR_BITMAP =
+ 0xE, /**< TP Query SRP Ctr Bitmap @see > ub_cmd_tp_query_srp_ctr_bitmap_s */
+ UB_CMD_TP_QUERY_OOR_INFO =
+ 0xF, /**< TP Query OOR Info @see > ub_cmd_tp_query_oor_info_s */
+
+ UB_CMD_TP_QUERY_WQE =
+ 0x10, /**< TP Query wqe @see > ub_cmd_tp_query_s */
+ UB_CMD_TP_CACHE_INVLD =
+ 0x11, /**< TP Destroy cache inalid @see > ub_cmd_tp_cache_invalid_s */
+ UB_CMD_TP_QUERY_PCQC =
+ 0x12, /**< TP Query pcqc @see > ub_cmd_tp_query_s */
+ UB_CMD_TP_QUERY_CNT =
+ 0x13, /**< TP Query count for status @see > ub_cmd_tp_query_s */
+ UB_CMD_TP_SET_DROP_LEVEL =
+ 0x14, /**< TP Drop set drop level @see > ub_cmd_tp_dfx_drop */
+ UB_CMD_TP_QUERY_CTX_EXT =
+ 0x15, /**< Query extern TP context @see > ub_cmd_tp_query_ctx_ext_s */
+ UB_CMD_TP_QUERY_CTX_FOR_UDMA = 0x16, /**< Query TP context for udma> */
+ UB_CMD_TP_QUERY_TPMSN_TABLE = 0x17, /**< Query TPMSN table for udma> */
+ UB_CMD_TP_MAX
+};
+
+#endif // UB_NPU_TP_CMD_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd_defs.h
new file mode 100644
index 000000000..7b534872a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tp_cmd_defs.h
@@ -0,0 +1,1274 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef UB_NPU_TP_CMD_DEFS_H
+#define UB_NPU_TP_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+#include "ub_npu_tpg_cmd_defs.h"
+
+#define UB_TP_WQEBB_SIZE 64 /**< tp WQEBB size 64B */
+#define UB_INVALID_TPGN 0xfffff /**< invaild TPGN */
+
+#define UB_CMD_TP_CNT_MAX 32 /**< 该值须同ubcore的保持一致 */
+#define UB_CMD_TP_MODIFY_CNT_MAX \
+ 16 /**< modify结构体太大,multi modify tp个数超过16个分两次cmdq下发 */
+
+#define UB_OOR_TP_BITMAP_SIZE 32 /**< TP bitmap size 32B */
+#define UB_OOR_TP_REORDER_TABLE_SIZE 8 /**< TP reorder table size 8B */
+#define UB_OOR_TP_REORDER_TABLE_MASK 1 /**< TP reorder table mask 1 */
+
+#define UB_CMD_TP_SRP_ONE_BITMAP 64 /**< for one tp 1/2 */
+#define UB_CMD_TP_SRP_ONE_CTR_BITMAP 32 /**< tp srp one ctr bitmap size */
+#define UB_CMD_TP_SRP_CTR_BITMAP_NUM 8 /**< tp srp ctr bitmap number */
+
+#define DCA_CMDQ_SML_ENTRY_NUM 32 /**< sml entry number */
+
+#define UB_TPC_QUERY_RSP_SIZE 1024
+
+/**< tp pool type */
+enum UB_TP_POOL_TYPE {
+ SQ_POOL, /**< send queue POOL */
+ RQ_POOL /**< recieve queue POOL */
+};
+
+enum UB_TP_STATE_E {
+ UB_TPC_STATE_RST = 0x0, /**< tp state: reset */
+ UB_TPC_STATE_RTR = 0x1, /**< tp state: ready to receive */
+ UB_TPC_STATE_RTS = 0x2, /**< tp state: ready to send */
+ UB_TPC_STATE_SUS = 0x3, /**< tp state: suspend */
+ UB_TPC_STATE_ERR = 0x4, /**< tp state: error */
+ UB_TPC_STATE_MAX
+};
+
+enum UB_LDCP_INJECT_CC_MODE {
+ LDCP_INJECT_CC_OFF = 0x0,
+ LDCP_INJECT_CC_FIX_PERCENT = 0x1,
+ LDCP_INJECT_CC_RED = 0x2,
+};
+
+#pragma pack(4)
+/**
+ * @brief struct tag_tp_sw_ctx/ub_tp_sw_ctx_s
+ * @details tp context 软件段
+ */
+typedef struct tag_tp_sw_ctx {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 transport_mode : 2;
+ u32 state : 3;
+ u32 retry_factor : 3;
+ u32 srctpn : 24;
+#else
+ u32 srctpn : 24;
+ u32 retry_factor : 3;
+ u32 state : 3;
+ u32 transport_mode : 2; /**> 0->RC, 1->RM, 2->UM */
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 data_udp_srcport : 16;
+ u32 tp_timeout : 5;
+ u32 tp_retry_num : 3;
+ u32 base_mtu_n : 1;
+ u32 mtu_code : 4;
+ u32 pmtu : 3;
+#else
+ u32 pmtu : 3;
+ u32 mtu_code : 4;
+ u32 base_mtu_n : 1;
+ u32 tp_retry_num : 3;
+ u32 tp_timeout : 5;
+ u32 data_udp_srcport : 16;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 next_epsn : 24;
+ u32 oor_en : 1;
+ u32 oor_bitmap_size : 3;
+ u32 rsvd0 : 4;
+#else
+ u32 rsvd0 : 4;
+ u32 oor_bitmap_size : 3;
+ u32 oor_en : 1;
+ u32 next_epsn : 24;
+
+#endif
+ };
+ u32 dw2_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 jetty_id : 20;
+ u32 cc_en : 1;
+ u32 dca_tx_en : 1;
+ u32 dca_rx_en : 1;
+ u32 loopback : 1;
+ u32 must_check_token_en : 1;
+ u32 ep_id : 5;
+ u32 rsvd2 : 2;
+#else
+ u32 rsvd2 : 2;
+ u32 ep_id : 5;
+ u32 must_check_token_en : 1;
+ u32 loopback : 1;
+ u32 dca_rx_en : 1;
+ u32 dca_tx_en : 1;
+ u32 cc_en : 1;
+ u32 jetty_id : 20;
+#endif
+ };
+ u32 dw3_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsp_tpgn : 20;
+ u32 rsvd3 : 12;
+#else
+ u32 rsvd3 : 12;
+ u32 rsp_tpgn : 20;
+#endif
+ };
+ u32 dw4_value;
+ };
+
+ u32 suspend_cnt;
+ u32 suspend_period;
+} ub_tp_sw_ctx_s;
+
+/**
+ * @brief struct tag_ub_tp_chip/ub_tp_chip_s
+ * @details tp context chip
+ */
+typedef struct tag_ub_tp_chip {
+ /** DW0~1 */
+ union {
+ u64 sq_rq_l0mtt_gpa; /**< hi[63:32],lo[31:03],sq_rq_gpa_sign[02:00] */
+ struct {
+ u32 sq_rq_l0mtt_gpa_hi;
+ u32 sq_rq_l0mtt_gpa_lo;
+ } bs;
+ } dw0;
+
+ /** DW2~3 */
+ union {
+ u64 sq_rq_pi_record_gpa_at_hop_num; /**< hi[63:32],lo[31:02],sq_rq_at_hop_num[01:00] */
+ struct {
+ u32 sq_rq_pi_record_gpa_hi;
+ u32 sq_rq_pi_record_gpa_lo_at_hop_num; /**< at_hop_num: bit[01:00] */
+ } bs;
+ } dw2;
+
+ /** DW4 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_wqe_prefetch_mode : 1;
+ u32 sq_mtt_prefetch_maxlen : 3;
+ u32 sq_rq_mtt_page_size : 4;
+ u32 sqa_mtt_prefetch_maxlen : 3;
+ u32 rq_base_ci : 5;
+ u32 rrw_mtt_prefetch_maxlen : 2;
+ u32 rc_mtt_prefetch_maxlen : 2;
+ u32 qp_rkey_en : 1;
+ u32 rc_entry_prefetch_maxnum : 3;
+ u32 sq_rkey_en : 1;
+ u32 sq_wqebb_size : 3;
+ u32 rsvd1 : 4;
+#else
+ u32 rsvd1 : 4;
+ u32 sq_wqebb_size : 3;
+ u32 sq_rkey_en : 1;
+ u32 rc_entry_prefetch_maxnum : 3;
+ u32 qp_rkey_en : 1;
+ u32 rc_mtt_prefetch_maxlen : 2;
+ u32 rrw_mtt_prefetch_maxlen : 2;
+ u32 rq_base_ci : 5;
+ u32 sqa_mtt_prefetch_maxlen : 3;
+ u32 sq_rq_mtt_page_size : 4;
+ u32 sq_mtt_prefetch_maxlen : 3;
+ u32 sq_wqe_prefetch_mode : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ /** DW5 */
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_wqe_prefetch_maxnum : 3;
+ u32 sq_wqe_prefetch_minnum : 3;
+ u32 sq_wqe_cache_thd_sel : 2;
+ u32 sq_wqecnt_lth : 4;
+ u32 sq_wqecnt_rctl_en : 1;
+ u32 sq_wqecnt_rctl : 1;
+ u32 sq_prefetch_one_wqe : 1;
+ u32 sq_prewqe_mode : 1;
+ u32 sqa_wqe_prefetch_maxnum : 3;
+ u32 sqa_wqe_prefetch_minnum : 3;
+ u32 sqa_wqe_cache_thd_sel : 2;
+ u32 sq_wqe_check_en : 1;
+ u32 sq_pi_on_chip : 1;
+ u32 sq_inline_en : 1;
+ u32 sq_size : 5;
+#else
+ u32 sq_size : 5;
+ u32 sq_inline_en : 1;
+ u32 sq_pi_on_chip : 1;
+ u32 sq_wqe_check_en : 1;
+ u32 sqa_wqe_cache_thd_sel : 2;
+ u32 sqa_wqe_prefetch_minnum : 3;
+ u32 sqa_wqe_prefetch_maxnum : 3;
+ u32 sq_prewqe_mode : 1;
+ u32 sq_prefetch_one_wqe : 1;
+ u32 sq_wqecnt_rctl : 1;
+ u32 sq_wqecnt_rctl_en : 1;
+ u32 sq_wqecnt_lth : 4;
+ u32 sq_wqe_cache_thd_sel : 2;
+ u32 sq_wqe_prefetch_minnum : 3;
+ u32 sq_wqe_prefetch_maxnum : 3;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+} ub_tp_chip_s;
+
+/**
+ * @brief struct tag_ub_tp_create_attr/ub_tp_create_attr_s
+ * @details tp create attr
+ */
+typedef struct tag_ub_tp_create_attr {
+ ub_tp_chip_s chip_seg;
+ ub_tp_sw_ctx_s tpc_com;
+} ub_tp_create_attr_s;
+
+/**
+ * @brief struct ub_cmd_tp_create_body/ub_cmd_tp_create_body_s
+ * @details tp create struct body
+ */
+typedef struct ub_cmd_tp_create_body {
+ u32 num; /**< 创建tp的个数 */
+ ub_tp_create_attr_s tp_attr[UB_CMD_TP_CNT_MAX];
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_create_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_create/ub_cmd_tp_create_s
+ * @details tp create cmd struct
+ */
+typedef struct ub_cmd_tp_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_create_body_s body;
+} ub_cmd_tp_create_s;
+
+/**
+ * @brief struct ub_tp_modify_droute_attr/ub_tp_modify_droute_attr_s
+ * @details tp modify droute attr
+ */
+typedef struct ub_tp_modify_droute_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ack_udp_srcport : 16;
+ u32 dmac_h16 : 16;
+#else
+ u32 dmac_h16 : 16;
+ u32 ack_udp_srcport : 16;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ u32 dmac_l32;
+
+ u32 dip0;
+
+ u32 dip1;
+
+ u32 dip2;
+
+ u32 dip3;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd2 : 4;
+ u32 tclass : 8;
+ u32 flow_label : 20;
+#else
+ u32 flow_label : 20;
+ u32 tclass : 8;
+ u32 rsvd2 : 4;
+#endif
+ };
+ u32 dw6_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sl : 3;
+ u32 rsvd1 : 9;
+ u32 vlan_id : 12;
+ u32 hoplmt : 8;
+#else
+ u32 hoplmt : 8;
+ u32 vlan_id : 12;
+ u32 rsvd1 : 9;
+ u32 sl : 3;
+#endif
+ };
+ u32 dw7_value;
+ };
+} ub_tp_modify_droute_attr_s;
+
+/**
+ * @brief struct tag_ub_tp_modify_attr/ub_tp_modify_attr_s
+ * @details tp modify attr
+ */
+typedef struct tag_ub_tp_modify_attr {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ /** 16-31 */
+ u32 reserved : 7;
+ u32 sq_err_state : 1;
+ u32 sqa_err_state : 1;
+ u32 rq_err_state : 1;
+ u32 rqa_err_state : 1;
+ u32 cmd_ignore : 1; /**< 置1表示此attr结构体cmdq modify微码不处理,直接跳过 */
+ u32 vlan_en : 1;
+ u32 mn : 1;
+ u32 port : 1;
+ u32 flow_label : 1;
+ /** 0-15 */
+ u32 hop_limit : 1;
+ u32 udp_range : 1;
+ u32 ack_udp_start : 1;
+ u32 data_udp_start : 1;
+ u32 peer_net_addr : 1;
+ u32 local_net_addr_idx : 1;
+ u32 oos_cnt : 1;
+ u32 peer_ext : 1;
+ u32 local_en : 1;
+ u32 cc_pattern_idx : 1;
+ u32 mtu : 1;
+ u32 rx_psn : 1; /**< modify both rx psn and tx psn when restore tp */
+ u32 tx_psn : 1;
+ u32 state : 1;
+ u32 peer_tpn : 1;
+ u32 flag : 1;
+#else
+ u32 flag : 1;
+ u32 peer_tpn : 1;
+ u32 state : 1;
+ u32 tx_psn : 1;
+ u32 rx_psn : 1; /**< modify both rx psn and tx psn when restore tp */
+ u32 mtu : 1;
+ u32 cc_pattern_idx : 1;
+ u32 local_en : 1;
+ u32 peer_ext : 1;
+ u32 oos_cnt : 1;
+ u32 local_net_addr_idx : 1;
+ u32 peer_net_addr : 1;
+ u32 data_udp_start : 1;
+ u32 ack_udp_start : 1;
+ u32 udp_range : 1;
+ u32 hop_limit : 1;
+ u32 flow_label : 1;
+ u32 port : 1;
+ u32 mn : 1;
+ u32 vlan_en : 1;
+ u32 cmd_ignore : 1;
+ u32 rqa_err_state : 1;
+ u32 rq_err_state : 1;
+ u32 sqa_err_state : 1;
+ u32 sq_err_state : 1;
+ u32 reserved : 7;
+#endif
+ } bs;
+ u32 value;
+ } attr_mask;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 port : 8;
+ u32 mn : 8; /**< 0~15, a packet contains only one msg if mn is set as 0 */
+ u32 data_udp_start : 16;
+#else
+ u32 data_udp_start : 16;
+ u32 mn : 8;
+ u32 port : 8;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 peer_tpn : 24;
+ u32 local_net_addr_idx : 8;
+#else
+ u32 local_net_addr_idx : 8;
+ u32 peer_tpn : 24;
+#endif
+ };
+ u32 dw2_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tx_psn : 24;
+ u32 spray_en : 1;
+ u32 cc_alg : 4;
+ u32 cc_en : 1;
+ u32 sr_en : 1;
+ u32 oor_en : 1;
+#else
+ u32 oor_en : 1; /**< out of order receive, 0: disable 1: enable */
+ u32 sr_en : 1; /**< selective retransmission, 0: disable 1: enable */
+ u32 cc_en : 1; /**< congestion control algorithm, 0: disable 1: enable */
+ u32 cc_alg : 4; /**< The value is ubcore_tp_cc_alg_t */
+ u32 spray_en : 1; /**< spray with src udp port, 0: disable 1: enable */
+ u32 tx_psn : 24;
+#endif
+ };
+ u32 dw3_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rx_psn : 24; /**< modify both rx psn and tx psn when restore tp */
+ u32 cc_pattern_idx : 4;
+ u32 sq_err_state : 1;
+ u32 sqa_err_state : 1;
+ u32 rq_err_state : 1;
+ u32 rqa_err_state : 1;
+#else
+ u32 rqa_err_state : 1;
+ u32 rq_err_state : 1;
+ u32 sqa_err_state : 1;
+ u32 sq_err_state : 1;
+ u32 cc_pattern_idx : 4;
+ u32 rx_psn : 24;
+#endif
+ };
+ u32 dw4_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tpgn : 20;
+ u32 oos_cnt : 3;
+ u32 cos : 3;
+ u32 mtu : 3;
+ u32 state : 3;
+#else
+ u32 state : 3;
+ u32 mtu : 3;
+ u32 cos : 3;
+ u32 oos_cnt : 3;
+ u32 tpgn : 20;
+#endif
+ };
+ u32 dw5_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 udp_range : 8;
+ u32 tpn : 24; /**< modify的tpn */
+#else
+ u32 tpn : 24;
+ u32 udp_range : 8;
+#endif
+ };
+ u32 dw6_value;
+ };
+
+ ub_tp_modify_droute_attr_s droute;
+
+ u32 rsvd3[4]; /**< 预留 */
+} ub_tp_modify_attr_s;
+
+/**
+ * @brief struct ub_cmd_tp_modify_body/ub_cmd_tp_modify_body_s
+ * @details tp modify struct body
+ */
+typedef struct ub_cmd_tp_modify_body {
+ u32 num; /**< modify tp的个数 */
+ ub_tp_modify_attr_s attr[UB_CMD_TP_MODIFY_CNT_MAX];
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_modify_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_modify/ub_cmd_tp_modify_s
+ * @details tp modify struct
+ */
+typedef struct ub_cmd_tp_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_modify_body_s body;
+} ub_cmd_tp_modify_s;
+#pragma pack()
+
+/**
+ * @brief struct tag_ub_tp_cc_modify_attr/ub_tp_cc_modify_attr_s
+ * @details tp cc modify attr
+ */
+typedef struct tag_ub_tp_cc_modify_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd0 : 14;
+ u32 inject_mode : 2;
+ u32 percent : 16;
+#else
+ u32 percent : 16;
+ u32 inject_mode : 2;
+ u32 rsvd0 : 14;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 prm_limit_h : 16;
+ u32 prm_limit_l : 16;
+#else
+ u32 prm_limit_l : 16;
+ u32 prm_limit_h : 16;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ u32 rsvd1[2];
+} ub_tp_cc_modify_attr_s;
+
+/**
+ * @brief struct ub_cmd_tp_cc_modify_body/ub_cmd_tp_cc_modify_body_s
+ * @details tp cc modify struct body
+ */
+typedef struct ub_cmd_tp_cc_modify_body {
+ ub_tp_cc_modify_attr_s attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_cc_modify_body_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_cc_modify/ub_cmd_tp_cc_modify_s
+ * @details tp cc modify struct
+ */
+typedef struct tag_ub_cmd_tp_cc_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_cc_modify_body_s body;
+} ub_cmd_tp_cc_modify_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_srp_attr/ub_cmd_tp_srp_attr_s
+ * @details tp srp attr
+ */
+typedef struct tag_ub_cmd_tp_srp_attr {
+ u32 tp_srp_index;
+ u32 bitmap_index;
+ u32 ctr_bitmap_index;
+ u32 bitmap_mode;
+} ub_cmd_tp_srp_attr_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_srp_modify_body/ub_cmd_tp_srp_modify_body_s
+ * @details tp srp modify struct body
+ */
+typedef struct tag_ub_cmd_tp_srp_modify_body {
+ ub_cmd_tp_srp_attr_s attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_srp_modify_body_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_srp_modify/ub_cmd_tp_srp_modify_s
+ * @details tp srp modify struct
+ */
+typedef struct tag_ub_cmd_tp_srp_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_srp_modify_body_s body;
+} ub_cmd_tp_srp_modify_s;
+
+/**
+ * @brief struct ub_cc_dfx_info_s
+ * @details used to query the infomation, contains cc fields.
+ */
+typedef struct tag_ub_cc_dfx_info {
+ /* 静态字段,只在开头打印一次 */
+ u8 cc_en;
+ u8 algo_type;
+ u8 para_idx;
+ u8 rsvd0;
+
+ /* 动态字段,需要多次读取打印,每次一行 */
+ u32 timestamp; /* 芯片时间戳,单位us */
+ u32 cwnd;
+ u32 send_out; /* counter */
+ u32 lost_out; /* counter */
+ u32 send_credit; /* counter */
+ u32 send_credit_rate;
+ u32 srtt;
+ u32 rsvd1[2];
+
+ /* 算法相关字段,需要根据algo_type解析,也是动态字段 */
+ union {
+ /* LDCP算法 */
+ struct {
+ u8 slow_start;
+ u8 cwnd_inc_cnt;
+ u8 rsvd2[2];
+ u32 acked_seq;
+ u32 acked_ce_seq;
+ u32 rsvd3[3];
+ } ldcp;
+ /* 其它算法暂未定义,预留扩展能力 */
+ };
+} ub_cc_dfx_info_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_cc_query_body/ub_cmd_tp_cc_query_body_s
+ * @details tp cc srp query struct body
+ */
+typedef struct tag_ub_cmd_tp_cc_query_body {
+ ub_cc_dfx_info_s attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_cc_query_body_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_cc_query/ub_cmd_tp_cc_query_s
+ * @details tp cc srp query struct
+ */
+typedef struct tag_ub_cmd_tp_cc_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_cc_query_body_s body;
+} ub_cmd_tp_cc_query_s;
+
+/**
+ * @brief struct ub_tpc_query_rsp
+ * @details tp context query response
+ */
+typedef struct ub_tpc_query_rsp {
+ u8 ctx[UB_TPC_QUERY_RSP_SIZE];
+} ub_tpc_query_rsp_s;
+
+/**
+ * @brief struct tag_ub_tp_batch_modify_attr/ub_tp_batch_modify_attr_s
+ * @details tp batch modify attr
+ */
+typedef struct tag_ub_tp_batch_modify_attr {
+ u32 offset;
+ u32 length;
+ ub_tpc_query_rsp_s tp_ctx;
+} ub_tp_batch_modify_attr_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_batch_modify_body/ub_cmd_tp_batch_modify_body_s
+ * @details tp batch modify struct body
+ */
+typedef struct tag_ub_cmd_tp_batch_modify_body {
+ ub_tp_batch_modify_attr_s attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_batch_modify_body_s;
+
+/**
+ * @brief struct tag_ub_cmd_tp_batch_modify/ub_cmd_tp_batch_modify_s
+ * @details tp batch modify struct
+ */
+typedef struct tag_ub_cmd_tp_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_batch_modify_body_s body;
+} ub_cmd_tp_batch_modify_s;
+
+/**
+ * @brief struct ub_oor_tp_info/ub_oor_tp_info_s
+ * @details tp oor info struct
+ */
+typedef struct ub_oor_tp_info {
+ u32 oor_tp_reorder_table[UB_OOR_TP_REORDER_TABLE_SIZE];
+ union {
+ struct {
+ u32 oor_tp_bitmap_top_half[UB_OOR_TP_BITMAP_SIZE / 2];
+ u32 oor_tp_bitmap_bottom_half[UB_OOR_TP_BITMAP_SIZE / 2];
+ };
+ u32 oor_tp_bitmap[UB_OOR_TP_BITMAP_SIZE];
+ };
+ u32 start_bit;
+} ub_oor_tp_info_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_oor_info_body/ub_cmd_tp_query_oor_info_body_s
+ * @details tp oor info struct body
+ */
+typedef struct ub_cmd_tp_query_oor_info_body {
+ struct {
+ u32 msn;
+ } attr;
+ u32 rsvd[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_query_oor_info_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_oor_info_outbuf/ub_cmd_tp_query_oor_info_outbuf_s
+ * @details tp query oor info outbuffer
+ */
+typedef struct ub_cmd_tp_query_oor_info_outbuf {
+ ub_oor_tp_info_s oor_tp_info;
+} ub_cmd_tp_query_oor_info_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_oor_info/ub_cmd_tp_query_oor_info_s
+ * @details tp query oor info struct
+ */
+typedef struct ub_cmd_tp_query_oor_info {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_query_oor_info_body_s body;
+} ub_cmd_tp_query_oor_info_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_tp_msn_enrty_body/ub_cmd_tp_query_tp_msn_enrty_body_s
+ * @details tp msn entry struct body
+ */
+typedef struct ub_cmd_tp_query_tp_msn_enrty_body {
+ u32 entry_index;
+ u32 rsvd[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_query_tp_msn_enrty_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_msn_entry_info/ub_cmd_tp_query_msn_entry_info_s
+ * @details tp query msn entry struct
+ */
+typedef struct ub_cmd_tp_query_msn_entry_info {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_query_tp_msn_enrty_body_s body;
+} ub_cmd_tp_query_msn_entry_info_s;
+
+/**
+ * @brief struct ub_tp_srp_bitmap/ub_tp_srp_bitmap_s
+ * @details tp srp bitmap
+ */
+typedef struct ub_tp_srp_bitmap {
+ u8 bitmap[UB_CMD_TP_SRP_ONE_BITMAP];
+} ub_tp_srp_bitmap_s;
+
+/**
+ * @brief struct ub_tp_srp_ctr_bitmap/ub_tp_srp_ctr_bitmap_s
+ * @details tp srp ctr bitmap
+ */
+typedef struct ub_tp_srp_ctr_bitmap {
+ u8 bitmap[UB_CMD_TP_SRP_ONE_CTR_BITMAP];
+} ub_tp_srp_ctr_bitmap_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_srp_bitmap_outbuf/ub_cmd_tp_query_srp_bitmap_outbuf_s
+ * @details tp srp bitmap query outbuffer
+ */
+typedef struct ub_cmd_tp_query_srp_bitmap_outbuf {
+ ub_tp_srp_bitmap_s bitmap_f;
+ ub_tp_srp_bitmap_s bitmap_s;
+} ub_cmd_tp_query_srp_bitmap_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_srp_bitmap/ub_cmd_tp_query_srp_bitmap_s
+ * @details tp srp bitmap query struct
+ */
+typedef struct ub_cmd_tp_query_srp_bitmap {
+ ub_cmd_com_header_s header;
+ u32 rsvd[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_query_srp_bitmap_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf/ub_cmd_tp_query_srp_ctr_bitmap_outbuf_s
+ * @details tp srp ctr bitmap query outbuffer
+ */
+typedef struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf {
+ ub_tp_srp_ctr_bitmap_s ctr_bitmap[UB_CMD_TP_SRP_CTR_BITMAP_NUM];
+} ub_cmd_tp_query_srp_ctr_bitmap_outbuf_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_srp_ctr_bitmap/ub_cmd_tp_query_srp_ctr_bitmap_s
+ * @details tp srp ctr bitmap query struct
+ */
+typedef struct ub_cmd_tp_query_srp_ctr_bitmap {
+ ub_cmd_com_header_s header;
+ u32 rsvd[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_query_srp_ctr_bitmap_s;
+
+/**
+ * @brief struct ub_dca_sq_info/ub_dca_sq_info_s
+ * @details dca sq info
+ */
+typedef struct ub_dca_sq_info {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 sq_hop_num : 2;
+ u32 sq_page_size : 4;
+ u32 rsvd : 26;
+
+#else
+ u32 rsvd : 26;
+ u32 sq_page_size : 4;
+ u32 sq_hop_num : 2;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ u32 sq_mtt_gpa_hi;
+ u32 sq_mtt_gpa_lo;
+} ub_dca_sq_info_s;
+
+/**
+ * @brief struct ub_dca_rq_info/ub_dca_rq_info_s
+ * @details dca rq info
+ */
+typedef struct ub_dca_rq_info {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 8;
+ u32 rc_page_gpa_h : 24;
+
+#else
+ u32 rc_page_gpa_h : 24;
+ u32 rsvd : 8;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 rc_page_gpa_l;
+} ub_dca_rq_info_s;
+
+/**
+ * @brief struct ub_dca_pool_header/ub_dca_pool_header_s
+ * @details dca pool struct header
+ */
+typedef struct ub_dca_pool_header {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 index : 16;
+ u32 num : 8;
+ u32 type : 1;
+ u32 rsvd : 7;
+
+#else
+ u32 rsvd : 7;
+ u32 type : 1;
+ u32 num : 8;
+ u32 index : 16;
+#endif
+ };
+ u32 dw0_value;
+ };
+} ub_dca_pool_header_s;
+
+/**
+ * @brief struct ub_cmd_body_dca_create_sq_pool/ub_cmd_body_dca_create_sq_pool_s
+ * @details dca sq pool create struct body
+ */
+typedef struct ub_cmd_body_dca_create_sq_pool {
+ ub_dca_pool_header_s dca_header;
+ ub_dca_sq_info_s dca_sq_info[DCA_CMDQ_SML_ENTRY_NUM];
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_dca_create_sq_pool_s;
+
+/**
+ * @brief struct ub_cmd_body_dca_create_rq_pool/ub_cmd_body_dca_create_rq_pool_s
+ * @details dca rq pool create struct body
+ */
+typedef struct ub_cmd_body_dca_create_rq_pool {
+ ub_dca_pool_header_s dca_header;
+ ub_dca_rq_info_s dca_rq_info[DCA_CMDQ_SML_ENTRY_NUM];
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_dca_create_rq_pool_s;
+
+/**
+ * @brief struct ub_cmd_dca_create_sq_pool/ub_cmd_dca_create_sq_pool_s
+ * @details dca sq pool create command struct
+ */
+typedef struct ub_cmd_dca_create_sq_pool {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_dca_create_sq_pool_s body;
+} ub_cmd_dca_create_sq_pool_s;
+
+/**
+ * @brief struct ub_cmd_dca_create_rq_pool/ub_cmd_dca_create_rq_pool_s
+ * @details dca rq pool create struct
+ */
+typedef struct ub_cmd_dca_create_rq_pool {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_dca_create_rq_pool_s body;
+} ub_cmd_dca_create_rq_pool_s;
+
+/**
+ * @brief struct ub_cmd_body_dca_delete/ub_cmd_body_dca_delete_s
+ * @details dca delete command struct body
+ */
+typedef struct ub_cmd_body_dca_delete {
+ ub_dca_pool_header_s dca_header;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_dca_delete_s;
+
+/**
+ * @brief struct ub_cmd_dca_delete/ub_cmd_dca_delete_s
+ * @details dca delete command struct
+ */
+typedef struct ub_cmd_dca_delete {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_dca_delete_s body;
+} ub_cmd_dca_delete_s;
+
+/**
+ * @brief struct ub_cmd_body_create_ubrc/ub_cmd_body_create_ubrc_s
+ * @details ubrc create command struct body
+ */
+typedef struct ub_cmd_body_create_ubrc {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rc_max_size : 3;
+ u32 rsvd0 : 29;
+#else
+ u32 rsvd0 : 29;
+ u32 rc_max_size : 3;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd1 : 2;
+ u32 rc_size : 4;
+ u32 rc_entry_size : 2;
+ u32 rc_page_gpa_h : 24;
+#else
+ u32 rc_page_gpa_h : 24;
+ u32 rc_entry_size : 2;
+ u32 rc_size : 4;
+ u32 rsvd1 : 2;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ u32 rc_page_gpa_l;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_create_ubrc_s;
+
+/**
+ * @brief struct ub_cmd_tp_create_ubrc/ub_cmd_tp_create_ubrc_s
+ * @details ubrc tp create command struct
+ */
+typedef struct ub_cmd_tp_create_ubrc {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_create_ubrc_s body;
+} ub_cmd_tp_create_ubrc_s;
+
+/**
+ * @brief struct ub_cmd_tp_query_body/ub_cmd_tp_query_body_s
+ * @details tp query command struct body
+ */
+typedef struct ub_cmd_tp_query_body {
+ u32 ci; /**< 查询RCQE时的目标ci */
+ u32 tp_srp_index;
+ u32 bitmap_index;
+ u32 ctr_bitmap_index;
+ u32 bitmap_mode;
+ u32 sencond_entry; /**< 查询第二段bitmap偏移 */
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_query_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_query/ub_cmd_tp_query_s
+ * @details tp query command struct body
+ */
+typedef struct ub_cmd_tp_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_query_body_s body;
+} ub_cmd_tp_query_s;
+
+/**
+ * @brief struct ub_tp_hw2sw_info/ub_tp_hw2sw_info_s
+ * @details tp hw2sw info
+ */
+typedef struct ub_tp_hw2sw_info {
+ /** DW0~1 */
+ u32 sq_buf_len; /**< Buffer length of the SQ queue */
+ u32 rq_buf_len; /**< Buffer length of the RQ queue */
+
+ /** DW2~6 */
+ 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 */
+
+ /** DW7~8 */
+ union {
+ u64 wb_gpa; /**< Address written back by the ucode after processing */
+
+ struct {
+ u32 syn_gpa_hi32; /**< Upper 32 bits of the start address of mr or mw */
+ u32 syn_gpa_lo32; /**< Lower 32 bits of the start address of mr or mw */
+ } gpa_dw;
+ };
+ union {
+ struct {
+ u32 rsvd : 16;
+ u32 host_oqid : 16;
+ };
+
+ u32 dw9_value;
+ };
+ u32 wqe_flags; /**< Indicates whether to kick out cache. by queue (0) or VF(1). */
+ u32 wqe_num; /**< Number of wqe, which needs to be assigned by the driver when the is kicked out by queue. */
+ u32 wqe_cache_line_start; /**< The driver needs to read the driver from the configuration file. */
+ u32 wqe_cache_line_end; /**< The driver needs to read the driver from the configuration file. */
+ u32 wqe_cache_line_size; /**< 0:256B,1:512B */
+} ub_tp_hw2sw_info_s;
+
+/**
+ * @brief struct ub_cmd_tp_cache_invalid_body/ub_cmd_tp_cache_invalid_body_s
+ * @details tp cache invalid struct body
+ */
+typedef struct ub_cmd_tp_cache_invalid_body {
+ ub_tp_hw2sw_info_s tp_cache;
+ u32 tp_cnt;
+ u32 ub_tpn[UB_CMD_TP_CNT_MAX];
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_cache_invalid_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_cache_invalid/ub_cmd_tp_cache_invalid_s
+ * @details tp cache invalid struct
+ */
+typedef struct ub_cmd_tp_cache_invalid {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_cache_invalid_body_s body;
+} ub_cmd_tp_cache_invalid_s;
+
+/**
+ * @brief struct ub_cmd_tp_dfx_drop_body/ub_cmd_tp_dfx_drop_body_s
+ * @details tp dfx drop struct body
+ */
+typedef struct ub_cmd_tp_dfx_drop_body {
+ u32 drop_level; /**< 丢包等级 */
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_dfx_drop_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_dfx_drop/ub_cmd_tp_dfx_drop_s
+ * @details tp dfx drop struct
+ */
+typedef struct ub_cmd_tp_dfx_drop {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_dfx_drop_body_s body;
+} ub_cmd_tp_dfx_drop_s;
+
+#pragma pack(4)
+/**
+ * @brief struct tag_ub_tp_destroy_attr/ub_tp_destroy_attr_s
+ * @details tp destory attr
+ */
+typedef struct tag_ub_tp_destroy_attr {
+ u32 tpn;
+} ub_tp_destroy_attr_s;
+
+/**
+ * @brief struct ub_cmd_tp_destroy_body/ub_cmd_tp_destroy_body_s
+ * @details tp destory command struct body
+ */
+typedef struct ub_cmd_tp_destroy_body {
+ u32 num; /**< 删除的tp个数 */
+ ub_tp_destroy_attr_s tp_attr[UB_CMD_TP_CNT_MAX];
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 dpath_flag : 1; /**< 排空标志 */
+ u32 rsvd0 : 31; /**< 预留 */
+#else
+ u32 rsvd0 : 31; /**< 预留 */
+ u32 dpath_flag : 1; /**< 排空标志 */
+#endif
+ } bs;
+ u32 rsvd[4]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tp_destroy_body_s;
+
+/**
+ * @brief struct ub_cmd_tp_destroy/ub_cmd_tp_destroy_s
+ * @details tp destory command struct
+ */
+typedef struct ub_cmd_tp_destroy {
+ ub_cmd_com_header_s header;
+ ub_cmd_tp_destroy_body_s body;
+} ub_cmd_tp_destroy_s;
+#pragma pack()
+
+/**
+ * @brief struct tag_ub_tpc_query_outbuf/ub_tpc_query_outbuf_s
+ * @details tpc query outbuffer
+ */
+typedef struct tag_ub_tpc_query_outbuf {
+ ub_tpc_query_rsp_s res_val;
+} ub_tpc_query_outbuf_s;
+
+typedef struct tag_ub_tpc_query_ext_outbuf {
+ ub_tpc_query_rsp_s ret_val;
+} ub_tpc_query_ext_outbuf_s;
+
+/**
+ * @brief struct tag_ub_tp_query_info_outbuf/ub_tpc_query_info_outbuf_s
+ * @details tpc query outbuffer
+ */
+typedef struct tag_ub_tp_query_info_outbuf {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 tclass : 8;
+ u32 oor_en : 1;
+ u32 state : 3;
+ u32 srp_en : 1;
+ u32 rsvd0 : 19; /**< 预留 */
+#else
+ u32 rsvd0 : 19; /**< 预留 */
+ u32 srp_en : 1;
+ u32 state : 3;
+ u32 oor_en : 1;
+ u32 tclass : 8;
+#endif
+ } dw0;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 ack_udp_srcport : 16;
+ u32 data_udp_srcport : 16;
+#else
+ u32 data_udp_srcport : 16;
+ u32 ack_udp_srcport : 16;
+#endif
+ } dw1;
+ u32 srctpn;
+ u32 tp_msn;
+ u32 next_epsn;
+ u32 next_send_psn;
+ u32 pending_wr;
+ u32 infly_wr;
+} ub_tpc_query_info_outbuf_s;
+
+#define UB_TP_WQE_NUM_WQEBB 2
+#define UB_TP_WQE_SIZE (UB_TP_WQEBB_SIZE * UB_TP_WQE_NUM_WQEBB)
+/**
+ * @brief struct ub_tp_wqe/ub_tp_wqe_t
+ * @details tp wqe 查询返回结果
+ */
+typedef struct ub_tp_wqe {
+ u8 tpqe[UB_TP_WQE_SIZE];
+} ub_tp_wqe_t;
+
+/**
+ * @brief struct ub_tp_cnt_query_outbuf/ub_tp_cnt_query_outbuf_s
+ * @details tp wqe query outbuffer
+ */
+typedef struct ub_tp_cnt_query_outbuf {
+ u32 tp_cnt[UB_TPC_STATE_MAX];
+} ub_tp_cnt_query_outbuf_s;
+
+/**
+ * @brief struct ub_tp_flow_info
+ * @details tp flow info
+ */
+struct ub_tp_flow_info {
+ u32 tpn;
+ u32 send_cnt;
+ u32 infly;
+ u32 wr;
+};
+
+/**
+ * @brief struct ub_tpg_flow
+ * @details tpg flow
+ */
+struct ub_tpg_flow {
+ u32 tpgn;
+ u32 tp_num;
+ struct ub_tp_flow_info tp_flow_info[MAX_TP_CNT_IN_TPG];
+};
+
+/**
+ * @brief struct ub_cmd_tp_query_ctx
+ * @details tp query command context
+ */
+typedef struct ub_cmd_tp_query_ctx {
+ ub_cmd_com_header_s header;
+} ub_cmd_tp_query_ctx_s;
+
+typedef struct ub_cmd_tp_query_ctx_ext {
+ ub_cmd_com_header_s header;
+} ub_cmd_tp_query_ctx_ext_s;
+
+#define UB_TPC_IN_TP_CONTEXT_SHIFT 80
+#define UB_TP_CONTEXT_SIZE 1024 /* 1825 TP上下文512B, 1823 TP上下文1024B */
+#define UB_TP_CONTEXT_QUERY_SIZE (UB_TP_CONTEXT_SIZE >> 2)
+/**
+ * @brief struct ub_dfx_tp_ctx_query/ub_dfx_tp_ctx_query_s
+ * @details used to query the context.
+ */
+typedef struct ub_dfx_tp_ctx_query {
+ u32 ctx[UB_TP_CONTEXT_QUERY_SIZE];
+} ub_dfx_tp_ctx_query_s;
+
+#define UB_TP_CTX_EXT_SIZE 512
+/**
+ * @brief struct ub_tp_ctx_ext_query
+ * @details used to query the tp ctx ext.
+ */
+struct ub_tp_ctx_ext_query {
+ u8 ctx_ext[UB_TP_CTX_EXT_SIZE];
+};
+
+#endif // UB_NPU_TP_CMD_DEFS_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd.h
new file mode 100644
index 000000000..9bf545adc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu tpg cmd define.
+ * Create: 2023-10-20
+ */
+
+#ifndef UB_NPU_TPG_CMD_H
+#define UB_NPU_TPG_CMD_H
+
+enum UB_CMD_TPG_TYPE {
+ UB_CMD_TPG_CREATE =
+ 0x1, /**< Create tpg Context @see > ub_cmd_tpg_create_s */
+ UB_CMD_TPG_DESTROY =
+ 0x2, /**< destroy tpg Context @see > ub_cmd_tpg_destroy_s */
+ UB_CMD_TPG_QUERY_CTX =
+ 0x3, /**< query tpg Context @see > ub_cmd_tpg_query_inbuf_s */
+ UB_CMD_TPG_CTX_SELECT_TP =
+ 0x4, /**< modify tpg Context dft @see > ub_cmd_tpg_modify_s */
+ UB_CMD_TPG_BATCH_MODIFY_CONTEXT =
+ 0x5, /**< batch tpg Context @see > ub_cmd_tpg_batch_modify_s */
+ UB_CMD_TPG_CLEAR_TP_LATCH_LOCK = 0x6, /** clear TP latch lock */
+ UB_CMD_TPG_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd_defs.h
new file mode 100644
index 000000000..e5251d3e4
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_tpg_cmd_defs.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu jetty cmd define.
+ * Create: 2023-10-13
+ */
+
+#ifndef UB_NPU_TPG_CMD_DEFS_H
+#define UB_NPU_TPG_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define MAX_TP_CNT_IN_TPG 32
+
+/**@struct ub_cmd_tpg_query_inbuf
+* @brief tpg query cmd inbuf
+*/
+typedef struct ub_cmd_tpg_query_inbuf {
+ ub_cmd_com_header_s header;
+} ub_cmd_tpg_query_inbuf_s;
+
+/**@struct tag_ub_tpg_create_attr
+* @brief tpg create cmd attr
+*/
+typedef struct tag_ub_tpg_create_attr {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vld : 1;
+ u32 rsvd1 : 3;
+ u32 sl : 4; /**< 即tc */
+ u32 all_tp_num : 8;
+ u32 ep_id : 5;
+ u32 rsvd2 : 3;
+ u32 ack_tp_num : 4;
+ u32 ack_tp_start_idx : 4;
+
+#else
+ u32 ack_tp_start_idx : 4;
+ u32 ack_tp_num : 4;
+ u32 rsvd2 : 3;
+ u32 ep_id : 5;
+ u32 all_tp_num : 8;
+ u32 sl : 4; /**< 即tc */
+ u32 rsvd1 : 3;
+ u32 vld : 1;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd3 : 5;
+ u32 multi_fast_tp_en : 1;
+ u32 multi_tp_en : 1;
+ u32 default_tpn : 4;
+ u32 fast : 1;
+ u32 fast_tpn : 20;
+#else
+ u32 fast_tpn : 20;
+ u32 fast : 1;
+ u32 default_tpn : 4;
+ u32 multi_tp_en : 1;
+ u32 multi_fast_tp_en : 1;
+ u32 rsvd3 : 5;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 v : 2;
+ u32 depth : 10;
+ u32 tpn : 20;
+#else
+ u32 tpn : 20;
+ u32 depth : 10;
+ u32 v : 2;
+#endif
+ } bs;
+ u32 value;
+ } tpn[MAX_TP_CNT_IN_TPG];
+} ub_tpg_create_attr_s;
+
+/**@struct ub_cmd_tpg_body
+* @brief tpg cmd body
+*/
+typedef struct ub_cmd_tpg_body {
+ ub_tpg_create_attr_s attr;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_tpg_body_s;
+
+/**@struct ub_cmd_tpg_create
+* @brief tpg cmd create
+*/
+typedef struct ub_cmd_tpg_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_tpg_body_s body;
+} ub_cmd_tpg_create_s;
+
+/**@struct ub_cmd_tpg_destroy
+* @brief tpg cmd destroy
+*/
+typedef struct ub_cmd_tpg_destroy {
+ ub_cmd_com_header_s header;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_tpg_destroy_s;
+
+/**@struct ub_cmd_tpg_modify
+* @brief tpg cmd modify
+*/
+typedef struct ub_cmd_tpg_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_tpg_body_s body;
+} ub_cmd_tpg_modify_s;
+
+#define UB_TPG_CONTEXT_SIZE 128
+#define UB_TPG_CONTEXT_QUERY_SIZE (UB_TPG_CONTEXT_SIZE >> 2)
+/**
+ * @brief struct ub_tpg_ctx_query/ub_tpg_ctx_query_s
+ * @details used to query the context.
+ */
+typedef struct ub_tpg_ctx_query {
+ u32 ctx_req[UB_TPG_CONTEXT_QUERY_SIZE];
+ u32 ctx_rsp[UB_TPG_CONTEXT_QUERY_SIZE];
+} ub_tpg_ctx_query_s;
+
+/* 每4个tpgc作为1组TP锁存空间 */
+#define UB_TP_LATCH_DATA_MAX_SIZE (sizeof(ub_tpg_ctx_query_s) << 2)
+/**
+ * @brief struct ub_tp_latch_data_outbuf/ub_tp_latch_data_outbuf_s
+ * @details tp latch data out buffer
+ */
+typedef struct ub_tp_latch_data_outbuf {
+ u8 tp_latch[UB_TP_LATCH_DATA_MAX_SIZE];
+ u32 tp_latch_size;
+} ub_tp_latch_data_outbuf_s;
+
+/* 对外不显示TPGC数据结构,只定义大小 */
+typedef struct ub_tpg_context_ext {
+ u8 ctx_ext[(UB_TPG_CONTEXT_SIZE << 1)];
+} ub_tpg_context_ext_s;
+
+/**
+ * @brief struct ub_tpg_batch_modify_attr/ub_tpg_batch_modify_attr_s
+ * @details tpg batch modify attr
+ */
+typedef struct ub_tpg_batch_modify_attr {
+ u32 offset;
+ u32 length;
+ ub_tpg_context_ext_s tpg_ctx;
+} ub_tpg_batch_modify_attr_s;
+
+/**
+ * @brief struct ub_cmd_tpg_batch_modify_body/ub_cmd_tpg_batch_modify_body_s
+ * @details tpg batch modify struct body
+ */
+typedef struct ub_cmd_tpg_batch_modify_body {
+ ub_tpg_batch_modify_attr_s attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_tpg_batch_modify_body_s;
+
+/**
+ * @brief struct ub_cmd_tpg_batch_modify/ub_cmd_tpg_batch_modify_s
+ * @details tpg batch modify struct
+ */
+typedef struct ub_cmd_tpg_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_tpg_batch_modify_body_s body;
+} ub_cmd_tpg_batch_modify_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd.h
new file mode 100644
index 000000000..c46ce5488
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu upi cmd define.
+ * Create: 2023-10-20
+ */
+
+#ifndef UB_NPU_UPI_CMD_H
+#define UB_NPU_UPI_CMD_H
+
+enum UB_CMD_UPI_TYPE {
+ UB_CMD_UPI_UPDATE = 0x1, /**< UPDATE UPI @see > ub_cmd_upi_update_s */
+ UB_CMD_UPI_QUERY = 0x2, /**< QUERY UPI @see > ub_cmd_upi_query_s */
+ UB_CMD_UPI_CLEAR = 0x3 /**< CLEAR UPI @see > ub_cmd_upi_update_s */
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd_defs.h
new file mode 100644
index 000000000..df81c8708
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_upi_cmd_defs.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu upi cmd define.
+ * Create: 2023-10-20
+ */
+
+#ifndef UB_NPU_UPI_CMD_DEFS_H
+#define UB_NPU_UPI_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_UEID_SIZE 16 /**< EID size 16B */
+#define UB_EID_LEN 4 /**< EID len 4B */
+
+typedef enum {
+ UB_UPI_NORM = 0x0, /**< upi normal */
+ UB_UPI_MIGR = 0x1, /**< upi migrate */
+ UB_UPI_ROLLBACK = 0x2 /**< upi rollback */
+} ub_upi_mig_state_e;
+
+/**
+ * @brief struct ub_cmd_body_upi_update/ub_cmd_body_upi_update_s
+ * @details upi update command struct body
+ */
+typedef struct ub_cmd_body_upi_update {
+ u8 id[UB_UEID_SIZE];
+ u32 upi;
+ u32 vfid;
+ u32 mig_state;
+ u32 resv[3];
+} ub_cmd_body_upi_update_s;
+
+/**
+ * @brief struct ub_cmd_upi_update/ub_cmd_upi_update_s
+ * @details upi update command struct
+ */
+typedef struct ub_cmd_upi_update {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_upi_update_s body;
+} ub_cmd_upi_update_s;
+
+/**
+ * @brief struct ub_cmd_body_upi_query/ub_cmd_body_upi_query_s
+ * @details upi query command struct body
+ */
+typedef struct ub_cmd_body_upi_query {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd : 7;
+ u32 type : 1;
+ u32 upi : 24;
+#else
+ u32 upi : 24;
+ u32 type : 1; // ueid 0; ip 1
+ u32 rsvd : 7;
+#endif
+ };
+ u32 value;
+ } dw0;
+
+ union {
+ u8 id[UB_UEID_SIZE];
+ u32 id_dw[UB_EID_LEN];
+ };
+ u32 resv[3];
+} ub_cmd_body_upi_query_s;
+
+/**
+ * @brief struct ub_cmd_upi_query/ub_cmd_upi_query_s
+ * @details upi query command struct
+ */
+typedef struct ub_cmd_upi_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_upi_query_s body;
+} ub_cmd_upi_query_s;
+
+/**
+ * @brief struct ub_cmd_upi_key_attr_s
+ * @details used to query the upi key.
+ */
+typedef struct {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 7;
+ u32 type : 1;
+ u32 upi : 24;
+#else
+ u32 upi : 24;
+ u32 type : 1; // ueid 0; ip 1
+ u32 rsvd : 7;
+#endif
+ };
+ u32 value;
+ } dw0;
+
+ /* EID 与 upi 共同作为key,通过hash得出 fun_id */
+ union {
+ u8 id[UB_UEID_SIZE];
+ u32 id_dw[UB_EID_LEN];
+ };
+} ub_cmd_upi_key_attr_s;
+
+/**
+ * @brief struct ub_cmd_upi_value_attr_s
+ * @details used to query the upi value.
+ */
+typedef struct {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 vld : 1;
+ u32 type : 1;
+ u32 rsvd : 18;
+ u32 vfid : 12;
+#else
+ u32 vfid : 12;
+ u32 rsvd : 18;
+ u32 type : 1;
+ u32 vld : 1;
+#endif
+ };
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 5;
+ u32 mig_state : 2;
+ u32 perm : 1;
+ u32 upi : 24;
+#else
+ u32 upi : 24;
+ u32 perm : 1;
+ u32 mig_state : 2;
+ u32 rsvd : 5;
+#endif
+ };
+ u32 value;
+ } dw1;
+} ub_cmd_upi_value_attr_s;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_userctl_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_userctl_defs.h
new file mode 100644
index 000000000..172f6180a
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_userctl_defs.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: UB npu jfc cmd define.
+ * Create: 2024-8-23
+ */
+
+#ifndef UB_NPU_USERCTL_DEFS_H
+#define UB_NPU_USERCTL_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define PFC_PRIORITY 8 /**< pdf priority */
+#define TRUNK_PRIORITY 8 /**< trunk priority */
+#define TRUNK_PORTS_NUM 4 /**< trunk ports number */
+
+/**
+ * @brief struct tag_ub_cmdq_type/ub_cmdq_type_s
+ * @details command queue type struct
+ */
+typedef struct tag_ub_cmdq_type {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 cmd_type : 8; /**< cmd type @see > enum ub_ucode_cmdq_cmd */
+ u32 rsvd0 : 24; /**< reserved */
+#else
+ u32 rsvd0 : 24;
+ u32 cmd_type : 8;
+#endif
+ } dw0;
+} ub_cmdq_type_s;
+
+/**
+ * @brief struct tag_ub_cmdq_vport_s/ub_cmdq_vport_s
+ * @details command queue vport queue
+ */
+typedef struct tag_ub_cmdq_vport_s {
+ ub_cmdq_type_s common; /**< cmd type @see > struct tag_ub_cmdq_type */
+ u32 host_id; /**< vport host id */
+ u32 func_id; /**< vport func id */
+ u32 rsp_addr_h; /**< response high address */
+ u32 rsp_addr_l; /**< response low address */
+} ub_cmdq_vport_s;
+
+/**
+ * @brief struct tag_ub_cmdq_vf_stats_s/ub_cmdq_vf_stats_s
+ * @details command queue virtual function status
+ */
+typedef struct tag_ub_cmdq_vf_stats_s {
+ ub_cmdq_type_s common; /**< cmd type @see > struct tag_ub_cmdq_type */
+ u32 host_id; /**< vport host id */
+ u32 func_id; /**< vport func id */
+ u32 rsp_addr_h; /**< response high address */
+ u32 rsp_addr_l; /**< response low address */
+} ub_cmdq_vf_stats_s;
+
+/**
+ * @brief struct tag_ub_cmdq_qos_stats_s/ub_cmdq_qos_stats_s
+ * @details command queue qos status
+ */
+typedef struct tag_ub_cmdq_qos_stats_s {
+ ub_cmdq_type_s common;
+ u32 rsp_addr_h;
+ u32 rsp_addr_l;
+ u32 cnt;
+ u32 data[0];
+} ub_cmdq_qos_stats_s;
+
+/**
+ * @brief union tag_ub_cmdq/ub_cmdq_u
+ * @details command queue union
+ */
+typedef union tag_ub_cmdq {
+ ub_cmdq_type_s common;
+ ub_cmdq_vport_s trunk_stats;
+ ub_cmdq_qos_stats_s qos_stats;
+ ub_cmdq_vf_stats_s vf_stats;
+} ub_cmdq_u;
+
+enum tag_ub_npu_cmdq_cmd {
+ UB_CMD_TRUNK_PFC_STATS = 0, /**< trunk pfc status command */
+ UB_CMD_TRUNK_STATS = 1, /**< trunk status command */
+ UB_CMD_VF_STATS /**< virtual function status command */
+};
+
+/**
+ * @brief struct ub_cmd_body_userctl/ub_cmd_body_userctl_s
+ * @details body userctl command struct body
+ */
+typedef struct ub_cmd_body_userctl {
+ u32 func_id;
+ u32 host_id;
+} ub_cmd_body_userctl_s;
+
+/**
+ * @brief struct ub_user_ctl_uvs_trunk_pfc_status_out/ub_user_ctl_uvs_trunk_pfc_status_out_s
+ * @details user ctl uvs trunk pfc status out
+ */
+typedef struct ub_user_ctl_uvs_trunk_pfc_status_out {
+ u64 rx_pfc_packets;
+ u64 rx_pri_pfc_packets[PFC_PRIORITY];
+ u64 tx_pfc_packets;
+ u64 tx_pri_pfc_packets[PFC_PRIORITY];
+} ub_user_ctl_uvs_trunk_pfc_status_out_s;
+
+/**
+ * @brief struct ub_user_ctl_uvs_card_status_out/ub_user_ctl_uvs_card_status_out_s
+ * @details user ctl uvs card status out
+ */
+typedef struct ub_user_ctl_uvs_card_status_out {
+ u32 rx_err_packets;
+ u32 rx_loss_packets;
+ u32 rx_ce_packets;
+ u32 tx_port_err_packets;
+
+ u64 tx_port_pkts;
+ u64 tx_port_bytes;
+ u64 rx_port_pkts;
+ u64 rx_port_bytes;
+} ub_user_ctl_uvs_card_status_out_s;
+
+/**
+ * @brief struct ub_user_ctl_uvs_vf_status_out/ub_user_ctl_uvs_vf_status_out_s
+ * @details user ctl uvs vf status out
+ */
+typedef struct ub_user_ctl_uvs_vf_status_out {
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_packets;
+ u64 tx_bytes;
+
+ u64 rx_err_pkt_cnt;
+ u64 rx_ce_pkt_cnt;
+ u64 rx_not_ready_cnt;
+ u64 tx_timeout_cnt;
+ u64 tx_no_vld_tp_cnt;
+
+ u64 rsvds[8];
+} ub_user_ctl_uvs_vf_status_out_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd.h
new file mode 100644
index 000000000..46e3d9501
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef UB_NPU_UTP_CMD_H
+#define UB_NPU_UTP_CMD_H
+
+enum UB_CMD_DIP_TYPE {
+ UB_CMD_ADD_DIP =
+ 0x1, /**< Create dip Context @see > ub_cmd_create_utp_s */
+ UB_CMD_DEL_DIP =
+ 0x2, /**< Delete dip Context @see > ub_cmd_destroy_utp_s */
+ UB_CMD_QUERY_DIP =
+ 0x3, /**< Query dip Context @see > ub_cmd_query_utp_s */
+ UB_CMD_DIP_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd_defs.h
new file mode 100644
index 000000000..71311e663
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_utp_cmd_defs.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef UB_NPU_UTP_CMD_DEFS_H
+#define UB_NPU_UTP_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+/**@struct tag_ub_create_utp_attr
+* @brief utp cmd attr
+*/
+typedef struct tag_ub_create_utp_attr {
+ u32 dmac_l32;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd1 : 1;
+ u32 mtu : 3;
+ u32 port_id : 4;
+ u32 ack_udp_srcport : 8;
+ u32 dmac_h16 : 16;
+#else
+ u32 dmac_h16 : 16;
+ u32 ack_udp_srcport : 8;
+ u32 port_id : 4;
+ u32 mtu : 3;
+ u32 rsvd1 : 1;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ u32 dip0;
+
+ u32 dip1;
+
+ u32 dip2;
+
+ u32 dip3;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd6 : 12;
+ u32 func_id : 16;
+ u32 vld : 1;
+ u32 dip_type : 2;
+ u32 loop_back : 1;
+#else
+ u32 loop_back : 1;
+ u32 dip_type : 2;
+ u32 vld : 1;
+ u32 func_id : 16;
+ u32 rsvd6 : 12;
+#endif
+ };
+ u32 dw6_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd7 : 8;
+ u32 hoplmt : 8;
+ u32 vlan_pri : 3;
+ u32 vlan_cfi : 1;
+ u32 vlan_id : 12;
+#else
+ u32 vlan_id : 12;
+ u32 vlan_cfi : 1;
+ u32 vlan_pri : 3;
+ u32 hoplmt : 8;
+ u32 rsvd7 : 8;
+#endif
+ };
+ u32 dw7_value;
+ };
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 rsvd8 : 1;
+ u32 cos : 3;
+ u32 tclass : 8;
+ u32 flow_label : 20;
+#else
+ u32 flow_label : 20;
+ u32 tclass : 8;
+ u32 cos : 3;
+ u32 rsvd8 : 1;
+#endif
+ };
+ u32 dw8_value;
+ };
+
+ u32 sip_idx;
+} ub_create_utp_attr_s;
+
+/**@struct ub_cmd_body_utp_create
+* @brief utp cmd create body
+*/
+typedef struct ub_cmd_body_utp_create {
+ ub_create_utp_attr_s utp_attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_utp_create_s;
+
+/**@struct tag_ub_cmd_create_utp
+* @brief utp cmd create
+*/
+typedef struct tag_ub_cmd_create_utp {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_utp_create_s body;
+} ub_cmd_create_utp_s;
+
+/**@struct ub_cmd_body_utp_destroy
+* @brief utp cmd destroy body
+*/
+typedef struct ub_cmd_body_utp_destroy {
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_utp_destroy_s;
+
+/**@struct tag_ub_cmd_destroy_utp
+* @brief utp cmd destroy
+*/
+typedef struct tag_ub_cmd_destroy_utp {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_utp_destroy_s body;
+} ub_cmd_destroy_utp_s;
+
+/**@struct ub_cmd_body_utp_query
+* @brief utp cmd query body
+*/
+typedef struct ub_cmd_body_utp_query {
+ u32 func_id;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_utp_query_s;
+
+/**@struct tag_ub_cmd_query_utp
+* @brief utp cmd query
+*/
+typedef struct tag_ub_cmd_query_utp {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_utp_query_s body;
+} ub_cmd_query_utp_s;
+
+#define UB_DIP_CTX_SIZE 44
+/**
+ * @brief struct ub_dip_ctx_query
+ * @details used to query the dip context.
+ */
+struct ub_dip_ctx_query {
+ u8 ctx[UB_DIP_CTX_SIZE];
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd.h
new file mode 100644
index 000000000..a67ec0c46
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu vtp cmd define.
+ * Create: 2023-10-21
+ */
+
+#ifndef UB_NPU_VTP_CMD_H
+#define UB_NPU_VTP_CMD_H
+
+enum UB_CMD_VTP_TYPE {
+ UB_CMD_VTP_CREATE_CTX =
+ 0x1, /**< Create VTP Context @see > ub_cmd_vtp_create_s */
+ UB_CMD_VTP_RESTORE_CTX =
+ 0x2, /**< Restore VTP Context @see ub_cmd_vtp_restore_s> */
+ UB_CMD_VTP_QUERY_CTX =
+ 0x3, /**< Query VTP Context @see ub_cmd_vtp_query_s> */
+ UB_CMD_VTP_DESTORY_CTX =
+ 0x4, /**< Destory VTP Context @see ub_cmd_vtp_destory_s> */
+ UB_CMD_VTP_MODIFY_CTX =
+ 0x5, /**< Modify VTP Context @see ub_cmd_vtp_modify_s> */
+ UB_CMD_VTP_BATCH_MODIFY_CONTEXT =
+ 0x6, /**< Batch Modify VTP Context @see ub_cmd_vtp_batch_modify_s> */
+ UB_CMD_VTP_MAX
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd_defs.h
new file mode 100644
index 000000000..f682b2509
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_npu_vtp_cmd_defs.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Description: UB npu vtp cmd define.
+ * Create: 2023-10-21
+ */
+
+#ifndef UB_NPU_VTP_CMD_DEFS_H
+#define UB_NPU_VTP_CMD_DEFS_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_VTP_TYPE_TPG 0 /**< vtp type: TPG */
+#define UB_VTP_TYPE_TP 1 /**< vtp type: TP */
+#define UB_VTP_TYPE_DIP 2 /**< vtp type: DIP */
+#define UB_VTP_RESTORE_NUM_MAX 32 /**< vtp restore max number */
+
+#define UB_EID_SW_DW_LEN 4 /**< EID sw dw len: 4B */
+
+/**
+ * @brief struct ub_cmd_body_vtp_create/ub_cmd_body_vtp_create_s
+ * @details vtp create command struct body
+ */
+typedef struct ub_cmd_body_vtp_create {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 func_id : 16;
+ u32 type : 3;
+ u32 dw0_rsvd : 13;
+#else
+ u32 dw0_rsvd : 13;
+ u32 type : 3;
+ u32 func_id : 16;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 id;
+ u32 seid[UB_EID_SW_DW_LEN];
+ u32 deid[UB_EID_SW_DW_LEN];
+ u32 upi;
+ u32 resv[4];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_vtp_create_s;
+
+/**
+ * @brief struct ub_cmd_vtp_create/ub_cmd_vtp_create_s
+ * @details vtp create command struct
+ */
+typedef struct ub_cmd_vtp_create {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_vtp_create_s body;
+} ub_cmd_vtp_create_s;
+
+/**
+ * @brief struct ub_cmd_restore_vtp_node/ub_cmd_restore_vtp_node_s
+ * @details vtp restore node command struct
+ */
+typedef struct ub_cmd_restore_vtp_node {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 vtpn : 20;
+ u32 type : 3; /**< 0表示tpg;1表示tp;2表示dip */
+ u32 vld : 1; // 1表示VTP表项占用,0表示空闲
+ u32 destroy : 1; // 1表示删除VTP请求,0表示创建VTP请求
+ u32 rsvd1 : 7;
+#else
+ u32 rsvd1 : 7;
+ u32 destroy : 1; // 1表示删除VTP请求,0表示创建VTP请求
+ u32 vld : 1; // 1表示VTP表项占用,0表示空闲
+ u32 type : 3; /**< 0表示tpg;1表示tp;2表示dip */
+ u32 vtpn : 20;
+#endif
+ };
+ u32 dw0_value;
+ };
+ u32 id;
+ u32 seid[UB_EID_SW_DW_LEN];
+ u32 deid[UB_EID_SW_DW_LEN];
+ u32 rsvd2;
+} ub_cmd_restore_vtp_node_s;
+
+/**
+ * @brief struct ub_cmd_body_vtp_restore/ub_cmd_body_vtp_restore_s
+ * @details vtp restore command struct body
+ */
+typedef struct ub_cmd_body_vtp_restore {
+ u32 vfid;
+ u32 num; /**< 单个cmdq的ctx数量,最大32 */
+ ub_cmd_restore_vtp_node_s nodes[UB_VTP_RESTORE_NUM_MAX];
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_vtp_restore_s;
+
+/**
+ * @brief struct ub_cmd_vtp_restore/ub_cmd_vtp_restore_s
+ * @details vtp restore command struct
+ */
+typedef struct ub_cmd_vtp_restore {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_vtp_restore_s body;
+} ub_cmd_vtp_restore_s;
+
+/**
+ * @brief struct ub_cmd_body_vtp_query/ub_cmd_body_vtp_query_s
+ * @details vtp query commond struct body
+ */
+typedef struct ub_cmd_body_vtp_query {
+ u32 func_id;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_vtp_query_s;
+
+/**
+ * @brief struct ub_cmd_vtp_query/ub_cmd_vtp_query_s
+ * @details vtp query commond struct
+ */
+typedef struct ub_cmd_vtp_query {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_vtp_query_s body;
+} ub_cmd_vtp_query_s;
+
+/**
+ * @brief struct ub_cmd_body_vtp_destroy/ub_cmd_body_vtp_destroy_s
+ * @details vtp destory commond struct body
+ */
+typedef struct ub_cmd_body_vtp_destroy {
+ u32 func_id;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_vtp_destroy_s;
+
+/**
+ * @brief struct ub_cmd_vtp_destory/ub_cmd_vtp_destory_s
+ * @details vtp destory commond struct
+ */
+typedef struct ub_cmd_vtp_destory {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_vtp_destroy_s body;
+} ub_cmd_vtp_destory_s;
+
+/**
+ * @brief struct ub_cmd_body_vtp_modify/ub_cmd_body_vtp_modify_s
+ * @details vtp modify commond struct body
+ */
+typedef struct ub_cmd_body_vtp_modify {
+ u32 func_id;
+ u32 index;
+ u32 resv[5];
+ u32 ub_cmd_ext[0];
+} ub_cmd_body_vtp_modify_s;
+
+/**
+ * @brief struct ub_cmd_vtp_modify/ub_cmd_vtp_modify_s
+ * @details vtp modify commond struct
+ */
+typedef struct ub_cmd_vtp_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_vtp_modify_s body;
+} ub_cmd_vtp_modify_s;
+
+/**
+ * @brief struct ub_vtp_ctx_info_s
+ * @details used to query the vtp information, contains context fields.
+ */
+typedef struct {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 vld : 1;
+ u32 type : 3; /* 0 tpgn 1 tpn 2 utpn(面向UM模式非可靠、非连接的tp) */
+ u32 dw0_rsvd : 8;
+ u32 index : 20;
+#else
+ u32 index : 20;
+ u32 dw0_rsvd : 8;
+ u32 type : 3;
+ u32 vld : 1;
+#endif
+ };
+ u32 dw0;
+ };
+ u32 upi;
+ u32 seid[UB_EID_SW_DW_LEN];
+ u32 deid[UB_EID_SW_DW_LEN];
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 ta2tp_type : 4;
+ u32 rsvd : 28;
+#else
+ u32 rsvd : 28;
+ u32 ta2tp_type : 4;
+#endif
+ u32 rsvd_dw[21]; /* 对齐到128B */
+} ub_vtp_ctx_info_s;
+
+#define UB_VTP_CTX_SIZE sizeof(ub_vtp_ctx_info_s)
+/**
+ * @brief struct ub_vtp_ctx_query
+ * @details used to query the vtp context or batch modify
+ */
+struct ub_vtp_ctx_query {
+ u8 ctx[UB_VTP_CTX_SIZE];
+};
+
+/**
+ * @brief struct ub_vtp_batch_modify_attr/ub_vtp_batch_modify_attr_s
+ * @details vtp batch modify attr
+ */
+typedef struct ub_vtp_batch_modify_attr {
+ u32 offset;
+ u32 length;
+ struct ub_vtp_ctx_query vtp_ctx;
+} ub_vtp_batch_modify_attr_s;
+
+/**
+ * @brief struct ub_cmd_vtp_batch_modify_body/ub_cmd_vtp_batch_modify_body_s
+ * @details vtp batch modify struct body
+ */
+typedef struct ub_cmd_vtp_batch_modify_body {
+ u32 func_id;
+ ub_vtp_batch_modify_attr_s attr;
+ u32 rsvd[5]; /**< 预留 */
+ u32 ub_cmd_ext[0];
+} ub_cmd_vtp_batch_modify_body_s;
+
+/**
+ * @brief struct ub_cmd_vtp_batch_modify/ub_cmd_vtp_batch_modify_s
+ * @details vtp batch modify struct
+ */
+typedef struct ub_cmd_vtp_batch_modify {
+ ub_cmd_com_header_s header;
+ ub_cmd_vtp_batch_modify_body_s body;
+} ub_cmd_vtp_batch_modify_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_define.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_define.h
new file mode 100644
index 000000000..a816cbbdd
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_define.h
@@ -0,0 +1,3007 @@
+/*
+ * 版权所有 (c) 华为技术有限公司 2024.
+ * 注意:本头文件由工具自动生成,请勿手动修改
+ */
+
+#ifndef _UB_TA_WQE_DEFINE_H_
+#define _UB_TA_WQE_DEFINE_H_
+
+#include "base_type.h"
+#include "ub_dw_index.h"
+
+#define UB_MAX_INDEX_WQE_CNT (8)
+
+typedef union tag_ubg_jfs_wqe_write_udf {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_index : 16; /* 【微码】用于david直通或主机侧多路场景,查询mptc获取DATA DMA的data fe, 用于数据面DMA; */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 dcs_index : 16;
+#endif
+
+ /* dw8 */
+ u32 rmt_addr_h; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw9 */
+ u32 rmt_addr_l; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* 0 */
+ u32 rmt_tokenid : 20; /* 【微码定义】远端tokenid,write和read类语义有效 */
+ u32 tp_idx : 8; /* 【微码定义】david直通/数据分离场景write/write imme报文使用此域段用于指定hash选择tpn,用于随路排空。Read报文可以使用此域段指定路径读报文。 */
+#else
+ u32 tp_idx : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 【微码定义】对端token value */
+
+ /* dw12~14 */
+ u32 rsvd_639_544[3]; /* */
+
+ /* dw15 */
+ u32 udf_hdr; /* 【微码】UDF hdr,用于inline reduce */
+
+ /* dw16~31 */
+ u32 inline_data_or_sge[16]; /* data或sge */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_write_udf_u;
+
+typedef union tag_ubg_jfs_wqe_ctrl_db {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1;
+ u32 ctrl_sl : 2;
+ u32 csl : 2;
+ u32 dif_sl : 3;
+ u32 cr : 1;
+ u32 df : 1;
+ u32 va : 1;
+ u32 tsl : 5;
+ u32 cf : 1;
+ u32 wf : 1;
+ u32 piv : 1;
+ u32 db_en : 1;
+ u32 fde : 1;
+ u32 f : 1;
+ u32 drv_sl : 2;
+ u32 bdsl : 8;
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4;
+ u32 vf_round : 8;
+ u32 mask_pi : 20;
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5;
+ u32 cos : 3;
+ u32 c : 1;
+ u32 n : 1;
+ u32 ctx_size : 2;
+ u32 xid : 20;
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4;
+ u32 db_udf : 12;
+ u32 pi : 16;
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+ } bs;
+
+ u32 dw_data[4];
+} ubg_jfs_wqe_ctrl_db_u;
+
+typedef union tag_ubg_jfs_wqe_task_com {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1;
+ u32 dcs_en : 1;
+ u32 cqe : 1;
+ u32 optype : 5;
+ u32 co : 1;
+ u32 eo : 2;
+ u32 fence : 1;
+ u32 sjt : 2;
+ u32 vtp_type : 2;
+ u32 eid_vld : 1;
+ u32 tk_vld : 1;
+ u32 ack_vld : 1;
+ u32 udf_vld : 1;
+ u32 fix_tp_en : 1;
+ u32 rsvd_874_873 : 2;
+ u32 head : 1;
+ u32 jetty_round : 8;
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw1 */
+ u32 data_len;
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8;
+ u32 sv : 1;
+ u32 rsvd_822_822 : 1;
+ u32 djt : 2;
+ u32 vtpn : 20;
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_index : 16;
+ u32 ssn : 16;
+#else
+ u32 ssn : 16;
+ u32 dcs_index : 16;
+#endif
+
+ /* dw4 */
+ u32 rmt_addr_h;
+
+ /* dw5 */
+ u32 rmt_addr_l;
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4;
+ u32 rmt_tokenid : 20;
+ u32 tp_idx : 8;
+#else
+ u32 tp_idx : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw7 */
+ u32 token_value;
+ } bs;
+
+ u32 dw_data[8];
+} ubg_jfs_wqe_task_com_u;
+
+typedef union tag_ubg_jfs_wqe_write {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_index : 16; /* 【微码】用于david直通或主机侧多路场景,查询mptc获取DATA DMA的data fe, 用于数据面DMA; */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 dcs_index : 16;
+#endif
+
+ /* dw8 */
+ u32 rmt_addr_h; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw9 */
+ u32 rmt_addr_l; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* 0 */
+ u32 rmt_tokenid : 20; /* 【微码定义】远端tokenid,write和read类语义有效 */
+ u32 tp_idx : 8; /* 【微码定义】david直通/数据分离场景write/write imme报文使用此域段用于指定hash选择tpn,用于随路排空。Read报文可以使用此域段指定路径读报文。 */
+#else
+ u32 tp_idx : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 【微码定义】对端token value */
+
+ /* dw12~31 */
+ u32 inline_data_or_sge[20]; /* inline数据或者sge */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_write_u;
+
+typedef union tag_ubg_jfs_wqe_write_imme {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_index : 16; /* 【微码】用于david直通或主机侧多路场景,查询mptc获取DATA DMA的data fe, 用于数据面DMA; */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 dcs_index : 16;
+#endif
+
+ /* dw8 */
+ u32 rmt_addr_h; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw9 */
+ u32 rmt_addr_l; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* 0 */
+ u32 rmt_tokenid : 20; /* 【微码定义】远端tokenid,write和read类语义有效 */
+ u32 tp_idx : 8; /* 【微码定义】david直通/数据分离场景write/write imme报文使用此域段用于指定hash选择tpn,用于随路排空。Read报文可以使用此域段指定路径读报文。 */
+#else
+ u32 tp_idx : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 【微码定义】对端token value */
+
+ /* dw12 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_639_628 : 12; /* 0 */
+ u32 djtn : 20; /* 目的jetty号,用于填充JETTY_ETAH */
+#else
+ u32 djtn : 20;
+ u32 rsvd_639_628 : 12;
+#endif
+
+ /* dw13 */
+ u32 imme_data_h; /* 立即数 */
+
+ /* dw14 */
+ u32 imme_data_l; /* 立即数 */
+
+ /* dw15 */
+ u32 imme_token_value; /* jfr对应的token value */
+
+ /* dw16~18 */
+ u32 rsvd_511_416[3]; /* */
+
+ /* dw19 */
+ u32 udf_hdr; /* udf_vld使能时,用于填充报文头中的UDF */
+
+ /* dw20~31 */
+ u32 inline_data_or_sge[12]; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_write_imme_u;
+
+typedef union tag_ubg_jfs_wqe_write_notify {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_799_784 : 16; /* */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 rsvd_799_784 : 16;
+#endif
+
+ /* dw8 */
+ u32 rmt_addr_h; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw9 */
+ u32 rmt_addr_l; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* 0 */
+ u32 rmt_tokenid : 20; /* 【微码定义】远端tokenid,write和read类语义有效 */
+ u32 rsvd_679_672 : 8; /* */
+#else
+ u32 rsvd_679_672 : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 【微码定义】对端token value */
+
+ /* dw12 */
+ u32 notify_va_h; /* notify语义notify地址,用于填充ta层报文头 */
+
+ /* dw13 */
+ u32 notify_va_l; /* notify语义notify地址,用于填充ta层报文头 */
+
+ /* dw14 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_575_572 : 4; /* */
+ u32 notify_token_id : 20; /* notify对应的tokenid,用于填充ta层报文头 */
+ u32 rsvd_551_544 : 8; /* */
+#else
+ u32 rsvd_551_544 : 8;
+ u32 notify_token_id : 20;
+ u32 rsvd_575_572 : 4;
+#endif
+
+ /* dw15 */
+ u32 notify_token_value; /* notify语义tokenValue,用于填充ta层报文头 */
+
+ /* dw16 */
+ u32 notify_data_h; /* notify语义数据 */
+
+ /* dw17 */
+ u32 notify_data_l; /* notify语义数据 */
+
+ /* dw18~19 */
+ u32 rsvd_447_384[2]; /* */
+
+ /* dw20~31 */
+ u32 inline_data_or_sge[12]; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_write_notify_u;
+
+typedef union tag_ubg_jfs_wqe_write_flush {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_index : 16; /* 【微码】用于david直通或主机侧多路场景,查询mptc获取DATA DMA的data fe, 用于数据面DMA; */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 dcs_index : 16;
+#endif
+
+ /* dw8~31 */
+ u32 rsvd_767_0[24]; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_write_flush_u;
+
+typedef union tag_ubg_jfs_wqe_read {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_index : 16; /* 【微码】用于david直通或主机侧多路场景,查询mptc获取DATA DMA的data fe, 用于数据面DMA; */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 dcs_index : 16;
+#endif
+
+ /* dw8 */
+ u32 rmt_addr_h; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw9 */
+ u32 rmt_addr_l; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* 0 */
+ u32 rmt_tokenid : 20; /* 【微码定义】远端tokenid,write和read类语义有效 */
+ u32 tp_idx : 8; /* 【微码定义】david直通/数据分离场景write/write imme报文使用此域段用于指定hash选择tpn,用于随路排空。Read报文可以使用此域段指定路径读报文。 */
+#else
+ u32 tp_idx : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 【微码定义】对端token value */
+
+ /* dw12~31 */
+ u32 for_sge[20]; /* SGE信息,可变,最大支持32个SGE. */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_read_u;
+
+typedef union tag_ubg_jfs_wqe_atomic {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_799_784 : 16; /* */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 rsvd_799_784 : 16;
+#endif
+
+ /* dw8 */
+ u32 rmt_addr_h; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw9 */
+ u32 rmt_addr_l; /* 【微码】远端访问地址,用于write/read类操作; */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* */
+ u32 rmt_tokenid : 20; /* 【微码定义】远端tokenid,write和read类语义有效 */
+ u32 rsvd_679_672 : 8; /* */
+#else
+ u32 rsvd_679_672 : 8;
+ u32 rmt_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 【微码定义】对端token value */
+
+ /* dw12 */
+ u32 atomic_data_add_or_cmp_h; /* 用于填充TA层报文头 */
+
+ /* dw13 */
+ u32 atomic_data_add_or_cmp_l; /* 用于填充TA层报文头 */
+
+ /* dw14 */
+ u32 atomic_data_swp_or_msk_h; /* 用于填充TA层报文头 */
+
+ /* dw15 */
+ u32 atomic_data_swp_or_msk_l; /* 用于填充TA层报文头 */
+
+ /* dw16~31 */
+ u32 for_sge[16]; /* sge */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_atomic_u;
+
+typedef union tag_ubg_jfs_wqe_send {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 fis : 1; /* 【微码】fast inline send标记,仅用于快路径场景。 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 fis : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_799_784 : 16; /* */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 rsvd_799_784 : 16;
+#endif
+
+ /* dw8 */
+ u32 fast_inline_data; /* 【微码】fast inline data,压缩send 2B的wqe为64B后,将inline data 拷贝一份放到64B内,最大只支持4B inline,此时没有BDSL */
+
+ /* dw9~10 */
+ u32 rsvd_735_672[2]; /* */
+
+ /* dw11 */
+ u32 token_value; /* 对端tokenValue */
+
+ /* dw12 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_639_628 : 12; /* */
+ u32 djtn : 20; /* 目的jetty号 */
+#else
+ u32 djtn : 20;
+ u32 rsvd_639_628 : 12;
+#endif
+
+ /* dw13~14 */
+ u32 rsvd_607_528_p1[2]; /* */
+
+ /* dw15 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_607_528_p2 : 16; /* */
+ u32 drv_timestamp : 16; /* 【微码】驱动侧生成的时间戳,用于E2E时间计算 */
+#else
+ u32 drv_timestamp : 16;
+ u32 rsvd_607_528_p2 : 16;
+#endif
+
+ /* dw16~31 */
+ u32 inline_data_or_sge[16]; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_send_u;
+
+typedef union tag_ubg_jfs_wqe_send_imme {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_799_784 : 16; /* 【微码】用于david直通或主机侧多路场景,查询mptc获取DATA DMA的data fe, 用于数据面DMA; */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 rsvd_799_784 : 16;
+#endif
+
+ /* dw8~10 */
+ u32 rsvd_767_672[3]; /* */
+
+ /* dw11 */
+ u32 token_value; /* 对端tokenValue */
+
+ /* dw12 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_639_628 : 12; /* */
+ u32 djtn : 20; /* 目的jetty号,用于填充报文头 */
+#else
+ u32 djtn : 20;
+ u32 rsvd_639_628 : 12;
+#endif
+
+ /* dw13 */
+ u32 imme_data_h; /* 立即数,用于填充报文头 */
+
+ /* dw14 */
+ u32 imme_data_l; /* 立即数,用于填充报文头 */
+
+ /* dw15 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_543_528 : 16; /* */
+ u32 drv_timestamp : 16; /* 驱动侧时间戳,预留用于时延打点 */
+#else
+ u32 drv_timestamp : 16;
+ u32 rsvd_543_528 : 16;
+#endif
+
+ /* dw16~31 */
+ u32 inline_data_or_sge[16]; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_send_imme_u;
+
+typedef union tag_ubg_jfs_wqe_send_invalid {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 mask_pi : 20; /* 【SM INFRA】SM使用mask PI(计算实际qsize对应的ci)生成dwqe地址用于写入SMMC,
+ 计算方法为:mask_pi == driver.PI & (2^sq_size - 1) & 0xffff;仅directWQE时有效。 */
+#else
+ u32 mask_pi : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 service_type : 5; /* 【DoorBell】[仅direct wqe有效]固定填0x2, 注意:填写dwqe时,service_type[4:3]填写ddb=2,对应的service_type[2:0]填0. */
+ u32 cos : 3; /* 【DoorBell】[仅direct wqe有效]芯片cos,初始化jetty时指定,按实际填写; */
+ u32 c : 1; /* 【DoorBell】[仅direct wqe有效]填0 */
+ u32 n : 1; /* 【DoorBell】[仅direct wqe有效]db是否走控制mq, jetty doorbell固定填0x0; */
+ u32 ctx_size : 2; /* 【DoorBell】[仅direct wqe有效]代表ctx大小, jetty doorbell固定填0x1; */
+ u32 xid : 20; /* 【DoorBell】[仅direct wqe有效]jetty number,填qpn */
+#else
+ u32 xid : 20;
+ u32 ctx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 service_type : 5;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4; /* 【DoorBell】[仅direct wqe有效]queue_id,用于芯片索引,默认填0。 */
+ u32 db_udf : 12; /* 【Doorbell】Doorbell的udf,仅direct wqe有效。 */
+ u32 pi : 16; /* 【DoorBell】[仅direct wqe有效]完整PI,为16bit. */
+#else
+ u32 pi : 16;
+ u32 db_udf : 12;
+ u32 queue_id : 4;
+#endif
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 vtpn : 20; /* 【微码】vtpn序列号 */
+#else
+ u32 vtpn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_799_784 : 16; /* */
+ u32 ssn : 16; /* 【微码】【pSM】TA层切片ssn,由驱动从初始值开始计算,根据slice size=64KB进行切片计算,每个切片,ssn+1; */
+#else
+ u32 ssn : 16;
+ u32 rsvd_799_784 : 16;
+#endif
+
+ /* dw8~9 */
+ u32 rsvd_767_700_p1[2]; /* */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_767_700_p2 : 4; /* */
+ u32 invalid_tokenid : 20; /* invalid tokenid用于填充报文头 */
+ u32 rsvd_679_672 : 8; /* */
+#else
+ u32 rsvd_679_672 : 8;
+ u32 invalid_tokenid : 20;
+ u32 rsvd_767_700_p2 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* 用于JFR校验token value */
+
+ /* dw12 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_639_628 : 12; /* */
+ u32 djtn : 20; /* 目的jetty号,用于填充报文头; */
+#else
+ u32 djtn : 20;
+ u32 rsvd_639_628 : 12;
+#endif
+
+ /* dw13~14 */
+ u32 rsvd_607_544[2]; /* */
+
+ /* dw15 */
+ u32 invalid_token_value; /* inline对应MR的token Value */
+
+ /* dw16~31 */
+ u32 inline_data_or_sge[16]; /* 数据或sge */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfs_wqe_send_invalid_u;
+
+typedef union tag_ubg_jfrc_wqe {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 【RDMA FS】owner bit,驱动填写(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+#else
+ u32 bdsl : 8;
+ u32 drv_sl : 2;
+ u32 f : 1;
+ u32 fde : 1;
+ u32 db_en : 1;
+ u32 piv : 1;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 dif_sl : 3;
+ u32 csl : 2;
+ u32 ctrl_sl : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 rsvd_979_896_p1 : 20; /* */
+#else
+ u32 rsvd_979_896_p1 : 20;
+ u32 vf_round : 8;
+ u32 cl : 4;
+#endif
+
+ /* dw2~3 */
+ u32 rsvd_979_896_p2[2]; /* */
+
+ /* dw4 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记data-control separation是否使能,驱动根据wqe关联的segment是否使能数控分离置位。 */
+ u32 cqe : 1; /* 【微码】正常流程标识该wqe是否需要上送cqe;flush流程不看该标记,微码强制产生cqe, 该标记当前未使用。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_FLUSH_DMA, 数控分离排空写操作
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 fix_tp_en : 1; /* 【微码】fix_tp_en=1时,微码使用wqe.hinit来作为hash值选择对应tpg中的tpn. */
+ u32 rsvd_874_873 : 2; /* 0 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+#else
+ u32 jetty_round : 8;
+ u32 head : 1;
+ u32 rsvd_874_873 : 2;
+ u32 fix_tp_en : 1;
+ u32 udf_vld : 1;
+ u32 ack_vld : 1;
+ u32 tk_vld : 1;
+ u32 eid_vld : 1;
+ u32 vtp_type : 2;
+ u32 sjt : 2;
+ u32 fence : 1;
+ u32 eo : 2;
+ u32 co : 1;
+ u32 optype : 5;
+ u32 cqe : 1;
+ u32 dcs_en : 1;
+ u32 se : 1;
+#endif
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR; */
+ u32 sv : 1; /* 【微码】same vtp,标识两个wqe使用了相同vtp,用于TATX包率场景loop加速; */
+ u32 rsvd_822_822 : 1; /* 0 */
+ u32 djt : 2; /* 【微码】目的jetty 类型,参考UB协议,定义如下:
+ 0:表示Destination JFR。
+ 1:表示Destination JETTY。
+ 2:表示Destination JETTYGROUP。 */
+ u32 tpgn : 20; /* 【微码】用于查询TPGC获取tp相关信息如cos/db_udf等; */
+#else
+ u32 tpgn : 20;
+ u32 djt : 2;
+ u32 rsvd_822_822 : 1;
+ u32 sv : 1;
+ u32 hint : 8;
+#endif
+
+ /* dw7 */
+ u32 udf_hdr; /* UDF值,用于填充UDF header */
+
+ /* dw8 */
+ u32 local_data_addr_h; /* read/atomic操作地址 */
+
+ /* dw9 */
+ u32 local_data_addr_l; /* read/atomic操作地址 */
+
+ /* dw10 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_703_700 : 4; /* */
+ u32 local_tokenid : 20; /* tokenid */
+ u32 rsvd_679_672 : 8; /* */
+#else
+ u32 rsvd_679_672 : 8;
+ u32 local_tokenid : 20;
+ u32 rsvd_703_700 : 4;
+#endif
+
+ /* dw11 */
+ u32 token_value; /* tokenvalue */
+
+ /* dw12 */
+ u32 atomic_data_or_add_or_cmp_h; /* atomic数据 */
+
+ /* dw13 */
+ u32 atomic_data_or_add_or_cmp_l; /* atomic数据 */
+
+ /* dw14 */
+ u32 atomic_data_swp_or_msk_h; /* atomic数据 */
+
+ /* dw15 */
+ u32 atomic_data_swp_or_msk_l; /* atomic数据 */
+
+ /* dw16 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_511_500 : 12; /* */
+ u32 sjtn : 20; /* 来自于报文头,src jetty号 */
+#else
+ u32 sjtn : 20;
+ u32 rsvd_511_500 : 12;
+#endif
+
+ /* dw17 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 taid : 16; /* read/atomic报文taidetah中携带的TAID */
+ u32 ssn : 16; /* 来自于报文头,ssn */
+#else
+ u32 ssn : 16;
+ u32 taid : 16;
+#endif
+
+ /* dw18 */
+ u32 offset; /* 来源于报文头,表示taid对应wqe的偏移值,单位固定为1KB */
+
+ /* dw19 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_415_404 : 12; /* */
+ u32 tpn : 20; /* 用于发送response或taack的tpn. */
+#else
+ u32 tpn : 20;
+ u32 rsvd_415_404 : 12;
+#endif
+
+ /* dw20~21 */
+ u32 rsvd_383_320[2]; /* */
+
+ /* dw22 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsp_st : 3; /* 用于填充TA层报文头 */
+ u32 rsp_info : 5; /* 用于填充TA层报文头 */
+ u32 limit_color : 2; /* 用于整机限速标记 */
+ u32 rsvd_309_288 : 22; /* */
+#else
+ u32 rsvd_309_288 : 22;
+ u32 limit_color : 2;
+ u32 rsp_info : 5;
+ u32 rsp_st : 3;
+#endif
+
+ /* dw23 */
+ u32 upi; /* 用于填充报文头 */
+
+ /* dw24~27 */
+ u32 seid[4]; /* 用于填充报文头 */
+
+ /* dw28~31 */
+ u32 deid[4]; /* 用于填充报文头 */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfrc_wqe_u;
+
+typedef union tag_ubg_jfc_cqe {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /* 合法值:CQE.owner = (CQC.cq_pi >> CQC.cq_size)&0x1 */
+ u32 size : 2; /* 固定填3,代表64B CQE */
+ u32 s_r : 1; /* 1'b1: 发送cqe,1'b0: 接收cqe:
+ enum UB_CQE_TYPE_E {
+ UB_RQ_CQE = 0, recieve queue element: 0
+ UB_SQ_CQE send queue element: 1
+ } */
+ u32 status : 8; /* 0x00 — OK(no error);
+ 0x01 — Unsupported Opcode
+ 0x02 — Local Operation Error
+ 0x03 — Remote Operation Error
+ 0x04 — Transaction Retry Counter Exceeded
+ 0x05 — Transaction ACK Timeout
+ 0x06 — Jetty Work Request Flushed(非异常)
+ Others: Reserved
+ 备注:JFS 场景1815E根据非零判断后,不再做硬件加速;JFR 将不将队列置错,透传错误给微码。 */
+ u32 tpgn : 20; /* tpg number,当前未使用。 */
+#else
+ u32 tpgn : 20;
+ u32 status : 8;
+ u32 s_r : 1;
+ u32 size : 2;
+ u32 o : 1;
+#endif
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 optype : 5; /* enum UB_CQE_RQ_OPTYPE_E {
+ UB_CQE_RQ_OPTYPE_WRITE_IMMEDIATE = 0, optype: write with immediate data
+ UB_CQE_RQ_OPTYPE_SEND, optype: send
+ UB_CQE_RQ_OPTYPE_SEND_IMMEDIATE, optype: send with immediate data
+ UB_CQE_RQ_OPTYPE_SEND_INVALIDATE, optype: send with invalidate
+ UB_CQE_RQ_OPTYPE_WRITE, optype: write
+ UB_CQE_RQ_OPTYPE_READ, optype: read
+ UB_CQE_RQ_OPTYPE_FLUSH_WRITE 指示CQE是David HBM直通场景按需排空WR
+ } */
+ u32 ts : 1; /* 标识ee_timestamp是否有效,微码透传 */
+ u32 inline_flag : 1; /* 指示inline data是否有效(注意:inline data最大支持4Bytes) */
+ u32 flush_done : 1; /* 标识flush_done,发送CQE用于标识硬件部分flush完毕, 接收CQE用于标识下软件flush边界;
+ 备注:1815E收到该标记后,后续此队列的所有CQE均送微码处理,不再做硬件加速。 */
+ u32 fake : 1; /* fake标记,标识当前cqe为无中生有,用于产生flush done CQE;
+ 注:1815E处理同flush done。 */
+ u32 rsvd_470_464 : 7; /* */
+ u32 wqebb_idx_or_ci : 16; /* s_r=1时,代表发送侧cqe,此时代表发送侧wqebb_cnt即ci;s_r=0时,代表接收侧cqe,此时代表wqebb_idx
+ (非container index,注意RQ_RXDMA时,微码需要使用container index) */
+#else
+ u32 wqebb_idx_or_ci : 16;
+ u32 rsvd_470_464 : 7;
+ u32 fake : 1;
+ u32 flush_done : 1;
+ u32 inline_flag : 1;
+ u32 ts : 1;
+ u32 optype : 5;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_447_445 : 3; /* */
+ u32 rtt_vld : 1; /* 标识当前cqe是否携带ta_rtt值,ta rtt定义为微码取wqe到ack回来的芯片时间差,以us为单位。 */
+ u32 sub_status : 8; /* CQE的完成子状态, 参考UB协议。
+ Status=Local Operation Error时,Sub-Status含义如下:
+ 0x01 — Local Length Error。
+ 0x02 — Local Access Error。
+ 0x03 — Remote Response Length Error。
+ 0x04 — Local Data Poison。
+ 0x05— Flush WR Error (DavidHBM直通按需排空WR执行失败)
+ Status=Remote Operation Error时,Sub-Status含义如下:
+ 0x01 — Remote Unsupported Request。
+ 0x02 — Remote Access Abort。
+ 0x04 — Remote Data Poison。
+ 其他错误场景Status非零场景时,Sub-Status此时无含义。默认应赋值为0。 */
+ u32 remote_jetty : 20; /* 源端jetty号,取自报文头src jetty */
+#else
+ u32 remote_jetty : 20;
+ u32 sub_status : 8;
+ u32 rtt_vld : 1;
+ u32 rsvd_447_445 : 3;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 dcs_idx : 8; /* 用于数控分离场景,上送tpn[7:0]给业务软件如HCCL,用于后续配合随路排空。 */
+ u32 rsvd_407_404 : 4; /* */
+ u32 local_jetty : 20; /* 接收侧:用于jetty类型接收,填写网络报文携带的jetty号;请求侧:发送请求的jetty号; */
+#else
+ u32 local_jetty : 20;
+ u32 rsvd_407_404 : 4;
+ u32 dcs_idx : 8;
+#endif
+
+ /* dw4 */
+ u32 msg_length; /* 消息长度,单位为Byte */
+
+ /* dw5 */
+ u32 usr_data_h; /* 自定义数据,当前未使用,15E取[19:0]作为global_qpn_mode0; */
+
+ /* dw6 */
+ u32 usr_data_l; /* 自定义数据,当前未使用,15E取[19:0]作为global_qpn_mode1; */
+
+ /* dw7~10 */
+ u32 rmt_eid0[4]; /* 报文中携带的seid */
+
+ /* dw11 */
+ u32 imme_data_h; /* 报文中携带的立即数高32bit */
+
+ /* dw12 */
+ u32 imme_data_l; /* 报文中携带的立即数低32bit */
+
+ /* dw13 */
+ u32 inline_data; /* inline数据,在inline_flag=1时有效; */
+
+ /* dw14 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 drv_timestamp : 16; /* 用于携带网络侧携带的时间戳(E2E时延DFX打点),RQ CQE有效。 */
+ u32 ta_rtt : 16; /* ta rtt,用于记录TA wqe从TA层调度出去到TAACK报文回来时消耗的时间,以us为单位 */
+#else
+ u32 ta_rtt : 16;
+ u32 drv_timestamp : 16;
+#endif
+
+ /* dw15 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 jetty_round : 8; /* jetty round,接收方向:从JFR contex中获取,用于驱动校验是否出现jetty重用;请求方向:从jetty context中获取,用于校验jetty重用。 */
+ u32 rsvd_23_20 : 4; /* */
+ u32 jfrn : 20; /* jfr number:来自于网络报文(注意:jetty / jetty group场景,由微码转换得到真实JFRN填入CQE)。 */
+#else
+ u32 jfrn : 20;
+ u32 rsvd_23_20 : 4;
+ u32 jetty_round : 8;
+#endif
+ } bs;
+
+ u32 dw_data[16];
+} ubg_jfc_cqe_u;
+
+typedef union tag_ubg_index_wqe {
+ struct {
+ /* dw0 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 vld : 1; /* 【pSM FS】wqe_idx有效标记 */
+ u32 udf : 15; /* 【pSM FS】用户自定义数据,可透传到微码 */
+ u32 index : 16; /* 【pSM FS】wqe_idx值,即container wqebb_index.(注意,这里是WQEBB索引,不是container索引) */
+#else
+ u32 index : 16;
+ u32 udf : 15;
+ u32 vld : 1;
+#endif
+ } bs;
+
+ u32 dw_data[1];
+} ubg_index_wqe_u;
+
+typedef struct tag_ubg_jfr_index_wqe {
+ /* dw0~7 */
+ ubg_index_wqe_u index_wqe[UB_MAX_INDEX_WQE_CNT]; /* */
+} ubg_jfr_index_wqe_s;
+
+typedef union tag_ubg_jfr_rq_wqe {
+ struct {
+ /* dw0 */
+ u32 va_h; /* 地址高位 */
+
+ /* dw1 */
+ u32 va_l; /* 地址低位 */
+
+ /* dw2 */
+ u32 len; /* 长度 */
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 l : 1; /* Last SGE. 指示当前SGE是否为WQE的最后一个SGE:0: 不是最后一个SGE,1: 当前SGE是WQE的最后一个SGE */
+ u32 e : 1; /* RDMA Engine不支持扩展SGE,所以本域段必须填0. */
+ u32 rsvd_925_924 : 2; /* */
+ u32 key : 28; /* key[27:8]为tokenid,其他域段rsvd,填0. */
+#else
+ u32 key : 28;
+ u32 rsvd_925_924 : 2;
+ u32 e : 1;
+ u32 l : 1;
+#endif
+
+ /* dw4~29 */
+ u32 rsvd_895_48_p1[26]; /* */
+
+ /* dw30 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_895_48_p2 : 16; /* */
+ u32 next_wqe_idx : 16; /* link到下一个wqebb(JFR SRQ模式,不使用link wqe(硬件约束占位),串链使用RQE中预留1个SGE位置实现,硬件不访问。 */
+#else
+ u32 next_wqe_idx : 16;
+ u32 rsvd_895_48_p2 : 16;
+#endif
+
+ /* dw31 */
+ u32 rsvd_31_0; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfr_rq_wqe_u;
+
+typedef union tag_ubg_jfr_link_wqe {
+ struct {
+ /* dw0 */
+ u32 rsvd_1023_972_p1; /* */
+
+ /* dw1 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_1023_972_p2 : 20; /* */
+ u32 vld : 1; /* */
+ u32 rsvd_970_944_p1 : 11; /* */
+#else
+ u32 rsvd_970_944_p1 : 11;
+ u32 vld : 1;
+ u32 rsvd_1023_972_p2 : 20;
+#endif
+
+ /* dw2 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_970_944_p2 : 16; /* */
+ u32 next_idx : 16; /* */
+#else
+ u32 next_idx : 16;
+ u32 rsvd_970_944_p2 : 16;
+#endif
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_927_927 : 1; /* */
+ u32 lk : 1; /* */
+ u32 rsvd_925_0_p1 : 30; /* */
+#else
+ u32 rsvd_925_0_p1 : 30;
+ u32 lk : 1;
+ u32 rsvd_927_927 : 1;
+#endif
+
+ /* dw4~31 */
+ u32 rsvd_925_0_p2[28]; /* */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_jfr_link_wqe_u;
+
+typedef union tag_ubg_sge {
+ struct {
+ /* dw0 */
+ u32 addr_h; /* 虚拟地址高32bit */
+
+ /* dw1 */
+ u32 addr_l; /* 虚拟地址低32bit */
+
+ /* dw2 */
+ u32 length; /* 长度 */
+
+ /* dw3 */
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd_31_28 : 4; /* */
+ u32 tokenid : 20; /* tokenID */
+ u32 rsvd_7_0 : 8; /* */
+#else
+ u32 rsvd_7_0 : 8;
+ u32 tokenid : 20;
+ u32 rsvd_31_28 : 4;
+#endif
+ } bs;
+
+ u32 dw_data[4];
+} ubg_sge_u;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_format.h
new file mode 100644
index 000000000..8b9b007ea
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_ta_wqe_format.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2015-2021. All rights reserved.
+ * File Name : ub_ta_wqe_format.h
+ * Version : 1.0
+ * Description : 1825v100 ta wqe format
+ * History : 2024/12/16
+ */
+
+#ifndef UB_TA_WQE_FORMAT_H
+#define UB_TA_WQE_FORMAT_H
+
+#include "ub_ta_wqe_define.h"
+
+typedef struct tag_ubg_jfs_wqe_common_s {
+ ubg_jfs_wqe_ctrl_db_u ctrl_db; /* wqe控制信息8B+doorbell 8B,共16B */
+ ubg_jfs_wqe_task_com_u task_com; /* wqe任务段common部分,32B */
+} ubg_jfs_wqe_common_s;
+
+typedef union tag_ubg_ta_wqe_u {
+ ubg_jfs_wqe_common_s com; /* WQE CTRL+DB+任务段common部分,8+8+32=48 B */
+ ubg_jfs_wqe_write_u write;
+ ubg_jfs_wqe_write_udf_u write_udf;
+ ubg_jfs_wqe_write_flush_u write_flush;
+ ubg_jfs_wqe_write_imme_u write_imme;
+ ubg_jfs_wqe_write_notify_u write_notify;
+ ubg_jfs_wqe_read_u read;
+ ubg_jfs_wqe_atomic_u atomic;
+ ubg_jfs_wqe_send_u send;
+ ubg_jfs_wqe_send_imme_u send_imme;
+ ubg_jfs_wqe_send_invalid_u send_inv;
+ ubg_jfrc_wqe_u resp;
+} ubg_ta_wqe_u;
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_define.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_define.h
new file mode 100644
index 000000000..45ddb5243
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_define.h
@@ -0,0 +1,349 @@
+/*
+ * 版权所有 (c) 华为技术有限公司 2024.
+ * 注意:本头文件由工具自动生成,请勿手动修改
+ */
+
+#ifndef _UB_TP_WQE_DEFINE_H_
+#define _UB_TP_WQE_DEFINE_H_
+
+#include "base_type.h"
+#include "ub_dw_index.h"
+
+typedef union tag_ub_tp_wqe_ctrl_sec {
+ struct {
+ /* dw0 */
+ u32 o : 1;
+ u32 ctrl_sl : 2;
+ u32 csl : 2;
+ u32 dif_sl : 3;
+ u32 cr : 1;
+ u32 df : 1;
+ u32 va : 1;
+ u32 tsl : 5;
+ u32 cf : 1;
+ u32 wf : 1;
+ u32 piv : 1;
+ u32 db_en : 1;
+ u32 fde : 1;
+ u32 f : 1;
+ u32 drv_sl : 2;
+ u32 bdsl : 8;
+
+ /* dw1 */
+ u32 cl : 4;
+ u32 vf_round : 8;
+ u32 rsvd_979_977 : 3;
+ u32 ts_en : 1;
+ u32 build_timestamp : 16;
+
+ /* dw2 */
+ u32 fde_vfid : 12;
+ u32 fde_jetty_id : 20;
+
+ /* dw3 */
+ u32 rsvd_927_912 : 16;
+ u32 fde_jetty_ci : 16;
+ } bs;
+
+ u32 dw_data[4];
+} ub_tp_wqe_ctrl_sec_u;
+
+typedef union tag_ub_tp_wqe_task_com {
+ struct {
+ /* dw0 */
+ u32 se : 1;
+ u32 dcs_en : 1;
+ u32 ack_flush : 1;
+ u32 optype : 5;
+ u32 co : 1;
+ u32 eo : 2;
+ u32 fence : 1;
+ u32 sjt : 2;
+ u32 vtp_type : 2;
+ u32 eid_vld : 1;
+ u32 tk_vld : 1;
+ u32 ack_vld : 1;
+ u32 udf_vld : 1;
+ u32 rsvd_875_874 : 2;
+ u32 dma_mp : 1;
+ u32 head : 1;
+ u32 jetty_round : 8;
+
+ /* dw1 */
+ u32 data_len;
+
+ /* dw2 */
+ u32 hint : 8;
+ u32 rsvd_823_822 : 2;
+ u32 djt : 2;
+ u32 vtpn : 20;
+
+ /* dw3 */
+ u32 udf_hdr;
+
+ /* dw4 */
+ u32 local_or_rmt_data_addr_h;
+
+ /* dw5 */
+ u32 local_or_rmt_data_addr_l;
+
+ /* dw6 */
+ u32 rsvd_703_700 : 4;
+ u32 local_or_rmt_tokenid : 20;
+ u32 rsvd_679_672 : 8;
+
+ /* dw7 */
+ u32 token_value;
+
+ /* dw8 */
+ u32 imme_data_h_or_notify_va_h_or_aotmic_add_cmp_data_h;
+
+ /* dw9 */
+ u32 imme_data_l_or_notify_va_l_or_atomic_add_cmp_data_l;
+
+ /* dw10 */
+ u32 notify_data_h_or_atomic_swap_mask_h;
+
+ /* dw11 */
+ u32 imme_message_len_or_notify_data_l_atomic_swap_mask_l_or_read_req_data_len;
+ } bs;
+
+ u32 dw_data[12];
+} ub_tp_wqe_task_com_u;
+
+typedef union tag_ub_tp_wqe_task_opt {
+ struct {
+ /* dw0 */
+ u32 rs_vld : 1;
+ u32 retry : 1;
+ u32 imme_last : 1;
+ u32 rsvd_508_503 : 6;
+ u32 host_id : 3;
+ u32 sjtn : 20;
+
+ /* dw1 */
+ u32 ci : 16;
+ u32 ssn : 16;
+
+ /* dw2 */
+ u32 offset;
+
+ /* dw3 */
+ u32 vfid : 12;
+ u32 dcs_index : 20;
+
+ /* dw4 */
+ u32 imme_or_inv_or_notify_token_value;
+
+ /* dw5 */
+ u32 rsvd_351_348 : 4;
+ u32 notify_token_id : 20;
+ u32 remote_host_id : 8;
+
+ /* dw6 */
+ u32 rsp_st : 3;
+ u32 rsp_info : 5;
+ u32 limit_color : 2;
+ u32 rsvd_309_308 : 2;
+ u32 djtn : 20;
+
+ /* dw7 */
+ u32 upi;
+
+ /* dw8~11 */
+ u32 seid[4];
+
+ /* dw12~15 */
+ u32 deid[4];
+ } bs;
+
+ u32 dw_data[16];
+} ub_tp_wqe_task_opt_u;
+
+typedef union tag_ubg_tp_sq_wqe {
+ struct {
+ /* dw0 */
+ u32 o : 1; /* 【RDMA FS】owner bit,(注意时序:最后写),RDMA engine用于校验wqe是否非法,
+ 合法值为:WQE.owner = (Driver.sq_pi >> QPC.sq_size) & 0x1; */
+ u32 ctrl_sl : 2; /* 【RDMA FS】必须填2,UBoE的控制段固定为16B */
+ u32 csl : 2; /* 【RDMA FS】固定填0 */
+ u32 dif_sl : 3; /* 【RDMA FS】固定填0 */
+ u32 cr : 1; /* 【RDMA FS】按需填写,标识该wqe是否产生cqe,由post接口中的WR中携带 */
+ u32 df : 1; /* 【RDMA FS】format of Buffer Description Section.0:carries a list of SGEs;1:carries inline data;READ/ATOMIC置0. */
+ u32 va : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 tsl : 5; /* 【RDMA FS】task section length,length 16B对齐,tsl字段值=length/8 */
+ u32 cf : 1; /* 【RDMA FS】固定填0,RDMA engine不看。 */
+ u32 wf : 1; /* 【RDMA FS】固定填0;在时延DFX场景,CPI识别到打点时,会根据匹配条件将WF字段置位,微码根据WF字段配合打点。 */
+ u32 piv : 1; /* 【微码】在fast_dwqe_en使能时,在pi_on_chip时,置位该bit,微码判断合法。 */
+ u32 db_en : 1; /* 【CPI FS】用于指示cpi是否敲DB到MQM,当前未使用。 */
+ u32 fde : 1; /* 【PSM FS】fast_direct_wqe_en,用于标记该directWqe走pSM快路径。 */
+ u32 f : 1; /* 【RDMA FS】Fast DMA Enable,指示在SQ_FETCH_WQE response API时,是否返回DMA。0:当前WQE不使能Fast DMA:当前WQE使能Fast DMA; */
+ u32 drv_sl : 2; /* 【RDMA FS】固定填0; */
+ u32 bdsl : 8; /* 【RDMA FS】数据段长度,单位8B,存放sge或者inline数据,变长按实际情况填写;
+ 携带sge case:sizeof(ub_cmd_sge_t)=16,16*seg number/8
+ 携带inline数据case:inline数据长度对齐到16B后/8,align_to_16B(inline data length)/8 */
+
+ /* dw1 */
+ u32 cl : 4; /* 【RDMA FS】只能配置为0~5.,8B对齐,标识sq_complete_wqe时返回域段。默认配2,即返回固定16B信息。 */
+ u32 vf_round : 8; /* 【软件】vf_round信息,用于校验重用,注意和wqe signature校验冲突,当前未使用wqe signature能力; */
+ u32 rsvd_979_977 : 3; /* */
+ u32 ts_en : 1; /* 【微码】标识build_time_stamp是否有效,用于TA提交wqe时填写时间戳用于TP 层计算build wqe到tpack 完成WQE更新CI的时间戳 */
+ u32 build_timestamp : 16; /* 【微码】在ts_en时表示生产wqe时的时间戳,其他场景无效。 */
+
+ /* dw2 */
+ u32 fde_vfid : 12; /* 【pSM】jetty对应的vfid,在PCQ GEN时,pSM用于判断去重 */
+ u32 fde_jetty_id : 20; /* 【pSM】jetty id,在PCQ Gen时,pSM用于判断去重 */
+
+ /* dw3 */
+ u32 rsvd_927_912 : 16; /* */
+ u32 fde_jetty_ci : 16; /* 【pSM】jetty ci,在PCQ Gen时,pSM用于判断去重 */
+
+ /* dw4 */
+ u32 se : 1; /* 【微码】se标记,来自于WR,用于填充TAH.se标记,用于接收侧上送事件; */
+ u32 dcs_en : 1; /* 【微码】用于标记数控分离使能,驱动侧创建Segment时感知,在数据面提交wqe时填写。 */
+ u32 ack_flush : 1; /* 【微码】用于标记,当前wqe需要通过读排空前序的写操作,达成回复taack时,写主机侧的报文已到达内存的功能,当前仅taack wqe有效。 */
+ u32 optype : 5; /* 【RDMA FS】optype,定义如下:
+ typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, tx send
+ UB_TX_SEND_IMMEDIATE, tx 携带立即数的send
+ UB_TX_SEND_INVALIDATE, tx 携带使无效指令的send
+ UB_TX_TA_ACK, ta ack
+
+ UB_TX_WRITE = 4, tx write
+ UB_TX_WRITE_IMMEDIATE, tx 携带立即数的write
+ UB_TX_WRITE_NTF, tx 携带notify的write
+ UB_TX_ATOMIC_RSP, 原子操作的rsp
+
+ UB_TX_READ = 8, tx read
+ UB_TX_READ_RSP, tx read rsponse
+ UB_TX_OPTYPE_RSVDA,
+ UB_TX_OPTYPE_RSVDB,
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, tx CAS原子操作
+ UB_TX_ATOMIC_FETCH_ADD, tx ADD原子操作
+ UB_TX_OPTYPE_RSVDE,
+ UB_TX_OPTYPE_RSVDF,
+
+ UB_TX_OPTYPE_RSVD10,
+ UB_TX_OPTYPE_RSVD11,
+ UB_TX_OPTYPE_RSVD12,
+ UB_TX_OPTYPE_RSVD13,
+
+ UB_TX_OPTYPE_WRITE_FLUSH,
+ UB_TX_OPTYPE_RSVD15,
+ UB_TX_OPTYPE_RSVD16,
+ UB_TX_OPTYPE_RSVD17,
+ UB_TX_OPTYPE_RSVD18,
+ UB_TX_OPTYPE_RSVD19,
+ UB_TX_OPTYPE_RSVD1A,
+ UB_TX_OPTYPE_RSVD1B,
+ UB_TX_OPTYPE_RSVD1C,
+ UB_TX_OPTYPE_RSVD1D,
+ UB_ERR_TYPE = 0x1e,
+ UB_TX_OPTYPE_RSVD1F
+ } ub_sqwqe_optype_e; */
+ u32 co : 1; /* 【微码】完成序标记,参考UB协议定义 */
+ u32 eo : 2; /* 【微码】执行序标记,参考UB协议定义 */
+ u32 fence : 1; /* 【微码】fence标记,只对read/atomic有效。 */
+ u32 sjt : 2; /* 【微码】源jetty type,指示SJETTY代表的数据类型,参考UB协议,定义如下:
+ 2b00: Source JFS;
+ 2b01: Source Jetty;
+ 2b10: Destination Sequence Context;
+ Else: reserved。 */
+ u32 vtp_type : 2; /* 【微码】vtp_type,定义如下:h2'0: TPG, h‘0x1:TP, h’0x2:vTP,h'0x3: uTP */
+ u32 eid_vld : 1; /* 【微码】eid有效标记,UPI/SEID/DEID同时有效; */
+ u32 tk_vld : 1; /* 【微码】tokenValue有效标记 */
+ u32 ack_vld : 1; /* 【微码】response_or_taack有效,仅用于微码自产自消的wqe类型。 */
+ u32 udf_vld : 1; /* 【微码】udf_vld=1表示报文中的udf_hdr有效,udf_hdr见write_udf/write_imme中定义。 */
+ u32 rsvd_875_874 : 2; /* */
+ u32 dma_mp : 1; /* 【微码】Dma使能多路径标记,即总线侧多路径,包括通用虚机场景和DAVID直通场景。注意:快路径该域段不可用。 */
+ u32 head : 1; /* 【微码】用于标记当前WQE为队头wqe,即当驱动通过判断ci=pi时,置位该bit,用于微码优化时延流性能,WR list时不置位。 */
+ u32 jetty_round : 8; /* 【微码】jetty翻圈标记,用于TP层校验是否jetty翻圈。 */
+
+ /* dw5 */
+ u32 data_len; /* 【RDMA FS】wqe报文长度,按Byte单位; 注意:tp wqe中read请求时,该域段填0. */
+
+ /* dw6 */
+ u32 hint : 8; /* 【微码】协议定义值,由WR传入,填充到JETTYETAH中用于接收放在在jetty group场景选择目的JFR,david直通场景write/read报文使用此域段用于指定hash选择tpn.
+ 【复用】TAACK场景,该域段由tp层到tp层产生,复用为携带channel_idx。(用于RX流程和ACK流程选择使用的通道一致即oqid一致) */
+ u32 rsvd_823_822 : 2; /* */
+ u32 djt : 2; /* 目的jetty类型 */
+ u32 vtpn : 20; /* vtpn/tpgn */
+
+ /* dw7 */
+ u32 udf_hdr; /* 【微码】UDF_HDR值,在udf_vld=1时有效,用于tp层填充报文头。Send场景,用于携带时间戳。 */
+
+ /* dw8 */
+ u32 local_or_rmt_data_addr_h; /* DMA地址 */
+
+ /* dw9 */
+ u32 local_or_rmt_data_addr_l; /* DMA地址 */
+
+ /* dw10 */
+ u32 rsvd_703_700 : 4; /* */
+ u32 local_or_rmt_tokenid : 20; /* tokenid,用于地址翻译或者组报文头 */
+ u32 rsvd_679_672 : 8; /* */
+
+ /* dw11 */
+ u32 token_value; /* 用于组报文头 */
+
+ /* dw12 */
+ u32 imme_data_h_or_notify_va_h_or_aotmic_add_cmp_data_h; /* 扩展语义操作数 */
+
+ /* dw13 */
+ u32 imme_data_l_or_notify_va_l_or_atomic_add_cmp_data_l; /* 扩展语义操作数 */
+
+ /* dw14 */
+ u32 notify_data_h_or_atomic_swap_mask_h; /* 扩展语义操作数 */
+
+ /* dw15 */
+ u32 imme_message_len_or_notify_data_l_atomic_swap_mask_l_or_read_req_data_len; /* 立即数或者notif数据或read的请求长度。 */
+
+ /* dw16 */
+ u32 rs_vld : 1; /* 1'b0: 非RS模式,1'b1:RS模式, PSM清零。 */
+ u32 retry : 1; /* 重传标记,用于填充报文头, PSM清零。 */
+ u32 imme_last : 1; /* 表示imme类型的尾片,只是message len填充, PSM清零。 */
+ u32 rsvd_508_503 : 6; /* */
+ u32 host_id : 3; /* 用于填充微码host_oqid,pSM不用感知,由于pSM获取不到host ID,因此默认只支持hostid=0的快路径,对于非0场景,需要重新load VF table. */
+ u32 sjtn : 20; /* source jetty number, PSM赋值。 */
+
+ /* dw17 */
+ u32 ci : 16; /* jetty 对应切片wqe的ci, PSM赋值。 */
+ u32 ssn : 16; /* jetty对应切片的ssn, PSM赋值。 */
+
+ /* dw18 */
+ u32 offset; /* jetty对应切片的offset, PSM清零。 */
+
+ /* dw19 */
+ u32 vfid : 12; /* 【pSM】jetty对应的vfid,在PCQ GEN时,pSM用于判断去重 */
+ u32 dcs_index : 20; /* 参考ubg_jfs_wqe_base定义 */
+
+ /* dw20 */
+ u32 imme_or_inv_or_notify_token_value; /* imme或者invalide或者notify语义中语义相关的token value,用于填充报文头。, PSM清零。 */
+
+ /* dw21 */
+ u32 rsvd_351_348 : 4; /* */
+ u32 notify_token_id : 20; /* 用于填充协议NTF_ETAH,pSM不用感知,notify语义不走pSM快路径。 */
+ u32 remote_host_id : 8; /* */
+
+ /* dw22 */
+ u32 rsp_st : 3; /* 用于协议ATAH填充, PSM清零。 */
+ u32 rsp_info : 5; /* 用于协议ATAH填充, PSM清零。 */
+ u32 limit_color : 2; /* 用于协议填充TPH, PSM清零。 */
+ u32 rsvd_309_308 : 2; /* */
+ u32 djtn : 20; /* 目的jetty number, PSM清零。 */
+
+ /* dw23 */
+ u32 upi; /* 组报文头 */
+
+ /* dw24~27 */
+ u32 seid[4]; /* 组报文头 */
+
+ /* dw28~31 */
+ u32 deid[4]; /* 组报文头 */
+ } bs;
+
+ u32 dw_data[32];
+} ubg_tp_sq_wqe_u;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_format.h
new file mode 100644
index 000000000..2312ff506
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_tp_wqe_format.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2015-2021. All rights reserved.
+ * File Name : ub_tp_wqe_format.h
+ * Version : 1.0
+ * Description : 1825v100 tp wqe format
+ * History : 2024/10/28
+ */
+
+#ifndef UB_TP_WQE_H
+#define UB_TP_WQE_H
+
+#include "ub_tp_wqe_define.h"
+
+typedef struct tag_ub_tp_sq_wqe_s {
+ ub_tp_wqe_ctrl_sec_u ctrl_sec; /* 16B */
+ ub_tp_wqe_task_com_u tsk_com; /* 48B */
+ ub_tp_wqe_task_opt_u tsk_opt; /* 64B */
+} ub_tp_sq_wqe_s;
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_wqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_wqe_format.h
new file mode 100644
index 000000000..cc8ea7ef0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_wqe_format.h
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2015-2021. All rights reserved.
+ * File Name : ub_wqe_format.h.h
+ * Version : 1.0
+ * Description :
+ * History :
+2023/4/15: First version
+ */
+
+#ifndef UB_WQE_FORMAT_H
+#define UB_WQE_FORMAT_H
+
+#include "base_type.h"
+
+/**
+ * @brief 获取SQWQE任务段的长度
+ * @param tsl:任务段长度
+ *
+ * @details tsl以8B计数,UB为8到48
+ *
+ * @return 任务段长度(字节数)
+ */
+#define UB_SQWQE_TASK_SEG_LEN(tsl) ((tsl) << 3)
+
+/**
+ * @brief 获取SQWQE数据段起始位置的偏移
+ * @param task_len:任务段的长度
+ *
+ * @return 数据段起始位置的偏移
+ */
+#define UB_SQWQE_DATA_SEG_OFFSET(task_len) \
+ (sizeof(smf_rdma_sq_fetch_wqe_resp_s) + (task_len))
+
+/**
+ * @brief 获取SQWQE数据段起始位置的地址
+ * @param wqe_addr:WQE起始地址
+ * @param task_len:任务段的长度
+ *
+ * @return SQWQE中数据段起始位置的地址
+ */
+#define UB_SQWQE_DATA_SEG_ADDR(wqe_addr, task_len) \
+ (u8 *)((u8 *)(wqe_addr) + UB_SQWQE_DATA_SEG_OFFSET((task_len)))
+
+#define UB_TA_WQE_IMM_EXT_LEN_ALIGN_QW (2) /**< ta wqe imm ext len align qw */
+#define UB_TA_WQE_NTF_EXT_LEN_ALIGN_QW \
+ (3) /**< ta wqe notify ext len align qw */
+#define UB_FAST_DATA_LEN_MAX 9216 /**< fast data max len */
+#define UB_RD_REQ_FAST_DATA_LEN_MAX 4096 /**<read fast data max len */
+
+typedef enum UB_SQWQE_OPTYPE_E {
+ UB_TX_SEND = 0, /**< tx send */
+ UB_TX_SEND_IMMEDIATE, /**< tx 携带立即数的send */
+ UB_TX_SEND_INVALIDATE, /**< tx 携带使无效指令的send */
+ UB_TX_TA_ACK, /**< ta ack */
+
+ UB_TX_WRITE = 4, /**< tx write */
+ UB_TX_WRITE_IMMEDIATE, /**< tx 携带立即数的write */
+ UB_TX_WRITE_NTF, /**< tx 携带notify的write */
+ UB_TX_ATOMIC_RSP, /**< 原子操作的rsp */
+
+ UB_TX_READ = 8, /**< tx read */
+ UB_TX_READ_RSP, /**< tx read rsponse */
+ UB_TX_OPTYPE_RSVDA, /**< reserved */
+ UB_TX_OPTYPE_RSVDB, /**< reserved */
+
+ UB_TX_ATOMIC_COMPARE_SWAP = 0xc, /**< tx CAS原子操作 */
+ UB_TX_ATOMIC_FETCH_ADD, /**< tx ADD原子操作 */
+ UB_TX_OPTYPE_RSVDE, /**< reserved */
+ UB_TX_OPTYPE_RSVDF, /**< reserved */
+
+ UB_TX_OPTYPE_RSVD10, /**< reserved */
+ UB_TX_OPTYPE_RSVD11, /**< reserved */
+ UB_TX_OPTYPE_RSVD12, /**< reserved */
+ UB_TX_OPTYPE_RSVD13, /**< reserved */
+
+ UB_TX_FLUSH_DMA, /**< tx 排空网卡侧多路径写操作,用于数控分离场景(含david直通、主机侧数控分离)*/
+ UB_TX_OPTYPE_RSVD15, /**< reserved */
+ UB_TX_OPTYPE_RSVD16, /**< reserved */
+ UB_TX_OPTYPE_RSVD17, /**< reserved */
+ UB_TX_OPTYPE_RSVD18, /**< reserved */
+ UB_TX_OPTYPE_RSVD19, /**< reserved */
+ UB_TX_OPTYPE_RSVD1A, /**< reserved */
+ UB_TX_OPTYPE_RSVD1B, /**< reserved */
+ UB_TX_OPTYPE_RSVD1C, /**< reserved */
+ UB_TX_OPTYPE_RSVD1D, /**< reserved */
+ UB_ERR_TYPE = 0x1e, /**< ERROR */
+ UB_TX_OPTYPE_RSVD1F /**< reserved */
+} ub_sqwqe_optype_e;
+
+/**
+ * @brief struct tag_ub_wqe_ctrl_sec/ub_wqe_ctrl_sec_s
+ * @details WQE控制域段
+ */
+typedef struct tag_ub_wqe_ctrl_sec {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1; /**< owner bit */
+ u32 ctrlsl : 2; /**< 控制段长度,固定为2 */
+ u32 csl : 2; /**< 固定为0 */
+ u32 difsl : 3;
+ u32 cr : 1; /**< 是否要上送cqe */
+ u32 df : 1; /**< inline wqe标记 */
+ u32 va : 1; /**< SGE地址格式标志位,0-SGE中包含的是物理地址和长度;1-SGE中包含的是虚拟地址和长度以及key,UB为1 */
+ u32 tsl : 5; /**< 任务段长度,以8B计数,UB为11到15 */
+ u32 cf : 1; /**< 完成段格式标志位,0-完成段直接包含状态信息;1-完成段包含SGL,用于描述状态信息,ROCE/UB业务填0 */
+ u32 wf : 1; /**< 0-正常WQE,1-link WQE */
+ u32 rsvd0 : 2;
+ u32 fast_dwqe_en : 1; /**< 0-Normal path, 1- fast path */
+ u32 rsvd1 : 1;
+ u32 drvsl : 2; /**< driver段长度,以8B计数,RoCE/UB为0 */
+ u32 bdsl : 8; /**< 数据段长度,以8B计数,即BDS段的长度为BDSL*8,当使用inline时,描述inline长度,驱动需使数据段总长度对齐到8B */
+#else
+ u32 bdsl : 8;
+ u32 drvsl : 2;
+ u32 rsvd1 : 1;
+ u32 fast_dwqe_en : 1;
+ u32 rsvd0 : 2;
+ u32 wf : 1;
+ u32 cf : 1;
+ u32 tsl : 5;
+ u32 va : 1;
+ u32 df : 1;
+ u32 cr : 1;
+ u32 difsl : 3;
+ u32 csl : 2;
+ u32 ctrlsl : 2;
+ u32 o : 1;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cl : 4; /**< 以8B计数,任务段中产生CQE需要的长度(该字段固定填1)(complete wqe返回的task长度) */
+ u32 rsvd2 : 8;
+ u32 mask_pi : 20; /**< pi与队列深度掩码所得值,direct wqe时有效 */
+#else
+ u32 mask_pi : 20;
+ u32 rsvd2 : 8;
+ u32 cl : 4;
+#endif
+ };
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd3 : 4; /** for cl*/
+ u32 build_timestamp : 28; /**< tp wqe不存在dwqe,复用与记录生产者时间戳 */
+#else
+ u32 build_timestamp : 28;
+ u32 rsvd3 : 4;
+#endif
+ };
+ u32 dw1_value;
+ };
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 type : 2;
+ u32 rsvd4 : 3;
+ u32 cos : 3;
+ u32 c : 1; /**< direct wqe时有效,固定为0 */
+ u32 r : 1;
+ u32 cntx_size : 2; /**< direct wqe时有效,context 大小,jetty是填1,tp时填2 */
+ u32 qpn : 20; /**< direct wqe时有效,qpn */
+#else
+ u32 qpn : 20;
+ u32 cntx_size : 2;
+ u32 r : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 rsvd4 : 3;
+ u32 type : 2;
+#endif
+ };
+ u32 dw2_value;
+ };
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 sub_type : 3; /**< direct wqe时有效,固定填0 */
+ u32 rsvd5 : 13;
+ u32 pi_l16 : 16; /**< direct wqe时有效,wqe的pi,由驱动带下来 */
+#else
+ u32 pi_l16 : 16;
+ u32 rsvd5 : 13;
+ u32 sub_type : 3;
+#endif
+ };
+ u32 dw3_value;
+ };
+} ub_wqe_ctrl_sec_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_com_task/ub_sq_wqe_task_com_s
+ * @details 通用WQE任务域段
+ */
+typedef struct tag_ub_sq_wqe_com_task {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 se : 1; /**< Solicited Event,用户传入 */
+ u32 retry : 1; /**< tpwqe时有效,指示是否是重传类型的wqe */
+ u32 c : 1; /**< cqe */
+ u32 op_type : 5; /**< operation type */
+ u32 odr : 3; /**< 协议定义的序->comletion order(1bit):协议定义的完成序;execution order(2bit):协议定义的执行序 */
+ u32 s : 1; /**< slice,指示是否要切片,tawqe时有效 */
+ u32 jetty_round : 8; /**< round,tpwqe时有效 */
+ u32 ta_func_id : 12;
+#else
+ u32 ta_func_id : 12;
+ u32 jetty_round : 8;
+ u32 s : 1;
+ u32 odr : 3;
+ u32 op_type : 5;
+ u32 c : 1;
+ u32 retry : 1;
+ u32 se : 1;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw0_value;
+ };
+#else
+ } bs;
+ u32 dw0_value;
+ } dw0;
+#endif
+ u32 data_len; /**< 引擎complete wqe计算时使用的数据长度,除了tp wqe的read/taack固定填0,其他场景填真实的数据长度 */
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 round : 8; /**< round,tpwqe时有效 */
+ u32 sqe_type : 2; /**< 预留给性能优化使用 */
+ u32 sjt : 2; /**< source jetty type,请求方向为源jetty类型;应答方向时为pkt.sjetty_type */
+ u32 sjtn : 20; /**< source jetty number,请求方向为源jettyn;应答方向时为pkt.sjettyn */
+#else
+ u32 sjtn : 20;
+ u32 sjt : 2;
+ u32 sqe_type : 2;
+ u32 round : 8;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw2_value;
+ };
+#else
+ } bs;
+ u32 dw2_value;
+ } dw2;
+#endif
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 ssn : 16; /**< segment sequence number,tpwqe时有效 */
+ u32 ci : 16; /**< consumer index,tpwqe时有效,请求方向指示为ta_wqe_idx,应答方向时指示为pkt.taid */
+#else
+ u32 ci : 16;
+ u32 ssn : 16;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw3_value;
+ };
+#else
+ } bs;
+ u32 dw3_value;
+ } dw3;
+#endif
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 mtype : 3; /**< my type,tpwqe时有效,预留给性能加速 */
+ u32 upi : 1; /**< upi valid,指示upi是否有效 */
+ u32 token_vld : 1; /**< token valid,指示token value是否有效 */
+ u32 ack_rsp : 1; /**< taack、tarsp、atomic rsp */
+ u32 f : 1; /**< fence标记 */
+ u32 is_rs : 1; /**< 当前模式为RS时有效,在请求方向指示当前为RS模式 */
+ u32 host_id : 3;
+ u32 is_tpg : 1; /**< 微码产生的tawqe时有效,判断是否是tpg */
+ u32 vtpn : 20; /**< vtpn/tpgn/tpn,tawqe时为vtpn,tpwqe时为tpgn/tpn */
+#else
+ u32 vtpn : 20;
+ u32 is_tpg : 1;
+ u32 host_id : 3;
+ u32 is_rs : 1;
+ u32 f : 1;
+ u32 ack_rsp : 1; /**< taack、tarsp、atomic rsp */
+ u32 token_vld : 1;
+ u32 upi : 1;
+ u32 mtype : 3;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+#else
+ } bs0;
+#endif
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 12;
+ u32 pjetty : 20; /**< producer jetty */
+#else
+ u32 pjetty : 20;
+ u32 rsvd2 : 12;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw4_value;
+ };
+#else
+ } bs1;
+ u32 dw4_value;
+ } dw4;
+#endif
+ u32 offset;
+} ub_sq_wqe_task_com_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_task_write/ub_sq_wqe_task_write_immt_s
+ * @details 带立即数的write wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_task_write {
+ u32 remote_va_h32; /**< va的高32位 */
+
+ u32 remote_va_l32; /**< va的低32位*/
+
+ u32 remote_token_id;
+
+ u32 length; /**< 真实的数据长度 */
+
+ u32 imme_data_h; /**< imme data */
+
+ u32 imme_data_l; /**< imme data */
+
+ u32 total_data_len; /**< imme wqe total length */
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /**< hint标记 */
+ u32 rsvd0 : 1;
+ u32 last : 1; /**< last标记,标识是否imme尾片(TP有效) */
+ u32 djt : 2; /**< Destination jetty type */
+ u32 djtn : 20; /**< Destination jetty number */
+#else
+ u32 djtn : 20;
+ u32 djt : 2;
+ u32 last : 1;
+ u32 rsvd0 : 1;
+ u32 hint : 8;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw3_value;
+ };
+#else
+ } bs;
+ u32 dw3_value;
+ } dw3;
+#endif
+
+ u32 remote_seg_token_value;
+ u32 remote_jfr_token_value;
+ u32 rsv6;
+ u32 rsv7;
+ u32 rsv8;
+ u32 upi;
+ u32 deid[4];
+ u32 seid[4];
+} ub_sq_wqe_task_write_immt_s;
+
+/**
+ * @brief struct ub_sq_wqe_task_write_notify_s
+ * @details 带notify的write wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_task_write_notify {
+ u32 remote_va_h32; /**< va的高32位 */
+
+ u32 remote_va_l32; /**< va的低32位*/
+
+ u32 remote_token_id;
+
+ u32 length; /**< 真实的数据长度 */
+
+ u32 notify_token_id; /**< Destination notify token id */
+
+ u32 notify_token_value; /**< Destination notify token value */
+
+ u32 notify_addr_h; /**< notify addr */
+
+ u32 notify_addr_l; /**< notify addr */
+
+ u32 notify_data_h; /**< notify data */
+
+ u32 notify_data_l; /**< notify data */
+
+ u32 remote_token_value;
+ u32 upi;
+ u32 deid[4];
+ u32 seid[4];
+} ub_sq_wqe_task_write_notify_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_task_read/ub_sq_wqe_task_write_read_s
+ * @details write/read wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_task_read {
+ u32 remote_va_h32;
+
+ u32 remote_va_l32;
+
+ u32 remote_token_id;
+
+ u32 length; /**< 真实的数据长度 */
+
+ u32 remote_token_value;
+ u32 upi;
+ u32 deid[4];
+ u32 seid[4];
+ u32 inline_data;
+} ub_sq_wqe_task_write_read_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_task_send/ub_sq_wqe_task_send_s
+ * @details send wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_task_send {
+ union {
+ u32 imme_data_h;
+ u32 invalid_token_id;
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+#else
+ } dw;
+#endif
+
+ u32 imme_data_l;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 hint : 8; /**< 用户传入,接收端根据hint找到jetty group */
+ u32 rsvd0 : 2;
+ u32 djt : 2;
+ u32 djtn : 20; /**< dest jetty number */
+#else
+ u32 djtn : 20;
+ u32 djt : 2;
+ u32 rsvd0 : 2;
+ u32 hint : 8;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw2_value;
+ };
+#else
+ } bs;
+ u32 dw2_value;
+ } dw2;
+#endif
+
+ u32 rsvd_dw3;
+
+ u32 remote_token_value;
+ u32 upi;
+ u32 deid[4];
+ u32 seid[4];
+} ub_sq_wqe_task_send_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_task_resp/ub_sq_wqe_task_resp_s
+ * @details response wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_task_resp {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsp_st : 3;
+ u32 rsp_info : 5;
+ u32 taid : 24;
+#else
+ u32 taid : 24;
+ u32 rsp_info : 5;
+ u32 rsp_st : 3;
+#endif
+ };
+ u32 dw0_value;
+ };
+
+ u32 tokenid;
+
+ u32 rmt_vah;
+
+ u32 rmt_val;
+
+ u32 atomic_data_cmp_or_msk_or_orgin_h;
+
+ u32 atomic_data_cmp_or_msk_or_orgin_l;
+
+ u32 atomic_data_swp_or_add_h;
+
+ u32 atomic_data_swp_or_add_l;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 atomic_type : 3;
+ u32 atomic_exec : 1;
+ u32 atomic_ret_rcq_id : 12;
+ u32 color : 3;
+ u32 rsv : 13;
+#else
+ u32 rsv : 13;
+ u32 color : 3;
+ u32 atomic_ret_rcq_id : 12;
+ u32 atomic_exec : 1;
+ u32 atomic_type : 3;
+#endif
+ };
+ u32 dw8_value;
+ };
+
+ u32 remote_token_value;
+ u32 upi;
+ u32 deid[4];
+ u32 seid[4];
+} ub_sq_wqe_task_resp_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_task_taack/ub_sq_wqe_task_taack_s
+ * @details ta ack wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_task_taack {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsp_st : 3;
+ u32 rsp_info : 5;
+ u32 color : 3;
+ u32 rsv : 21;
+#else
+ u32 rsv : 21;
+ u32 color : 3;
+ u32 rsp_info : 5;
+ u32 rsp_st : 3;
+#endif
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+ u32 dw0_value;
+ };
+#else
+ } bs;
+ u32 dw0_value;
+ } dw0;
+#endif
+ u32 rsvd_dw1;
+
+ u32 rsvd_dw2;
+
+ u32 rsvd_dw3;
+
+ u32 remote_token_value;
+ u32 upi;
+ u32 deid[4];
+ u32 seid[4];
+} ub_sq_wqe_task_taack_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_tsk/ub_sq_wqe_tsk_s
+ * @details sq wqe的任务段
+ */
+typedef struct tag_ub_sq_wqe_tsk {
+ ub_sq_wqe_task_com_s com;
+ union {
+ ub_sq_wqe_task_write_read_s wr_rd; /**< write read */
+ ub_sq_wqe_task_send_s send;
+ ub_sq_wqe_task_resp_s resp;
+ ub_sq_wqe_task_taack_s taack;
+ ub_sq_wqe_task_write_immt_s write_immt;
+ ub_sq_wqe_task_write_notify_s write_notify;
+#ifndef PLATFORM_MODE_SNP_MACC
+ };
+#else
+ } dw;
+#endif
+} ub_sq_wqe_tsk_s;
+
+/**
+ * @brief struct tag_ub_sq_wqe_s/ub_sq_wqe_s
+ * @details sq wqe
+ */
+typedef struct tag_ub_sq_wqe_s {
+ ub_wqe_ctrl_sec_s ctrl_sec; /**< wqe控制段(固定16B) */
+ ub_sq_wqe_tsk_s tsk_sec; /**< wqe任务段(变长) */
+} ub_sq_wqe_s;
+
+/**
+ * @brief struct ub_wqe_srq_data_seg/ub_wqe_srq_data_seg_s
+ * @details wqe sq/rq 数据段
+ */
+typedef struct ub_wqe_srq_data_seg {
+ /** DW0~1 */
+ union {
+ u64 addr;
+
+ struct {
+ u32 addr_h32;
+ u32 addr_l32;
+ } bs;
+ };
+
+ /** DW2 */
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsv : 1; /**< Reserved field */
+ u32 len : 31; /**< Data length. The value can be [0 or 2G-1]. */
+#else
+ u32 len : 31;
+ u32 rsv : 1;
+#endif
+ } bs;
+ u32 length;
+ } dw2;
+
+ /** DW3 */
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 last : 1;
+ u32 ext : 1;
+ u32 key : 30;
+#else
+ u32 key : 30;
+ u32 ext : 1;
+ u32 last : 1;
+#endif
+ } bs;
+ u32 lkey;
+ } dw3;
+} ub_wqe_srq_data_seg_s;
+
+#endif /**< UB_WQE_FORMAT.H_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_xqe_format.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_xqe_format.h
new file mode 100644
index 000000000..9e55a1671
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/ub_xqe_format.h
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2015-2021. All rights reserved.
+ * File Name : ub_xqe_format.h.h
+ * Version : 1.0
+ * Description :
+ * History :
+2023/4/15: First version
+ */
+
+#ifndef UB_XQE_FORMAT_H
+#define UB_XQE_FORMAT_H
+
+#include "base_type.h"
+#include "ub_npu_base_cmd.h"
+
+/** Macro Definition */
+enum UB_SRQC_STATE_E {
+ UB_SRQC_STATE_SW = 0, /**< SRQC归属权为软件端 */
+ UB_SRQC_STATE_ERR = 1, /**< SRQ context state: error */
+ UB_SRQC_STATE_HW = 0xF /**< SRQC归属权为硬件端 */
+};
+
+enum UB_CQC_STATE_E {
+ UB_CQC_STATE_SW = 0, /**< CQC归属权为软件端 */
+ UB_CQC_STATE_ERR = 1, /**< CQ context state: error */
+ UB_CQC_STATE_OVERFLOW = 3, /**< CQC context state: overflow */
+ UB_CQC_STATE_HW = 0xF /**< CQC归属权为硬件端 */
+};
+
+typedef enum ub_cqe_flush_status {
+ UB_CQE_FLUSH_NOT_DONE = 0, /**< CQE flush未完成 */
+ UB_CQE_FLUSH_DONE = 1 /**< CQE flusn完成 */
+} ub_cqe_flush_status_t;
+
+/** 1823 V200 CQE STATUS 实现 */
+typedef enum ub_cqe_status {
+ UB_CQ_STATUS_OK = 0, /**< 正常 */
+ UB_CQ_STATUS_UNSUPPORTED_OPCODE = 1, /**< 不支持的opcode */
+ UB_CQ_STATUS_LOCAL_OPERATION_ERROR =
+ 2, /**< 由sub status 决定具体错误 */
+ UB_CQ_STATUS_REMOTE_OPERATION_ERROR =
+ 3, /**< 由sub status 决定具体错误 */
+ UB_CQ_STATUS_TRANSACTION_RETRY_COUNTER_EXCEEDED = 4, /**< TA RNR超次 */
+ UB_CQ_STATUS_TRANSACTION_ACK_TIMEOUT = 5, /**< TA ACK超时 */
+ UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED = 6, /**< jetty flush */
+ UB_CQ_STATUS_DEFAULT = 7
+} ub_cqe_status_t;
+
+typedef enum ub_cqe_local_op_sub_status {
+ UB_CQ_SUB_STATUS_LOCAL_LENGTH_ERROR = 1, /**< 本地长度校验错误 */
+ UB_CQ_SUB_STATUS_LOCAL_ACCESS_ERROR = 2, /**< 本地访问校验错误 */
+ UB_CQ_SUB_STATUS_REMOTE_RESPONSE_LENGTH_ERROR =
+ 3, /**< rsp长度校验错误 */
+
+ UB_CQ_SUB_STATUS_FLUSH_WR_ERROR = 5 /**< DavidHBM直通排空WR失败 */
+} ub_cqe_local_op_sub_status_t;
+
+typedef enum ub_cqe_remote_op_sub_status {
+ UB_CQ_SUB_STATUS_REMOTE_UNSUPPORTED_REQUEST =
+ 1, /**< 对端回复相关TA/TP nak */
+ UB_CQ_SUB_STATUS_REMOTE_ACCESS_ABORT = 2 /**< 对端回复相关TA/TP nak */
+} ub_cqe_remote_op_sub_status_t;
+
+enum UB_CQE_TYPE_E {
+ UB_RQ_CQE = 0, /**< recieve queue element: 0 */
+ UB_SQ_CQE = 1 /**< send queue element: 1 */
+};
+
+enum UB_CQE_OPTYPE_E {
+ UB_CQE_RQ_OPTYPE_WRITE_IMMEDIATE =
+ 0, /**< optype: write with immediate data */
+ UB_CQE_RQ_OPTYPE_SEND = 1, /**< optype: send */
+ UB_CQE_RQ_OPTYPE_SEND_IMMEDIATE =
+ 2, /**< optype: send with immediate data */
+ UB_CQE_RQ_OPTYPE_SEND_INVALIDATE =
+ 3, /**< optype: send with invalidate */
+ UB_CQE_RQ_OPTYPE_WRITE = 4, /**< optype: write */
+ UB_CQE_RQ_OPTYPE_READ = 5, /**< optype: read */
+ UB_CQE_SQ_OPTYPE_FLUSH_WRITE = 6, /**< optype: flush write for DMA*/
+};
+
+enum {
+ UB_DB_MTU_256B_SHIFT = 0, /**< MTU shift size: 256 bytes */
+ UB_DB_MTU_512B_SHIFT = 1, /**< MTU shift size: 512 bytes */
+ UB_DB_MTU_1K_SHIFT = 2, /**< MTU shift size: 1 KB */
+ UB_DB_MTU_2K_SHIFT = 3, /**< MTU shift size: 2 KB */
+ UB_DB_MTU_4K_SHIFT = 4, /**< MTU shift size: 4 KB */
+ UB_DB_MTU_8K_SHIFT = 5 /**< MTU shift size: 8 KB */
+};
+
+enum UB_CQE_SIZE_E {
+ UB_CQE_SIZE_8B = 0, /**< CQE size: 8 bytes */
+ UB_CQE_SIZE_16B = 1, /**< CQE size: 16 bytes */
+ UB_CQE_SIZE_32B = 2, /**< CQE size: 32 bytes */
+ UB_CQE_SIZE_64B = 3 /**< CQE size: 64 bytes */
+};
+
+/**
+ * @brief struct tag_ub_cqe/ub_cqe_s
+ * @details ub cqe struct
+ */
+typedef struct tag_ub_cqe { /* excel生成,勿手动修改 */
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1;
+ u32 size : 2;
+ u32 s_r : 1;
+ u32 status : 8;
+ u32 tpn : 20;
+#else
+ u32 tpn : 20;
+ u32 status : 8;
+ u32 s_r : 1;
+ u32 size : 2;
+ u32 o : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 op_type : 5;
+ u32 dif : 1;
+ u32 inline_flag : 1;
+ u32 flush_done : 1;
+ u32 fake : 1;
+ u32 is_jetty : 3;
+ u32 rsvd0 : 3;
+ u32 pi : 17;
+#else
+ u32 pi : 17;
+ u32 rsvd0 : 3;
+ u32 is_jetty : 3;
+ u32 fake : 1;
+ u32 flush_done : 1;
+ u32 inline_flag : 1;
+ u32 dif : 1;
+ u32 op_type : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 sub_status : 12;
+ u32 rmt_jfx_num : 20;
+#else
+ u32 rmt_jfx_num : 20;
+ u32 sub_status : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 wqe_idx : 12;
+ u32 local_jfx_num : 20;
+#else
+ u32 local_jfx_num : 20;
+ u32 wqe_idx : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ u32 byte_cnt;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 big_rqe_idx : 16;
+ u32 rsvd : 16;
+#else
+ u32 rsvd : 16;
+ u32 big_rqe_idx : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ u32 usr_data;
+
+ u32 remote_eid[4];
+
+ u32 imme_data[2];
+
+ u32 inline_data[2];
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 jetty_round : 8;
+ u32 rsvd : 4;
+ u32 jfrn : 20;
+#else
+ u32 jfrn : 20;
+ u32 rsvd : 4;
+ u32 jetty_round : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw15;
+} ub_cqe_s; /* excel生成,勿手动修改 */
+
+#define UB_CQE_DW0_O_OFFSET 31 /**< CQE dw0的 o 字段相较dw0的偏移:31 b */
+
+#define UB_CQE_DW0_SIZE_OFFSET 29 /**< CQE dw0的 size 字段相较dw0的偏移:29 b */
+
+#define UB_CQE_DW0_S_R_OFFSET 28 /**< CQE dw0的 s_r 字段相较dw0的偏移:28 b */
+
+#define UB_CQE_DW0_STATUS_OFFSET \
+ 20 /**< CQE dw0的 status 字段相较dw0的偏移:20 b */
+
+#define UB_CQE_DW0_TPN_OFFSET 0 /**< CQE dw0的 tpn 字段相较dw0的偏移:0 b */
+
+#define UB_CQE_DW1_OPTYPE_OFFSET \
+ 27 /**< CQE dw1的 optype 字段相较dw1的偏移:27 b */
+
+#define UB_CQE_DW1_DIF_OFFSET 26 /**< CQE dw1的 dif 字段相较dw1的偏移:26 b */
+
+#define UB_CQE_DW1_INLINE_FLAG_OFFSET \
+ 25 /**< CQE dw1的 inline_flag 字段相较dw1的偏移:25 b */
+
+#define UB_CQE_DW1_FLUSH_DONE_OFFSET \
+ 24 /**< CQE dw1的 flush_done 字段相较dw1的偏移:24 b */
+
+#define UB_CQE_DW1_FAKE_OFFSET 23 /**< CQE dw1的 fake 字段相较dw1的偏移:23 b */
+
+#define UB_CQE_DW1_IS_JETTY_OFFSET \
+ 20 /**< CQE dw1的 is_jetty 字段相较dw1的偏移:20 b */
+
+#define UB_CQE_DW1_PI_OFFSET 0 /**< CQE dw1的 pi 字段相较dw1的偏移:0 b */
+
+#define UB_CQE_DW2_RTT_VLD_OFFSET \
+ 28 /**< CQE dw2的 rtt_vld 字段相较dw2的偏移:28 b */
+
+#define UB_CQE_DW2_SUB_STATUS_OFFSET \
+ 20 /**< CQE dw2的 sub_status 字段相较dw2的偏移:20 b */
+
+#define UB_CQE_DW2_REMOTE_JFX_NUM_OFFSET \
+ 0 /**< CQE dw2的 sub_status 字段相较dw2的偏移:0 b */
+
+#define UB_CQE_DW3_WQE_IDX_OFFSET \
+ 20 /**< CQE dw3的 wqe_idx 字段相较dw3的偏移:20 b */
+
+#define UB_CQE_DW3_LOCAL_JFX_NUM_OFFSET \
+ 0 /**< CQE dw3的 local_jfx_num 字段相较dw3的偏移:0 b */
+
+#define UB_CQE_DW15_ROUND_OFFSET \
+ 24 /**< CQE dw12的 jetty_round 字段相较dw15的偏移:24 b */
+
+#define UB_CQE_DW15_JFRN_OFFSET \
+ 0 /**< CQE dw12的 jfrn 字段相较dw15的偏移:0 b */
+
+/**
+ * @brief struct tag_ub_sq_db/ub_sq_db_s
+ * @details sq doorbell struct
+ */
+typedef struct tag_ub_sq_db {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 type : 5; /**< ta时为2,tp时为4,remote tp DB为16 */
+ u32 cos : 3;
+ u32 c : 1;
+ u32 n : 1;
+ u32 cntx_size : 2; /**< tp时为1K,jetty时为512B */
+ u32 xqn : 20;
+#else
+ u32 xqn : 20;
+ u32 cntx_size : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 type : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 queue_id : 4;
+ u32 rsvd0 : 12;
+ u32 pi : 16;
+#else
+ u32 pi : 16;
+ u32 rsvd0 : 12;
+ u32 queue_id : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+} ub_sq_db_s;
+
+/**
+ * @brief union tag_ub_sq_db_u
+ * @details cq doorbell union
+ */
+union tag_ub_sq_db_u {
+ struct tag_ub_sq_db sq_db; /**< sq db structure; */
+ u64 sq_db_value; /**< sq doorbell value; */
+};
+
+/**
+ * @brief struct tag_ub_cq_db/ub_cq_db_s
+ * @details cq doorbell struct
+ */
+typedef struct tag_ub_cq_db {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 type : 5;
+ u32 cos : 3;
+ u32 c : 1;
+ u32 n : 1;
+ u32 cqc_type : 2;
+ u32 cqn : 20;
+#else
+ u32 cqn : 20;
+ u32 cqc_type : 2;
+ u32 n : 1;
+ u32 c : 1;
+ u32 cos : 3;
+ u32 type : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 cmd_sn : 2;
+ u32 cmd : 2;
+ u32 rsvd0 : 4;
+ u32 ci : 24;
+#else
+ u32 ci : 24;
+ u32 rsvd0 : 4;
+ u32 cmd : 2;
+ u32 cmd_sn : 2;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+} ub_cq_db_s;
+
+/**
+ * @brief union tag_ub_cq_db_u
+ * @details cq doorbell union
+ */
+union tag_ub_cq_db_u {
+ struct tag_ub_cq_db cq_db; /**< cq db structure; */
+ u64 cq_db_value; /**< cq doorbell value; */
+};
+
+/**
+ * @brief struct tag_ub_remote_db/ub_remote_db_s
+ * @details remote doorbell struct
+ */
+typedef struct tag_ub_remote_db {
+ union {
+ struct {
+ u32 type : 5;
+ u32 cos : 3;
+ u32 c : 1;
+ u32 n : 1;
+ u32 cntx_size : 2;
+ u32 xqn : 20;
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+ u32 queue_id : 4;
+ u32 mtu_shift : 3;
+ u32 rsvd0 : 25;
+ } bs;
+ u32 value;
+ } dw1;
+} ub_remote_db_s;
+
+/* *****************************************************************************
+ Data Structure: UB_TA_CQE
+ Description: 1825v100 cqe data struct
+***************************************************************************** */
+typedef struct tag_ub_ta_cqe {
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 o : 1;
+ u32 size : 2;
+ u32 s_r : 1;
+ u32 status : 8;
+ u32 tpgn : 20;
+#else
+ u32 tpgn : 20;
+ u32 status : 8;
+ u32 s_r : 1;
+ u32 size : 2;
+ u32 o : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 optype : 5;
+ u32 rsvd0 : 1;
+ u32 inline_flag : 1;
+ u32 flush_done : 1;
+ u32 fake : 1;
+ u32 rsvd1 : 7;
+ u32 wqebb_idx_or_ci : 16;
+#else
+ u32 wqebb_idx_or_ci : 16;
+ u32 rsvd1 : 7;
+ u32 fake : 1;
+ u32 flush_done : 1;
+ u32 inline_flag : 1;
+ u32 rsvd0 : 1;
+ u32 optype : 5;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 4;
+ u32 sub_status : 8;
+ u32 remote_jetty : 20;
+#else
+ u32 remote_jetty : 20;
+ u32 sub_status : 8;
+ u32 rsvd : 4;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd : 12;
+ u32 local_jetty : 20;
+#else
+ u32 local_jetty : 20;
+ u32 rsvd : 12;
+#endif
+ } bs;
+ u32 value;
+ } dw3;
+
+ u32 msg_length;
+
+ u32 usr_data_h;
+
+ u32 usr_data_l;
+
+ u32 rmt_eid[4];
+
+ u32 imme_data[2];
+
+ u32 inline_data;
+
+ u32 rsvd_dw14;
+
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 jetty_round : 8;
+ u32 rsvd : 4;
+ u32 jfrn : 20;
+#else
+ u32 jfrn : 20;
+ u32 rsvd : 4;
+ u32 jetty_round : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw15;
+} ub_ta_cqe_s;
+
+#endif /**< UB_XQE_FORMAT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/uboe_pub_tbl_def.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/uboe_pub_tbl_def.h
new file mode 100644
index 000000000..c45a85f30
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/uboe/uboe_pub_tbl_def.h
@@ -0,0 +1,52 @@
+/* *****************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
+ ******************************************************************************
+ File Name : uboe_pub_tbl_def.h
+ Version : Initial Draft
+ Created : 2025/12/29
+ Last Modified :
+ Description : UBoE public table definition
+ Function List :
+ History :
+ 1.Date : 2025/12/29
+ Modification: Created file
+***************************************************************************** */
+#ifndef UBOE_PUB_TBL_DEF_H
+#define UBOE_PUB_TBL_DEF_H
+
+#include "base_type.h"
+
+/**@struct ub_vm_global_xid_cfg
+* @brief SML线性表的xid全局配置表项结构
+*/
+typedef struct ub_vm_global_xid_cfg {
+ union {
+ struct {
+ u32 min_jetty_num; /**< min jetty num */
+ u32 max_jetty_num; /**< max jetty num */
+ u32 min_jfr_num; /**< min jfr num */
+ u32 max_jfr_num; /**< max jfr num */
+ };
+ struct {
+ u32 fake_dma_pa_l32;
+ u32 fake_dma_pa_h32;
+ };
+ }; /** fake_dma_pa仅为tp function配置,此时jetty数量字段无效 */
+ union {
+ struct {
+ u32 min_jetty_num : 1; /**< min jetty num */
+ u32 max_jetty_num : 1; /**< max jetty num */
+ u32 min_jfr_num : 1; /**< min jfr num */
+ u32 max_jfr_num : 1; /**< max jfr num */
+ u32 fake_dma_pa : 1; /**< fake_dma_pa_l32 && fake_dma_pa_h32*/
+ u32 rsvd : 27;
+ } bs; /**< 1表示对应字段有效,0表示无效 */
+ u32 value;
+ } mask;
+
+ u32 tid0; /* 通算数控分离记录访问1650侧Segment TID */
+ u32 deid0; /* 通算数控分离记录访问1650侧EID */
+ u32 rsvd;
+} ub_vm_global_xid_cfg_s;
+
+#endif /* UBOE_PUB_TBL_DEF_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/cfm_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/cfm_pub_cmd.h
new file mode 100644
index 000000000..c13b33dfa
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/cfm_pub_cmd.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description : tool与MPU公共部分
+ * Creation time : 2025/11/05
+ */
+
+#ifndef CFM_PUB_CMD_H
+#define CFM_PUB_CMD_H
+
+#endif /* CFM_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/hihtr_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hihtr_pub_cmd.h
new file mode 100644
index 000000000..8539515d0
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hihtr_pub_cmd.h
@@ -0,0 +1,33 @@
+#ifndef HIHTR_PUB_CMD_H
+#define HIHTR_PUB_CMD_H
+
+#include "base_type.h"
+#include "hinic5_mt.h"
+
+enum hihtr_driver_cmd_type {
+ HIHTR_CMD_GET_DRIVER_COUNT = SERVICE_DRV_BASE_CMD, /**< 获取驱动计数 */
+ HIHTR_CMD_SET_SCC_CTRL_INFO,
+ HIHTR_CMD_QUERY_SCC_CTRL_INFO,
+ HIHTR_CMD_SET_SCC_TEMPLATE_INFO,
+ HIHTR_CMD_QUERY_SCC_TEMPLATE_INFO,
+ HIHTR_CMD_GET_SCC_CTX,
+ HIHTR_CMD_GET_DATA_PATH_MOD_PKT_CNT,
+ HIHTR_CMD_GET_QPC,
+ HIHTR_CMD_GET_CQC,
+ HIHTR_CMD_GET_SRQC,
+ HIHTR_CMD_GET_AEQC,
+ HIHTR_CMD_GET_MPT,
+ HIHTR_CMD_GET_GID,
+ HIHTR_CMD_GET_QPC_CQC_PI_CI,
+ HIHTR_CMD_GET_QP_COUNT,
+ HIHTR_CMD_GET_HW_COUNT,
+ HIHTR_CMD_GET_DEV_TYPE,
+ HIHTR_CMD_GET_SPECIFICATIONS,
+ HIHTR_CMD_SET_BYPASS,
+ HIHTR_CMD_QUERY_BYPASS,
+ HIHTR_CMD_ORDER_SET,
+ HIHTR_CMD_ORDER_QUERY,
+ HIHTR_CMD_INVALID,
+};
+
+#endif /* _HIHTR_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/hyper_roce_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hyper_roce_pub_cmd.h
new file mode 100644
index 000000000..e7bad48b2
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hyper_roce_pub_cmd.h
@@ -0,0 +1,48 @@
+#ifndef HYPER_ROCE_PUB_CMD_H
+#define HYPER_ROCE_PUB_CMD_H
+
+#include "base_type.h"
+#define PKTDROP_QP_MAX_NUM 512
+
+typedef struct l2d_pktdrop_dfx_tbl_attr {
+ u32 rsvd[15];
+ union {
+ u32 value;
+ struct {
+ u32 drop_pkt_ratio : 7;
+ u32 drop_pkt_type : 3;
+ u32 drop_opcode : 6;
+ u32 tx_rx : 2;
+ u32 rsvd_bits : 14;
+ } bs;
+ } dw15;
+} l2d_pktdrop_dfx_tbl_attr_s;
+
+typedef struct l2d_pktdrop_dfx_tbl_mask {
+ union {
+ u32 value;
+ struct {
+ u32 drop_pkt_ratio : 1;
+ u32 drop_pkt_type : 1;
+ u32 drop_opcode : 1;
+ u32 tx_rx : 1;
+ u32 rsvd_bits : 28;
+ } bs;
+ } dw0;
+} l2d_pktdrop_dfx_tbl_mask_s;
+
+struct pktdrop_l2d_tbl_dfx {
+ l2d_pktdrop_dfx_tbl_attr_s attr;
+ l2d_pktdrop_dfx_tbl_mask_s mask;
+};
+
+struct pktdrop_qp_info {
+ u32 qp_num;
+ u32 qpn[PKTDROP_QP_MAX_NUM];
+};
+
+union pktdrop_outbuf {
+ struct pktdrop_qp_info qp_capture_info;
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/mig_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/mig_pub_cmd.h
new file mode 100644
index 000000000..27bd1c63b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/mig_pub_cmd.h
@@ -0,0 +1,42 @@
+#ifndef MIG_PUB_CMD_H
+#define MIG_PUB_CMD_H
+
+#include "base_type.h"
+
+#define MAX_MIGRATE_STAGE 15
+#define HIMIG_ULD_DEV_NAME "himig"
+typedef struct ub_mig_time {
+ u64 start_time; /* stage start times */
+ u64 end_time; /* stage end times */
+} ub_mig_time_t;
+
+typedef struct ub_migrate_stat_resp {
+ struct ub_mig_time stage_time[MAX_MIGRATE_STAGE];
+ u64 mig_start_time;
+ u64 mig_end_time;
+ u64 success_cnt;
+ u64 fail_cnt;
+ u16 stage;
+ u16 func_id;
+} ub_migrate_stat_resp_t;
+
+typedef struct mig_query_inbuf {
+ /* public */
+ u32 service_type;
+ u32 cmd_type;
+ u32 bdf;
+
+ /* 特性定制参数 */
+} mig_query_inbuf_t;
+
+typedef union mig_query_outbuf {
+ struct ub_migrate_stat_resp stat_resp;
+} mig_query_outbuf_u;
+
+typedef enum tag_mig_query_cmd {
+ /* Public MIGRATE */
+ MIG_QUERY_CMD_QUERY_UB_MIG_STAT_INFO = 0,
+ MIG_QUERY_CMD_MAX
+} mig_query_cmd_e;
+
+#endif /* MIG_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/roce_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/roce_pub_cmd.h
new file mode 100644
index 000000000..1ae8484c5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/roce_pub_cmd.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: commonds between hinicadmdfx tools and roce driver.
+ * Create: 2024-12-20
+ */
+
+#ifndef ROCE_PUB_CMD_H
+#define ROCE_PUB_CMD_H
+
+#include "base_type.h"
+
+#define ROCE_SERVICE_TYPE 2
+#define INVALID_QPN ((u32)~0u)
+#define ROCE_ATTACK_LEN 4
+#define ATTACK_VALUE_SIZE 256
+#define ATTACK_VALUE_MAX 128
+
+enum roce_attack_type {
+ ROCE_ATTACK_TYPE_SQDB_HARD = 0,
+ ROCE_ATTACK_TYPE_DWQE,
+ ROCE_ATTACK_TYPE_SQWQE,
+ ROCE_ATTACK_TYPE_RQWQE,
+ ROCE_ATTACK_TYPE_CMTT,
+ ROCE_ATTACK_TYPE_DMTT,
+ ROCE_ATTACK_TYPE_RDMARC,
+ ROCE_ATTACK_TYPE_CQE,
+ ROCE_ATTACK_TYPE_INVALID
+};
+
+struct roce_attack_outbuf {
+ u64 db;
+};
+
+struct roce_attack_inbuf {
+ u32 convert_endian;
+ u32 qpn;
+ u32 mpt_index;
+ u32 attack_type;
+ u32 offset;
+ u32 length;
+ u32 srv_type;
+ u32 attack_len;
+ u32 mask;
+ u32 attack_value[32];
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/ub_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/ub_pub_cmd.h
new file mode 100644
index 000000000..645a13b5b
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/ub_pub_cmd.h
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+ * Description: commonds between hinicadm tools and ub driver.
+ * Create: 2023-7-30
+ */
+
+#ifndef UB_PUB_CMD_H
+#define UB_PUB_CMD_H
+
+#include "ub_npu_jfrc_cmd_defs.h"
+#include "ub_npu_jfc_cmd_defs.h"
+#include "ub_npu_srq_cmd_defs.h"
+#include "ub_npu_utp_cmd_defs.h"
+#include "ub_npu_upi_cmd_defs.h"
+#include "ub_npu_tp_cmd_defs.h"
+#include "ub_npu_vtp_cmd_defs.h"
+#include "ub_npu_eid_cmd_defs.h"
+#include "ub_npu_mig_cmd_defs.h"
+#include "ub_npu_jetty_cmd_defs.h"
+#include "ub_npu_sip_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
+#include "ub_mpu_dfx_cmd_defs.h"
+#include "ub_mpu_cmd_defs.h"
+#include "ub_wqe_format.h"
+#include "mig_mpu_cmd_defs.h"
+#include "ub_npu_mapt_cmd_defs.h"
+
+#define udma_dfx_print(fmt, args...) \
+ do { \
+ (void)printk("[udma_dfx] : " fmt "\n", ##args); \
+ } while (0)
+
+#define MAX_JFC_CMTT_SIZE 256
+#define MAX_JFS_CMTT_SIZE 256
+#define MAX_JFR_CMTT_SIZE MAX_JFC_CMTT_SIZE
+#define MAX_TP_CMTT_SIZE 256
+#define UB_SQ_WRITE_WQEBB_LEN 64
+#define UB_SRQ_WRITE_WQEBB_LEN 128
+#define UB_MAX_JFS_DFX_BUF 1024
+#define UB_MAX_JFR_DFX_BUF 4096
+#define UB_MAX_JFC_DFX_BUF 1024
+#define UB_MAX_IDX_WQE_DFX_BUF 32
+#define UB_SEID_CTX_DFX_LEN 32
+#define UB_QUERY_TYPE_BIT 8
+#define UB_CAPTURE_TP_MAX_NUM 512
+#define UB_CQM_MODIFY_DATA_LEN 4096
+#define UB_CQM_MODIFY_DATA_LEN_MAPT 128
+#define UB_CQM_MODIFY_DATA_LEN_JFC 256
+#define UB_CQM_MODIFY_DATA_LEN_TP 1024
+#define UB_ATTACK_DW_NUM 4
+#define UB_ATTACK_LEN (UB_ATTACK_DW_NUM * sizeof(u32))
+#define UB_ATTACK_TAMSN_MAX_LEN (32 * 256) /**< tamsn size * tamasn num */
+#define UDMA_DSCP_MAX_NUM 64
+#define UB_MSN_ENTRY_SIZE 32 /**< msn entry size 32B */
+#define UB_CMD_TP_MSN_ENTRY_SIZE 32 /**< TP msn entry size 32B */
+
+#define UB_MAX_PORT_CNT 8
+#define UB_QUERY_RES_CNT 64
+#define UB_EID_SIZE 16
+#define UB_EID_FMT \
+ "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x"
+#define UB_EID_RAW_ARGS(eid) \
+ eid[0], eid[1], eid[2], eid[3], eid[4], eid[5], eid[6], eid[7], \
+ eid[8], eid[9], eid[10], eid[11], eid[12], eid[13], eid[14], \
+ eid[15]
+
+struct ub_l2d_dfx_inbuf {
+ u32 cmd_type;
+ union {
+ u32 rsvd; /* 预留后续扩展使用 */
+ };
+ union {
+ ub_l2d_mem_cfg_s l2d_cfg;
+ };
+};
+
+union ub_l2d_dfx_outbuf {
+ u32 ub_l2d_dfx_data[UB_L2D_DFX_CMD_RESP_DATA_LEN];
+};
+
+struct ub_cc_params {
+ u8 index;
+ u8 ub_cc_algo;
+ union {
+ struct {
+ u8 init_wnd;
+ u8 alpha;
+ u8 beta;
+ u8 gamma;
+ u8 eta;
+ u8 wnd_min;
+ u8 cc_unit;
+ u8 rsvd[9];
+ };
+ u32 dw[4];
+ };
+};
+
+/* jetty/jfs/jfr等资源下发/接收wr的数量 */
+typedef struct ub_driver_comm_ctr {
+ u64 post_send_wr_num;
+ u64 post_recv_wr_num;
+ u64 poll_total_num;
+ u64 poll_sq_num;
+ u64 poll_rq_num;
+} ub_driver_comm_ctr_t;
+
+struct ub_rx_rate_limit_params {
+ u16 down_period;
+ u16 up_period;
+ u16 alpha1;
+ u16 n1;
+ u16 alpha2;
+ u8 n2;
+ u16 alpha3;
+ u8 beta;
+ u16 min_rate;
+ u16 init_rate;
+};
+
+struct ub_qos_params {
+ u16 func_id;
+ u16 vnic_id;
+ u8 xir_type;
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 bps;
+ u32 pps;
+};
+
+struct udma_tp_modify_dfx {
+ union {
+ struct {
+ /* dw0 */
+ /* flag */
+ u32 oor_en : 1;
+ u32 sr_en : 1;
+ u32 cc_en : 1;
+ u32 spray_en : 1;
+ u32 cc_alg : 4;
+ /* peer_tpn */
+ u32 peer_tpn : 24;
+
+ /* dw1 */
+ /* rx_psn */
+ u32 rx_psn : 24;
+ /* cc_pattern_idx */
+ u32 cc_pattern_idx : 4;
+ /* state */
+ u32 state : 3;
+ u32 rsvd1 : 1;
+
+ /* dw2 */
+ /* tx_psn */
+ u32 tx_psn : 24;
+ /* mtu */
+ u32 mtu : 3;
+ u32 rsvd2 : 1;
+ /* sq_err_state */
+ u32 sq_err_state : 1;
+ /* rq_err_state */
+ u32 rq_err_state : 1;
+ /* sqa_err_state */
+ u32 sqa_err_state : 1;
+ /* rqa_err_state */
+ u32 rqa_err_state : 1;
+
+ /* dw3 */
+ u32 rsvd;
+ };
+ u32 value[4];
+ } attr;
+ union {
+ struct {
+ u32 flag : 1;
+ u32 peer_tpn : 1;
+ u32 cc_pattern_idx : 1;
+ u32 rx_psn : 1;
+ u32 tx_psn : 1;
+ u32 state : 1;
+ u32 mtu : 1;
+ u32 sq_err_state : 1;
+ u32 rq_err_state : 1;
+ u32 sqa_err_state : 1;
+ u32 rqa_err_state : 1;
+ u32 rsvd : 21;
+ };
+ u32 value;
+ } mask;
+};
+
+struct udma_jetty_modify_dfx {
+ union {
+ struct {
+ /* dw0 */
+ /* next_send_tassn */
+ u32 next_send_tassn : 16;
+ /* next_ack_tassn */
+ u32 next_ack_tassn : 16;
+
+ /* dw1 */
+ u32 rsvd_dw1;
+
+ /* dw2 */
+ u32 rsvd_dw2;
+
+ /* dw3 */
+ u32 rsvd_dw3;
+ };
+ u32 value[4];
+ } attr;
+ union {
+ struct {
+ u32 next_send_tassn : 1;
+ u32 next_ack_tassn : 1;
+ u32 rsvd : 30;
+ };
+ u32 value;
+ } mask;
+};
+
+struct ub_query_inbuf {
+ u32 cmd_type;
+ union {
+ u32 xid;
+ u32 tpn;
+ u32 tokenid;
+ u32 jfcid;
+ u32 jfrid;
+ u32 jfsid;
+ u32 jettyid;
+ u32 jetty_group_id;
+ u32 sipid;
+ u32 dipid;
+ u32 rcq_id; /* rc queue ctx/pcqc xid */
+ u32 tpg_id;
+ u32 vtp_id;
+ u32 seid_id;
+ u32 pattern_index;
+ u32 func_id;
+ };
+ u32 length;
+ u32 offset;
+ u32 layers;
+ u32 wqe_id;
+ u32 smf_id;
+ u32 vfid;
+ u32 peer_tpn;
+ u32 tx_psn;
+ u32 rx_psn;
+ u32 state;
+ u32 mtu;
+ u32 msn;
+ u32 cc_pattern_idx;
+ u32 flag;
+ u32 oor_en;
+ u32 sr_en;
+ u32 cc_en;
+ u32 cc_alg;
+ u32 spray_en;
+ u32 drop_aeqe_en;
+ u8 cfg_cos_en;
+ u8 slice_cfg_en;
+ u8 multi_tp_en;
+ u8 default_tpn;
+ u8 event_type;
+ u8 queue_type;
+ u8 event_sub_type;
+ u32 peer_tpn_mask : 1;
+ u32 tx_psn_mask : 1;
+ u32 rx_psn_mask : 1;
+ u32 state_mask : 1;
+ u32 mtu_mask : 1;
+ u32 mtu_1k_mask : 1;
+ u32 max_jetty_mask : 1;
+ u32 cc_pattern_idx_mask : 1;
+ u32 multi_path_mode : 2;
+ u32 slice_cfg_set : 1;
+ u32 reserved : 21;
+ u32 is_jetty;
+ u32 rsvd_to_remove;
+ ub_cmd_upi_key_attr_s upi_key;
+ struct ub_cc_params cc_params;
+ u32 tp_srp_index;
+ u32 bitmap_index;
+ u32 ctr_bitmap_index;
+ u32 bitmap_mode;
+ struct ub_qos_params qos_params;
+ u32 entry_index;
+ u32 q_depth;
+ u8 mtu_1k_en;
+ u32 max_jetty_num;
+ u32 idx;
+ u8 dscp;
+ u8 cos;
+ u8 msn_type;
+ u8 rsvd[1];
+ u64 gpa;
+ struct {
+ struct {
+ u32 rsvd : 27;
+ u32 mtt_pro_en : 1;
+ u32 ub_link_en : 1;
+ u32 traffic_en : 1;
+ u32 debug_en : 1;
+ u32 lwb_en : 1;
+ } dw15;
+ struct {
+ u32 rsvd : 27;
+ u32 mtt_pro_en : 1;
+ u32 ub_link_en : 1;
+ u32 traffic_en : 1;
+ u32 debug_en : 1;
+ u32 lwb_en : 1;
+ } dw15_flag; /** 是否修改的标记*/
+ } func_table_modify_attr;
+ struct udma_jetty_modify_dfx jetty_attr;
+ struct udma_tp_modify_dfx tp_attr;
+};
+
+struct ub_secure_addr_info {
+ struct vmsec_ctx_gpa_info ctx_gpa;
+ struct vmsec_pcie_hole_info pcie_hole;
+};
+
+typedef enum ub_port_state {
+ UB_PORT_NOP = 0,
+ UB_PORT_DOWN,
+ UB_PORT_INIT,
+ UB_PORT_ARMED,
+ UB_PORT_ACTIVE,
+ UB_PORT_ACTIVE_DEFER
+} ub_port_state_t;
+
+typedef enum ub_speed {
+ UB_SP_10M = 0,
+ UB_SP_100M,
+ UB_SP_1G,
+ UB_SP_2_5G,
+ UB_SP_5G,
+ UB_SP_10G,
+ UB_SP_14G,
+ UB_SP_25G,
+ UB_SP_40G,
+ UB_SP_50G,
+ UB_SP_100G,
+ UB_SP_200G,
+ UB_SP_400G,
+ UB_SP_800G
+} ub_speed_t;
+
+typedef enum ub_link_width {
+ UB_LINK_X1 = 0x1,
+ UB_LINK_X2 = 0x1 << 1,
+ UB_LINK_X4 = 0x1 << 2,
+ UB_LINK_X8 = 0x1 << 3,
+ UB_LINK_X16 = 0x1 << 4,
+ UB_LINK_X32 = 0x1 << 5
+} ub_link_width_t;
+
+typedef enum ub_mtu {
+ UB_MTU_256 = 1,
+ UB_MTU_512,
+ UB_MTU_1024,
+ UB_MTU_2048,
+ UB_MTU_4096,
+ UB_MTU_8192
+} ub_mtu_t;
+
+typedef struct ub_port_status {
+ ub_port_state_t state; /* PORT_DOWN, PORT_INIT, PORT_ACTIVE */
+ ub_speed_t active_speed; /* bandwidth */
+ ub_link_width_t active_width; /* link width: X1, X2, X4 */
+ ub_mtu_t active_mtu;
+} ub_port_status_t;
+
+typedef struct ub_seg_attr {
+ u8 eid[UB_EID_SIZE];
+ u32 uasid;
+ u64 va;
+ u64 len;
+ u32 key_id;
+} ub_seg_attr_t;
+
+typedef struct ub_dev_res {
+ u32 port_cnt;
+ ub_port_status_t port_status[UB_MAX_PORT_CNT];
+ u32 seg_cnt;
+ struct ub_seg_attr seg_list[UB_QUERY_RES_CNT]; // SEG key_id list
+ u32 jfs_cnt;
+ u32 jfs_list[UB_QUERY_RES_CNT]; // JFS ID list
+ u32 jfr_cnt;
+ u32 jfr_list[UB_QUERY_RES_CNT]; // JFR ID list
+ u32 jfc_cnt;
+ u32 jfc_list[UB_QUERY_RES_CNT]; // JFC ID list
+ u32 jetty_cnt;
+ u32 jetty_list[UB_QUERY_RES_CNT]; // Jetty ID list
+ u32 jetty_group_cnt;
+ u32 jetty_group_list[UB_QUERY_RES_CNT]; // Jetty group ID list
+ u32 tp_cnt;
+ u32 tp_list[UB_QUERY_RES_CNT]; // RC
+ u32 vtp_cnt;
+ u32 vtp_list[UB_QUERY_RES_CNT]; // VTP
+ u32 tpg_cnt;
+ u32 tpg_list[UB_QUERY_RES_CNT]; // RM
+ u32 rc_cnt;
+ u32 rc_list[UB_QUERY_RES_CNT];
+ u32 utp_cnt;
+ u32 utp_list[UB_QUERY_RES_CNT]; // UM
+} ub_dev_res_t;
+
+typedef struct ub_query_dev_cap {
+ u32 feature;
+ u32 max_jfc_num;
+ u32 max_jfs_num;
+ u32 max_jfr_num;
+ u32 max_jetty_num;
+ u32 max_tp_num;
+ u32 max_tpg_num;
+ u32 max_jetty_group_num;
+ u32 max_vtp_num;
+ u32 max_jfc_depth;
+ u32 max_jfs_depth;
+ u32 max_jfr_depth;
+ u32 max_jfs_inline_size;
+ u32 max_jfc_inline_size;
+ u32 max_jfs_sge;
+ u32 max_jfs_rsge;
+ u32 max_jfr_sge;
+ u32 max_dma_msg_sz;
+ u32 max_send_msg_sz;
+ u32 max_rc_outstd_cnt;
+ u32 trans_mode;
+ u32 congestion_ctrl_alg;
+ u32 comp_vector_cnt;
+ u32 utp_cnt;
+ u32 max_eid_cnt;
+ u32 guid;
+ u32 max_upi_cnt;
+ u32 port_cnt;
+ u32 virtualization;
+ u32 vf_cnt;
+ u32 is_tpf;
+ u32 max_oor_cnt;
+ u32 max_sip_cnt_per_vf;
+ u32 max_dip_cnt_per_vf;
+ u32 max_seid_cnt_per_vf;
+ u32 max_jetty_cnt_per_jtg;
+ u32 max_tp_cnt_per_tpg;
+ u32 max_mtu;
+ u32 seid_idx_start;
+ u32 max_rc_num;
+ u32 max_rc_depth;
+ u32 rc_entry_size;
+ u32 slice_min_size;
+ u32 slice_max_size;
+ u32 max_pi_on_chip_num;
+ u32 max_mpts;
+ u32 num_ceq_vectors;
+ u32 cqc_entry_size;
+ u32 qpc_entry_size;
+ u32 srqc_entry_size;
+ u32 direct_wqe_size;
+ u32 log_mtt;
+ u32 num_mtts;
+ u32 log_mtt_seg;
+ u32 mtt_entry_sz;
+ u32 mpt_entry_sz;
+ u32 dmtt_cl_start;
+ u32 dmtt_cl_end;
+ u32 dmtt_cl_sz;
+ u32 max_jetty_dest_ub;
+ u32 ubrc_entry_sz;
+ u32 log_ubrc_seg;
+ 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 device_type; /* 设备类型 */
+ u32 fe_idx; /* func id */
+} ub_query_dev_cap_t;
+
+#define HINIC5_MAX_BUF_SIZE 262144
+union ub_query_outbuf {
+ struct ub_dfx_tp_ctx_query tp;
+ struct ub_tp_ctx_ext_query tpc_ext;
+ struct ub_mapt_ctx_query mpt;
+ struct ub_jfc_ctx_query jfc_ctx;
+ u64 cmtt[MAX_JFC_CMTT_SIZE];
+ struct ub_ta_context_query jfs_ctx;
+ struct ub_ta_context_query jetty_ctx;
+ struct ub_jetty_grp_ctx_query jetty_grp_ctx;
+ ub_cmd_srq_query_rsp_s srq_ctx;
+ struct ub_ta_context_query rcq_ctx;
+ ub_pcqc_query_rsp_s pcqc;
+ struct ub_rc_queue_wqe rcqe;
+ struct tag_ub_sq_wqe_s jfs_sqe;
+ u8 sqe[UB_MAX_JFS_DFX_BUF];
+ u8 rqe[UB_MAX_JFR_DFX_BUF];
+ u8 cqe[UB_MAX_JFC_DFX_BUF];
+ u8 idx_wqe[UB_MAX_IDX_WQE_DFX_BUF];
+ struct ub_sip_attr sip_attr;
+ struct ub_dip_ctx_query dip_ctx;
+ struct ub_dev_res dev_res;
+ u64 dmtt[HINIC5_MAX_BUF_SIZE];
+ struct ub_tp_wqe tpqe;
+ u32 tp_state_num[UB_TPC_STATE_MAX];
+ struct ub_tpg_ctx_query tpg_ctx;
+ struct ub_vtp_ctx_query vtp_ctx;
+ struct ub_seid_ctx_query seid_ctx;
+ ub_cmd_upi_value_attr_s upi_value;
+ struct ub_tpg_flow tpg_flow;
+ struct ub_cc_params cc_params;
+ struct ub_oor_tp_info oor_tp_info;
+ struct ub_ta_rdma_rc_outbuf ta_rdma_rc;
+ struct ub_query_dev_cap dev_cap;
+ struct ub_cmd_tp_query_srp_bitmap_outbuf srp_bitmap;
+ struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf srp_ctr_bitmap;
+ ub_cc_dfx_info_s cc_info;
+ struct ub_cmd_mig_drain_status_outbuf mig_ctr;
+ struct ub_cmd_func_resp func_info;
+ struct ub_secure_addr_info sec_addr_info;
+ u32 q_depth;
+ u8 dscp_dev[UDMA_DSCP_MAX_NUM];
+ u8 dscp_port[UDMA_DSCP_MAX_NUM];
+ struct ub_ta_rdma_rc_ext_outbuf ta_rdma_rc_ext;
+ struct ub_cmd_get_ub_filter_info_resp func_filter;
+ ub_driver_comm_ctr_t ub_driver_comm_ctr;
+ struct ub_oor_ta_info oor_ta_info;
+ struct ub_msn_entry_outbuf msn_entry_info;
+ struct ub_cmd_safe_dmtt_bitmap_outbuf safe_dmtt_bitmap;
+ struct ub_cmd_safe_dmtt_ctx_outbuf safe_dmtt_ctx;
+ struct ub_ta_latch_data_outbuf ta_latch_data;
+ struct ub_tp_latch_data_outbuf tp_latch_data;
+};
+
+struct ub_capture_info {
+ u32 cap_status;
+ u32 cap_mode;
+ u32 tp_mode;
+ u32 cap_block_num_shift;
+ u32 cap_func;
+ u32 cap_state;
+ u32 cap_max_num;
+ u32 cap_pi;
+ u32 cap_ci;
+};
+
+struct ub_tp_capture_info {
+ u32 tp_num;
+ u32 tpn[UB_CAPTURE_TP_MAX_NUM];
+};
+
+union ub_packet_outbuf {
+ struct ub_capture_info capture_info;
+ struct ub_tp_capture_info tp_capture_info;
+};
+
+struct udma_l2d_tbl_dfx {
+ l2d_ub_dfx_tbl_attr_s attr; /* ub l2d dfx_tbl_attr */
+ l2d_ub_dfx_tbl_mask_s mask; /* ub l2d dfx_tbl_mask */
+};
+struct ub_packet_inbuf {
+ u32 cmd_type;
+ u32 mode;
+ u32 tpn;
+ u32 drop_level;
+ u32 cc_inject_mode;
+ u32 cc_percent;
+ u32 cc_limit_low;
+ u32 cc_limit_high;
+ struct udma_l2d_tbl_dfx data;
+};
+
+struct ub_attack_outbuf {
+ u64 db;
+};
+
+struct ub_attack_inbuf {
+ u32 convert_endian;
+ u32 pi_ci;
+ u32 object;
+ u32 cmd_type;
+ u32 offset;
+ u32 length;
+ u32 srv_type;
+ u32 attack_value[UB_ATTACK_DW_NUM];
+ u32 attack_mask[UB_ATTACK_DW_NUM];
+};
+
+struct ub_cqm_modify_inbuf {
+ u32 cmd_type;
+ u32 xid;
+ u32 offset;
+ u32 length;
+ u32 vf_id;
+ u32 data_len;
+ u8 data[UB_CQM_MODIFY_DATA_LEN + 1];
+ bool is_data_set;
+};
+
+union ub_cqm_modify_outbuf {
+ u32 rsvd;
+};
+
+struct ub_port_traffic {
+ u64 dp_tx_pkt_num;
+ u64 dp_tx_pkt_bytes;
+ u64 dp_rx_pkt_num;
+ u64 dp_rx_pkt_bytes;
+ u64 local_tx_pkt_num;
+ u64 local_tx_pkt_bytes;
+ u64 local_rx_pkt_num;
+ u64 local_rx_pkt_bytes;
+};
+
+union ub_port_sta_outbuf {
+ struct ub_dfx_port_statistics_cmd port_traffic;
+};
+
+struct ub_port_sta_inbuf {
+ u32 cmd_type;
+ u8 port_id;
+ u8 cos;
+ u8 gap;
+ u8 all;
+ u8 exec_cos_set;
+ u8 exec_port_set;
+ u8 exec_time_set;
+ u8 vf_id;
+};
+
+struct ub_perf_ctr_inbuf {
+ u32 cmd_type;
+ u8 gap_index;
+ bool exec_time_set;
+};
+
+struct ub_perf_query_outbuf {
+ u64 dispatch_times; // 成功执行次数
+ u64 cmdq_rtt_sum; // 总时延(单位是纳秒)
+ u64 cmdq_npu_rtt_sum; // 微码部分总时延
+};
+
+struct ub_perf_query_inbuf {
+ u32 cmd_type;
+ u32 xid;
+ u32 vfid;
+ u8 clear_flag;
+};
+
+enum ub_dfx_type {
+ UB_DFX_QUERY = 0x80,
+ UB_DFX_MODIFY = 0x81,
+ UB_DFX_PACKET = 0x82,
+ UB_DFX_PORT_STA = 0x83,
+ UB_DFX_CQM_MODIFY = 0x84,
+ UB_DFX_ATTACK = 0x85,
+ UB_DFX_PERF_CTR = 0x86,
+ UB_DFX_L2D_MEM = 0x87,
+ UB_DFX_PERF_QUERY = 0x88,
+};
+
+enum ub_query_type_source {
+ UB_QUERY_FROM_CACHE = 0,
+ UB_QUERY_FROM_HOST = 1,
+};
+
+enum ub_query_sq_rq {
+ UB_QUERY_SQ = 0,
+ UB_QUERY_RQ = 1,
+};
+
+enum ub_query_sub_type {
+ UB_QUERY_SUB_TYPE_CTX = 0x0,
+ UB_QUERY_SUB_TYPE_MTT = 0x1,
+ UB_QUERY_SUB_TYPE_WQE = 0x2,
+ UB_QUERY_SUB_TYPE_INFO = 0x3,
+ UB_QUERY_SUB_TYPE_SIP = 0x4,
+ UB_QUERY_SUB_TYPE_DIP = 0x5,
+ UB_QUERY_SUB_TYPE_PCQC = 0x6,
+ UB_QUERY_SUB_TYPE_MPT = 0x7,
+ UB_QUERY_SUB_TYPE_SRQ = 0x8,
+ UB_QUERY_SUB_TYPE_CNT = 0x9,
+ UB_QUERY_SUB_TYPE_FLOW = 0xa,
+ UB_QUERY_SUB_TYPE_RDMARC = 0xb,
+ UB_QUERY_SUB_TYPE_OOR_INFO = 0xc,
+ UB_QUERY_SUB_TYPE_TASK_LIST_INFO = 0xd,
+ UB_QUERY_SUB_TYPE_SRP_BITMAP = 0xe,
+ UB_QUERY_SUB_TYPE_SRP_CTR_BITMAP = 0xf,
+ UB_QUERY_SUB_TYPE_CC_INFO = 0x10,
+ UB_QUERY_SUB_TYPE_FUNC_INFO = 0x11,
+ UB_QUERY_SUB_TYPE_MIG_COUNTER_INFO = 0x12,
+ UB_QUERY_SUB_TYPE_INVALID = 0x13,
+ UB_QUERY_SUB_TYPE_CAP = 0x14,
+ UB_QUERY_SUB_TYPE_SECURE_MEM_INFO = 0x15,
+ UB_QUERY_SUB_TYPE_Q_DEPTH = 0x16,
+ UB_QUERY_SUB_TYPE_DSCP = 0x17,
+ UB_QUERY_SUB_TYPE_RDMARC_EXT = 0x18,
+ UB_QUERY_SUB_TYPE_CTX_EXT = 0x19,
+ UB_QUERY_SUB_TYPE_SAFE_DMTT_BITMAP =
+ 0x1a, /* 1823 添加,考虑1825 1823兼容性预留 */
+ UB_QUERY_SUB_TYPE_SAFE_DMTT_CTX =
+ 0x1b, /* 1823 添加,考虑1825 1823兼容性预留 */
+ UB_QUERY_SUB_TYPE_IDX_WQE = 0x1c,
+ UB_QUERY_SUB_TYPE_IO_STAT = 0x1d,
+ UB_QUERY_SUB_TYPE_TA_OOR_INFO = 0x1e,
+ UB_QUERY_SUB_TYPE_MSN_ENTRY = 0x1f,
+ UB_QUERY_SUB_TYPE_TA_LATCH =
+ 0x20, /* 1823 1825 TA锁存信息查询命令归一 */
+ UB_QUERY_SUB_TYPE_TP_LATCH = 0X21, /* 1825 添加TP锁存信息查询 */
+ UB_QUERY_SUB_TYPE_XSN_TP =
+ 0X22, /* UB_QUERY_TYPE_XSN 的 subtype 不会作为cmd传给芯片 */
+ UB_QUERY_SUB_TYPE_XSN_TPG = 0X23
+ /* 考虑兼容性,增加消息id,只能往后追加 */
+};
+
+enum udma_query_cmd_type {
+ UB_QUERY_TYPE_JFS = 0x0,
+ UB_QUERY_TYPE_JFR = 0x1,
+ UB_QUERY_TYPE_JFC = 0x2,
+ UB_QUERY_TYPE_JETTY = 0x3,
+ UB_QUERY_TYPE_JETTY_GROUP = 0x4,
+ UB_QUERY_TYPE_SEG = 0x5,
+ UB_QUERY_TYPE_DEV = 0x6,
+ UB_QUERY_TYPE_TP = 0x7,
+ UB_QUERY_TYPE_TPG = 0x8,
+ UB_QUERY_TYPE_VTP = 0x9,
+ UB_QUERY_TYPE_RC_QUEUE = 0xa,
+ UB_QUERY_TYPE_UPI = 0xb,
+ UB_QUERY_TYPE_CC = 0xc,
+ UB_QUERY_TYPE_SEID = 0xd,
+ UB_QUERY_TYPE_MIG = 0xe,
+ UB_QUERY_TYPE_LATCH = 0xf,
+ UB_QUERY_TYPE_XSN = 0x10, /* UB_QUERY_TYPE_XSN 不会作为cmd传给芯片 */
+ UB_QUERY_TYPE_INVALID,
+ /* 考虑兼容性,增加消息id,只能往后追加 */
+};
+
+enum udma_packet_cmd_type {
+ /* 抓包 */
+ UB_CMD_START_CAP_PACKET = 0x0, /* 兼容性预留,暂无使用 */
+ UB_CMD_STOP_CAP_PACKET = 0x1, /* 兼容性预留,暂无使用 */
+ UB_CMD_QUERY_CAP_INFO = 0x2, /* 兼容性预留,暂无使用 */
+ UB_CMD_ENABLE_TP_CAP_PACKET = 0x3, /* 兼容性预留,暂无使用 */
+ UB_CMD_DISABLE_TP_CAP_PACKET = 0x4,
+ UB_CMD_QUERY_TP_CAP_INFO = 0x5, /* 兼容性预留,暂无使用 */
+
+ /* 丢包 */
+ UB_CMD_START_DROP_FUNC_PACKET = 0x6,
+ UB_CMD_STOP_DROP_FUNC_PACKET = 0x7,
+ UB_CMD_START_DROP_TP_PACKET = 0x8,
+ UB_CMD_STOP_DROP_TP_PACKET = 0x9,
+
+ /* CC capture */
+ UB_CMD_CC_INJECT = 0xa,
+
+ /* 丢包 */
+ UB_CMD_START_DROP_CARD_PACKET = 0xb,
+ UB_CMD_STOP_DROP_CARD_PACKET = 0xc,
+ /* 考虑兼容性,增加消息id,只能往后追加 */
+};
+
+enum udma_modity_cmd_type {
+ UB_MODIFY_TYPE_TP = 0x0,
+ UB_MODIFY_TYPE_TPG_MULTIPATH = 0x1,
+ UB_MODIFY_TYPE_CC = 0x2,
+ UB_MODIFY_TYPE_TP_SRP = 0x3,
+ UB_MODIFY_TYPE_AEQE = 0x4,
+ UB_MODIFY_TYPE_DROP_AEQE = 0x5,
+ UB_MODIFY_TYPE_QOS = 0x6,
+ UB_MODIFY_TYPE_MUL_MODE = 0x7,
+ UB_MODIFY_TYPE_FUNC_TABLE = 0x8,
+ UB_MODIFY_TYPE_CFG_COS_EN = 0x9,
+ UB_MODIFY_TYPE_DEVICE = 0xa,
+ UB_MODIFY_TYPE_JETTY = 0xb,
+ UB_MODIFY_TYPE_LATCH_LOCK = 0xc,
+ UB_MODIFY_TYPE_INVALID,
+ /* 考虑兼容性,增加消息id,只能往后追加 */
+};
+
+enum udma_modity_cmd_sub_type {
+ UB_MODIFY_SUB_TYPE_SRP_BITMAP = 0x0,
+ UB_MODIFY_SUB_TYPE_SRP_CTR_BITMAP = 0x1,
+ UB_MODIFY_SUB_TYPE_FUNC_MAPPING = 0x2,
+ UB_MODIFY_SUB_TYPE_BPS = 0x3,
+ UB_MODIFY_SUB_TYPE_PPS = 0x4,
+ UB_MODIFY_SUB_TYPE_Q_DEPTH = 0x5,
+ UB_MODIFY_SUB_TYPE_MTU_1K_EN = 0x6,
+ UB_MODIFY_SUB_TYPE_CLEAR_IO_STAT = 0x7,
+ UB_MODIFY_SUB_TYPE_CLEAR_TA_LATCH_LOCK = 0x8,
+ UB_MODIFY_SUB_TYPE_CLEAR_TP_LATCH_LOCK = 0x9,
+ UB_MODIFY_SUB_TYPE_MAX_JETTY = 0xa,
+ UB_MODIFY_SUB_TYPE_INVALID,
+ /* 考虑兼容性,增加消息id,只能往后追加 */
+};
+
+enum ub_attack_type {
+ UB_ATTACK_TYPE_DB = 0,
+ UB_ATTACK_TYPE_WQE,
+ UB_ATTACK_TYPE_MTT,
+ UB_ATTACK_TYPE_PICI,
+ UB_ATTACK_TYPE_TAMSN,
+ UB_ATTACK_TYPE_INVALID
+};
+
+enum ub_attack_sub_type {
+ UB_ATTACK_SUB_TYPE_JETTY = 0,
+ UB_ATTACK_SUB_TYPE_JFS,
+ UB_ATTACK_SUB_TYPE_JFR,
+ UB_ATTACK_SUB_TYPE_JFRC,
+ UB_ATTACK_SUB_TYPE_JFC,
+ UB_ATTACK_SUB_TYPE_SEG,
+ UB_ATTACK_SUB_TYPE_IDX_Q,
+ UB_ATTACK_SUB_TYPE_INVALID
+};
+
+enum udma_port_sta_cmd_type {
+ UB_PORT_STA_RTCB = 0,
+ UB_VF_STA_RTCB,
+};
+
+enum udma_performance_cmd_type {
+ UB_PERF_CMD_TYPE = 0,
+};
+
+enum udma_cqm_modify_cmd_type {
+ UB_CQM_MODIFY_TYPE_JETTY_CTX = 0x0,
+ UB_CQM_MODIFY_TYPE_TP_CTX = 0x1,
+ UB_CQM_MODIFY_TYPE_JFR_SRQ_CTX = 0x2,
+ UB_CQM_MODIFY_TYPE_JFR_CTX = 0x3,
+ UB_CQM_MODIFY_TYPE_JFC_CTX = 0x4,
+ UB_CQM_MODIFY_TYPE_SEG_CTX = 0x5,
+ UB_CQM_MODIFY_TYPE_JFS_CTX = 0x6,
+ UB_CQM_MODIFY_TYPE_JFRC_CTX = 0x7,
+ UB_CQM_MODIFY_TYPE_CLEAR_LATCH_LOCK = 0x8,
+ UB_CQM_MODIFY_TYPE_VTP_CTX = 0x9,
+ UB_CQM_MODIFY_TYPE_TPG_CTX = 0xa,
+ UB_CQM_MODIFY_TYPE_JFRC_PCQC = 0xb,
+ UB_CQM_MODIFY_TYPE_SIP_TBL = 0xc,
+ UB_CQM_MODIFY_TYPE_INVALID,
+ /* 考虑兼容性,增加消息id,只能往后追加 */
+};
+
+static inline u32 ub_dfx_get_cmd_type(u32 cmd_type, u32 sub_type,
+ u32 source_type)
+{
+ return ((cmd_type << UB_QUERY_TYPE_BIT) + (sub_type << 1) +
+ source_type);
+}
+
+#define UB_DFX_QUERY_SOURCE_TYPE_BIT (1U)
+#define UB_DFX_QUERY_SOURCE_TYPE_SHIELD_MASK (~UB_DFX_QUERY_SOURCE_TYPE_BIT)
+
+#endif /* UB_PUB_CMD_H */
--
2.37.7
2
1