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/types.h> 8 #include <linux/netdevice.h> 9 #include <linux/etherdevice.h> 10 #include <linux/if_vlan.h> 11 #include <linux/pci.h> 12 #include <linux/device.h> 13 #include <linux/errno.h> 14 15 #include "hinic_hw_if.h" 16 #include "hinic_hw_dev.h" 17 #include "hinic_port.h" 18 #include "hinic_dev.h" 19 20 #define HINIC_MIN_MTU_SIZE 256 21 #define HINIC_MAX_JUMBO_FRAME_SIZE 15872 22 23 enum mac_op { 24 MAC_DEL, 25 MAC_SET, 26 }; 27 28 /** 29 * change_mac - change(add or delete) mac address 30 * @nic_dev: nic device 31 * @addr: mac address 32 * @vlan_id: vlan number to set with the mac 33 * @op: add or delete the mac 34 * 35 * Return 0 - Success, negative - Failure 36 **/ 37 static int change_mac(struct hinic_dev *nic_dev, const u8 *addr, 38 u16 vlan_id, enum mac_op op) 39 { 40 struct net_device *netdev = nic_dev->netdev; 41 struct hinic_hwdev *hwdev = nic_dev->hwdev; 42 struct hinic_port_mac_cmd port_mac_cmd; 43 struct hinic_hwif *hwif = hwdev->hwif; 44 struct pci_dev *pdev = hwif->pdev; 45 enum hinic_port_cmd cmd; 46 u16 out_size; 47 int err; 48 49 if (vlan_id >= VLAN_N_VID) { 50 netif_err(nic_dev, drv, netdev, "Invalid VLAN number\n"); 51 return -EINVAL; 52 } 53 54 if (op == MAC_SET) 55 cmd = HINIC_PORT_CMD_SET_MAC; 56 else 57 cmd = HINIC_PORT_CMD_DEL_MAC; 58 59 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 60 port_mac_cmd.vlan_id = vlan_id; 61 memcpy(port_mac_cmd.mac, addr, ETH_ALEN); 62 63 err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd, 64 sizeof(port_mac_cmd), 65 &port_mac_cmd, &out_size); 66 if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) { 67 dev_err(&pdev->dev, "Failed to change MAC, ret = %d\n", 68 port_mac_cmd.status); 69 return -EFAULT; 70 } 71 72 return 0; 73 } 74 75 /** 76 * hinic_port_add_mac - add mac address 77 * @nic_dev: nic device 78 * @addr: mac address 79 * @vlan_id: vlan number to set with the mac 80 * 81 * Return 0 - Success, negative - Failure 82 **/ 83 int hinic_port_add_mac(struct hinic_dev *nic_dev, 84 const u8 *addr, u16 vlan_id) 85 { 86 return change_mac(nic_dev, addr, vlan_id, MAC_SET); 87 } 88 89 /** 90 * hinic_port_del_mac - remove mac address 91 * @nic_dev: nic device 92 * @addr: mac address 93 * @vlan_id: vlan number that is connected to the mac 94 * 95 * Return 0 - Success, negative - Failure 96 **/ 97 int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr, 98 u16 vlan_id) 99 { 100 return change_mac(nic_dev, addr, vlan_id, MAC_DEL); 101 } 102 103 /** 104 * hinic_port_get_mac - get the mac address of the nic device 105 * @nic_dev: nic device 106 * @addr: returned mac address 107 * 108 * Return 0 - Success, negative - Failure 109 **/ 110 int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr) 111 { 112 struct hinic_hwdev *hwdev = nic_dev->hwdev; 113 struct hinic_port_mac_cmd port_mac_cmd; 114 struct hinic_hwif *hwif = hwdev->hwif; 115 struct pci_dev *pdev = hwif->pdev; 116 u16 out_size; 117 int err; 118 119 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 120 121 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC, 122 &port_mac_cmd, sizeof(port_mac_cmd), 123 &port_mac_cmd, &out_size); 124 if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) { 125 dev_err(&pdev->dev, "Failed to get mac, ret = %d\n", 126 port_mac_cmd.status); 127 return -EFAULT; 128 } 129 130 memcpy(addr, port_mac_cmd.mac, ETH_ALEN); 131 return 0; 132 } 133 134 /** 135 * hinic_port_set_mtu - set mtu 136 * @nic_dev: nic device 137 * @new_mtu: new mtu 138 * 139 * Return 0 - Success, negative - Failure 140 **/ 141 int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu) 142 { 143 struct net_device *netdev = nic_dev->netdev; 144 struct hinic_hwdev *hwdev = nic_dev->hwdev; 145 struct hinic_port_mtu_cmd port_mtu_cmd; 146 struct hinic_hwif *hwif = hwdev->hwif; 147 struct pci_dev *pdev = hwif->pdev; 148 int err, max_frame; 149 u16 out_size; 150 151 if (new_mtu < HINIC_MIN_MTU_SIZE) { 152 netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size"); 153 return -EINVAL; 154 } 155 156 max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; 157 if (max_frame > HINIC_MAX_JUMBO_FRAME_SIZE) { 158 netif_err(nic_dev, drv, netdev, "mtu > MAX MTU size"); 159 return -EINVAL; 160 } 161 162 port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 163 port_mtu_cmd.mtu = new_mtu; 164 165 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU, 166 &port_mtu_cmd, sizeof(port_mtu_cmd), 167 &port_mtu_cmd, &out_size); 168 if (err || (out_size != sizeof(port_mtu_cmd)) || port_mtu_cmd.status) { 169 dev_err(&pdev->dev, "Failed to set mtu, ret = %d\n", 170 port_mtu_cmd.status); 171 return -EFAULT; 172 } 173 174 return 0; 175 } 176 177 /** 178 * hinic_port_add_vlan - add vlan to the nic device 179 * @nic_dev: nic device 180 * @vlan_id: the vlan number to add 181 * 182 * Return 0 - Success, negative - Failure 183 **/ 184 int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id) 185 { 186 struct hinic_hwdev *hwdev = nic_dev->hwdev; 187 struct hinic_port_vlan_cmd port_vlan_cmd; 188 189 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 190 port_vlan_cmd.vlan_id = vlan_id; 191 192 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN, 193 &port_vlan_cmd, sizeof(port_vlan_cmd), 194 NULL, NULL); 195 } 196 197 /** 198 * hinic_port_del_vlan - delete vlan from the nic device 199 * @nic_dev: nic device 200 * @vlan_id: the vlan number to delete 201 * 202 * Return 0 - Success, negative - Failure 203 **/ 204 int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id) 205 { 206 struct hinic_hwdev *hwdev = nic_dev->hwdev; 207 struct hinic_port_vlan_cmd port_vlan_cmd; 208 209 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 210 port_vlan_cmd.vlan_id = vlan_id; 211 212 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN, 213 &port_vlan_cmd, sizeof(port_vlan_cmd), 214 NULL, NULL); 215 } 216 217 /** 218 * hinic_port_set_rx_mode - set rx mode in the nic device 219 * @nic_dev: nic device 220 * @rx_mode: the rx mode to set 221 * 222 * Return 0 - Success, negative - Failure 223 **/ 224 int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode) 225 { 226 struct hinic_hwdev *hwdev = nic_dev->hwdev; 227 struct hinic_port_rx_mode_cmd rx_mode_cmd; 228 229 rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 230 rx_mode_cmd.rx_mode = rx_mode; 231 232 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE, 233 &rx_mode_cmd, sizeof(rx_mode_cmd), 234 NULL, NULL); 235 } 236 237 /** 238 * hinic_port_link_state - get the link state 239 * @nic_dev: nic device 240 * @link_state: the returned link state 241 * 242 * Return 0 - Success, negative - Failure 243 **/ 244 int hinic_port_link_state(struct hinic_dev *nic_dev, 245 enum hinic_port_link_state *link_state) 246 { 247 struct hinic_hwdev *hwdev = nic_dev->hwdev; 248 struct hinic_hwif *hwif = hwdev->hwif; 249 struct hinic_port_link_cmd link_cmd; 250 struct pci_dev *pdev = hwif->pdev; 251 u16 out_size; 252 int err; 253 254 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 255 dev_err(&pdev->dev, "unsupported PCI Function type\n"); 256 return -EINVAL; 257 } 258 259 link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 260 261 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE, 262 &link_cmd, sizeof(link_cmd), 263 &link_cmd, &out_size); 264 if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) { 265 dev_err(&pdev->dev, "Failed to get link state, ret = %d\n", 266 link_cmd.status); 267 return -EINVAL; 268 } 269 270 *link_state = link_cmd.state; 271 return 0; 272 } 273 274 /** 275 * hinic_port_set_state - set port state 276 * @nic_dev: nic device 277 * @state: the state to set 278 * 279 * Return 0 - Success, negative - Failure 280 **/ 281 int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state) 282 { 283 struct hinic_hwdev *hwdev = nic_dev->hwdev; 284 struct hinic_port_state_cmd port_state; 285 struct hinic_hwif *hwif = hwdev->hwif; 286 struct pci_dev *pdev = hwif->pdev; 287 u16 out_size; 288 int err; 289 290 if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { 291 dev_err(&pdev->dev, "unsupported PCI Function type\n"); 292 return -EINVAL; 293 } 294 295 port_state.state = state; 296 297 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE, 298 &port_state, sizeof(port_state), 299 &port_state, &out_size); 300 if (err || (out_size != sizeof(port_state)) || port_state.status) { 301 dev_err(&pdev->dev, "Failed to set port state, ret = %d\n", 302 port_state.status); 303 return -EFAULT; 304 } 305 306 return 0; 307 } 308 309 /** 310 * hinic_port_set_func_state- set func device state 311 * @nic_dev: nic device 312 * @state: the state to set 313 * 314 * Return 0 - Success, negative - Failure 315 **/ 316 int hinic_port_set_func_state(struct hinic_dev *nic_dev, 317 enum hinic_func_port_state state) 318 { 319 struct hinic_port_func_state_cmd func_state; 320 struct hinic_hwdev *hwdev = nic_dev->hwdev; 321 struct hinic_hwif *hwif = hwdev->hwif; 322 struct pci_dev *pdev = hwif->pdev; 323 u16 out_size; 324 int err; 325 326 func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 327 func_state.state = state; 328 329 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE, 330 &func_state, sizeof(func_state), 331 &func_state, &out_size); 332 if (err || (out_size != sizeof(func_state)) || func_state.status) { 333 dev_err(&pdev->dev, "Failed to set port func state, ret = %d\n", 334 func_state.status); 335 return -EFAULT; 336 } 337 338 return 0; 339 } 340 341 /** 342 * hinic_port_get_cap - get port capabilities 343 * @nic_dev: nic device 344 * @port_cap: returned port capabilities 345 * 346 * Return 0 - Success, negative - Failure 347 **/ 348 int hinic_port_get_cap(struct hinic_dev *nic_dev, 349 struct hinic_port_cap *port_cap) 350 { 351 struct hinic_hwdev *hwdev = nic_dev->hwdev; 352 struct hinic_hwif *hwif = hwdev->hwif; 353 struct pci_dev *pdev = hwif->pdev; 354 u16 out_size; 355 int err; 356 357 port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif); 358 359 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP, 360 port_cap, sizeof(*port_cap), 361 port_cap, &out_size); 362 if (err || (out_size != sizeof(*port_cap)) || port_cap->status) { 363 dev_err(&pdev->dev, 364 "Failed to get port capabilities, ret = %d\n", 365 port_cap->status); 366 return -EINVAL; 367 } 368 369 return 0; 370 } 371 372 /** 373 * hinic_port_set_tso - set port tso configuration 374 * @nic_dev: nic device 375 * @state: the tso state to set 376 * 377 * Return 0 - Success, negative - Failure 378 **/ 379 int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state) 380 { 381 struct hinic_hwdev *hwdev = nic_dev->hwdev; 382 struct hinic_hwif *hwif = hwdev->hwif; 383 struct hinic_tso_config tso_cfg = {0}; 384 struct pci_dev *pdev = hwif->pdev; 385 u16 out_size; 386 int err; 387 388 tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 389 tso_cfg.tso_en = state; 390 391 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO, 392 &tso_cfg, sizeof(tso_cfg), 393 &tso_cfg, &out_size); 394 if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) { 395 dev_err(&pdev->dev, 396 "Failed to set port tso, ret = %d\n", 397 tso_cfg.status); 398 return -EINVAL; 399 } 400 401 return 0; 402 } 403 404 int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en) 405 { 406 struct hinic_checksum_offload rx_csum_cfg = {0}; 407 struct hinic_hwdev *hwdev = nic_dev->hwdev; 408 struct hinic_hwif *hwif; 409 struct pci_dev *pdev; 410 u16 out_size; 411 int err; 412 413 if (!hwdev) 414 return -EINVAL; 415 416 hwif = hwdev->hwif; 417 pdev = hwif->pdev; 418 rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 419 rx_csum_cfg.rx_csum_offload = en; 420 421 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM, 422 &rx_csum_cfg, sizeof(rx_csum_cfg), 423 &rx_csum_cfg, &out_size); 424 if (err || !out_size || rx_csum_cfg.status) { 425 dev_err(&pdev->dev, 426 "Failed to set rx csum offload, ret = %d\n", 427 rx_csum_cfg.status); 428 return -EINVAL; 429 } 430 431 return 0; 432 } 433 434 int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en) 435 { 436 struct hinic_hwdev *hwdev = nic_dev->hwdev; 437 struct hinic_vlan_cfg vlan_cfg; 438 struct hinic_hwif *hwif; 439 struct pci_dev *pdev; 440 u16 out_size; 441 int err; 442 443 if (!hwdev) 444 return -EINVAL; 445 446 hwif = hwdev->hwif; 447 pdev = hwif->pdev; 448 vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 449 vlan_cfg.vlan_rx_offload = en; 450 451 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD, 452 &vlan_cfg, sizeof(vlan_cfg), 453 &vlan_cfg, &out_size); 454 if (err || !out_size || vlan_cfg.status) { 455 dev_err(&pdev->dev, 456 "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n", 457 err, vlan_cfg.status, out_size); 458 return -EINVAL; 459 } 460 461 return 0; 462 } 463 464 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs) 465 { 466 struct hinic_hwdev *hwdev = nic_dev->hwdev; 467 struct hinic_hwif *hwif = hwdev->hwif; 468 struct pci_dev *pdev = hwif->pdev; 469 struct hinic_rq_num rq_num = { 0 }; 470 u16 out_size = sizeof(rq_num); 471 int err; 472 473 rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif); 474 rq_num.num_rqs = num_rqs; 475 rq_num.rq_depth = ilog2(HINIC_SQ_DEPTH); 476 477 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP, 478 &rq_num, sizeof(rq_num), 479 &rq_num, &out_size); 480 if (err || !out_size || rq_num.status) { 481 dev_err(&pdev->dev, 482 "Failed to rxq number, ret = %d\n", 483 rq_num.status); 484 return -EINVAL; 485 } 486 487 return 0; 488 } 489 490 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en, 491 u8 max_wqe_num) 492 { 493 struct hinic_hwdev *hwdev = nic_dev->hwdev; 494 struct hinic_hwif *hwif = hwdev->hwif; 495 struct hinic_lro_config lro_cfg = { 0 }; 496 struct pci_dev *pdev = hwif->pdev; 497 u16 out_size = sizeof(lro_cfg); 498 int err; 499 500 lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 501 lro_cfg.lro_ipv4_en = ipv4_en; 502 lro_cfg.lro_ipv6_en = ipv6_en; 503 lro_cfg.lro_max_wqe_num = max_wqe_num; 504 505 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO, 506 &lro_cfg, sizeof(lro_cfg), 507 &lro_cfg, &out_size); 508 if (err || !out_size || lro_cfg.status) { 509 dev_err(&pdev->dev, 510 "Failed to set lro offload, ret = %d\n", 511 lro_cfg.status); 512 return -EINVAL; 513 } 514 515 return 0; 516 } 517 518 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value) 519 { 520 struct hinic_hwdev *hwdev = nic_dev->hwdev; 521 struct hinic_lro_timer lro_timer = { 0 }; 522 struct hinic_hwif *hwif = hwdev->hwif; 523 struct pci_dev *pdev = hwif->pdev; 524 u16 out_size = sizeof(lro_timer); 525 int err; 526 527 lro_timer.status = 0; 528 lro_timer.type = 0; 529 lro_timer.enable = 1; 530 lro_timer.timer = timer_value; 531 532 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER, 533 &lro_timer, sizeof(lro_timer), 534 &lro_timer, &out_size); 535 if (lro_timer.status == 0xFF) { 536 /* For this case, we think status (0xFF) is OK */ 537 lro_timer.status = 0; 538 dev_dbg(&pdev->dev, 539 "Set lro timer not supported by the current FW version, it will be 1ms default\n"); 540 } 541 542 if (err || !out_size || lro_timer.status) { 543 dev_err(&pdev->dev, 544 "Failed to set lro timer, ret = %d\n", 545 lro_timer.status); 546 547 return -EINVAL; 548 } 549 550 return 0; 551 } 552 553 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en, 554 u32 lro_timer, u32 wqe_num) 555 { 556 struct hinic_hwdev *hwdev = nic_dev->hwdev; 557 u8 ipv4_en; 558 u8 ipv6_en; 559 int err; 560 561 if (!hwdev) 562 return -EINVAL; 563 564 ipv4_en = lro_en ? 1 : 0; 565 ipv6_en = lro_en ? 1 : 0; 566 567 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num); 568 if (err) 569 return err; 570 571 err = hinic_set_rx_lro_timer(nic_dev, lro_timer); 572 if (err) 573 return err; 574 575 return 0; 576 } 577 578 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 579 const u32 *indir_table) 580 { 581 struct hinic_rss_indirect_tbl *indir_tbl; 582 struct hinic_func_to_io *func_to_io; 583 struct hinic_cmdq_buf cmd_buf; 584 struct hinic_hwdev *hwdev; 585 struct hinic_hwif *hwif; 586 struct pci_dev *pdev; 587 u32 indir_size; 588 u64 out_param; 589 int err, i; 590 u32 *temp; 591 592 hwdev = nic_dev->hwdev; 593 func_to_io = &hwdev->func_to_io; 594 hwif = hwdev->hwif; 595 pdev = hwif->pdev; 596 597 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 598 if (err) { 599 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n"); 600 return err; 601 } 602 603 cmd_buf.size = sizeof(*indir_tbl); 604 605 indir_tbl = cmd_buf.buf; 606 indir_tbl->group_index = cpu_to_be32(tmpl_idx); 607 608 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) { 609 indir_tbl->entry[i] = indir_table[i]; 610 611 if (0x3 == (i & 0x3)) { 612 temp = (u32 *)&indir_tbl->entry[i - 3]; 613 *temp = cpu_to_be32(*temp); 614 } 615 } 616 617 /* cfg the rss indirect table by command queue */ 618 indir_size = HINIC_RSS_INDIR_SIZE / 2; 619 indir_tbl->offset = 0; 620 indir_tbl->size = cpu_to_be32(indir_size); 621 622 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 623 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 624 &cmd_buf, &out_param); 625 if (err || out_param != 0) { 626 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 627 err = -EFAULT; 628 goto free_buf; 629 } 630 631 indir_tbl->offset = cpu_to_be32(indir_size); 632 indir_tbl->size = cpu_to_be32(indir_size); 633 memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size); 634 635 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 636 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 637 &cmd_buf, &out_param); 638 if (err || out_param != 0) { 639 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 640 err = -EFAULT; 641 } 642 643 free_buf: 644 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 645 646 return err; 647 } 648 649 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 650 u32 *indir_table) 651 { 652 struct hinic_rss_indir_table rss_cfg = { 0 }; 653 struct hinic_hwdev *hwdev = nic_dev->hwdev; 654 struct hinic_hwif *hwif = hwdev->hwif; 655 struct pci_dev *pdev = hwif->pdev; 656 u16 out_size = sizeof(rss_cfg); 657 int err = 0, i; 658 659 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 660 rss_cfg.template_id = tmpl_idx; 661 662 err = hinic_port_msg_cmd(hwdev, 663 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL, 664 &rss_cfg, sizeof(rss_cfg), &rss_cfg, 665 &out_size); 666 if (err || !out_size || rss_cfg.status) { 667 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n", 668 err, rss_cfg.status, out_size); 669 return -EINVAL; 670 } 671 672 hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE); 673 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) 674 indir_table[i] = rss_cfg.indir[i]; 675 676 return 0; 677 } 678 679 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 680 struct hinic_rss_type rss_type) 681 { 682 struct hinic_rss_context_tbl *ctx_tbl; 683 struct hinic_func_to_io *func_to_io; 684 struct hinic_cmdq_buf cmd_buf; 685 struct hinic_hwdev *hwdev; 686 struct hinic_hwif *hwif; 687 struct pci_dev *pdev; 688 u64 out_param; 689 u32 ctx = 0; 690 int err; 691 692 hwdev = nic_dev->hwdev; 693 func_to_io = &hwdev->func_to_io; 694 hwif = hwdev->hwif; 695 pdev = hwif->pdev; 696 697 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 698 if (err) { 699 dev_err(&pdev->dev, "Failed to allocate cmd buf\n"); 700 return -ENOMEM; 701 } 702 703 ctx |= HINIC_RSS_TYPE_SET(1, VALID) | 704 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) | 705 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) | 706 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) | 707 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) | 708 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) | 709 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) | 710 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) | 711 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6); 712 713 cmd_buf.size = sizeof(struct hinic_rss_context_tbl); 714 715 ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf; 716 ctx_tbl->group_index = cpu_to_be32(tmpl_idx); 717 ctx_tbl->offset = 0; 718 ctx_tbl->size = sizeof(u32); 719 ctx_tbl->size = cpu_to_be32(ctx_tbl->size); 720 ctx_tbl->rsvd = 0; 721 ctx_tbl->ctx = cpu_to_be32(ctx); 722 723 /* cfg the rss context table by command queue */ 724 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 725 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE, 726 &cmd_buf, &out_param); 727 728 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 729 730 if (err || out_param != 0) { 731 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n", 732 err); 733 return -EFAULT; 734 } 735 736 return 0; 737 } 738 739 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 740 struct hinic_rss_type *rss_type) 741 { 742 struct hinic_rss_context_table ctx_tbl = { 0 }; 743 struct hinic_hwdev *hwdev = nic_dev->hwdev; 744 struct hinic_hwif *hwif; 745 struct pci_dev *pdev; 746 u16 out_size = sizeof(ctx_tbl); 747 int err; 748 749 if (!hwdev || !rss_type) 750 return -EINVAL; 751 752 hwif = hwdev->hwif; 753 pdev = hwif->pdev; 754 755 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif); 756 ctx_tbl.template_id = tmpl_idx; 757 758 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL, 759 &ctx_tbl, sizeof(ctx_tbl), 760 &ctx_tbl, &out_size); 761 if (err || !out_size || ctx_tbl.status) { 762 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n", 763 err, ctx_tbl.status, out_size); 764 return -EINVAL; 765 } 766 767 rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4); 768 rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6); 769 rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT); 770 rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4); 771 rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6); 772 rss_type->tcp_ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, 773 TCP_IPV6_EXT); 774 rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4); 775 rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6); 776 777 return 0; 778 } 779 780 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id, 781 const u8 *temp) 782 { 783 struct hinic_hwdev *hwdev = nic_dev->hwdev; 784 struct hinic_hwif *hwif = hwdev->hwif; 785 struct hinic_rss_key rss_key = { 0 }; 786 struct pci_dev *pdev = hwif->pdev; 787 u16 out_size; 788 int err; 789 790 rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 791 rss_key.template_id = template_id; 792 memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE); 793 794 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL, 795 &rss_key, sizeof(rss_key), 796 &rss_key, &out_size); 797 if (err || !out_size || rss_key.status) { 798 dev_err(&pdev->dev, 799 "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n", 800 err, rss_key.status, out_size); 801 return -EINVAL; 802 } 803 804 return 0; 805 } 806 807 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 808 u8 *temp) 809 { 810 struct hinic_rss_template_key temp_key = { 0 }; 811 struct hinic_hwdev *hwdev = nic_dev->hwdev; 812 struct hinic_hwif *hwif; 813 struct pci_dev *pdev; 814 u16 out_size = sizeof(temp_key); 815 int err; 816 817 if (!hwdev || !temp) 818 return -EINVAL; 819 820 hwif = hwdev->hwif; 821 pdev = hwif->pdev; 822 823 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 824 temp_key.template_id = tmpl_idx; 825 826 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, 827 &temp_key, sizeof(temp_key), 828 &temp_key, &out_size); 829 if (err || !out_size || temp_key.status) { 830 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n", 831 err, temp_key.status, out_size); 832 return -EINVAL; 833 } 834 835 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE); 836 837 return 0; 838 } 839 840 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id, 841 u8 type) 842 { 843 struct hinic_rss_engine_type rss_engine = { 0 }; 844 struct hinic_hwdev *hwdev = nic_dev->hwdev; 845 struct hinic_hwif *hwif = hwdev->hwif; 846 struct pci_dev *pdev = hwif->pdev; 847 u16 out_size; 848 int err; 849 850 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif); 851 rss_engine.hash_engine = type; 852 rss_engine.template_id = template_id; 853 854 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE, 855 &rss_engine, sizeof(rss_engine), 856 &rss_engine, &out_size); 857 if (err || !out_size || rss_engine.status) { 858 dev_err(&pdev->dev, 859 "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 860 err, rss_engine.status, out_size); 861 return -EINVAL; 862 } 863 864 return 0; 865 } 866 867 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type) 868 { 869 struct hinic_rss_engine_type hash_type = { 0 }; 870 struct hinic_hwdev *hwdev = nic_dev->hwdev; 871 struct hinic_hwif *hwif; 872 struct pci_dev *pdev; 873 u16 out_size = sizeof(hash_type); 874 int err; 875 876 if (!hwdev || !type) 877 return -EINVAL; 878 879 hwif = hwdev->hwif; 880 pdev = hwif->pdev; 881 882 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif); 883 hash_type.template_id = tmpl_idx; 884 885 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, 886 &hash_type, sizeof(hash_type), 887 &hash_type, &out_size); 888 if (err || !out_size || hash_type.status) { 889 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 890 err, hash_type.status, out_size); 891 return -EINVAL; 892 } 893 894 *type = hash_type.hash_engine; 895 return 0; 896 } 897 898 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id) 899 { 900 struct hinic_hwdev *hwdev = nic_dev->hwdev; 901 struct hinic_rss_config rss_cfg = { 0 }; 902 struct hinic_hwif *hwif = hwdev->hwif; 903 struct pci_dev *pdev = hwif->pdev; 904 u16 out_size; 905 int err; 906 907 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 908 rss_cfg.rss_en = rss_en; 909 rss_cfg.template_id = template_id; 910 rss_cfg.rq_priority_number = 0; 911 912 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG, 913 &rss_cfg, sizeof(rss_cfg), 914 &rss_cfg, &out_size); 915 if (err || !out_size || rss_cfg.status) { 916 dev_err(&pdev->dev, 917 "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n", 918 err, rss_cfg.status, out_size); 919 return -EINVAL; 920 } 921 922 return 0; 923 } 924 925 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx) 926 { 927 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 928 struct hinic_hwdev *hwdev = nic_dev->hwdev; 929 struct hinic_hwif *hwif = hwdev->hwif; 930 struct pci_dev *pdev = hwif->pdev; 931 u16 out_size; 932 int err; 933 934 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 935 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC; 936 937 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 938 &template_mgmt, sizeof(template_mgmt), 939 &template_mgmt, &out_size); 940 if (err || !out_size || template_mgmt.status) { 941 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n", 942 err, template_mgmt.status, out_size); 943 return -EINVAL; 944 } 945 946 *tmpl_idx = template_mgmt.template_id; 947 948 return 0; 949 } 950 951 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx) 952 { 953 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 954 struct hinic_hwdev *hwdev = nic_dev->hwdev; 955 struct hinic_hwif *hwif = hwdev->hwif; 956 struct pci_dev *pdev = hwif->pdev; 957 u16 out_size; 958 int err; 959 960 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 961 template_mgmt.template_id = tmpl_idx; 962 template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE; 963 964 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 965 &template_mgmt, sizeof(template_mgmt), 966 &template_mgmt, &out_size); 967 if (err || !out_size || template_mgmt.status) { 968 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n", 969 err, template_mgmt.status, out_size); 970 return -EINVAL; 971 } 972 973 return 0; 974 } 975 976 int hinic_get_vport_stats(struct hinic_dev *nic_dev, 977 struct hinic_vport_stats *stats) 978 { 979 struct hinic_cmd_vport_stats vport_stats = { 0 }; 980 struct hinic_port_stats_info stats_info = { 0 }; 981 struct hinic_hwdev *hwdev = nic_dev->hwdev; 982 struct hinic_hwif *hwif = hwdev->hwif; 983 u16 out_size = sizeof(vport_stats); 984 struct pci_dev *pdev = hwif->pdev; 985 int err; 986 987 stats_info.stats_version = HINIC_PORT_STATS_VERSION; 988 stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif); 989 stats_info.stats_size = sizeof(vport_stats); 990 991 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT, 992 &stats_info, sizeof(stats_info), 993 &vport_stats, &out_size); 994 if (err || !out_size || vport_stats.status) { 995 dev_err(&pdev->dev, 996 "Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n", 997 err, vport_stats.status, out_size); 998 return -EFAULT; 999 } 1000 1001 memcpy(stats, &vport_stats.stats, sizeof(*stats)); 1002 return 0; 1003 } 1004 1005 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev, 1006 struct hinic_phy_port_stats *stats) 1007 { 1008 struct hinic_port_stats_info stats_info = { 0 }; 1009 struct hinic_hwdev *hwdev = nic_dev->hwdev; 1010 struct hinic_hwif *hwif = hwdev->hwif; 1011 struct hinic_port_stats *port_stats; 1012 u16 out_size = sizeof(*port_stats); 1013 struct pci_dev *pdev = hwif->pdev; 1014 int err; 1015 1016 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); 1017 if (!port_stats) 1018 return -ENOMEM; 1019 1020 stats_info.stats_version = HINIC_PORT_STATS_VERSION; 1021 stats_info.stats_size = sizeof(*port_stats); 1022 1023 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS, 1024 &stats_info, sizeof(stats_info), 1025 port_stats, &out_size); 1026 if (err || !out_size || port_stats->status) { 1027 dev_err(&pdev->dev, 1028 "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", 1029 err, port_stats->status, out_size); 1030 err = -EINVAL; 1031 goto out; 1032 } 1033 1034 memcpy(stats, &port_stats->stats, sizeof(*stats)); 1035 1036 out: 1037 kfree(port_stats); 1038 1039 return err; 1040 } 1041 1042 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver) 1043 { 1044 struct hinic_hwdev *hwdev = nic_dev->hwdev; 1045 struct hinic_version_info up_ver = {0}; 1046 struct hinic_hwif *hwif; 1047 struct pci_dev *pdev; 1048 u16 out_size; 1049 int err; 1050 1051 if (!hwdev) 1052 return -EINVAL; 1053 1054 hwif = hwdev->hwif; 1055 pdev = hwif->pdev; 1056 1057 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION, 1058 &up_ver, sizeof(up_ver), &up_ver, 1059 &out_size); 1060 if (err || !out_size || up_ver.status) { 1061 dev_err(&pdev->dev, 1062 "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n", 1063 err, up_ver.status, out_size); 1064 return -EINVAL; 1065 } 1066 1067 snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver); 1068 1069 return 0; 1070 } 1071