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 struct hinic_pfhwdev *pfhwdev; 268 u16 out_size; 269 int err; 270 271 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 272 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 273 return -EINVAL; 274 } 275 276 fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 277 fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ; 278 279 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 280 281 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_FWCTXT_INIT, 282 &fw_ctxt, sizeof(fw_ctxt), 283 &fw_ctxt, &out_size); 284 if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) { 285 dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n", 286 fw_ctxt.status); 287 return -EFAULT; 288 } 289 290 return 0; 291 } 292 293 /** 294 * set_hw_ioctxt - set the shape of the IO queues in FW 295 * @hwdev: the NIC HW device 296 * @rq_depth: rq depth 297 * @sq_depth: sq depth 298 * 299 * Return 0 - Success, negative - Failure 300 **/ 301 static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, 302 unsigned int sq_depth) 303 { 304 struct hinic_hwif *hwif = hwdev->hwif; 305 struct hinic_cmd_hw_ioctxt hw_ioctxt; 306 struct pci_dev *pdev = hwif->pdev; 307 struct hinic_pfhwdev *pfhwdev; 308 309 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 310 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 311 return -EINVAL; 312 } 313 314 hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 315 316 hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; 317 hw_ioctxt.cmdq_depth = 0; 318 319 hw_ioctxt.rq_depth = ilog2(rq_depth); 320 321 hw_ioctxt.rx_buf_sz_idx = HINIC_RX_BUF_SZ_IDX; 322 323 hw_ioctxt.sq_depth = ilog2(sq_depth); 324 325 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 326 327 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 328 HINIC_COMM_CMD_HWCTXT_SET, 329 &hw_ioctxt, sizeof(hw_ioctxt), NULL, 330 NULL, HINIC_MGMT_MSG_SYNC); 331 } 332 333 static int wait_for_outbound_state(struct hinic_hwdev *hwdev) 334 { 335 enum hinic_outbound_state outbound_state; 336 struct hinic_hwif *hwif = hwdev->hwif; 337 struct pci_dev *pdev = hwif->pdev; 338 unsigned long end; 339 340 end = jiffies + msecs_to_jiffies(OUTBOUND_STATE_TIMEOUT); 341 do { 342 outbound_state = hinic_outbound_state_get(hwif); 343 344 if (outbound_state == HINIC_OUTBOUND_ENABLE) 345 return 0; 346 347 msleep(20); 348 } while (time_before(jiffies, end)); 349 350 dev_err(&pdev->dev, "Wait for OUTBOUND - Timeout\n"); 351 return -EFAULT; 352 } 353 354 static int wait_for_db_state(struct hinic_hwdev *hwdev) 355 { 356 struct hinic_hwif *hwif = hwdev->hwif; 357 struct pci_dev *pdev = hwif->pdev; 358 enum hinic_db_state db_state; 359 unsigned long end; 360 361 end = jiffies + msecs_to_jiffies(DB_STATE_TIMEOUT); 362 do { 363 db_state = hinic_db_state_get(hwif); 364 365 if (db_state == HINIC_DB_ENABLE) 366 return 0; 367 368 msleep(20); 369 } while (time_before(jiffies, end)); 370 371 dev_err(&pdev->dev, "Wait for DB - Timeout\n"); 372 return -EFAULT; 373 } 374 375 static int wait_for_io_stopped(struct hinic_hwdev *hwdev) 376 { 377 struct hinic_cmd_io_status cmd_io_status; 378 struct hinic_hwif *hwif = hwdev->hwif; 379 struct pci_dev *pdev = hwif->pdev; 380 struct hinic_pfhwdev *pfhwdev; 381 unsigned long end; 382 u16 out_size; 383 int err; 384 385 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 386 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 387 return -EINVAL; 388 } 389 390 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 391 392 cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 393 394 end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT); 395 do { 396 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 397 HINIC_COMM_CMD_IO_STATUS_GET, 398 &cmd_io_status, sizeof(cmd_io_status), 399 &cmd_io_status, &out_size, 400 HINIC_MGMT_MSG_SYNC); 401 if ((err) || (out_size != sizeof(cmd_io_status))) { 402 dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n", 403 err); 404 return err; 405 } 406 407 if (cmd_io_status.status == IO_STOPPED) { 408 dev_info(&pdev->dev, "IO stopped\n"); 409 return 0; 410 } 411 412 msleep(20); 413 } while (time_before(jiffies, end)); 414 415 dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n"); 416 return -ETIMEDOUT; 417 } 418 419 /** 420 * clear_io_resource - set the IO resources as not active in the NIC 421 * @hwdev: the NIC HW device 422 * 423 * Return 0 - Success, negative - Failure 424 **/ 425 static int clear_io_resources(struct hinic_hwdev *hwdev) 426 { 427 struct hinic_cmd_clear_io_res cmd_clear_io_res; 428 struct hinic_hwif *hwif = hwdev->hwif; 429 struct pci_dev *pdev = hwif->pdev; 430 struct hinic_pfhwdev *pfhwdev; 431 int err; 432 433 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 434 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 435 return -EINVAL; 436 } 437 438 err = wait_for_io_stopped(hwdev); 439 if (err) { 440 dev_err(&pdev->dev, "IO has not stopped yet\n"); 441 return err; 442 } 443 444 cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 445 446 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 447 448 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 449 HINIC_COMM_CMD_IO_RES_CLEAR, &cmd_clear_io_res, 450 sizeof(cmd_clear_io_res), NULL, NULL, 451 HINIC_MGMT_MSG_SYNC); 452 if (err) { 453 dev_err(&pdev->dev, "Failed to clear IO resources\n"); 454 return err; 455 } 456 457 return 0; 458 } 459 460 /** 461 * set_resources_state - set the state of the resources in the NIC 462 * @hwdev: the NIC HW device 463 * @state: the state to set 464 * 465 * Return 0 - Success, negative - Failure 466 **/ 467 static int set_resources_state(struct hinic_hwdev *hwdev, 468 enum hinic_res_state state) 469 { 470 struct hinic_cmd_set_res_state res_state; 471 struct hinic_hwif *hwif = hwdev->hwif; 472 struct pci_dev *pdev = hwif->pdev; 473 struct hinic_pfhwdev *pfhwdev; 474 475 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 476 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 477 return -EINVAL; 478 } 479 480 res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 481 res_state.state = state; 482 483 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 484 485 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, 486 HINIC_MOD_COMM, 487 HINIC_COMM_CMD_RES_STATE_SET, 488 &res_state, sizeof(res_state), NULL, 489 NULL, HINIC_MGMT_MSG_SYNC); 490 } 491 492 /** 493 * get_base_qpn - get the first qp number 494 * @hwdev: the NIC HW device 495 * @base_qpn: returned qp number 496 * 497 * Return 0 - Success, negative - Failure 498 **/ 499 static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn) 500 { 501 struct hinic_cmd_base_qpn cmd_base_qpn; 502 struct hinic_hwif *hwif = hwdev->hwif; 503 struct pci_dev *pdev = hwif->pdev; 504 u16 out_size; 505 int err; 506 507 cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 508 509 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_GLOBAL_QPN, 510 &cmd_base_qpn, sizeof(cmd_base_qpn), 511 &cmd_base_qpn, &out_size); 512 if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) { 513 dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n", 514 cmd_base_qpn.status); 515 return -EFAULT; 516 } 517 518 *base_qpn = cmd_base_qpn.qpn; 519 return 0; 520 } 521 522 /** 523 * hinic_hwdev_ifup - Preparing the HW for passing IO 524 * @hwdev: the NIC HW device 525 * 526 * Return 0 - Success, negative - Failure 527 **/ 528 int hinic_hwdev_ifup(struct hinic_hwdev *hwdev) 529 { 530 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 531 struct hinic_cap *nic_cap = &hwdev->nic_cap; 532 struct hinic_hwif *hwif = hwdev->hwif; 533 int err, num_aeqs, num_ceqs, num_qps; 534 struct msix_entry *ceq_msix_entries; 535 struct msix_entry *sq_msix_entries; 536 struct msix_entry *rq_msix_entries; 537 struct pci_dev *pdev = hwif->pdev; 538 u16 base_qpn; 539 540 err = get_base_qpn(hwdev, &base_qpn); 541 if (err) { 542 dev_err(&pdev->dev, "Failed to get global base qp number\n"); 543 return err; 544 } 545 546 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); 547 num_ceqs = HINIC_HWIF_NUM_CEQS(hwif); 548 549 ceq_msix_entries = &hwdev->msix_entries[num_aeqs]; 550 551 err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs, 552 ceq_msix_entries); 553 if (err) { 554 dev_err(&pdev->dev, "Failed to init IO channel\n"); 555 return err; 556 } 557 558 num_qps = nic_cap->num_qps; 559 sq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs]; 560 rq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs + num_qps]; 561 562 err = hinic_io_create_qps(func_to_io, base_qpn, num_qps, 563 sq_msix_entries, rq_msix_entries); 564 if (err) { 565 dev_err(&pdev->dev, "Failed to create QPs\n"); 566 goto err_create_qps; 567 } 568 569 err = wait_for_db_state(hwdev); 570 if (err) { 571 dev_warn(&pdev->dev, "db - disabled, try again\n"); 572 hinic_db_state_set(hwif, HINIC_DB_ENABLE); 573 } 574 575 err = set_hw_ioctxt(hwdev, HINIC_SQ_DEPTH, HINIC_RQ_DEPTH); 576 if (err) { 577 dev_err(&pdev->dev, "Failed to set HW IO ctxt\n"); 578 goto err_hw_ioctxt; 579 } 580 581 return 0; 582 583 err_hw_ioctxt: 584 hinic_io_destroy_qps(func_to_io, num_qps); 585 586 err_create_qps: 587 hinic_io_free(func_to_io); 588 return err; 589 } 590 591 /** 592 * hinic_hwdev_ifdown - Closing the HW for passing IO 593 * @hwdev: the NIC HW device 594 * 595 **/ 596 void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev) 597 { 598 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 599 struct hinic_cap *nic_cap = &hwdev->nic_cap; 600 601 clear_io_resources(hwdev); 602 603 hinic_io_destroy_qps(func_to_io, nic_cap->num_qps); 604 hinic_io_free(func_to_io); 605 } 606 607 /** 608 * hinic_hwdev_cb_register - register callback handler for MGMT events 609 * @hwdev: the NIC HW device 610 * @cmd: the mgmt event 611 * @handle: private data for the handler 612 * @handler: event handler 613 **/ 614 void hinic_hwdev_cb_register(struct hinic_hwdev *hwdev, 615 enum hinic_mgmt_msg_cmd cmd, void *handle, 616 void (*handler)(void *handle, void *buf_in, 617 u16 in_size, void *buf_out, 618 u16 *out_size)) 619 { 620 struct hinic_hwif *hwif = hwdev->hwif; 621 struct pci_dev *pdev = hwif->pdev; 622 struct hinic_pfhwdev *pfhwdev; 623 struct hinic_nic_cb *nic_cb; 624 u8 cmd_cb; 625 626 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 627 dev_err(&pdev->dev, "unsupported PCI Function type\n"); 628 return; 629 } 630 631 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 632 633 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; 634 nic_cb = &pfhwdev->nic_cb[cmd_cb]; 635 636 nic_cb->handler = handler; 637 nic_cb->handle = handle; 638 nic_cb->cb_state = HINIC_CB_ENABLED; 639 } 640 641 /** 642 * hinic_hwdev_cb_unregister - unregister callback handler for MGMT events 643 * @hwdev: the NIC HW device 644 * @cmd: the mgmt event 645 **/ 646 void hinic_hwdev_cb_unregister(struct hinic_hwdev *hwdev, 647 enum hinic_mgmt_msg_cmd cmd) 648 { 649 struct hinic_hwif *hwif = hwdev->hwif; 650 struct pci_dev *pdev = hwif->pdev; 651 struct hinic_pfhwdev *pfhwdev; 652 struct hinic_nic_cb *nic_cb; 653 u8 cmd_cb; 654 655 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 656 dev_err(&pdev->dev, "unsupported PCI Function type\n"); 657 return; 658 } 659 660 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 661 662 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; 663 nic_cb = &pfhwdev->nic_cb[cmd_cb]; 664 665 nic_cb->cb_state &= ~HINIC_CB_ENABLED; 666 667 while (nic_cb->cb_state & HINIC_CB_RUNNING) 668 schedule(); 669 670 nic_cb->handler = NULL; 671 } 672 673 /** 674 * nic_mgmt_msg_handler - nic mgmt event handler 675 * @handle: private data for the handler 676 * @buf_in: input buffer 677 * @in_size: input size 678 * @buf_out: output buffer 679 * @out_size: returned output size 680 **/ 681 static void nic_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in, 682 u16 in_size, void *buf_out, u16 *out_size) 683 { 684 struct hinic_pfhwdev *pfhwdev = handle; 685 enum hinic_cb_state cb_state; 686 struct hinic_nic_cb *nic_cb; 687 struct hinic_hwdev *hwdev; 688 struct hinic_hwif *hwif; 689 struct pci_dev *pdev; 690 u8 cmd_cb; 691 692 hwdev = &pfhwdev->hwdev; 693 hwif = hwdev->hwif; 694 pdev = hwif->pdev; 695 696 if ((cmd < HINIC_MGMT_MSG_CMD_BASE) || 697 (cmd >= HINIC_MGMT_MSG_CMD_MAX)) { 698 dev_err(&pdev->dev, "unknown L2NIC event, cmd = %d\n", cmd); 699 return; 700 } 701 702 cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE; 703 704 nic_cb = &pfhwdev->nic_cb[cmd_cb]; 705 706 cb_state = cmpxchg(&nic_cb->cb_state, 707 HINIC_CB_ENABLED, 708 HINIC_CB_ENABLED | HINIC_CB_RUNNING); 709 710 if ((cb_state == HINIC_CB_ENABLED) && (nic_cb->handler)) 711 nic_cb->handler(nic_cb->handle, buf_in, 712 in_size, buf_out, out_size); 713 else 714 dev_err(&pdev->dev, "Unhandled NIC Event %d\n", cmd); 715 716 nic_cb->cb_state &= ~HINIC_CB_RUNNING; 717 } 718 719 /** 720 * init_pfhwdev - Initialize the extended components of PF 721 * @pfhwdev: the HW device for PF 722 * 723 * Return 0 - success, negative - failure 724 **/ 725 static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev) 726 { 727 struct hinic_hwdev *hwdev = &pfhwdev->hwdev; 728 struct hinic_hwif *hwif = hwdev->hwif; 729 struct pci_dev *pdev = hwif->pdev; 730 int err; 731 732 err = hinic_pf_to_mgmt_init(&pfhwdev->pf_to_mgmt, hwif); 733 if (err) { 734 dev_err(&pdev->dev, "Failed to initialize PF to MGMT channel\n"); 735 return err; 736 } 737 738 hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, 739 pfhwdev, nic_mgmt_msg_handler); 740 741 hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE); 742 return 0; 743 } 744 745 /** 746 * free_pfhwdev - Free the extended components of PF 747 * @pfhwdev: the HW device for PF 748 **/ 749 static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev) 750 { 751 struct hinic_hwdev *hwdev = &pfhwdev->hwdev; 752 753 hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT); 754 755 hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC); 756 757 hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); 758 } 759 760 /** 761 * hinic_init_hwdev - Initialize the NIC HW 762 * @pdev: the NIC pci device 763 * 764 * Return initialized NIC HW device 765 * 766 * Initialize the NIC HW device and return a pointer to it 767 **/ 768 struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev) 769 { 770 struct hinic_pfhwdev *pfhwdev; 771 struct hinic_hwdev *hwdev; 772 struct hinic_hwif *hwif; 773 int err, num_aeqs; 774 775 hwif = devm_kzalloc(&pdev->dev, sizeof(*hwif), GFP_KERNEL); 776 if (!hwif) 777 return ERR_PTR(-ENOMEM); 778 779 err = hinic_init_hwif(hwif, pdev); 780 if (err) { 781 dev_err(&pdev->dev, "Failed to init HW interface\n"); 782 return ERR_PTR(err); 783 } 784 785 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 786 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 787 err = -EFAULT; 788 goto err_func_type; 789 } 790 791 pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL); 792 if (!pfhwdev) { 793 err = -ENOMEM; 794 goto err_pfhwdev_alloc; 795 } 796 797 hwdev = &pfhwdev->hwdev; 798 hwdev->hwif = hwif; 799 800 err = init_msix(hwdev); 801 if (err) { 802 dev_err(&pdev->dev, "Failed to init msix\n"); 803 goto err_init_msix; 804 } 805 806 err = wait_for_outbound_state(hwdev); 807 if (err) { 808 dev_warn(&pdev->dev, "outbound - disabled, try again\n"); 809 hinic_outbound_state_set(hwif, HINIC_OUTBOUND_ENABLE); 810 } 811 812 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); 813 814 err = hinic_aeqs_init(&hwdev->aeqs, hwif, num_aeqs, 815 HINIC_DEFAULT_AEQ_LEN, HINIC_EQ_PAGE_SIZE, 816 hwdev->msix_entries); 817 if (err) { 818 dev_err(&pdev->dev, "Failed to init async event queues\n"); 819 goto err_aeqs_init; 820 } 821 822 err = init_pfhwdev(pfhwdev); 823 if (err) { 824 dev_err(&pdev->dev, "Failed to init PF HW device\n"); 825 goto err_init_pfhwdev; 826 } 827 828 err = get_dev_cap(hwdev); 829 if (err) { 830 dev_err(&pdev->dev, "Failed to get device capabilities\n"); 831 goto err_dev_cap; 832 } 833 834 err = init_fw_ctxt(hwdev); 835 if (err) { 836 dev_err(&pdev->dev, "Failed to init function table\n"); 837 goto err_init_fw_ctxt; 838 } 839 840 err = set_resources_state(hwdev, HINIC_RES_ACTIVE); 841 if (err) { 842 dev_err(&pdev->dev, "Failed to set resources state\n"); 843 goto err_resources_state; 844 } 845 846 return hwdev; 847 848 err_resources_state: 849 err_init_fw_ctxt: 850 err_dev_cap: 851 free_pfhwdev(pfhwdev); 852 853 err_init_pfhwdev: 854 hinic_aeqs_free(&hwdev->aeqs); 855 856 err_aeqs_init: 857 disable_msix(hwdev); 858 859 err_init_msix: 860 err_pfhwdev_alloc: 861 err_func_type: 862 hinic_free_hwif(hwif); 863 return ERR_PTR(err); 864 } 865 866 /** 867 * hinic_free_hwdev - Free the NIC HW device 868 * @hwdev: the NIC HW device 869 **/ 870 void hinic_free_hwdev(struct hinic_hwdev *hwdev) 871 { 872 struct hinic_pfhwdev *pfhwdev = container_of(hwdev, 873 struct hinic_pfhwdev, 874 hwdev); 875 876 set_resources_state(hwdev, HINIC_RES_CLEAN); 877 878 free_pfhwdev(pfhwdev); 879 880 hinic_aeqs_free(&hwdev->aeqs); 881 882 disable_msix(hwdev); 883 884 hinic_free_hwif(hwdev->hwif); 885 } 886 887 /** 888 * hinic_hwdev_num_qps - return the number QPs available for use 889 * @hwdev: the NIC HW device 890 * 891 * Return number QPs available for use 892 **/ 893 int hinic_hwdev_num_qps(struct hinic_hwdev *hwdev) 894 { 895 struct hinic_cap *nic_cap = &hwdev->nic_cap; 896 897 return nic_cap->num_qps; 898 } 899 900 /** 901 * hinic_hwdev_get_sq - get SQ 902 * @hwdev: the NIC HW device 903 * @i: the position of the SQ 904 * 905 * Return: the SQ in the i position 906 **/ 907 struct hinic_sq *hinic_hwdev_get_sq(struct hinic_hwdev *hwdev, int i) 908 { 909 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 910 struct hinic_qp *qp = &func_to_io->qps[i]; 911 912 if (i >= hinic_hwdev_num_qps(hwdev)) 913 return NULL; 914 915 return &qp->sq; 916 } 917 918 /** 919 * hinic_hwdev_get_sq - get RQ 920 * @hwdev: the NIC HW device 921 * @i: the position of the RQ 922 * 923 * Return: the RQ in the i position 924 **/ 925 struct hinic_rq *hinic_hwdev_get_rq(struct hinic_hwdev *hwdev, int i) 926 { 927 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io; 928 struct hinic_qp *qp = &func_to_io->qps[i]; 929 930 if (i >= hinic_hwdev_num_qps(hwdev)) 931 return NULL; 932 933 return &qp->rq; 934 } 935 936 /** 937 * hinic_hwdev_msix_cnt_set - clear message attribute counters for msix entry 938 * @hwdev: the NIC HW device 939 * @msix_index: msix_index 940 * 941 * Return 0 - Success, negative - Failure 942 **/ 943 int hinic_hwdev_msix_cnt_set(struct hinic_hwdev *hwdev, u16 msix_index) 944 { 945 return hinic_msix_attr_cnt_clear(hwdev->hwif, msix_index); 946 } 947 948 /** 949 * hinic_hwdev_msix_set - set message attribute for msix entry 950 * @hwdev: the NIC HW device 951 * @msix_index: msix_index 952 * @pending_limit: the maximum pending interrupt events (unit 8) 953 * @coalesc_timer: coalesc period for interrupt (unit 8 us) 954 * @lli_timer: replenishing period for low latency credit (unit 8 us) 955 * @lli_credit_limit: maximum credits for low latency msix messages (unit 8) 956 * @resend_timer: maximum wait for resending msix (unit coalesc period) 957 * 958 * Return 0 - Success, negative - Failure 959 **/ 960 int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index, 961 u8 pending_limit, u8 coalesc_timer, 962 u8 lli_timer_cfg, u8 lli_credit_limit, 963 u8 resend_timer) 964 { 965 return hinic_msix_attr_set(hwdev->hwif, msix_index, 966 pending_limit, coalesc_timer, 967 lli_timer_cfg, lli_credit_limit, 968 resend_timer); 969 } 970 971 /** 972 * hinic_hwdev_hw_ci_addr_set - set cons idx addr and attributes in HW for sq 973 * @hwdev: the NIC HW device 974 * @sq: send queue 975 * @pending_limit: the maximum pending update ci events (unit 8) 976 * @coalesc_timer: coalesc period for update ci (unit 8 us) 977 * 978 * Return 0 - Success, negative - Failure 979 **/ 980 int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq, 981 u8 pending_limit, u8 coalesc_timer) 982 { 983 struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq); 984 struct hinic_hwif *hwif = hwdev->hwif; 985 struct pci_dev *pdev = hwif->pdev; 986 struct hinic_pfhwdev *pfhwdev; 987 struct hinic_cmd_hw_ci hw_ci; 988 989 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 990 dev_err(&pdev->dev, "Unsupported PCI Function type\n"); 991 return -EINVAL; 992 } 993 994 hw_ci.dma_attr_off = 0; 995 hw_ci.pending_limit = pending_limit; 996 hw_ci.coalesc_timer = coalesc_timer; 997 998 hw_ci.msix_en = 1; 999 hw_ci.msix_entry_idx = sq->msix_entry; 1000 1001 hw_ci.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 1002 1003 hw_ci.sq_id = qp->q_id; 1004 1005 hw_ci.ci_addr = ADDR_IN_4BYTES(sq->hw_ci_dma_addr); 1006 1007 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 1008 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, 1009 HINIC_MOD_COMM, 1010 HINIC_COMM_CMD_SQ_HI_CI_SET, 1011 &hw_ci, sizeof(hw_ci), NULL, 1012 NULL, HINIC_MGMT_MSG_SYNC); 1013 } 1014