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