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 enum mac_op { 21 MAC_DEL, 22 MAC_SET, 23 }; 24 25 /** 26 * change_mac - change(add or delete) mac address 27 * @nic_dev: nic device 28 * @addr: mac address 29 * @vlan_id: vlan number to set with the mac 30 * @op: add or delete the mac 31 * 32 * Return 0 - Success, negative - Failure 33 **/ 34 static int change_mac(struct hinic_dev *nic_dev, const u8 *addr, 35 u16 vlan_id, enum mac_op op) 36 { 37 struct hinic_hwdev *hwdev = nic_dev->hwdev; 38 struct hinic_port_mac_cmd port_mac_cmd; 39 struct hinic_hwif *hwif = hwdev->hwif; 40 u16 out_size = sizeof(port_mac_cmd); 41 struct pci_dev *pdev = hwif->pdev; 42 enum hinic_port_cmd cmd; 43 int err; 44 45 if (op == MAC_SET) 46 cmd = HINIC_PORT_CMD_SET_MAC; 47 else 48 cmd = HINIC_PORT_CMD_DEL_MAC; 49 50 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 51 port_mac_cmd.vlan_id = vlan_id; 52 memcpy(port_mac_cmd.mac, addr, ETH_ALEN); 53 54 err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd, 55 sizeof(port_mac_cmd), 56 &port_mac_cmd, &out_size); 57 if (err || out_size != sizeof(port_mac_cmd) || 58 (port_mac_cmd.status && 59 (port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) && 60 port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) { 61 dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n", 62 err, port_mac_cmd.status, out_size); 63 return -EFAULT; 64 } 65 66 if (port_mac_cmd.status == HINIC_PF_SET_VF_ALREADY) { 67 dev_warn(&pdev->dev, "PF has already set VF mac, ignore %s operation\n", 68 (op == MAC_SET) ? "set" : "del"); 69 return HINIC_PF_SET_VF_ALREADY; 70 } 71 72 if (cmd == HINIC_PORT_CMD_SET_MAC && port_mac_cmd.status == 73 HINIC_MGMT_STATUS_EXIST) 74 dev_warn(&pdev->dev, "MAC is repeated, ignore set operation\n"); 75 76 return 0; 77 } 78 79 /** 80 * hinic_port_add_mac - add mac address 81 * @nic_dev: nic device 82 * @addr: mac address 83 * @vlan_id: vlan number to set with the mac 84 * 85 * Return 0 - Success, negative - Failure 86 **/ 87 int hinic_port_add_mac(struct hinic_dev *nic_dev, 88 const u8 *addr, u16 vlan_id) 89 { 90 return change_mac(nic_dev, addr, vlan_id, MAC_SET); 91 } 92 93 /** 94 * hinic_port_del_mac - remove mac address 95 * @nic_dev: nic device 96 * @addr: mac address 97 * @vlan_id: vlan number that is connected to the mac 98 * 99 * Return 0 - Success, negative - Failure 100 **/ 101 int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr, 102 u16 vlan_id) 103 { 104 return change_mac(nic_dev, addr, vlan_id, MAC_DEL); 105 } 106 107 /** 108 * hinic_port_get_mac - get the mac address of the nic device 109 * @nic_dev: nic device 110 * @addr: returned mac address 111 * 112 * Return 0 - Success, negative - Failure 113 **/ 114 int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr) 115 { 116 struct hinic_hwdev *hwdev = nic_dev->hwdev; 117 struct hinic_port_mac_cmd port_mac_cmd; 118 struct hinic_hwif *hwif = hwdev->hwif; 119 u16 out_size = sizeof(port_mac_cmd); 120 struct pci_dev *pdev = hwif->pdev; 121 int err; 122 123 port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 124 125 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC, 126 &port_mac_cmd, sizeof(port_mac_cmd), 127 &port_mac_cmd, &out_size); 128 if (err || out_size != sizeof(port_mac_cmd) || port_mac_cmd.status) { 129 dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n", 130 err, port_mac_cmd.status, out_size); 131 return -EFAULT; 132 } 133 134 memcpy(addr, port_mac_cmd.mac, ETH_ALEN); 135 return 0; 136 } 137 138 /** 139 * hinic_port_set_mtu - set mtu 140 * @nic_dev: nic device 141 * @new_mtu: new mtu 142 * 143 * Return 0 - Success, negative - Failure 144 **/ 145 int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu) 146 { 147 struct hinic_hwdev *hwdev = nic_dev->hwdev; 148 struct hinic_port_mtu_cmd port_mtu_cmd; 149 struct hinic_hwif *hwif = hwdev->hwif; 150 u16 out_size = sizeof(port_mtu_cmd); 151 struct pci_dev *pdev = hwif->pdev; 152 int err; 153 154 port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 155 port_mtu_cmd.mtu = new_mtu; 156 157 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU, 158 &port_mtu_cmd, sizeof(port_mtu_cmd), 159 &port_mtu_cmd, &out_size); 160 if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) { 161 dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n", 162 err, port_mtu_cmd.status, out_size); 163 return -EFAULT; 164 } 165 166 return 0; 167 } 168 169 /** 170 * hinic_port_add_vlan - add vlan to the nic device 171 * @nic_dev: nic device 172 * @vlan_id: the vlan number to add 173 * 174 * Return 0 - Success, negative - Failure 175 **/ 176 int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id) 177 { 178 struct hinic_hwdev *hwdev = nic_dev->hwdev; 179 struct hinic_port_vlan_cmd port_vlan_cmd; 180 181 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 182 port_vlan_cmd.vlan_id = vlan_id; 183 184 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN, 185 &port_vlan_cmd, sizeof(port_vlan_cmd), 186 NULL, NULL); 187 } 188 189 /** 190 * hinic_port_del_vlan - delete vlan from the nic device 191 * @nic_dev: nic device 192 * @vlan_id: the vlan number to delete 193 * 194 * Return 0 - Success, negative - Failure 195 **/ 196 int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id) 197 { 198 struct hinic_hwdev *hwdev = nic_dev->hwdev; 199 struct hinic_port_vlan_cmd port_vlan_cmd; 200 201 port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 202 port_vlan_cmd.vlan_id = vlan_id; 203 204 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN, 205 &port_vlan_cmd, sizeof(port_vlan_cmd), 206 NULL, NULL); 207 } 208 209 /** 210 * hinic_port_set_rx_mode - set rx mode in the nic device 211 * @nic_dev: nic device 212 * @rx_mode: the rx mode to set 213 * 214 * Return 0 - Success, negative - Failure 215 **/ 216 int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode) 217 { 218 struct hinic_hwdev *hwdev = nic_dev->hwdev; 219 struct hinic_port_rx_mode_cmd rx_mode_cmd; 220 221 rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 222 rx_mode_cmd.rx_mode = rx_mode; 223 224 return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE, 225 &rx_mode_cmd, sizeof(rx_mode_cmd), 226 NULL, NULL); 227 } 228 229 /** 230 * hinic_port_link_state - get the link state 231 * @nic_dev: nic device 232 * @link_state: the returned link state 233 * 234 * Return 0 - Success, negative - Failure 235 **/ 236 int hinic_port_link_state(struct hinic_dev *nic_dev, 237 enum hinic_port_link_state *link_state) 238 { 239 struct hinic_hwdev *hwdev = nic_dev->hwdev; 240 struct hinic_hwif *hwif = hwdev->hwif; 241 struct hinic_port_link_cmd link_cmd; 242 struct pci_dev *pdev = hwif->pdev; 243 u16 out_size = sizeof(link_cmd); 244 int err; 245 246 link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 247 248 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE, 249 &link_cmd, sizeof(link_cmd), 250 &link_cmd, &out_size); 251 if (err || out_size != sizeof(link_cmd) || link_cmd.status) { 252 dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n", 253 err, link_cmd.status, out_size); 254 return -EINVAL; 255 } 256 257 *link_state = link_cmd.state; 258 return 0; 259 } 260 261 /** 262 * hinic_port_set_state - set port state 263 * @nic_dev: nic device 264 * @state: the state to set 265 * 266 * Return 0 - Success, negative - Failure 267 **/ 268 int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state) 269 { 270 struct hinic_hwdev *hwdev = nic_dev->hwdev; 271 struct hinic_port_state_cmd port_state; 272 struct hinic_hwif *hwif = hwdev->hwif; 273 struct pci_dev *pdev = hwif->pdev; 274 u16 out_size = sizeof(port_state); 275 int err; 276 277 if (HINIC_IS_VF(hwdev->hwif)) 278 return 0; 279 280 port_state.state = state; 281 282 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE, 283 &port_state, sizeof(port_state), 284 &port_state, &out_size); 285 if (err || out_size != sizeof(port_state) || port_state.status) { 286 dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n", 287 err, port_state.status, out_size); 288 return -EFAULT; 289 } 290 291 return 0; 292 } 293 294 /** 295 * hinic_port_set_func_state- set func device state 296 * @nic_dev: nic device 297 * @state: the state to set 298 * 299 * Return 0 - Success, negative - Failure 300 **/ 301 int hinic_port_set_func_state(struct hinic_dev *nic_dev, 302 enum hinic_func_port_state state) 303 { 304 struct hinic_port_func_state_cmd func_state; 305 struct hinic_hwdev *hwdev = nic_dev->hwdev; 306 struct hinic_hwif *hwif = hwdev->hwif; 307 struct pci_dev *pdev = hwif->pdev; 308 u16 out_size = sizeof(func_state); 309 int err; 310 311 func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 312 func_state.state = state; 313 314 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE, 315 &func_state, sizeof(func_state), 316 &func_state, &out_size); 317 if (err || out_size != sizeof(func_state) || func_state.status) { 318 dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n", 319 err, func_state.status, out_size); 320 return -EFAULT; 321 } 322 323 return 0; 324 } 325 326 /** 327 * hinic_port_get_cap - get port capabilities 328 * @nic_dev: nic device 329 * @port_cap: returned port capabilities 330 * 331 * Return 0 - Success, negative - Failure 332 **/ 333 int hinic_port_get_cap(struct hinic_dev *nic_dev, 334 struct hinic_port_cap *port_cap) 335 { 336 struct hinic_hwdev *hwdev = nic_dev->hwdev; 337 struct hinic_hwif *hwif = hwdev->hwif; 338 struct pci_dev *pdev = hwif->pdev; 339 u16 out_size = sizeof(*port_cap); 340 int err; 341 342 port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif); 343 344 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP, 345 port_cap, sizeof(*port_cap), 346 port_cap, &out_size); 347 if (err || out_size != sizeof(*port_cap) || port_cap->status) { 348 dev_err(&pdev->dev, 349 "Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n", 350 err, port_cap->status, out_size); 351 return -EIO; 352 } 353 354 return 0; 355 } 356 357 /** 358 * hinic_port_set_tso - set port tso configuration 359 * @nic_dev: nic device 360 * @state: the tso state to set 361 * 362 * Return 0 - Success, negative - Failure 363 **/ 364 int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state) 365 { 366 struct hinic_hwdev *hwdev = nic_dev->hwdev; 367 struct hinic_hwif *hwif = hwdev->hwif; 368 struct hinic_tso_config tso_cfg = {0}; 369 struct pci_dev *pdev = hwif->pdev; 370 u16 out_size = sizeof(tso_cfg); 371 int err; 372 373 tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 374 tso_cfg.tso_en = state; 375 376 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO, 377 &tso_cfg, sizeof(tso_cfg), 378 &tso_cfg, &out_size); 379 if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) { 380 dev_err(&pdev->dev, 381 "Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n", 382 err, tso_cfg.status, out_size); 383 return -EIO; 384 } 385 386 return 0; 387 } 388 389 int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en) 390 { 391 struct hinic_checksum_offload rx_csum_cfg = {0}; 392 struct hinic_hwdev *hwdev = nic_dev->hwdev; 393 u16 out_size = sizeof(rx_csum_cfg); 394 struct hinic_hwif *hwif; 395 struct pci_dev *pdev; 396 int err; 397 398 if (!hwdev) 399 return -EINVAL; 400 401 hwif = hwdev->hwif; 402 pdev = hwif->pdev; 403 rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 404 rx_csum_cfg.rx_csum_offload = en; 405 406 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM, 407 &rx_csum_cfg, sizeof(rx_csum_cfg), 408 &rx_csum_cfg, &out_size); 409 if (err || !out_size || rx_csum_cfg.status) { 410 dev_err(&pdev->dev, 411 "Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n", 412 err, rx_csum_cfg.status, out_size); 413 return -EIO; 414 } 415 416 return 0; 417 } 418 419 int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en) 420 { 421 struct hinic_hwdev *hwdev = nic_dev->hwdev; 422 struct hinic_vlan_cfg vlan_cfg; 423 struct hinic_hwif *hwif; 424 struct pci_dev *pdev; 425 u16 out_size; 426 int err; 427 428 if (!hwdev) 429 return -EINVAL; 430 431 out_size = sizeof(vlan_cfg); 432 hwif = hwdev->hwif; 433 pdev = hwif->pdev; 434 vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 435 vlan_cfg.vlan_rx_offload = en; 436 437 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD, 438 &vlan_cfg, sizeof(vlan_cfg), 439 &vlan_cfg, &out_size); 440 if (err || !out_size || vlan_cfg.status) { 441 dev_err(&pdev->dev, 442 "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n", 443 err, vlan_cfg.status, out_size); 444 return -EINVAL; 445 } 446 447 return 0; 448 } 449 450 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs) 451 { 452 struct hinic_hwdev *hwdev = nic_dev->hwdev; 453 struct hinic_hwif *hwif = hwdev->hwif; 454 struct hinic_rq_num rq_num = { 0 }; 455 struct pci_dev *pdev = hwif->pdev; 456 u16 out_size = sizeof(rq_num); 457 int err; 458 459 rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif); 460 rq_num.num_rqs = num_rqs; 461 rq_num.rq_depth = ilog2(nic_dev->rq_depth); 462 463 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP, 464 &rq_num, sizeof(rq_num), 465 &rq_num, &out_size); 466 if (err || !out_size || rq_num.status) { 467 dev_err(&pdev->dev, 468 "Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n", 469 err, rq_num.status, out_size); 470 return -EIO; 471 } 472 473 return 0; 474 } 475 476 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en, 477 u8 max_wqe_num) 478 { 479 struct hinic_hwdev *hwdev = nic_dev->hwdev; 480 struct hinic_lro_config lro_cfg = { 0 }; 481 struct hinic_hwif *hwif = hwdev->hwif; 482 struct pci_dev *pdev = hwif->pdev; 483 u16 out_size = sizeof(lro_cfg); 484 int err; 485 486 lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 487 lro_cfg.lro_ipv4_en = ipv4_en; 488 lro_cfg.lro_ipv6_en = ipv6_en; 489 lro_cfg.lro_max_wqe_num = max_wqe_num; 490 491 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO, 492 &lro_cfg, sizeof(lro_cfg), 493 &lro_cfg, &out_size); 494 if (err || !out_size || lro_cfg.status) { 495 dev_err(&pdev->dev, 496 "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n", 497 err, lro_cfg.status, out_size); 498 return -EIO; 499 } 500 501 return 0; 502 } 503 504 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value) 505 { 506 struct hinic_hwdev *hwdev = nic_dev->hwdev; 507 struct hinic_lro_timer lro_timer = { 0 }; 508 struct hinic_hwif *hwif = hwdev->hwif; 509 struct pci_dev *pdev = hwif->pdev; 510 u16 out_size = sizeof(lro_timer); 511 int err; 512 513 lro_timer.status = 0; 514 lro_timer.type = 0; 515 lro_timer.enable = 1; 516 lro_timer.timer = timer_value; 517 518 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER, 519 &lro_timer, sizeof(lro_timer), 520 &lro_timer, &out_size); 521 if (lro_timer.status == 0xFF) { 522 /* For this case, we think status (0xFF) is OK */ 523 lro_timer.status = 0; 524 dev_dbg(&pdev->dev, 525 "Set lro timer not supported by the current FW version, it will be 1ms default\n"); 526 } 527 528 if (err || !out_size || lro_timer.status) { 529 dev_err(&pdev->dev, 530 "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n", 531 err, lro_timer.status, out_size); 532 533 return -EIO; 534 } 535 536 return 0; 537 } 538 539 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en, 540 u32 lro_timer, u32 wqe_num) 541 { 542 struct hinic_hwdev *hwdev = nic_dev->hwdev; 543 u8 ipv4_en; 544 u8 ipv6_en; 545 int err; 546 547 if (!hwdev) 548 return -EINVAL; 549 550 ipv4_en = lro_en ? 1 : 0; 551 ipv6_en = lro_en ? 1 : 0; 552 553 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num); 554 if (err) 555 return err; 556 557 if (HINIC_IS_VF(nic_dev->hwdev->hwif)) 558 return 0; 559 560 err = hinic_set_rx_lro_timer(nic_dev, lro_timer); 561 if (err) 562 return err; 563 564 return 0; 565 } 566 567 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 568 const u32 *indir_table) 569 { 570 struct hinic_rss_indirect_tbl *indir_tbl; 571 struct hinic_func_to_io *func_to_io; 572 struct hinic_cmdq_buf cmd_buf; 573 struct hinic_hwdev *hwdev; 574 struct hinic_hwif *hwif; 575 struct pci_dev *pdev; 576 u32 indir_size; 577 u64 out_param; 578 int err, i; 579 u32 *temp; 580 581 hwdev = nic_dev->hwdev; 582 func_to_io = &hwdev->func_to_io; 583 hwif = hwdev->hwif; 584 pdev = hwif->pdev; 585 586 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 587 if (err) { 588 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n"); 589 return err; 590 } 591 592 cmd_buf.size = sizeof(*indir_tbl); 593 594 indir_tbl = cmd_buf.buf; 595 indir_tbl->group_index = cpu_to_be32(tmpl_idx); 596 597 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) { 598 indir_tbl->entry[i] = indir_table[i]; 599 600 if (0x3 == (i & 0x3)) { 601 temp = (u32 *)&indir_tbl->entry[i - 3]; 602 *temp = cpu_to_be32(*temp); 603 } 604 } 605 606 /* cfg the rss indirect table by command queue */ 607 indir_size = HINIC_RSS_INDIR_SIZE / 2; 608 indir_tbl->offset = 0; 609 indir_tbl->size = cpu_to_be32(indir_size); 610 611 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 612 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 613 &cmd_buf, &out_param); 614 if (err || out_param != 0) { 615 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 616 err = -EFAULT; 617 goto free_buf; 618 } 619 620 indir_tbl->offset = cpu_to_be32(indir_size); 621 indir_tbl->size = cpu_to_be32(indir_size); 622 memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size); 623 624 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 625 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 626 &cmd_buf, &out_param); 627 if (err || out_param != 0) { 628 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 629 err = -EFAULT; 630 } 631 632 free_buf: 633 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 634 635 return err; 636 } 637 638 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 639 u32 *indir_table) 640 { 641 struct hinic_rss_indir_table rss_cfg = { 0 }; 642 struct hinic_hwdev *hwdev = nic_dev->hwdev; 643 struct hinic_hwif *hwif = hwdev->hwif; 644 struct pci_dev *pdev = hwif->pdev; 645 u16 out_size = sizeof(rss_cfg); 646 int err = 0, i; 647 648 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 649 rss_cfg.template_id = tmpl_idx; 650 651 err = hinic_port_msg_cmd(hwdev, 652 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL, 653 &rss_cfg, sizeof(rss_cfg), &rss_cfg, 654 &out_size); 655 if (err || !out_size || rss_cfg.status) { 656 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n", 657 err, rss_cfg.status, out_size); 658 return -EINVAL; 659 } 660 661 hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE); 662 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) 663 indir_table[i] = rss_cfg.indir[i]; 664 665 return 0; 666 } 667 668 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 669 struct hinic_rss_type rss_type) 670 { 671 struct hinic_rss_context_tbl *ctx_tbl; 672 struct hinic_func_to_io *func_to_io; 673 struct hinic_cmdq_buf cmd_buf; 674 struct hinic_hwdev *hwdev; 675 struct hinic_hwif *hwif; 676 struct pci_dev *pdev; 677 u64 out_param; 678 u32 ctx = 0; 679 int err; 680 681 hwdev = nic_dev->hwdev; 682 func_to_io = &hwdev->func_to_io; 683 hwif = hwdev->hwif; 684 pdev = hwif->pdev; 685 686 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 687 if (err) { 688 dev_err(&pdev->dev, "Failed to allocate cmd buf\n"); 689 return -ENOMEM; 690 } 691 692 ctx |= HINIC_RSS_TYPE_SET(1, VALID) | 693 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) | 694 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) | 695 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) | 696 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) | 697 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) | 698 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) | 699 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) | 700 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6); 701 702 cmd_buf.size = sizeof(struct hinic_rss_context_tbl); 703 704 ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf; 705 ctx_tbl->group_index = cpu_to_be32(tmpl_idx); 706 ctx_tbl->offset = 0; 707 ctx_tbl->size = sizeof(u32); 708 ctx_tbl->size = cpu_to_be32(ctx_tbl->size); 709 ctx_tbl->rsvd = 0; 710 ctx_tbl->ctx = cpu_to_be32(ctx); 711 712 /* cfg the rss context table by command queue */ 713 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 714 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE, 715 &cmd_buf, &out_param); 716 717 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 718 719 if (err || out_param != 0) { 720 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n", 721 err); 722 return -EFAULT; 723 } 724 725 return 0; 726 } 727 728 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 729 struct hinic_rss_type *rss_type) 730 { 731 struct hinic_rss_context_table ctx_tbl = { 0 }; 732 struct hinic_hwdev *hwdev = nic_dev->hwdev; 733 u16 out_size = sizeof(ctx_tbl); 734 struct hinic_hwif *hwif; 735 struct pci_dev *pdev; 736 int err; 737 738 if (!hwdev || !rss_type) 739 return -EINVAL; 740 741 hwif = hwdev->hwif; 742 pdev = hwif->pdev; 743 744 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif); 745 ctx_tbl.template_id = tmpl_idx; 746 747 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL, 748 &ctx_tbl, sizeof(ctx_tbl), 749 &ctx_tbl, &out_size); 750 if (err || !out_size || ctx_tbl.status) { 751 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n", 752 err, ctx_tbl.status, out_size); 753 return -EINVAL; 754 } 755 756 rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4); 757 rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6); 758 rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT); 759 rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4); 760 rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6); 761 rss_type->tcp_ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, 762 TCP_IPV6_EXT); 763 rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4); 764 rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6); 765 766 return 0; 767 } 768 769 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id, 770 const u8 *temp) 771 { 772 struct hinic_hwdev *hwdev = nic_dev->hwdev; 773 struct hinic_hwif *hwif = hwdev->hwif; 774 struct hinic_rss_key rss_key = { 0 }; 775 struct pci_dev *pdev = hwif->pdev; 776 u16 out_size = sizeof(rss_key); 777 int err; 778 779 rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 780 rss_key.template_id = template_id; 781 memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE); 782 783 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL, 784 &rss_key, sizeof(rss_key), 785 &rss_key, &out_size); 786 if (err || !out_size || rss_key.status) { 787 dev_err(&pdev->dev, 788 "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n", 789 err, rss_key.status, out_size); 790 return -EINVAL; 791 } 792 793 return 0; 794 } 795 796 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 797 u8 *temp) 798 { 799 struct hinic_rss_template_key temp_key = { 0 }; 800 struct hinic_hwdev *hwdev = nic_dev->hwdev; 801 u16 out_size = sizeof(temp_key); 802 struct hinic_hwif *hwif; 803 struct pci_dev *pdev; 804 int err; 805 806 if (!hwdev || !temp) 807 return -EINVAL; 808 809 hwif = hwdev->hwif; 810 pdev = hwif->pdev; 811 812 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 813 temp_key.template_id = tmpl_idx; 814 815 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, 816 &temp_key, sizeof(temp_key), 817 &temp_key, &out_size); 818 if (err || !out_size || temp_key.status) { 819 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n", 820 err, temp_key.status, out_size); 821 return -EINVAL; 822 } 823 824 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE); 825 826 return 0; 827 } 828 829 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id, 830 u8 type) 831 { 832 struct hinic_rss_engine_type rss_engine = { 0 }; 833 struct hinic_hwdev *hwdev = nic_dev->hwdev; 834 struct hinic_hwif *hwif = hwdev->hwif; 835 struct pci_dev *pdev = hwif->pdev; 836 u16 out_size = sizeof(rss_engine); 837 int err; 838 839 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif); 840 rss_engine.hash_engine = type; 841 rss_engine.template_id = template_id; 842 843 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE, 844 &rss_engine, sizeof(rss_engine), 845 &rss_engine, &out_size); 846 if (err || !out_size || rss_engine.status) { 847 dev_err(&pdev->dev, 848 "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 849 err, rss_engine.status, out_size); 850 return -EINVAL; 851 } 852 853 return 0; 854 } 855 856 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type) 857 { 858 struct hinic_rss_engine_type hash_type = { 0 }; 859 struct hinic_hwdev *hwdev = nic_dev->hwdev; 860 u16 out_size = sizeof(hash_type); 861 struct hinic_hwif *hwif; 862 struct pci_dev *pdev; 863 int err; 864 865 if (!hwdev || !type) 866 return -EINVAL; 867 868 hwif = hwdev->hwif; 869 pdev = hwif->pdev; 870 871 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif); 872 hash_type.template_id = tmpl_idx; 873 874 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, 875 &hash_type, sizeof(hash_type), 876 &hash_type, &out_size); 877 if (err || !out_size || hash_type.status) { 878 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 879 err, hash_type.status, out_size); 880 return -EINVAL; 881 } 882 883 *type = hash_type.hash_engine; 884 return 0; 885 } 886 887 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id) 888 { 889 struct hinic_hwdev *hwdev = nic_dev->hwdev; 890 struct hinic_rss_config rss_cfg = { 0 }; 891 struct hinic_hwif *hwif = hwdev->hwif; 892 struct pci_dev *pdev = hwif->pdev; 893 u16 out_size = sizeof(rss_cfg); 894 int err; 895 896 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 897 rss_cfg.rss_en = rss_en; 898 rss_cfg.template_id = template_id; 899 rss_cfg.rq_priority_number = 0; 900 901 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG, 902 &rss_cfg, sizeof(rss_cfg), 903 &rss_cfg, &out_size); 904 if (err || !out_size || rss_cfg.status) { 905 dev_err(&pdev->dev, 906 "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n", 907 err, rss_cfg.status, out_size); 908 return -EINVAL; 909 } 910 911 return 0; 912 } 913 914 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx) 915 { 916 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 917 struct hinic_hwdev *hwdev = nic_dev->hwdev; 918 struct hinic_hwif *hwif = hwdev->hwif; 919 u16 out_size = sizeof(template_mgmt); 920 struct pci_dev *pdev = hwif->pdev; 921 int err; 922 923 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 924 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC; 925 926 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 927 &template_mgmt, sizeof(template_mgmt), 928 &template_mgmt, &out_size); 929 if (err || !out_size || template_mgmt.status) { 930 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n", 931 err, template_mgmt.status, out_size); 932 return -EINVAL; 933 } 934 935 *tmpl_idx = template_mgmt.template_id; 936 937 return 0; 938 } 939 940 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx) 941 { 942 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 943 struct hinic_hwdev *hwdev = nic_dev->hwdev; 944 struct hinic_hwif *hwif = hwdev->hwif; 945 u16 out_size = sizeof(template_mgmt); 946 struct pci_dev *pdev = hwif->pdev; 947 int err; 948 949 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 950 template_mgmt.template_id = tmpl_idx; 951 template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE; 952 953 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 954 &template_mgmt, sizeof(template_mgmt), 955 &template_mgmt, &out_size); 956 if (err || !out_size || template_mgmt.status) { 957 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n", 958 err, template_mgmt.status, out_size); 959 return -EINVAL; 960 } 961 962 return 0; 963 } 964 965 int hinic_get_vport_stats(struct hinic_dev *nic_dev, 966 struct hinic_vport_stats *stats) 967 { 968 struct hinic_cmd_vport_stats vport_stats = { 0 }; 969 struct hinic_port_stats_info stats_info = { 0 }; 970 struct hinic_hwdev *hwdev = nic_dev->hwdev; 971 struct hinic_hwif *hwif = hwdev->hwif; 972 u16 out_size = sizeof(vport_stats); 973 struct pci_dev *pdev = hwif->pdev; 974 int err; 975 976 stats_info.stats_version = HINIC_PORT_STATS_VERSION; 977 stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif); 978 stats_info.stats_size = sizeof(vport_stats); 979 980 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT, 981 &stats_info, sizeof(stats_info), 982 &vport_stats, &out_size); 983 if (err || !out_size || vport_stats.status) { 984 dev_err(&pdev->dev, 985 "Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n", 986 err, vport_stats.status, out_size); 987 return -EFAULT; 988 } 989 990 memcpy(stats, &vport_stats.stats, sizeof(*stats)); 991 return 0; 992 } 993 994 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev, 995 struct hinic_phy_port_stats *stats) 996 { 997 struct hinic_port_stats_info stats_info = { 0 }; 998 struct hinic_hwdev *hwdev = nic_dev->hwdev; 999 struct hinic_hwif *hwif = hwdev->hwif; 1000 struct hinic_port_stats *port_stats; 1001 u16 out_size = sizeof(*port_stats); 1002 struct pci_dev *pdev = hwif->pdev; 1003 int err; 1004 1005 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); 1006 if (!port_stats) 1007 return -ENOMEM; 1008 1009 stats_info.stats_version = HINIC_PORT_STATS_VERSION; 1010 stats_info.stats_size = sizeof(*port_stats); 1011 1012 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS, 1013 &stats_info, sizeof(stats_info), 1014 port_stats, &out_size); 1015 if (err || !out_size || port_stats->status) { 1016 dev_err(&pdev->dev, 1017 "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", 1018 err, port_stats->status, out_size); 1019 err = -EINVAL; 1020 goto out; 1021 } 1022 1023 memcpy(stats, &port_stats->stats, sizeof(*stats)); 1024 1025 out: 1026 kfree(port_stats); 1027 1028 return err; 1029 } 1030 1031 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver) 1032 { 1033 struct hinic_hwdev *hwdev = nic_dev->hwdev; 1034 struct hinic_version_info up_ver = {0}; 1035 u16 out_size = sizeof(up_ver); 1036 struct hinic_hwif *hwif; 1037 struct pci_dev *pdev; 1038 int err; 1039 1040 if (!hwdev) 1041 return -EINVAL; 1042 1043 hwif = hwdev->hwif; 1044 pdev = hwif->pdev; 1045 1046 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION, 1047 &up_ver, sizeof(up_ver), &up_ver, 1048 &out_size); 1049 if (err || !out_size || up_ver.status) { 1050 dev_err(&pdev->dev, 1051 "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n", 1052 err, up_ver.status, out_size); 1053 return -EINVAL; 1054 } 1055 1056 snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver); 1057 1058 return 0; 1059 } 1060 1061 int hinic_get_link_mode(struct hinic_hwdev *hwdev, 1062 struct hinic_link_mode_cmd *link_mode) 1063 { 1064 u16 out_size; 1065 int err; 1066 1067 if (!hwdev || !link_mode) 1068 return -EINVAL; 1069 1070 link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1071 out_size = sizeof(*link_mode); 1072 1073 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE, 1074 link_mode, sizeof(*link_mode), 1075 link_mode, &out_size); 1076 if (err || !out_size || link_mode->status) { 1077 dev_err(&hwdev->hwif->pdev->dev, 1078 "Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x\n", 1079 err, link_mode->status, out_size); 1080 return -EIO; 1081 } 1082 1083 return 0; 1084 } 1085 1086 int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable) 1087 { 1088 struct hinic_set_autoneg_cmd autoneg = {0}; 1089 u16 out_size = sizeof(autoneg); 1090 int err; 1091 1092 if (!hwdev) 1093 return -EINVAL; 1094 1095 autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1096 autoneg.enable = enable; 1097 1098 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_AUTONEG, 1099 &autoneg, sizeof(autoneg), 1100 &autoneg, &out_size); 1101 if (err || !out_size || autoneg.status) { 1102 dev_err(&hwdev->hwif->pdev->dev, "Failed to %s autoneg, err: %d, status: 0x%x, out size: 0x%x\n", 1103 enable ? "enable" : "disable", err, autoneg.status, 1104 out_size); 1105 return -EIO; 1106 } 1107 1108 return 0; 1109 } 1110 1111 int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed) 1112 { 1113 struct hinic_speed_cmd speed_info = {0}; 1114 u16 out_size = sizeof(speed_info); 1115 int err; 1116 1117 if (!hwdev) 1118 return -EINVAL; 1119 1120 speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1121 speed_info.speed = speed; 1122 1123 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_SPEED, 1124 &speed_info, sizeof(speed_info), 1125 &speed_info, &out_size); 1126 if (err || !out_size || speed_info.status) { 1127 dev_err(&hwdev->hwif->pdev->dev, 1128 "Failed to set speed, err: %d, status: 0x%x, out size: 0x%x\n", 1129 err, speed_info.status, out_size); 1130 return -EIO; 1131 } 1132 1133 return 0; 1134 } 1135 1136 int hinic_set_link_settings(struct hinic_hwdev *hwdev, 1137 struct hinic_link_ksettings_info *info) 1138 { 1139 u16 out_size = sizeof(*info); 1140 int err; 1141 1142 err = hinic_hilink_msg_cmd(hwdev, HINIC_HILINK_CMD_SET_LINK_SETTINGS, 1143 info, sizeof(*info), info, &out_size); 1144 if ((info->status != HINIC_MGMT_CMD_UNSUPPORTED && 1145 info->status) || err || !out_size) { 1146 dev_err(&hwdev->hwif->pdev->dev, 1147 "Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n", 1148 err, info->status, out_size); 1149 return -EFAULT; 1150 } 1151 1152 return info->status; 1153 } 1154 1155 int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev, 1156 struct hinic_pause_config *pause_info) 1157 { 1158 u16 out_size = sizeof(*pause_info); 1159 int err; 1160 1161 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1162 1163 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO, 1164 pause_info, sizeof(*pause_info), 1165 pause_info, &out_size); 1166 if (err || !out_size || pause_info->status) { 1167 dev_err(&hwdev->hwif->pdev->dev, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n", 1168 err, pause_info->status, out_size); 1169 return -EIO; 1170 } 1171 1172 return 0; 1173 } 1174 1175 int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev, 1176 struct hinic_pause_config *pause_info) 1177 { 1178 u16 out_size = sizeof(*pause_info); 1179 int err; 1180 1181 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1182 1183 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO, 1184 pause_info, sizeof(*pause_info), 1185 pause_info, &out_size); 1186 if (err || !out_size || pause_info->status) { 1187 dev_err(&hwdev->hwif->pdev->dev, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x\n", 1188 err, pause_info->status, out_size); 1189 return -EIO; 1190 } 1191 1192 return 0; 1193 } 1194 1195 int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap) 1196 { 1197 struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg; 1198 struct hinic_set_pfc pfc = {0}; 1199 u16 out_size = sizeof(pfc); 1200 int err; 1201 1202 if (HINIC_IS_VF(hwdev->hwif)) 1203 return 0; 1204 1205 mutex_lock(&nic_cfg->cfg_mutex); 1206 1207 pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1208 pfc.pfc_bitmap = pfc_bitmap; 1209 pfc.pfc_en = pfc_en; 1210 1211 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC, 1212 &pfc, sizeof(pfc), &pfc, &out_size); 1213 if (err || pfc.status || !out_size) { 1214 dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n", 1215 pfc_en ? "enable" : "disable", err, pfc.status, 1216 out_size); 1217 mutex_unlock(&nic_cfg->cfg_mutex); 1218 return -EIO; 1219 } 1220 1221 /* pause settings is opposite from pfc */ 1222 nic_cfg->rx_pause = pfc_en ? 0 : 1; 1223 nic_cfg->tx_pause = pfc_en ? 0 : 1; 1224 1225 mutex_unlock(&nic_cfg->cfg_mutex); 1226 1227 return 0; 1228 } 1229 1230 int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable) 1231 { 1232 struct hinic_port_loopback lb = {0}; 1233 u16 out_size = sizeof(lb); 1234 int err; 1235 1236 lb.mode = mode; 1237 lb.en = enable; 1238 1239 if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) { 1240 dev_err(&hwdev->hwif->pdev->dev, 1241 "Invalid loopback mode %d to set\n", mode); 1242 return -EINVAL; 1243 } 1244 1245 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE, 1246 &lb, sizeof(lb), &lb, &out_size); 1247 if (err || !out_size || lb.status) { 1248 dev_err(&hwdev->hwif->pdev->dev, 1249 "Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n", 1250 mode, enable, err, lb.status, out_size); 1251 return -EIO; 1252 } 1253 1254 return 0; 1255 } 1256 1257 static int _set_led_status(struct hinic_hwdev *hwdev, u8 port, 1258 enum hinic_led_type type, 1259 enum hinic_led_mode mode, u8 reset) 1260 { 1261 struct hinic_led_info led_info = {0}; 1262 u16 out_size = sizeof(led_info); 1263 struct hinic_pfhwdev *pfhwdev; 1264 int err; 1265 1266 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 1267 1268 led_info.port = port; 1269 led_info.reset = reset; 1270 1271 led_info.type = type; 1272 led_info.mode = mode; 1273 1274 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 1275 HINIC_COMM_CMD_SET_LED_STATUS, 1276 &led_info, sizeof(led_info), 1277 &led_info, &out_size, HINIC_MGMT_MSG_SYNC); 1278 if (err || led_info.status || !out_size) { 1279 dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n", 1280 err, led_info.status, out_size); 1281 return -EIO; 1282 } 1283 1284 return 0; 1285 } 1286 1287 int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port, 1288 enum hinic_led_type type, enum hinic_led_mode mode) 1289 { 1290 if (!hwdev) 1291 return -EINVAL; 1292 1293 return _set_led_status(hwdev, port, type, mode, 0); 1294 } 1295 1296 int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port) 1297 { 1298 int err; 1299 1300 if (!hwdev) 1301 return -EINVAL; 1302 1303 err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID, 1304 HINIC_LED_MODE_INVALID, 1); 1305 if (err) 1306 dev_err(&hwdev->hwif->pdev->dev, 1307 "Failed to reset led status\n"); 1308 1309 return err; 1310 } 1311 1312 static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev) 1313 { 1314 struct hinic_cmd_get_light_module_abs sfp_abs = {0}; 1315 u16 out_size = sizeof(sfp_abs); 1316 u8 port_id = hwdev->port_id; 1317 int err; 1318 1319 sfp_abs.port_id = port_id; 1320 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS, 1321 &sfp_abs, sizeof(sfp_abs), &sfp_abs, 1322 &out_size); 1323 if (sfp_abs.status || err || !out_size) { 1324 dev_err(&hwdev->hwif->pdev->dev, 1325 "Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n", 1326 port_id, err, sfp_abs.status, out_size); 1327 return true; 1328 } 1329 1330 return ((sfp_abs.abs_status == 0) ? false : true); 1331 } 1332 1333 int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len) 1334 { 1335 struct hinic_cmd_get_std_sfp_info sfp_info = {0}; 1336 u16 out_size = sizeof(sfp_info); 1337 u8 port_id; 1338 int err; 1339 1340 if (!hwdev || !data || !len) 1341 return -EINVAL; 1342 1343 port_id = hwdev->port_id; 1344 1345 if (hinic_if_sfp_absent(hwdev)) 1346 return -ENXIO; 1347 1348 sfp_info.port_id = port_id; 1349 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO, 1350 &sfp_info, sizeof(sfp_info), &sfp_info, 1351 &out_size); 1352 if (sfp_info.status || err || !out_size) { 1353 dev_err(&hwdev->hwif->pdev->dev, 1354 "Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n", 1355 port_id, err, sfp_info.status, out_size); 1356 return -EIO; 1357 } 1358 1359 *len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE); 1360 memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE); 1361 1362 return 0; 1363 } 1364 1365 int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1) 1366 { 1367 u8 sfp_data[STD_SFP_INFO_MAX_SIZE]; 1368 u16 len; 1369 int err; 1370 1371 if (hinic_if_sfp_absent(hwdev)) 1372 return -ENXIO; 1373 1374 err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len); 1375 if (err) 1376 return err; 1377 1378 *data0 = sfp_data[0]; 1379 *data1 = sfp_data[1]; 1380 1381 return 0; 1382 } 1383