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_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs) 435 { 436 struct hinic_hwdev *hwdev = nic_dev->hwdev; 437 struct hinic_hwif *hwif = hwdev->hwif; 438 struct pci_dev *pdev = hwif->pdev; 439 struct hinic_rq_num rq_num = { 0 }; 440 u16 out_size = sizeof(rq_num); 441 int err; 442 443 rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif); 444 rq_num.num_rqs = num_rqs; 445 rq_num.rq_depth = ilog2(HINIC_SQ_DEPTH); 446 447 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP, 448 &rq_num, sizeof(rq_num), 449 &rq_num, &out_size); 450 if (err || !out_size || rq_num.status) { 451 dev_err(&pdev->dev, 452 "Failed to rxq number, ret = %d\n", 453 rq_num.status); 454 return -EINVAL; 455 } 456 457 return 0; 458 } 459 460 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en, 461 u8 max_wqe_num) 462 { 463 struct hinic_hwdev *hwdev = nic_dev->hwdev; 464 struct hinic_hwif *hwif = hwdev->hwif; 465 struct hinic_lro_config lro_cfg = { 0 }; 466 struct pci_dev *pdev = hwif->pdev; 467 u16 out_size = sizeof(lro_cfg); 468 int err; 469 470 lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 471 lro_cfg.lro_ipv4_en = ipv4_en; 472 lro_cfg.lro_ipv6_en = ipv6_en; 473 lro_cfg.lro_max_wqe_num = max_wqe_num; 474 475 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO, 476 &lro_cfg, sizeof(lro_cfg), 477 &lro_cfg, &out_size); 478 if (err || !out_size || lro_cfg.status) { 479 dev_err(&pdev->dev, 480 "Failed to set lro offload, ret = %d\n", 481 lro_cfg.status); 482 return -EINVAL; 483 } 484 485 return 0; 486 } 487 488 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value) 489 { 490 struct hinic_hwdev *hwdev = nic_dev->hwdev; 491 struct hinic_lro_timer lro_timer = { 0 }; 492 struct hinic_hwif *hwif = hwdev->hwif; 493 struct pci_dev *pdev = hwif->pdev; 494 u16 out_size = sizeof(lro_timer); 495 int err; 496 497 lro_timer.status = 0; 498 lro_timer.type = 0; 499 lro_timer.enable = 1; 500 lro_timer.timer = timer_value; 501 502 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER, 503 &lro_timer, sizeof(lro_timer), 504 &lro_timer, &out_size); 505 if (lro_timer.status == 0xFF) { 506 /* For this case, we think status (0xFF) is OK */ 507 lro_timer.status = 0; 508 dev_dbg(&pdev->dev, 509 "Set lro timer not supported by the current FW version, it will be 1ms default\n"); 510 } 511 512 if (err || !out_size || lro_timer.status) { 513 dev_err(&pdev->dev, 514 "Failed to set lro timer, ret = %d\n", 515 lro_timer.status); 516 517 return -EINVAL; 518 } 519 520 return 0; 521 } 522 523 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en, 524 u32 lro_timer, u32 wqe_num) 525 { 526 struct hinic_hwdev *hwdev = nic_dev->hwdev; 527 u8 ipv4_en; 528 u8 ipv6_en; 529 int err; 530 531 if (!hwdev) 532 return -EINVAL; 533 534 ipv4_en = lro_en ? 1 : 0; 535 ipv6_en = lro_en ? 1 : 0; 536 537 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num); 538 if (err) 539 return err; 540 541 err = hinic_set_rx_lro_timer(nic_dev, lro_timer); 542 if (err) 543 return err; 544 545 return 0; 546 } 547 548 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 549 const u32 *indir_table) 550 { 551 struct hinic_rss_indirect_tbl *indir_tbl; 552 struct hinic_func_to_io *func_to_io; 553 struct hinic_cmdq_buf cmd_buf; 554 struct hinic_hwdev *hwdev; 555 struct hinic_hwif *hwif; 556 struct pci_dev *pdev; 557 u32 indir_size; 558 u64 out_param; 559 int err, i; 560 u32 *temp; 561 562 hwdev = nic_dev->hwdev; 563 func_to_io = &hwdev->func_to_io; 564 hwif = hwdev->hwif; 565 pdev = hwif->pdev; 566 567 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 568 if (err) { 569 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n"); 570 return err; 571 } 572 573 cmd_buf.size = sizeof(*indir_tbl); 574 575 indir_tbl = cmd_buf.buf; 576 indir_tbl->group_index = cpu_to_be32(tmpl_idx); 577 578 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) { 579 indir_tbl->entry[i] = indir_table[i]; 580 581 if (0x3 == (i & 0x3)) { 582 temp = (u32 *)&indir_tbl->entry[i - 3]; 583 *temp = cpu_to_be32(*temp); 584 } 585 } 586 587 /* cfg the rss indirect table by command queue */ 588 indir_size = HINIC_RSS_INDIR_SIZE / 2; 589 indir_tbl->offset = 0; 590 indir_tbl->size = cpu_to_be32(indir_size); 591 592 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 593 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 594 &cmd_buf, &out_param); 595 if (err || out_param != 0) { 596 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 597 err = -EFAULT; 598 goto free_buf; 599 } 600 601 indir_tbl->offset = cpu_to_be32(indir_size); 602 indir_tbl->size = cpu_to_be32(indir_size); 603 memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size); 604 605 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 606 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 607 &cmd_buf, &out_param); 608 if (err || out_param != 0) { 609 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 610 err = -EFAULT; 611 } 612 613 free_buf: 614 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 615 616 return err; 617 } 618 619 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 620 u32 *indir_table) 621 { 622 struct hinic_rss_indir_table rss_cfg = { 0 }; 623 struct hinic_hwdev *hwdev = nic_dev->hwdev; 624 struct hinic_hwif *hwif = hwdev->hwif; 625 struct pci_dev *pdev = hwif->pdev; 626 u16 out_size = sizeof(rss_cfg); 627 int err = 0, i; 628 629 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 630 rss_cfg.template_id = tmpl_idx; 631 632 err = hinic_port_msg_cmd(hwdev, 633 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL, 634 &rss_cfg, sizeof(rss_cfg), &rss_cfg, 635 &out_size); 636 if (err || !out_size || rss_cfg.status) { 637 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n", 638 err, rss_cfg.status, out_size); 639 return -EINVAL; 640 } 641 642 hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE); 643 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) 644 indir_table[i] = rss_cfg.indir[i]; 645 646 return 0; 647 } 648 649 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 650 struct hinic_rss_type rss_type) 651 { 652 struct hinic_rss_context_tbl *ctx_tbl; 653 struct hinic_func_to_io *func_to_io; 654 struct hinic_cmdq_buf cmd_buf; 655 struct hinic_hwdev *hwdev; 656 struct hinic_hwif *hwif; 657 struct pci_dev *pdev; 658 u64 out_param; 659 u32 ctx = 0; 660 int err; 661 662 hwdev = nic_dev->hwdev; 663 func_to_io = &hwdev->func_to_io; 664 hwif = hwdev->hwif; 665 pdev = hwif->pdev; 666 667 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 668 if (err) { 669 dev_err(&pdev->dev, "Failed to allocate cmd buf\n"); 670 return -ENOMEM; 671 } 672 673 ctx |= HINIC_RSS_TYPE_SET(1, VALID) | 674 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) | 675 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) | 676 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) | 677 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) | 678 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) | 679 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) | 680 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) | 681 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6); 682 683 cmd_buf.size = sizeof(struct hinic_rss_context_tbl); 684 685 ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf; 686 ctx_tbl->group_index = cpu_to_be32(tmpl_idx); 687 ctx_tbl->offset = 0; 688 ctx_tbl->size = sizeof(u32); 689 ctx_tbl->size = cpu_to_be32(ctx_tbl->size); 690 ctx_tbl->rsvd = 0; 691 ctx_tbl->ctx = cpu_to_be32(ctx); 692 693 /* cfg the rss context table by command queue */ 694 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 695 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE, 696 &cmd_buf, &out_param); 697 698 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 699 700 if (err || out_param != 0) { 701 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n", 702 err); 703 return -EFAULT; 704 } 705 706 return 0; 707 } 708 709 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 710 struct hinic_rss_type *rss_type) 711 { 712 struct hinic_rss_context_table ctx_tbl = { 0 }; 713 struct hinic_hwdev *hwdev = nic_dev->hwdev; 714 struct hinic_hwif *hwif; 715 struct pci_dev *pdev; 716 u16 out_size = sizeof(ctx_tbl); 717 int err; 718 719 if (!hwdev || !rss_type) 720 return -EINVAL; 721 722 hwif = hwdev->hwif; 723 pdev = hwif->pdev; 724 725 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif); 726 ctx_tbl.template_id = tmpl_idx; 727 728 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL, 729 &ctx_tbl, sizeof(ctx_tbl), 730 &ctx_tbl, &out_size); 731 if (err || !out_size || ctx_tbl.status) { 732 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n", 733 err, ctx_tbl.status, out_size); 734 return -EINVAL; 735 } 736 737 rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4); 738 rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6); 739 rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT); 740 rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4); 741 rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6); 742 rss_type->tcp_ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, 743 TCP_IPV6_EXT); 744 rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4); 745 rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6); 746 747 return 0; 748 } 749 750 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id, 751 const u8 *temp) 752 { 753 struct hinic_hwdev *hwdev = nic_dev->hwdev; 754 struct hinic_hwif *hwif = hwdev->hwif; 755 struct hinic_rss_key rss_key = { 0 }; 756 struct pci_dev *pdev = hwif->pdev; 757 u16 out_size; 758 int err; 759 760 rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 761 rss_key.template_id = template_id; 762 memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE); 763 764 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL, 765 &rss_key, sizeof(rss_key), 766 &rss_key, &out_size); 767 if (err || !out_size || rss_key.status) { 768 dev_err(&pdev->dev, 769 "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n", 770 err, rss_key.status, out_size); 771 return -EINVAL; 772 } 773 774 return 0; 775 } 776 777 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 778 u8 *temp) 779 { 780 struct hinic_rss_template_key temp_key = { 0 }; 781 struct hinic_hwdev *hwdev = nic_dev->hwdev; 782 struct hinic_hwif *hwif; 783 struct pci_dev *pdev; 784 u16 out_size = sizeof(temp_key); 785 int err; 786 787 if (!hwdev || !temp) 788 return -EINVAL; 789 790 hwif = hwdev->hwif; 791 pdev = hwif->pdev; 792 793 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 794 temp_key.template_id = tmpl_idx; 795 796 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, 797 &temp_key, sizeof(temp_key), 798 &temp_key, &out_size); 799 if (err || !out_size || temp_key.status) { 800 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n", 801 err, temp_key.status, out_size); 802 return -EINVAL; 803 } 804 805 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE); 806 807 return 0; 808 } 809 810 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id, 811 u8 type) 812 { 813 struct hinic_rss_engine_type rss_engine = { 0 }; 814 struct hinic_hwdev *hwdev = nic_dev->hwdev; 815 struct hinic_hwif *hwif = hwdev->hwif; 816 struct pci_dev *pdev = hwif->pdev; 817 u16 out_size; 818 int err; 819 820 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif); 821 rss_engine.hash_engine = type; 822 rss_engine.template_id = template_id; 823 824 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE, 825 &rss_engine, sizeof(rss_engine), 826 &rss_engine, &out_size); 827 if (err || !out_size || rss_engine.status) { 828 dev_err(&pdev->dev, 829 "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 830 err, rss_engine.status, out_size); 831 return -EINVAL; 832 } 833 834 return 0; 835 } 836 837 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type) 838 { 839 struct hinic_rss_engine_type hash_type = { 0 }; 840 struct hinic_hwdev *hwdev = nic_dev->hwdev; 841 struct hinic_hwif *hwif; 842 struct pci_dev *pdev; 843 u16 out_size = sizeof(hash_type); 844 int err; 845 846 if (!hwdev || !type) 847 return -EINVAL; 848 849 hwif = hwdev->hwif; 850 pdev = hwif->pdev; 851 852 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif); 853 hash_type.template_id = tmpl_idx; 854 855 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, 856 &hash_type, sizeof(hash_type), 857 &hash_type, &out_size); 858 if (err || !out_size || hash_type.status) { 859 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 860 err, hash_type.status, out_size); 861 return -EINVAL; 862 } 863 864 *type = hash_type.hash_engine; 865 return 0; 866 } 867 868 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id) 869 { 870 struct hinic_hwdev *hwdev = nic_dev->hwdev; 871 struct hinic_rss_config rss_cfg = { 0 }; 872 struct hinic_hwif *hwif = hwdev->hwif; 873 struct pci_dev *pdev = hwif->pdev; 874 u16 out_size; 875 int err; 876 877 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 878 rss_cfg.rss_en = rss_en; 879 rss_cfg.template_id = template_id; 880 rss_cfg.rq_priority_number = 0; 881 882 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG, 883 &rss_cfg, sizeof(rss_cfg), 884 &rss_cfg, &out_size); 885 if (err || !out_size || rss_cfg.status) { 886 dev_err(&pdev->dev, 887 "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n", 888 err, rss_cfg.status, out_size); 889 return -EINVAL; 890 } 891 892 return 0; 893 } 894 895 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx) 896 { 897 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 898 struct hinic_hwdev *hwdev = nic_dev->hwdev; 899 struct hinic_hwif *hwif = hwdev->hwif; 900 struct pci_dev *pdev = hwif->pdev; 901 u16 out_size; 902 int err; 903 904 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 905 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC; 906 907 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 908 &template_mgmt, sizeof(template_mgmt), 909 &template_mgmt, &out_size); 910 if (err || !out_size || template_mgmt.status) { 911 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n", 912 err, template_mgmt.status, out_size); 913 return -EINVAL; 914 } 915 916 *tmpl_idx = template_mgmt.template_id; 917 918 return 0; 919 } 920 921 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx) 922 { 923 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 924 struct hinic_hwdev *hwdev = nic_dev->hwdev; 925 struct hinic_hwif *hwif = hwdev->hwif; 926 struct pci_dev *pdev = hwif->pdev; 927 u16 out_size; 928 int err; 929 930 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 931 template_mgmt.template_id = tmpl_idx; 932 template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE; 933 934 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 935 &template_mgmt, sizeof(template_mgmt), 936 &template_mgmt, &out_size); 937 if (err || !out_size || template_mgmt.status) { 938 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n", 939 err, template_mgmt.status, out_size); 940 return -EINVAL; 941 } 942 943 return 0; 944 } 945