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