1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Huawei HiNIC PCI Express Linux driver 4 * Copyright(c) 2017 Huawei Technologies Co., Ltd 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/types.h> 9 #include <linux/pci.h> 10 #include <linux/device.h> 11 #include <linux/errno.h> 12 #include <linux/slab.h> 13 #include <linux/bitops.h> 14 #include <linux/delay.h> 15 #include <linux/jiffies.h> 16 #include <linux/log2.h> 17 #include <linux/err.h> 18 #include <linux/netdevice.h> 19 #include <net/devlink.h> 20 21 #include "hinic_devlink.h" 22 #include "hinic_sriov.h" 23 #include "hinic_dev.h" 24 #include "hinic_hw_if.h" 25 #include "hinic_hw_eqs.h" 26 #include "hinic_hw_mgmt.h" 27 #include "hinic_hw_qp_ctxt.h" 28 #include "hinic_hw_qp.h" 29 #include "hinic_hw_io.h" 30 #include "hinic_hw_dev.h" 31 32 #define IO_STATUS_TIMEOUT 100 33 #define OUTBOUND_STATE_TIMEOUT 100 34 #define DB_STATE_TIMEOUT 100 35 36 #define MAX_IRQS(max_qps, num_aeqs, num_ceqs) \ 37 (2 * (max_qps) + (num_aeqs) + (num_ceqs)) 38 39 #define ADDR_IN_4BYTES(addr) ((addr) >> 2) 40 41 enum intr_type { 42 INTR_MSIX_TYPE, 43 }; 44 45 enum io_status { 46 IO_STOPPED = 0, 47 IO_RUNNING = 1, 48 }; 49 50 /** 51 * parse_capability - convert device capabilities to NIC capabilities 52 * @hwdev: the HW device to set and convert device capabilities for 53 * @dev_cap: device capabilities from FW 54 * 55 * Return 0 - Success, negative - Failure 56 **/ 57 static int parse_capability(struct hinic_hwdev *hwdev, 58 struct hinic_dev_cap *dev_cap) 59 { 60 struct hinic_cap *nic_cap = &hwdev->nic_cap; 61 int num_aeqs, num_ceqs, num_irqs; 62 63 if (!HINIC_IS_VF(hwdev->hwif) && dev_cap->intr_type != INTR_MSIX_TYPE) 64 return -EFAULT; 65 66 num_aeqs = HINIC_HWIF_NUM_AEQS(hwdev->hwif); 67 num_ceqs = HINIC_HWIF_NUM_CEQS(hwdev->hwif); 68 num_irqs = HINIC_HWIF_NUM_IRQS(hwdev->hwif); 69 70 /* Each QP has its own (SQ + RQ) interrupts */ 71 nic_cap->num_qps = (num_irqs - (num_aeqs + num_ceqs)) / 2; 72 73 if (nic_cap->num_qps > HINIC_Q_CTXT_MAX) 74 nic_cap->num_qps = HINIC_Q_CTXT_MAX; 75 76 if (!HINIC_IS_VF(hwdev->hwif)) 77 nic_cap->max_qps = dev_cap->max_sqs + 1; 78 else 79 nic_cap->max_qps = dev_cap->max_sqs; 80 81 if (nic_cap->num_qps > nic_cap->max_qps) 82 nic_cap->num_qps = nic_cap->max_qps; 83 84 if (!HINIC_IS_VF(hwdev->hwif)) { 85 nic_cap->max_vf = dev_cap->max_vf; 86 nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1; 87 } 88 89 hwdev->port_id = dev_cap->port_id; 90 91 return 0; 92 } 93 94 /** 95 * get_capability - get device capabilities from FW 96 * @pfhwdev: the PF HW device to get capabilities for 97 * 98 * Return 0 - Success, negative - Failure 99 **/ 100 static int get_capability(struct hinic_pfhwdev *pfhwdev) 101 { 102 struct hinic_hwdev *hwdev = &pfhwdev->hwdev; 103 struct hinic_hwif *hwif = hwdev->hwif; 104 struct pci_dev *pdev = hwif->pdev; 105 struct hinic_dev_cap dev_cap; 106 u16 out_len; 107 int err; 108 109 out_len = sizeof(dev_cap); 110 111 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_CFGM, 112 HINIC_CFG_NIC_CAP, &dev_cap, sizeof(dev_cap), 113 &dev_cap, &out_len, HINIC_MGMT_MSG_SYNC); 114 if (err) { 115 dev_err(&pdev->dev, "Failed to get capability from FW\n"); 116 return err; 117 } 118 119 return parse_capability(hwdev, &dev_cap); 120 } 121 122 /** 123 * get_dev_cap - get device capabilities 124 * @hwdev: the NIC HW device to get capabilities for 125 * 126 * Return 0 - Success, negative - Failure 127 **/ 128 static int get_dev_cap(struct hinic_hwdev *hwdev) 129 { 130 struct hinic_hwif *hwif = hwdev->hwif; 131 struct pci_dev *pdev = hwif->pdev; 132 struct hinic_pfhwdev *pfhwdev; 133 int err; 134 135 switch (HINIC_FUNC_TYPE(hwif)) { 136 case HINIC_PPF: 137 case HINIC_PF: 138 case HINIC_VF: 139 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 140 err = get_capability(pfhwdev); 141 if (err) { 142 dev_err(&pdev->dev, "Failed to get capability\n"); 143 return err; 144 } 145 break; 146 default: 147 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 148 return -EINVAL; 149 } 150 151 return 0; 152 } 153 154 /** 155 * init_msix - enable the msix and save the entries 156 * @hwdev: the NIC HW device 157 * 158 * Return 0 - Success, negative - Failure 159 **/ 160 static int init_msix(struct hinic_hwdev *hwdev) 161 { 162 struct hinic_hwif *hwif = hwdev->hwif; 163 struct pci_dev *pdev = hwif->pdev; 164 int nr_irqs, num_aeqs, num_ceqs; 165 int i, err; 166 167 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); 168 num_ceqs = HINIC_HWIF_NUM_CEQS(hwif); 169 nr_irqs = MAX_IRQS(HINIC_MAX_QPS, num_aeqs, num_ceqs); 170 if (nr_irqs > HINIC_HWIF_NUM_IRQS(hwif)) 171 nr_irqs = HINIC_HWIF_NUM_IRQS(hwif); 172 173 hwdev->msix_entries = devm_kcalloc(&pdev->dev, nr_irqs, 174 sizeof(*hwdev->msix_entries), 175 GFP_KERNEL); 176 if (!hwdev->msix_entries) 177 return -ENOMEM; 178 179 for (i = 0; i < nr_irqs; i++) 180 hwdev->msix_entries[i].entry = i; 181 182 err = pci_enable_msix_exact(pdev, hwdev->msix_entries, nr_irqs); 183 if (err) { 184 dev_err(&pdev->dev, "Failed to enable pci msix\n"); 185 return err; 186 } 187 188 return 0; 189 } 190 191 /** 192 * disable_msix - disable the msix 193 * @hwdev: the NIC HW device 194 **/ 195 static void disable_msix(struct hinic_hwdev *hwdev) 196 { 197 struct hinic_hwif *hwif = hwdev->hwif; 198 struct pci_dev *pdev = hwif->pdev; 199 200 pci_disable_msix(pdev); 201 } 202 203 /** 204 * hinic_port_msg_cmd - send port msg to mgmt 205 * @hwdev: the NIC HW device 206 * @cmd: the port command 207 * @buf_in: input buffer 208 * @in_size: input size 209 * @buf_out: output buffer 210 * @out_size: returned output size 211 * 212 * Return 0 - Success, negative - Failure 213 **/ 214 int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd, 215 void *buf_in, u16 in_size, void *buf_out, u16 *out_size) 216 { 217 struct hinic_pfhwdev *pfhwdev; 218 219 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 220 221 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, cmd, 222 buf_in, in_size, buf_out, out_size, 223 HINIC_MGMT_MSG_SYNC); 224 } 225 226 int hinic_hilink_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_hilink_cmd cmd, 227 void *buf_in, u16 in_size, void *buf_out, 228 u16 *out_size) 229 { 230 struct hinic_pfhwdev *pfhwdev; 231 232 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 233 234 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_HILINK, cmd, 235 buf_in, in_size, buf_out, out_size, 236 HINIC_MGMT_MSG_SYNC); 237 } 238 239 /** 240 * init_fw_ctxt- Init Firmware tables before network mgmt and io operations 241 * @hwdev: the NIC HW device 242 * 243 * Return 0 - Success, negative - Failure 244 **/ 245 static int init_fw_ctxt(struct hinic_hwdev *hwdev) 246 { 247 struct hinic_hwif *hwif = hwdev->hwif; 248 struct pci_dev *pdev = hwif->pdev; 249 struct hinic_cmd_fw_ctxt fw_ctxt; 250 u16 out_size = sizeof(fw_ctxt); 251 int err; 252 253 fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 254 fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ; 255 256 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_FWCTXT_INIT, 257 &fw_ctxt, sizeof(fw_ctxt), 258 &fw_ctxt, &out_size); 259 if (err || out_size != sizeof(fw_ctxt) || fw_ctxt.status) { 260 dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n", 261 err, fw_ctxt.status, out_size); 262 return -EIO; 263 } 264 265 return 0; 266 } 267 268 /** 269 * set_hw_ioctxt - set the shape of the IO queues in FW 270 * @hwdev: the NIC HW device 271 * @rq_depth: rq depth 272 * @sq_depth: sq depth 273 * 274 * Return 0 - Success, negative - Failure 275 **/ 276 static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth, 277 unsigned int rq_depth) 278 { 279 struct hinic_hwif *hwif = hwdev->hwif; 280 struct hinic_cmd_hw_ioctxt hw_ioctxt; 281 struct hinic_pfhwdev *pfhwdev; 282 283 hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 284 hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); 285 286 hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; 287 hw_ioctxt.cmdq_depth = 0; 288 289 hw_ioctxt.lro_en = 1; 290 291 hw_ioctxt.rq_depth = ilog2(rq_depth); 292 293 hw_ioctxt.rx_buf_sz_idx = HINIC_RX_BUF_SZ_IDX; 294 295 hw_ioctxt.sq_depth = ilog2(sq_depth); 296 297 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 298 299 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 300 HINIC_COMM_CMD_HWCTXT_SET, 301 &hw_ioctxt, sizeof(hw_ioctxt), NULL, 302 NULL, HINIC_MGMT_MSG_SYNC); 303 } 304 305 static int wait_for_outbound_state(struct hinic_hwdev *hwdev) 306 { 307 enum hinic_outbound_state outbound_state; 308 struct hinic_hwif *hwif = hwdev->hwif; 309 struct pci_dev *pdev = hwif->pdev; 310 unsigned long end; 311 312 end = jiffies + msecs_to_jiffies(OUTBOUND_STATE_TIMEOUT); 313 do { 314 outbound_state = hinic_outbound_state_get(hwif); 315 316 if (outbound_state == HINIC_OUTBOUND_ENABLE) 317 return 0; 318 319 msleep(20); 320 } while (time_before(jiffies, end)); 321 322 dev_err(&pdev->dev, "Wait for OUTBOUND - Timeout\n"); 323 return -EFAULT; 324 } 325 326 static int wait_for_db_state(struct hinic_hwdev *hwdev) 327 { 328 struct hinic_hwif *hwif = hwdev->hwif; 329 struct pci_dev *pdev = hwif->pdev; 330 enum hinic_db_state db_state; 331 unsigned long end; 332 333 end = jiffies + msecs_to_jiffies(DB_STATE_TIMEOUT); 334 do { 335 db_state = hinic_db_state_get(hwif); 336 337 if (db_state == HINIC_DB_ENABLE) 338 return 0; 339 340 msleep(20); 341 } while (time_before(jiffies, end)); 342 343 dev_err(&pdev->dev, "Wait for DB - Timeout\n"); 344 return -EFAULT; 345 } 346 347 /** 348 * clear_io_resources - set the IO resources as not active in the NIC 349 * @hwdev: the NIC HW device 350 * 351 * Return 0 - Success, negative - Failure 352 **/ 353 static int clear_io_resources(struct hinic_hwdev *hwdev) 354 { 355 struct hinic_cmd_clear_io_res cmd_clear_io_res; 356 struct hinic_hwif *hwif = hwdev->hwif; 357 struct pci_dev *pdev = hwif->pdev; 358 struct hinic_pfhwdev *pfhwdev; 359 int err; 360 361 /* sleep 100ms to wait for firmware stopping I/O */ 362 msleep(100); 363 364 cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 365 366 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 367 368 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 369 HINIC_COMM_CMD_IO_RES_CLEAR, &cmd_clear_io_res, 370 sizeof(cmd_clear_io_res), NULL, NULL, 371 HINIC_MGMT_MSG_SYNC); 372 if (err) { 373 dev_err(&pdev->dev, "Failed to clear IO resources\n"); 374 return err; 375 } 376 377 return 0; 378 } 379 380 /** 381 * set_resources_state - set the state of the resources in the NIC 382 * @hwdev: the NIC HW device 383 * @state: the state to set 384 * 385 * Return 0 - Success, negative - Failure 386 **/ 387 static int set_resources_state(struct hinic_hwdev *hwdev, 388 enum hinic_res_state state) 389 { 390 struct hinic_cmd_set_res_state res_state; 391 struct hinic_hwif *hwif = hwdev->hwif; 392 struct hinic_pfhwdev *pfhwdev; 393 394 res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 395 res_state.state = state; 396 397 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 398 399 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, 400 HINIC_MOD_COMM, 401 HINIC_COMM_CMD_RES_STATE_SET, 402 &res_state, sizeof(res_state), NULL, 403 NULL, HINIC_MGMT_MSG_SYNC); 404 } 405 406 /** 407 * get_base_qpn - get the first qp number 408 * @hwdev: the NIC HW device 409 * @base_qpn: returned qp number 410 * 411 * Return 0 - Success, negative - Failure 412 **/ 413 static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn) 414 { 415 struct hinic_cmd_base_qpn cmd_base_qpn; 416 struct hinic_hwif *hwif = hwdev->hwif; 417 u16 out_size = sizeof(cmd_base_qpn); 418 struct pci_dev *pdev = hwif->pdev; 419 int err; 420 421 cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 422 423 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_GLOBAL_QPN, 424 &cmd_base_qpn, sizeof(cmd_base_qpn), 425 &cmd_base_qpn, &out_size); 426 if (err || out_size != sizeof(cmd_base_qpn) || cmd_base_qpn.status) { 427 dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n", 428 err, cmd_base_qpn.status, out_size); 429 return -EIO; 430 } 431 432 *base_qpn = cmd_base_qpn.qpn; 433 return 0; 434 } 435 436 /** 437 * hinic_hwdev_ifup - Preparing the HW for passing IO 438 * @hwdev: the NIC HW device 439 * @sq_depth: the send queue depth 440 * @rq_depth: the receive queue depth 441 * 442 * Return 0 - Success, negative - Failure 443 **/ 444 int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth) 445 { 446 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 447 struct hinic_cap *nic_cap = &hwdev->nic_cap; 448 struct hinic_hwif *hwif = hwdev->hwif; 449 int err, num_aeqs, num_ceqs, num_qps; 450 struct msix_entry *ceq_msix_entries; 451 struct msix_entry *sq_msix_entries; 452 struct msix_entry *rq_msix_entries; 453 struct pci_dev *pdev = hwif->pdev; 454 u16 base_qpn; 455 456 err = get_base_qpn(hwdev, &base_qpn); 457 if (err) { 458 dev_err(&pdev->dev, "Failed to get global base qp number\n"); 459 return err; 460 } 461 462 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); 463 num_ceqs = HINIC_HWIF_NUM_CEQS(hwif); 464 465 ceq_msix_entries = &hwdev->msix_entries[num_aeqs]; 466 func_to_io->hwdev = hwdev; 467 func_to_io->sq_depth = sq_depth; 468 func_to_io->rq_depth = rq_depth; 469 func_to_io->global_qpn = base_qpn; 470 471 err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs, 472 ceq_msix_entries); 473 if (err) { 474 dev_err(&pdev->dev, "Failed to init IO channel\n"); 475 return err; 476 } 477 478 num_qps = nic_cap->num_qps; 479 sq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs]; 480 rq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs + num_qps]; 481 482 err = hinic_io_create_qps(func_to_io, base_qpn, num_qps, 483 sq_msix_entries, rq_msix_entries); 484 if (err) { 485 dev_err(&pdev->dev, "Failed to create QPs\n"); 486 goto err_create_qps; 487 } 488 489 err = wait_for_db_state(hwdev); 490 if (err) { 491 dev_warn(&pdev->dev, "db - disabled, try again\n"); 492 hinic_db_state_set(hwif, HINIC_DB_ENABLE); 493 } 494 495 err = set_hw_ioctxt(hwdev, sq_depth, rq_depth); 496 if (err) { 497 dev_err(&pdev->dev, "Failed to set HW IO ctxt\n"); 498 goto err_hw_ioctxt; 499 } 500 501 return 0; 502 503 err_hw_ioctxt: 504 hinic_io_destroy_qps(func_to_io, num_qps); 505 506 err_create_qps: 507 hinic_io_free(func_to_io); 508 return err; 509 } 510 511 /** 512 * hinic_hwdev_ifdown - Closing the HW for passing IO 513 * @hwdev: the NIC HW device 514 * 515 **/ 516 void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev) 517 { 518 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 519 struct hinic_cap *nic_cap = &hwdev->nic_cap; 520 521 clear_io_resources(hwdev); 522 523 hinic_io_destroy_qps(func_to_io, nic_cap->num_qps); 524 hinic_io_free(func_to_io); 525 } 526 527 /** 528 * hinic_hwdev_cb_register - register callback handler for MGMT events 529 * @hwdev: the NIC HW device 530 * @cmd: the mgmt event 531 * @handle: private data for the handler 532 * @handler: event handler 533 **/ 534 void hinic_hwdev_cb_register(struct hinic_hwdev *hwdev, 535 enum hinic_mgmt_msg_cmd cmd, void *handle, 536 void (*handler)(void *handle, void *buf_in, 537 u16 in_size, void *buf_out, 538 u16 *out_size)) 539 { 540 struct hinic_pfhwdev *pfhwdev; 541 struct hinic_nic_cb *nic_cb; 542 u8 cmd_cb; 543 544 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 545 546 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; 547 nic_cb = &pfhwdev->nic_cb[cmd_cb]; 548 549 nic_cb->handler = handler; 550 nic_cb->handle = handle; 551 nic_cb->cb_state = HINIC_CB_ENABLED; 552 } 553 554 /** 555 * hinic_hwdev_cb_unregister - unregister callback handler for MGMT events 556 * @hwdev: the NIC HW device 557 * @cmd: the mgmt event 558 **/ 559 void hinic_hwdev_cb_unregister(struct hinic_hwdev *hwdev, 560 enum hinic_mgmt_msg_cmd cmd) 561 { 562 struct hinic_hwif *hwif = hwdev->hwif; 563 struct hinic_pfhwdev *pfhwdev; 564 struct hinic_nic_cb *nic_cb; 565 u8 cmd_cb; 566 567 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) 568 return; 569 570 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 571 572 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; 573 nic_cb = &pfhwdev->nic_cb[cmd_cb]; 574 575 nic_cb->cb_state &= ~HINIC_CB_ENABLED; 576 577 while (nic_cb->cb_state & HINIC_CB_RUNNING) 578 schedule(); 579 580 nic_cb->handler = NULL; 581 } 582 583 /** 584 * nic_mgmt_msg_handler - nic mgmt event handler 585 * @handle: private data for the handler 586 * @cmd: message command 587 * @buf_in: input buffer 588 * @in_size: input size 589 * @buf_out: output buffer 590 * @out_size: returned output size 591 **/ 592 static void nic_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in, 593 u16 in_size, void *buf_out, u16 *out_size) 594 { 595 struct hinic_pfhwdev *pfhwdev = handle; 596 enum hinic_cb_state cb_state; 597 struct hinic_nic_cb *nic_cb; 598 struct hinic_hwdev *hwdev; 599 struct hinic_hwif *hwif; 600 struct pci_dev *pdev; 601 u8 cmd_cb; 602 603 hwdev = &pfhwdev->hwdev; 604 hwif = hwdev->hwif; 605 pdev = hwif->pdev; 606 607 if (cmd < HINIC_MGMT_MSG_CMD_BASE || 608 cmd >= HINIC_MGMT_MSG_CMD_MAX) { 609 dev_err(&pdev->dev, "unknown L2NIC event, cmd = %d\n", cmd); 610 return; 611 } 612 613 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; 614 615 nic_cb = &pfhwdev->nic_cb[cmd_cb]; 616 617 cb_state = cmpxchg(&nic_cb->cb_state, 618 HINIC_CB_ENABLED, 619 HINIC_CB_ENABLED | HINIC_CB_RUNNING); 620 621 if (cb_state == HINIC_CB_ENABLED && nic_cb->handler) 622 nic_cb->handler(nic_cb->handle, buf_in, 623 in_size, buf_out, out_size); 624 else 625 dev_err(&pdev->dev, "Unhandled NIC Event %d\n", cmd); 626 627 nic_cb->cb_state &= ~HINIC_CB_RUNNING; 628 } 629 630 static void hinic_comm_recv_mgmt_self_cmd_reg(struct hinic_pfhwdev *pfhwdev, 631 u8 cmd, 632 comm_mgmt_self_msg_proc proc) 633 { 634 u8 cmd_idx; 635 636 cmd_idx = pfhwdev->proc.cmd_num; 637 if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) { 638 dev_err(&pfhwdev->hwdev.hwif->pdev->dev, 639 "Register recv mgmt process failed, cmd: 0x%x\n", cmd); 640 return; 641 } 642 643 pfhwdev->proc.info[cmd_idx].cmd = cmd; 644 pfhwdev->proc.info[cmd_idx].proc = proc; 645 pfhwdev->proc.cmd_num++; 646 } 647 648 static void hinic_comm_recv_mgmt_self_cmd_unreg(struct hinic_pfhwdev *pfhwdev, 649 u8 cmd) 650 { 651 u8 cmd_idx; 652 653 cmd_idx = pfhwdev->proc.cmd_num; 654 if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) { 655 dev_err(&pfhwdev->hwdev.hwif->pdev->dev, "Unregister recv mgmt process failed, cmd: 0x%x\n", 656 cmd); 657 return; 658 } 659 660 for (cmd_idx = 0; cmd_idx < HINIC_COMM_SELF_CMD_MAX; cmd_idx++) { 661 if (cmd == pfhwdev->proc.info[cmd_idx].cmd) { 662 pfhwdev->proc.info[cmd_idx].cmd = 0; 663 pfhwdev->proc.info[cmd_idx].proc = NULL; 664 pfhwdev->proc.cmd_num--; 665 } 666 } 667 } 668 669 static void comm_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in, 670 u16 in_size, void *buf_out, u16 *out_size) 671 { 672 struct hinic_pfhwdev *pfhwdev = handle; 673 u8 cmd_idx; 674 675 for (cmd_idx = 0; cmd_idx < pfhwdev->proc.cmd_num; cmd_idx++) { 676 if (cmd == pfhwdev->proc.info[cmd_idx].cmd) { 677 if (!pfhwdev->proc.info[cmd_idx].proc) { 678 dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, 679 "PF recv mgmt comm msg handle null, cmd: 0x%x\n", 680 cmd); 681 } else { 682 pfhwdev->proc.info[cmd_idx].proc 683 (&pfhwdev->hwdev, buf_in, in_size, 684 buf_out, out_size); 685 } 686 687 return; 688 } 689 } 690 691 dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, "Received unknown mgmt cpu event: 0x%x\n", 692 cmd); 693 694 *out_size = 0; 695 } 696 697 /* pf fault report event */ 698 static void pf_fault_event_handler(void *dev, void *buf_in, u16 in_size, 699 void *buf_out, u16 *out_size) 700 { 701 struct hinic_cmd_fault_event *fault_event = buf_in; 702 struct hinic_hwdev *hwdev = dev; 703 704 if (in_size != sizeof(*fault_event)) { 705 dev_err(&hwdev->hwif->pdev->dev, "Invalid fault event report, length: %d, should be %zu\n", 706 in_size, sizeof(*fault_event)); 707 return; 708 } 709 710 if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->hw_fault_reporter)) 711 return; 712 713 devlink_health_report(hwdev->devlink_dev->hw_fault_reporter, 714 "HW fatal error reported", &fault_event->event); 715 } 716 717 static void mgmt_watchdog_timeout_event_handler(void *dev, 718 void *buf_in, u16 in_size, 719 void *buf_out, u16 *out_size) 720 { 721 struct hinic_mgmt_watchdog_info *watchdog_info = buf_in; 722 struct hinic_hwdev *hwdev = dev; 723 724 if (in_size != sizeof(*watchdog_info)) { 725 dev_err(&hwdev->hwif->pdev->dev, "Invalid mgmt watchdog report, length: %d, should be %zu\n", 726 in_size, sizeof(*watchdog_info)); 727 return; 728 } 729 730 if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->fw_fault_reporter)) 731 return; 732 733 devlink_health_report(hwdev->devlink_dev->fw_fault_reporter, 734 "FW fatal error reported", watchdog_info); 735 } 736 737 /** 738 * init_pfhwdev - Initialize the extended components of PF 739 * @pfhwdev: the HW device for PF 740 * 741 * Return 0 - success, negative - failure 742 **/ 743 static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev) 744 { 745 struct hinic_hwdev *hwdev = &pfhwdev->hwdev; 746 struct hinic_hwif *hwif = hwdev->hwif; 747 struct pci_dev *pdev = hwif->pdev; 748 int err; 749 750 err = hinic_pf_to_mgmt_init(&pfhwdev->pf_to_mgmt, hwif); 751 if (err) { 752 dev_err(&pdev->dev, "Failed to initialize PF to MGMT channel\n"); 753 return err; 754 } 755 756 err = hinic_func_to_func_init(hwdev); 757 if (err) { 758 dev_err(&hwif->pdev->dev, "Failed to init mailbox\n"); 759 hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); 760 return err; 761 } 762 763 if (!HINIC_IS_VF(hwif)) { 764 hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, 765 HINIC_MOD_L2NIC, pfhwdev, 766 nic_mgmt_msg_handler); 767 hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 768 pfhwdev, comm_mgmt_msg_handler); 769 hinic_comm_recv_mgmt_self_cmd_reg(pfhwdev, 770 HINIC_COMM_CMD_FAULT_REPORT, 771 pf_fault_event_handler); 772 hinic_comm_recv_mgmt_self_cmd_reg 773 (pfhwdev, HINIC_COMM_CMD_WATCHDOG_INFO, 774 mgmt_watchdog_timeout_event_handler); 775 } else { 776 hinic_register_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC, 777 nic_mgmt_msg_handler); 778 } 779 780 hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE); 781 hinic_devlink_register(hwdev->devlink_dev); 782 return 0; 783 } 784 785 /** 786 * free_pfhwdev - Free the extended components of PF 787 * @pfhwdev: the HW device for PF 788 **/ 789 static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev) 790 { 791 struct hinic_hwdev *hwdev = &pfhwdev->hwdev; 792 793 hinic_devlink_unregister(hwdev->devlink_dev); 794 hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT); 795 796 if (!HINIC_IS_VF(hwdev->hwif)) { 797 hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev, 798 HINIC_COMM_CMD_WATCHDOG_INFO); 799 hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev, 800 HINIC_COMM_CMD_FAULT_REPORT); 801 hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, 802 HINIC_MOD_COMM); 803 hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, 804 HINIC_MOD_L2NIC); 805 } else { 806 hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC); 807 } 808 809 hinic_func_to_func_free(hwdev); 810 811 hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); 812 } 813 814 static int hinic_l2nic_reset(struct hinic_hwdev *hwdev) 815 { 816 struct hinic_cmd_l2nic_reset l2nic_reset = {0}; 817 u16 out_size = sizeof(l2nic_reset); 818 struct hinic_pfhwdev *pfhwdev; 819 int err; 820 821 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 822 823 l2nic_reset.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 824 /* 0 represents standard l2nic reset flow */ 825 l2nic_reset.reset_flag = 0; 826 827 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 828 HINIC_COMM_CMD_L2NIC_RESET, &l2nic_reset, 829 sizeof(l2nic_reset), &l2nic_reset, 830 &out_size, HINIC_MGMT_MSG_SYNC); 831 if (err || !out_size || l2nic_reset.status) { 832 dev_err(&hwdev->hwif->pdev->dev, "Failed to reset L2NIC resources, err: %d, status: 0x%x, out_size: 0x%x\n", 833 err, l2nic_reset.status, out_size); 834 return -EIO; 835 } 836 837 return 0; 838 } 839 840 int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev, 841 struct hinic_msix_config *interrupt_info) 842 { 843 u16 out_size = sizeof(*interrupt_info); 844 struct hinic_pfhwdev *pfhwdev; 845 int err; 846 847 if (!hwdev || !interrupt_info) 848 return -EINVAL; 849 850 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 851 852 interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 853 854 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 855 HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP, 856 interrupt_info, sizeof(*interrupt_info), 857 interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC); 858 if (err || !out_size || interrupt_info->status) { 859 dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n", 860 err, interrupt_info->status, out_size); 861 return -EIO; 862 } 863 864 return 0; 865 } 866 867 int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev, 868 struct hinic_msix_config *interrupt_info) 869 { 870 u16 out_size = sizeof(*interrupt_info); 871 struct hinic_msix_config temp_info; 872 struct hinic_pfhwdev *pfhwdev; 873 int err; 874 875 if (!hwdev) 876 return -EINVAL; 877 878 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 879 880 interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 881 882 err = hinic_get_interrupt_cfg(hwdev, &temp_info); 883 if (err) 884 return -EINVAL; 885 886 interrupt_info->lli_credit_cnt = temp_info.lli_timer_cnt; 887 interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt; 888 889 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 890 HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP, 891 interrupt_info, sizeof(*interrupt_info), 892 interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC); 893 if (err || !out_size || interrupt_info->status) { 894 dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n", 895 err, interrupt_info->status, out_size); 896 return -EIO; 897 } 898 899 return 0; 900 } 901 902 /** 903 * hinic_init_hwdev - Initialize the NIC HW 904 * @pdev: the NIC pci device 905 * @devlink: the poniter of hinic devlink 906 * 907 * Return initialized NIC HW device 908 * 909 * Initialize the NIC HW device and return a pointer to it 910 **/ 911 struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink) 912 { 913 struct hinic_pfhwdev *pfhwdev; 914 struct hinic_hwdev *hwdev; 915 struct hinic_hwif *hwif; 916 int err, num_aeqs; 917 918 hwif = devm_kzalloc(&pdev->dev, sizeof(*hwif), GFP_KERNEL); 919 if (!hwif) 920 return ERR_PTR(-ENOMEM); 921 922 err = hinic_init_hwif(hwif, pdev); 923 if (err) { 924 dev_err(&pdev->dev, "Failed to init HW interface\n"); 925 return ERR_PTR(err); 926 } 927 928 pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL); 929 if (!pfhwdev) { 930 err = -ENOMEM; 931 goto err_pfhwdev_alloc; 932 } 933 934 hwdev = &pfhwdev->hwdev; 935 hwdev->hwif = hwif; 936 hwdev->devlink_dev = devlink_priv(devlink); 937 hwdev->devlink_dev->hwdev = hwdev; 938 939 err = init_msix(hwdev); 940 if (err) { 941 dev_err(&pdev->dev, "Failed to init msix\n"); 942 goto err_init_msix; 943 } 944 945 err = wait_for_outbound_state(hwdev); 946 if (err) { 947 dev_warn(&pdev->dev, "outbound - disabled, try again\n"); 948 hinic_outbound_state_set(hwif, HINIC_OUTBOUND_ENABLE); 949 } 950 951 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); 952 953 err = hinic_aeqs_init(&hwdev->aeqs, hwif, num_aeqs, 954 HINIC_DEFAULT_AEQ_LEN, HINIC_EQ_PAGE_SIZE, 955 hwdev->msix_entries); 956 if (err) { 957 dev_err(&pdev->dev, "Failed to init async event queues\n"); 958 goto err_aeqs_init; 959 } 960 961 err = init_pfhwdev(pfhwdev); 962 if (err) { 963 dev_err(&pdev->dev, "Failed to init PF HW device\n"); 964 goto err_init_pfhwdev; 965 } 966 967 err = hinic_l2nic_reset(hwdev); 968 if (err) 969 goto err_l2nic_reset; 970 971 err = get_dev_cap(hwdev); 972 if (err) { 973 dev_err(&pdev->dev, "Failed to get device capabilities\n"); 974 goto err_dev_cap; 975 } 976 977 mutex_init(&hwdev->func_to_io.nic_cfg.cfg_mutex); 978 979 err = hinic_vf_func_init(hwdev); 980 if (err) { 981 dev_err(&pdev->dev, "Failed to init nic mbox\n"); 982 goto err_vf_func_init; 983 } 984 985 err = init_fw_ctxt(hwdev); 986 if (err) { 987 dev_err(&pdev->dev, "Failed to init function table\n"); 988 goto err_init_fw_ctxt; 989 } 990 991 err = set_resources_state(hwdev, HINIC_RES_ACTIVE); 992 if (err) { 993 dev_err(&pdev->dev, "Failed to set resources state\n"); 994 goto err_resources_state; 995 } 996 997 return hwdev; 998 999 err_resources_state: 1000 err_init_fw_ctxt: 1001 hinic_vf_func_free(hwdev); 1002 err_vf_func_init: 1003 err_l2nic_reset: 1004 err_dev_cap: 1005 free_pfhwdev(pfhwdev); 1006 1007 err_init_pfhwdev: 1008 hinic_aeqs_free(&hwdev->aeqs); 1009 1010 err_aeqs_init: 1011 disable_msix(hwdev); 1012 1013 err_init_msix: 1014 err_pfhwdev_alloc: 1015 hinic_free_hwif(hwif); 1016 if (err > 0) 1017 err = -EIO; 1018 return ERR_PTR(err); 1019 } 1020 1021 /** 1022 * hinic_free_hwdev - Free the NIC HW device 1023 * @hwdev: the NIC HW device 1024 **/ 1025 void hinic_free_hwdev(struct hinic_hwdev *hwdev) 1026 { 1027 struct hinic_pfhwdev *pfhwdev = container_of(hwdev, 1028 struct hinic_pfhwdev, 1029 hwdev); 1030 1031 set_resources_state(hwdev, HINIC_RES_CLEAN); 1032 1033 hinic_vf_func_free(hwdev); 1034 1035 free_pfhwdev(pfhwdev); 1036 1037 hinic_aeqs_free(&hwdev->aeqs); 1038 1039 disable_msix(hwdev); 1040 1041 hinic_free_hwif(hwdev->hwif); 1042 } 1043 1044 int hinic_hwdev_max_num_qps(struct hinic_hwdev *hwdev) 1045 { 1046 struct hinic_cap *nic_cap = &hwdev->nic_cap; 1047 1048 return nic_cap->max_qps; 1049 } 1050 1051 /** 1052 * hinic_hwdev_num_qps - return the number QPs available for use 1053 * @hwdev: the NIC HW device 1054 * 1055 * Return number QPs available for use 1056 **/ 1057 int hinic_hwdev_num_qps(struct hinic_hwdev *hwdev) 1058 { 1059 struct hinic_cap *nic_cap = &hwdev->nic_cap; 1060 1061 return nic_cap->num_qps; 1062 } 1063 1064 /** 1065 * hinic_hwdev_get_sq - get SQ 1066 * @hwdev: the NIC HW device 1067 * @i: the position of the SQ 1068 * 1069 * Return: the SQ in the i position 1070 **/ 1071 struct hinic_sq *hinic_hwdev_get_sq(struct hinic_hwdev *hwdev, int i) 1072 { 1073 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 1074 struct hinic_qp *qp = &func_to_io->qps[i]; 1075 1076 if (i >= hinic_hwdev_num_qps(hwdev)) 1077 return NULL; 1078 1079 return &qp->sq; 1080 } 1081 1082 /** 1083 * hinic_hwdev_get_rq - get RQ 1084 * @hwdev: the NIC HW device 1085 * @i: the position of the RQ 1086 * 1087 * Return: the RQ in the i position 1088 **/ 1089 struct hinic_rq *hinic_hwdev_get_rq(struct hinic_hwdev *hwdev, int i) 1090 { 1091 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 1092 struct hinic_qp *qp = &func_to_io->qps[i]; 1093 1094 if (i >= hinic_hwdev_num_qps(hwdev)) 1095 return NULL; 1096 1097 return &qp->rq; 1098 } 1099 1100 /** 1101 * hinic_hwdev_msix_cnt_set - clear message attribute counters for msix entry 1102 * @hwdev: the NIC HW device 1103 * @msix_index: msix_index 1104 * 1105 * Return 0 - Success, negative - Failure 1106 **/ 1107 int hinic_hwdev_msix_cnt_set(struct hinic_hwdev *hwdev, u16 msix_index) 1108 { 1109 return hinic_msix_attr_cnt_clear(hwdev->hwif, msix_index); 1110 } 1111 1112 /** 1113 * hinic_hwdev_msix_set - set message attribute for msix entry 1114 * @hwdev: the NIC HW device 1115 * @msix_index: msix_index 1116 * @pending_limit: the maximum pending interrupt events (unit 8) 1117 * @coalesc_timer: coalesc period for interrupt (unit 8 us) 1118 * @lli_timer_cfg: replenishing period for low latency credit (unit 8 us) 1119 * @lli_credit_limit: maximum credits for low latency msix messages (unit 8) 1120 * @resend_timer: maximum wait for resending msix (unit coalesc period) 1121 * 1122 * Return 0 - Success, negative - Failure 1123 **/ 1124 int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index, 1125 u8 pending_limit, u8 coalesc_timer, 1126 u8 lli_timer_cfg, u8 lli_credit_limit, 1127 u8 resend_timer) 1128 { 1129 return hinic_msix_attr_set(hwdev->hwif, msix_index, 1130 pending_limit, coalesc_timer, 1131 lli_timer_cfg, lli_credit_limit, 1132 resend_timer); 1133 } 1134 1135 /** 1136 * hinic_hwdev_hw_ci_addr_set - set cons idx addr and attributes in HW for sq 1137 * @hwdev: the NIC HW device 1138 * @sq: send queue 1139 * @pending_limit: the maximum pending update ci events (unit 8) 1140 * @coalesc_timer: coalesc period for update ci (unit 8 us) 1141 * 1142 * Return 0 - Success, negative - Failure 1143 **/ 1144 int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq, 1145 u8 pending_limit, u8 coalesc_timer) 1146 { 1147 struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq); 1148 struct hinic_hwif *hwif = hwdev->hwif; 1149 struct hinic_pfhwdev *pfhwdev; 1150 struct hinic_cmd_hw_ci hw_ci; 1151 1152 hw_ci.dma_attr_off = 0; 1153 hw_ci.pending_limit = pending_limit; 1154 hw_ci.coalesc_timer = coalesc_timer; 1155 1156 hw_ci.msix_en = 1; 1157 hw_ci.msix_entry_idx = sq->msix_entry; 1158 1159 hw_ci.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 1160 1161 hw_ci.sq_id = qp->q_id; 1162 1163 hw_ci.ci_addr = ADDR_IN_4BYTES(sq->hw_ci_dma_addr); 1164 1165 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 1166 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, 1167 HINIC_MOD_COMM, 1168 HINIC_COMM_CMD_SQ_HI_CI_SET, 1169 &hw_ci, sizeof(hw_ci), NULL, 1170 NULL, HINIC_MGMT_MSG_SYNC); 1171 } 1172 1173 /** 1174 * hinic_hwdev_set_msix_state- set msix state 1175 * @hwdev: the NIC HW device 1176 * @msix_index: IRQ corresponding index number 1177 * @flag: msix state 1178 * 1179 **/ 1180 void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index, 1181 enum hinic_msix_state flag) 1182 { 1183 hinic_set_msix_state(hwdev->hwif, msix_index, flag); 1184 } 1185 1186 int hinic_get_board_info(struct hinic_hwdev *hwdev, 1187 struct hinic_comm_board_info *board_info) 1188 { 1189 u16 out_size = sizeof(*board_info); 1190 struct hinic_pfhwdev *pfhwdev; 1191 int err; 1192 1193 if (!hwdev || !board_info) 1194 return -EINVAL; 1195 1196 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 1197 1198 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 1199 HINIC_COMM_CMD_GET_BOARD_INFO, 1200 board_info, sizeof(*board_info), 1201 board_info, &out_size, HINIC_MGMT_MSG_SYNC); 1202 if (err || board_info->status || !out_size) { 1203 dev_err(&hwdev->hwif->pdev->dev, 1204 "Failed to get board info, err: %d, status: 0x%x, out size: 0x%x\n", 1205 err, board_info->status, out_size); 1206 return -EIO; 1207 } 1208 1209 return 0; 1210 } 1211