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