]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 288
[mirror_ubuntu-focal-kernel.git] / drivers / net / ethernet / huawei / hinic / hinic_hw_mgmt.c
CommitLineData
2025cf9e 1// SPDX-License-Identifier: GPL-2.0-only
a5564e7e
AK
2/*
3 * Huawei HiNIC PCI Express Linux driver
4 * Copyright(c) 2017 Huawei Technologies Co., Ltd
a5564e7e
AK
5 */
6
7#include <linux/kernel.h>
8#include <linux/types.h>
9#include <linux/errno.h>
6dd8b682
AK
10#include <linux/pci.h>
11#include <linux/device.h>
12#include <linux/semaphore.h>
13#include <linux/completion.h>
14#include <linux/slab.h>
15#include <asm/barrier.h>
a5564e7e
AK
16
17#include "hinic_hw_if.h"
18#include "hinic_hw_eqs.h"
eabf0fad 19#include "hinic_hw_api_cmd.h"
a5564e7e
AK
20#include "hinic_hw_mgmt.h"
21#include "hinic_hw_dev.h"
22
6dd8b682
AK
23#define SYNC_MSG_ID_MASK 0x1FF
24
25#define SYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->sync_msg_id)
26
27#define SYNC_MSG_ID_INC(pf_to_mgmt) (SYNC_MSG_ID(pf_to_mgmt) = \
28 ((SYNC_MSG_ID(pf_to_mgmt) + 1) & \
29 SYNC_MSG_ID_MASK))
30
31#define MSG_SZ_IS_VALID(in_size) ((in_size) <= MAX_MSG_LEN)
32
33#define MGMT_MSG_LEN_MIN 20
34#define MGMT_MSG_LEN_STEP 16
35#define MGMT_MSG_RSVD_FOR_DEV 8
36
37#define SEGMENT_LEN 48
38
39#define MAX_PF_MGMT_BUF_SIZE 2048
40
41/* Data should be SEG LEN size aligned */
42#define MAX_MSG_LEN 2016
43
44#define MSG_NOT_RESP 0xFFFF
45
46#define MGMT_MSG_TIMEOUT 1000
47
a5564e7e
AK
48#define mgmt_to_pfhwdev(pf_mgmt) \
49 container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt)
50
6dd8b682
AK
51enum msg_segment_type {
52 NOT_LAST_SEGMENT = 0,
53 LAST_SEGMENT = 1,
54};
55
56enum mgmt_direction_type {
57 MGMT_DIRECT_SEND = 0,
58 MGMT_RESP = 1,
59};
60
61enum msg_ack_type {
62 MSG_ACK = 0,
63 MSG_NO_ACK = 1,
64};
65
c4d06d2d
AK
66/**
67 * hinic_register_mgmt_msg_cb - register msg handler for a msg from a module
68 * @pf_to_mgmt: PF to MGMT channel
69 * @mod: module in the chip that this handler will handle its messages
70 * @handle: private data for the callback
71 * @callback: the handler that will handle messages
72 **/
73void hinic_register_mgmt_msg_cb(struct hinic_pf_to_mgmt *pf_to_mgmt,
74 enum hinic_mod_type mod,
75 void *handle,
76 void (*callback)(void *handle,
77 u8 cmd, void *buf_in,
78 u16 in_size, void *buf_out,
79 u16 *out_size))
80{
81 struct hinic_mgmt_cb *mgmt_cb = &pf_to_mgmt->mgmt_cb[mod];
82
83 mgmt_cb->cb = callback;
84 mgmt_cb->handle = handle;
85 mgmt_cb->state = HINIC_MGMT_CB_ENABLED;
86}
87
88/**
89 * hinic_unregister_mgmt_msg_cb - unregister msg handler for a msg from a module
90 * @pf_to_mgmt: PF to MGMT channel
91 * @mod: module in the chip that this handler handles its messages
92 **/
93void hinic_unregister_mgmt_msg_cb(struct hinic_pf_to_mgmt *pf_to_mgmt,
94 enum hinic_mod_type mod)
95{
96 struct hinic_mgmt_cb *mgmt_cb = &pf_to_mgmt->mgmt_cb[mod];
97
98 mgmt_cb->state &= ~HINIC_MGMT_CB_ENABLED;
99
100 while (mgmt_cb->state & HINIC_MGMT_CB_RUNNING)
101 schedule();
102
103 mgmt_cb->cb = NULL;
104}
105
6dd8b682
AK
106/**
107 * prepare_header - prepare the header of the message
108 * @pf_to_mgmt: PF to MGMT channel
109 * @msg_len: the length of the message
110 * @mod: module in the chip that will get the message
111 * @ack_type: ask for response
112 * @direction: the direction of the message
113 * @cmd: command of the message
114 * @msg_id: message id
115 *
116 * Return the prepared header value
117 **/
118static u64 prepare_header(struct hinic_pf_to_mgmt *pf_to_mgmt,
119 u16 msg_len, enum hinic_mod_type mod,
120 enum msg_ack_type ack_type,
121 enum mgmt_direction_type direction,
122 u16 cmd, u16 msg_id)
123{
124 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
125
126 return HINIC_MSG_HEADER_SET(msg_len, MSG_LEN) |
127 HINIC_MSG_HEADER_SET(mod, MODULE) |
128 HINIC_MSG_HEADER_SET(SEGMENT_LEN, SEG_LEN) |
129 HINIC_MSG_HEADER_SET(ack_type, NO_ACK) |
130 HINIC_MSG_HEADER_SET(0, ASYNC_MGMT_TO_PF) |
131 HINIC_MSG_HEADER_SET(0, SEQID) |
132 HINIC_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
133 HINIC_MSG_HEADER_SET(direction, DIRECTION) |
134 HINIC_MSG_HEADER_SET(cmd, CMD) |
135 HINIC_MSG_HEADER_SET(HINIC_HWIF_PCI_INTF(hwif), PCI_INTF) |
136 HINIC_MSG_HEADER_SET(HINIC_HWIF_PF_IDX(hwif), PF_IDX) |
137 HINIC_MSG_HEADER_SET(msg_id, MSG_ID);
138}
139
140/**
141 * prepare_mgmt_cmd - prepare the mgmt command
142 * @mgmt_cmd: pointer to the command to prepare
143 * @header: pointer of the header for the message
144 * @msg: the data of the message
145 * @msg_len: the length of the message
146 **/
147static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, u8 *msg, u16 msg_len)
148{
149 memset(mgmt_cmd, 0, MGMT_MSG_RSVD_FOR_DEV);
150
151 mgmt_cmd += MGMT_MSG_RSVD_FOR_DEV;
152 memcpy(mgmt_cmd, header, sizeof(*header));
153
154 mgmt_cmd += sizeof(*header);
155 memcpy(mgmt_cmd, msg, msg_len);
156}
157
158/**
159 * mgmt_msg_len - calculate the total message length
160 * @msg_data_len: the length of the message data
161 *
162 * Return the total message length
163 **/
164static u16 mgmt_msg_len(u16 msg_data_len)
165{
166 /* RSVD + HEADER_SIZE + DATA_LEN */
167 u16 msg_len = MGMT_MSG_RSVD_FOR_DEV + sizeof(u64) + msg_data_len;
168
169 if (msg_len > MGMT_MSG_LEN_MIN)
170 msg_len = MGMT_MSG_LEN_MIN +
171 ALIGN((msg_len - MGMT_MSG_LEN_MIN),
172 MGMT_MSG_LEN_STEP);
173 else
174 msg_len = MGMT_MSG_LEN_MIN;
175
176 return msg_len;
177}
178
179/**
180 * send_msg_to_mgmt - send message to mgmt by API CMD
181 * @pf_to_mgmt: PF to MGMT channel
182 * @mod: module in the chip that will get the message
183 * @cmd: command of the message
184 * @data: the msg data
185 * @data_len: the msg data length
186 * @ack_type: ask for response
187 * @direction: the direction of the original message
188 * @resp_msg_id: msg id to response for
189 *
190 * Return 0 - Success, negative - Failure
191 **/
192static int send_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt,
193 enum hinic_mod_type mod, u8 cmd,
194 u8 *data, u16 data_len,
195 enum msg_ack_type ack_type,
196 enum mgmt_direction_type direction,
197 u16 resp_msg_id)
198{
199 struct hinic_api_cmd_chain *chain;
200 u64 header;
201 u16 msg_id;
202
203 msg_id = SYNC_MSG_ID(pf_to_mgmt);
204
205 if (direction == MGMT_RESP) {
206 header = prepare_header(pf_to_mgmt, data_len, mod, ack_type,
207 direction, cmd, resp_msg_id);
208 } else {
209 SYNC_MSG_ID_INC(pf_to_mgmt);
210 header = prepare_header(pf_to_mgmt, data_len, mod, ack_type,
211 direction, cmd, msg_id);
212 }
213
214 prepare_mgmt_cmd(pf_to_mgmt->sync_msg_buf, &header, data, data_len);
215
216 chain = pf_to_mgmt->cmd_chain[HINIC_API_CMD_WRITE_TO_MGMT_CPU];
217 return hinic_api_cmd_write(chain, HINIC_NODE_ID_MGMT,
218 pf_to_mgmt->sync_msg_buf,
219 mgmt_msg_len(data_len));
220}
221
222/**
223 * msg_to_mgmt_sync - send sync message to mgmt
224 * @pf_to_mgmt: PF to MGMT channel
225 * @mod: module in the chip that will get the message
226 * @cmd: command of the message
227 * @buf_in: the msg data
228 * @in_size: the msg data length
229 * @buf_out: response
230 * @out_size: response length
231 * @direction: the direction of the original message
232 * @resp_msg_id: msg id to response for
233 *
234 * Return 0 - Success, negative - Failure
235 **/
236static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt,
237 enum hinic_mod_type mod, u8 cmd,
238 u8 *buf_in, u16 in_size,
239 u8 *buf_out, u16 *out_size,
240 enum mgmt_direction_type direction,
241 u16 resp_msg_id)
242{
243 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
244 struct pci_dev *pdev = hwif->pdev;
245 struct hinic_recv_msg *recv_msg;
246 struct completion *recv_done;
247 u16 msg_id;
248 int err;
249
250 /* Lock the sync_msg_buf */
251 down(&pf_to_mgmt->sync_msg_lock);
252
253 recv_msg = &pf_to_mgmt->recv_resp_msg_from_mgmt;
254 recv_done = &recv_msg->recv_done;
255
256 if (resp_msg_id == MSG_NOT_RESP)
257 msg_id = SYNC_MSG_ID(pf_to_mgmt);
258 else
259 msg_id = resp_msg_id;
260
261 init_completion(recv_done);
262
263 err = send_msg_to_mgmt(pf_to_mgmt, mod, cmd, buf_in, in_size,
264 MSG_ACK, direction, resp_msg_id);
265 if (err) {
266 dev_err(&pdev->dev, "Failed to send sync msg to mgmt\n");
267 goto unlock_sync_msg;
268 }
269
270 if (!wait_for_completion_timeout(recv_done, MGMT_MSG_TIMEOUT)) {
271 dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
272 err = -ETIMEDOUT;
273 goto unlock_sync_msg;
274 }
275
276 smp_rmb(); /* verify reading after completion */
277
278 if (recv_msg->msg_id != msg_id) {
279 dev_err(&pdev->dev, "incorrect MSG for id = %d\n", msg_id);
280 err = -EFAULT;
281 goto unlock_sync_msg;
282 }
283
284 if ((buf_out) && (recv_msg->msg_len <= MAX_PF_MGMT_BUF_SIZE)) {
285 memcpy(buf_out, recv_msg->msg, recv_msg->msg_len);
286 *out_size = recv_msg->msg_len;
287 }
288
289unlock_sync_msg:
290 up(&pf_to_mgmt->sync_msg_lock);
291 return err;
292}
293
294/**
295 * msg_to_mgmt_async - send message to mgmt without response
296 * @pf_to_mgmt: PF to MGMT channel
297 * @mod: module in the chip that will get the message
298 * @cmd: command of the message
299 * @buf_in: the msg data
300 * @in_size: the msg data length
301 * @direction: the direction of the original message
302 * @resp_msg_id: msg id to response for
303 *
304 * Return 0 - Success, negative - Failure
305 **/
306static int msg_to_mgmt_async(struct hinic_pf_to_mgmt *pf_to_mgmt,
307 enum hinic_mod_type mod, u8 cmd,
308 u8 *buf_in, u16 in_size,
309 enum mgmt_direction_type direction,
310 u16 resp_msg_id)
311{
312 int err;
313
314 /* Lock the sync_msg_buf */
315 down(&pf_to_mgmt->sync_msg_lock);
316
317 err = send_msg_to_mgmt(pf_to_mgmt, mod, cmd, buf_in, in_size,
318 MSG_NO_ACK, direction, resp_msg_id);
319
320 up(&pf_to_mgmt->sync_msg_lock);
321 return err;
322}
323
a5564e7e
AK
324/**
325 * hinic_msg_to_mgmt - send message to mgmt
326 * @pf_to_mgmt: PF to MGMT channel
327 * @mod: module in the chip that will get the message
328 * @cmd: command of the message
329 * @buf_in: the msg data
330 * @in_size: the msg data length
331 * @buf_out: response
332 * @out_size: returned response length
333 * @sync: sync msg or async msg
334 *
335 * Return 0 - Success, negative - Failure
336 **/
337int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt,
338 enum hinic_mod_type mod, u8 cmd,
339 void *buf_in, u16 in_size, void *buf_out, u16 *out_size,
340 enum hinic_mgmt_msg_type sync)
341{
6dd8b682
AK
342 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
343 struct pci_dev *pdev = hwif->pdev;
344
345 if (sync != HINIC_MGMT_MSG_SYNC) {
346 dev_err(&pdev->dev, "Invalid MGMT msg type\n");
347 return -EINVAL;
348 }
349
350 if (!MSG_SZ_IS_VALID(in_size)) {
351 dev_err(&pdev->dev, "Invalid MGMT msg buffer size\n");
352 return -EINVAL;
353 }
354
355 return msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size,
356 buf_out, out_size, MGMT_DIRECT_SEND,
357 MSG_NOT_RESP);
358}
359
360/**
361 * mgmt_recv_msg_handler - handler for message from mgmt cpu
362 * @pf_to_mgmt: PF to MGMT channel
363 * @recv_msg: received message details
364 **/
365static void mgmt_recv_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt,
366 struct hinic_recv_msg *recv_msg)
367{
368 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
369 struct pci_dev *pdev = hwif->pdev;
370 u8 *buf_out = recv_msg->buf_out;
c4d06d2d
AK
371 struct hinic_mgmt_cb *mgmt_cb;
372 unsigned long cb_state;
6dd8b682
AK
373 u16 out_size = 0;
374
c4d06d2d
AK
375 if (recv_msg->mod >= HINIC_MOD_MAX) {
376 dev_err(&pdev->dev, "Unknown MGMT MSG module = %d\n",
377 recv_msg->mod);
378 return;
379 }
380
381 mgmt_cb = &pf_to_mgmt->mgmt_cb[recv_msg->mod];
382
383 cb_state = cmpxchg(&mgmt_cb->state,
384 HINIC_MGMT_CB_ENABLED,
385 HINIC_MGMT_CB_ENABLED | HINIC_MGMT_CB_RUNNING);
386
387 if ((cb_state == HINIC_MGMT_CB_ENABLED) && (mgmt_cb->cb))
388 mgmt_cb->cb(mgmt_cb->handle, recv_msg->cmd,
389 recv_msg->msg, recv_msg->msg_len,
390 buf_out, &out_size);
391 else
392 dev_err(&pdev->dev, "No MGMT msg handler, mod = %d\n",
393 recv_msg->mod);
394
395 mgmt_cb->state &= ~HINIC_MGMT_CB_RUNNING;
6dd8b682
AK
396
397 if (!recv_msg->async_mgmt_to_pf)
398 /* MGMT sent sync msg, send the response */
399 msg_to_mgmt_async(pf_to_mgmt, recv_msg->mod, recv_msg->cmd,
400 buf_out, out_size, MGMT_RESP,
401 recv_msg->msg_id);
402}
403
404/**
405 * mgmt_resp_msg_handler - handler for a response message from mgmt cpu
406 * @pf_to_mgmt: PF to MGMT channel
407 * @recv_msg: received message details
408 **/
409static void mgmt_resp_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt,
410 struct hinic_recv_msg *recv_msg)
411{
412 wmb(); /* verify writing all, before reading */
413
414 complete(&recv_msg->recv_done);
415}
416
417/**
418 * recv_mgmt_msg_handler - handler for a message from mgmt cpu
419 * @pf_to_mgmt: PF to MGMT channel
420 * @header: the header of the message
421 * @recv_msg: received message details
422 **/
423static void recv_mgmt_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt,
424 u64 *header, struct hinic_recv_msg *recv_msg)
425{
426 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
427 struct pci_dev *pdev = hwif->pdev;
428 int seq_id, seg_len;
429 u8 *msg_body;
430
431 seq_id = HINIC_MSG_HEADER_GET(*header, SEQID);
432 seg_len = HINIC_MSG_HEADER_GET(*header, SEG_LEN);
433
434 if (seq_id >= (MAX_MSG_LEN / SEGMENT_LEN)) {
435 dev_err(&pdev->dev, "recv big mgmt msg\n");
436 return;
437 }
438
439 msg_body = (u8 *)header + sizeof(*header);
440 memcpy(recv_msg->msg + seq_id * SEGMENT_LEN, msg_body, seg_len);
441
442 if (!HINIC_MSG_HEADER_GET(*header, LAST))
443 return;
444
445 recv_msg->cmd = HINIC_MSG_HEADER_GET(*header, CMD);
446 recv_msg->mod = HINIC_MSG_HEADER_GET(*header, MODULE);
447 recv_msg->async_mgmt_to_pf = HINIC_MSG_HEADER_GET(*header,
448 ASYNC_MGMT_TO_PF);
449 recv_msg->msg_len = HINIC_MSG_HEADER_GET(*header, MSG_LEN);
450 recv_msg->msg_id = HINIC_MSG_HEADER_GET(*header, MSG_ID);
451
452 if (HINIC_MSG_HEADER_GET(*header, DIRECTION) == MGMT_RESP)
453 mgmt_resp_msg_handler(pf_to_mgmt, recv_msg);
454 else
455 mgmt_recv_msg_handler(pf_to_mgmt, recv_msg);
a5564e7e
AK
456}
457
458/**
459 * mgmt_msg_aeqe_handler - handler for a mgmt message event
460 * @handle: PF to MGMT channel
461 * @data: the header of the message
462 * @size: unused
463 **/
464static void mgmt_msg_aeqe_handler(void *handle, void *data, u8 size)
465{
6dd8b682
AK
466 struct hinic_pf_to_mgmt *pf_to_mgmt = handle;
467 struct hinic_recv_msg *recv_msg;
468 u64 *header = (u64 *)data;
469
470 recv_msg = HINIC_MSG_HEADER_GET(*header, DIRECTION) ==
471 MGMT_DIRECT_SEND ?
472 &pf_to_mgmt->recv_msg_from_mgmt :
473 &pf_to_mgmt->recv_resp_msg_from_mgmt;
474
475 recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg);
476}
477
478/**
479 * alloc_recv_msg - allocate receive message memory
480 * @pf_to_mgmt: PF to MGMT channel
481 * @recv_msg: pointer that will hold the allocated data
482 *
483 * Return 0 - Success, negative - Failure
484 **/
485static int alloc_recv_msg(struct hinic_pf_to_mgmt *pf_to_mgmt,
486 struct hinic_recv_msg *recv_msg)
487{
488 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
489 struct pci_dev *pdev = hwif->pdev;
490
491 recv_msg->msg = devm_kzalloc(&pdev->dev, MAX_PF_MGMT_BUF_SIZE,
492 GFP_KERNEL);
493 if (!recv_msg->msg)
494 return -ENOMEM;
495
496 recv_msg->buf_out = devm_kzalloc(&pdev->dev, MAX_PF_MGMT_BUF_SIZE,
497 GFP_KERNEL);
498 if (!recv_msg->buf_out)
499 return -ENOMEM;
500
501 return 0;
502}
503
504/**
505 * alloc_msg_buf - allocate all the message buffers of PF to MGMT channel
506 * @pf_to_mgmt: PF to MGMT channel
507 *
508 * Return 0 - Success, negative - Failure
509 **/
510static int alloc_msg_buf(struct hinic_pf_to_mgmt *pf_to_mgmt)
511{
512 struct hinic_hwif *hwif = pf_to_mgmt->hwif;
513 struct pci_dev *pdev = hwif->pdev;
514 int err;
515
516 err = alloc_recv_msg(pf_to_mgmt,
517 &pf_to_mgmt->recv_msg_from_mgmt);
518 if (err) {
519 dev_err(&pdev->dev, "Failed to allocate recv msg\n");
520 return err;
521 }
522
523 err = alloc_recv_msg(pf_to_mgmt,
524 &pf_to_mgmt->recv_resp_msg_from_mgmt);
525 if (err) {
526 dev_err(&pdev->dev, "Failed to allocate resp recv msg\n");
527 return err;
528 }
529
530 pf_to_mgmt->sync_msg_buf = devm_kzalloc(&pdev->dev,
531 MAX_PF_MGMT_BUF_SIZE,
532 GFP_KERNEL);
533 if (!pf_to_mgmt->sync_msg_buf)
534 return -ENOMEM;
535
536 return 0;
a5564e7e
AK
537}
538
539/**
540 * hinic_pf_to_mgmt_init - initialize PF to MGMT channel
541 * @pf_to_mgmt: PF to MGMT channel
542 * @hwif: HW interface the PF to MGMT will use for accessing HW
543 *
544 * Return 0 - Success, negative - Failure
545 **/
546int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt,
547 struct hinic_hwif *hwif)
548{
549 struct hinic_pfhwdev *pfhwdev = mgmt_to_pfhwdev(pf_to_mgmt);
550 struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
eabf0fad
AK
551 struct pci_dev *pdev = hwif->pdev;
552 int err;
a5564e7e
AK
553
554 pf_to_mgmt->hwif = hwif;
555
6dd8b682
AK
556 sema_init(&pf_to_mgmt->sync_msg_lock, 1);
557 pf_to_mgmt->sync_msg_id = 0;
558
559 err = alloc_msg_buf(pf_to_mgmt);
560 if (err) {
561 dev_err(&pdev->dev, "Failed to allocate msg buffers\n");
562 return err;
563 }
564
eabf0fad
AK
565 err = hinic_api_cmd_init(pf_to_mgmt->cmd_chain, hwif);
566 if (err) {
567 dev_err(&pdev->dev, "Failed to initialize cmd chains\n");
568 return err;
569 }
570
a5564e7e
AK
571 hinic_aeq_register_hw_cb(&hwdev->aeqs, HINIC_MSG_FROM_MGMT_CPU,
572 pf_to_mgmt,
573 mgmt_msg_aeqe_handler);
574 return 0;
575}
576
577/**
578 * hinic_pf_to_mgmt_free - free PF to MGMT channel
579 * @pf_to_mgmt: PF to MGMT channel
580 **/
581void hinic_pf_to_mgmt_free(struct hinic_pf_to_mgmt *pf_to_mgmt)
582{
583 struct hinic_pfhwdev *pfhwdev = mgmt_to_pfhwdev(pf_to_mgmt);
584 struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
585
586 hinic_aeq_unregister_hw_cb(&hwdev->aeqs, HINIC_MSG_FROM_MGMT_CPU);
eabf0fad 587 hinic_api_cmd_free(pf_to_mgmt->cmd_chain);
a5564e7e 588}