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