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_vlan_fliter(struct hinic_dev *nic_dev, u32 en) 451 { 452 struct hinic_hwdev *hwdev = nic_dev->hwdev; 453 struct hinic_hwif *hwif = hwdev->hwif; 454 struct pci_dev *pdev = hwif->pdev; 455 struct hinic_vlan_filter vlan_filter; 456 u16 out_size = sizeof(vlan_filter); 457 int err; 458 459 if (!hwdev) 460 return -EINVAL; 461 462 vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif); 463 vlan_filter.enable = en; 464 465 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER, 466 &vlan_filter, sizeof(vlan_filter), 467 &vlan_filter, &out_size); 468 if (vlan_filter.status == HINIC_MGMT_CMD_UNSUPPORTED) { 469 err = HINIC_MGMT_CMD_UNSUPPORTED; 470 } else if ((err == HINIC_MBOX_VF_CMD_ERROR) && 471 HINIC_IS_VF(hwif)) { 472 err = HINIC_MGMT_CMD_UNSUPPORTED; 473 } else if (err || !out_size || vlan_filter.status) { 474 dev_err(&pdev->dev, 475 "Failed to set vlan fliter, err: %d, status: 0x%x, out size: 0x%x\n", 476 err, vlan_filter.status, out_size); 477 err = -EINVAL; 478 } 479 480 return err; 481 } 482 483 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs) 484 { 485 struct hinic_hwdev *hwdev = nic_dev->hwdev; 486 struct hinic_hwif *hwif = hwdev->hwif; 487 struct hinic_rq_num rq_num = { 0 }; 488 struct pci_dev *pdev = hwif->pdev; 489 u16 out_size = sizeof(rq_num); 490 int err; 491 492 rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif); 493 rq_num.num_rqs = num_rqs; 494 rq_num.rq_depth = ilog2(nic_dev->rq_depth); 495 496 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP, 497 &rq_num, sizeof(rq_num), 498 &rq_num, &out_size); 499 if (err || !out_size || rq_num.status) { 500 dev_err(&pdev->dev, 501 "Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n", 502 err, rq_num.status, out_size); 503 return -EIO; 504 } 505 506 return 0; 507 } 508 509 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en, 510 u8 max_wqe_num) 511 { 512 struct hinic_hwdev *hwdev = nic_dev->hwdev; 513 struct hinic_lro_config lro_cfg = { 0 }; 514 struct hinic_hwif *hwif = hwdev->hwif; 515 struct pci_dev *pdev = hwif->pdev; 516 u16 out_size = sizeof(lro_cfg); 517 int err; 518 519 lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 520 lro_cfg.lro_ipv4_en = ipv4_en; 521 lro_cfg.lro_ipv6_en = ipv6_en; 522 lro_cfg.lro_max_wqe_num = max_wqe_num; 523 524 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO, 525 &lro_cfg, sizeof(lro_cfg), 526 &lro_cfg, &out_size); 527 if (err || !out_size || lro_cfg.status) { 528 dev_err(&pdev->dev, 529 "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n", 530 err, lro_cfg.status, out_size); 531 return -EIO; 532 } 533 534 return 0; 535 } 536 537 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value) 538 { 539 struct hinic_hwdev *hwdev = nic_dev->hwdev; 540 struct hinic_lro_timer lro_timer = { 0 }; 541 struct hinic_hwif *hwif = hwdev->hwif; 542 struct pci_dev *pdev = hwif->pdev; 543 u16 out_size = sizeof(lro_timer); 544 int err; 545 546 lro_timer.status = 0; 547 lro_timer.type = 0; 548 lro_timer.enable = 1; 549 lro_timer.timer = timer_value; 550 551 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER, 552 &lro_timer, sizeof(lro_timer), 553 &lro_timer, &out_size); 554 if (lro_timer.status == 0xFF) { 555 /* For this case, we think status (0xFF) is OK */ 556 lro_timer.status = 0; 557 dev_dbg(&pdev->dev, 558 "Set lro timer not supported by the current FW version, it will be 1ms default\n"); 559 } 560 561 if (err || !out_size || lro_timer.status) { 562 dev_err(&pdev->dev, 563 "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n", 564 err, lro_timer.status, out_size); 565 566 return -EIO; 567 } 568 569 return 0; 570 } 571 572 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en, 573 u32 lro_timer, u32 wqe_num) 574 { 575 struct hinic_hwdev *hwdev = nic_dev->hwdev; 576 u8 ipv4_en; 577 u8 ipv6_en; 578 int err; 579 580 if (!hwdev) 581 return -EINVAL; 582 583 ipv4_en = lro_en ? 1 : 0; 584 ipv6_en = lro_en ? 1 : 0; 585 586 err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num); 587 if (err) 588 return err; 589 590 if (HINIC_IS_VF(nic_dev->hwdev->hwif)) 591 return 0; 592 593 err = hinic_set_rx_lro_timer(nic_dev, lro_timer); 594 if (err) 595 return err; 596 597 return 0; 598 } 599 600 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 601 const u32 *indir_table) 602 { 603 struct hinic_rss_indirect_tbl *indir_tbl; 604 struct hinic_func_to_io *func_to_io; 605 struct hinic_cmdq_buf cmd_buf; 606 struct hinic_hwdev *hwdev; 607 struct hinic_hwif *hwif; 608 struct pci_dev *pdev; 609 u32 indir_size; 610 u64 out_param; 611 int err, i; 612 u32 *temp; 613 614 hwdev = nic_dev->hwdev; 615 func_to_io = &hwdev->func_to_io; 616 hwif = hwdev->hwif; 617 pdev = hwif->pdev; 618 619 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 620 if (err) { 621 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n"); 622 return err; 623 } 624 625 cmd_buf.size = sizeof(*indir_tbl); 626 627 indir_tbl = cmd_buf.buf; 628 indir_tbl->group_index = cpu_to_be32(tmpl_idx); 629 630 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) { 631 indir_tbl->entry[i] = indir_table[i]; 632 633 if (0x3 == (i & 0x3)) { 634 temp = (u32 *)&indir_tbl->entry[i - 3]; 635 *temp = cpu_to_be32(*temp); 636 } 637 } 638 639 /* cfg the rss indirect table by command queue */ 640 indir_size = HINIC_RSS_INDIR_SIZE / 2; 641 indir_tbl->offset = 0; 642 indir_tbl->size = cpu_to_be32(indir_size); 643 644 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 645 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 646 &cmd_buf, &out_param); 647 if (err || out_param != 0) { 648 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 649 err = -EFAULT; 650 goto free_buf; 651 } 652 653 indir_tbl->offset = cpu_to_be32(indir_size); 654 indir_tbl->size = cpu_to_be32(indir_size); 655 memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size); 656 657 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 658 HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE, 659 &cmd_buf, &out_param); 660 if (err || out_param != 0) { 661 dev_err(&pdev->dev, "Failed to set rss indir table\n"); 662 err = -EFAULT; 663 } 664 665 free_buf: 666 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 667 668 return err; 669 } 670 671 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 672 u32 *indir_table) 673 { 674 struct hinic_rss_indir_table rss_cfg = { 0 }; 675 struct hinic_hwdev *hwdev = nic_dev->hwdev; 676 struct hinic_hwif *hwif = hwdev->hwif; 677 struct pci_dev *pdev = hwif->pdev; 678 u16 out_size = sizeof(rss_cfg); 679 int err = 0, i; 680 681 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 682 rss_cfg.template_id = tmpl_idx; 683 684 err = hinic_port_msg_cmd(hwdev, 685 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL, 686 &rss_cfg, sizeof(rss_cfg), &rss_cfg, 687 &out_size); 688 if (err || !out_size || rss_cfg.status) { 689 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n", 690 err, rss_cfg.status, out_size); 691 return -EINVAL; 692 } 693 694 hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE); 695 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) 696 indir_table[i] = rss_cfg.indir[i]; 697 698 return 0; 699 } 700 701 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 702 struct hinic_rss_type rss_type) 703 { 704 struct hinic_rss_context_tbl *ctx_tbl; 705 struct hinic_func_to_io *func_to_io; 706 struct hinic_cmdq_buf cmd_buf; 707 struct hinic_hwdev *hwdev; 708 struct hinic_hwif *hwif; 709 struct pci_dev *pdev; 710 u64 out_param; 711 u32 ctx = 0; 712 int err; 713 714 hwdev = nic_dev->hwdev; 715 func_to_io = &hwdev->func_to_io; 716 hwif = hwdev->hwif; 717 pdev = hwif->pdev; 718 719 err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 720 if (err) { 721 dev_err(&pdev->dev, "Failed to allocate cmd buf\n"); 722 return -ENOMEM; 723 } 724 725 ctx |= HINIC_RSS_TYPE_SET(1, VALID) | 726 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) | 727 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) | 728 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) | 729 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) | 730 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) | 731 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) | 732 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) | 733 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6); 734 735 cmd_buf.size = sizeof(struct hinic_rss_context_tbl); 736 737 ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf; 738 ctx_tbl->group_index = cpu_to_be32(tmpl_idx); 739 ctx_tbl->offset = 0; 740 ctx_tbl->size = sizeof(u32); 741 ctx_tbl->size = cpu_to_be32(ctx_tbl->size); 742 ctx_tbl->rsvd = 0; 743 ctx_tbl->ctx = cpu_to_be32(ctx); 744 745 /* cfg the rss context table by command queue */ 746 err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC, 747 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE, 748 &cmd_buf, &out_param); 749 750 hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf); 751 752 if (err || out_param != 0) { 753 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n", 754 err); 755 return -EFAULT; 756 } 757 758 return 0; 759 } 760 761 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx, 762 struct hinic_rss_type *rss_type) 763 { 764 struct hinic_rss_context_table ctx_tbl = { 0 }; 765 struct hinic_hwdev *hwdev = nic_dev->hwdev; 766 u16 out_size = sizeof(ctx_tbl); 767 struct hinic_hwif *hwif; 768 struct pci_dev *pdev; 769 int err; 770 771 if (!hwdev || !rss_type) 772 return -EINVAL; 773 774 hwif = hwdev->hwif; 775 pdev = hwif->pdev; 776 777 ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif); 778 ctx_tbl.template_id = tmpl_idx; 779 780 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL, 781 &ctx_tbl, sizeof(ctx_tbl), 782 &ctx_tbl, &out_size); 783 if (err || !out_size || ctx_tbl.status) { 784 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n", 785 err, ctx_tbl.status, out_size); 786 return -EINVAL; 787 } 788 789 rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4); 790 rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6); 791 rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT); 792 rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4); 793 rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6); 794 rss_type->tcp_ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, 795 TCP_IPV6_EXT); 796 rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4); 797 rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6); 798 799 return 0; 800 } 801 802 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id, 803 const u8 *temp) 804 { 805 struct hinic_hwdev *hwdev = nic_dev->hwdev; 806 struct hinic_hwif *hwif = hwdev->hwif; 807 struct hinic_rss_key rss_key = { 0 }; 808 struct pci_dev *pdev = hwif->pdev; 809 u16 out_size = sizeof(rss_key); 810 int err; 811 812 rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 813 rss_key.template_id = template_id; 814 memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE); 815 816 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL, 817 &rss_key, sizeof(rss_key), 818 &rss_key, &out_size); 819 if (err || !out_size || rss_key.status) { 820 dev_err(&pdev->dev, 821 "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n", 822 err, rss_key.status, out_size); 823 return -EINVAL; 824 } 825 826 return 0; 827 } 828 829 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx, 830 u8 *temp) 831 { 832 struct hinic_rss_template_key temp_key = { 0 }; 833 struct hinic_hwdev *hwdev = nic_dev->hwdev; 834 u16 out_size = sizeof(temp_key); 835 struct hinic_hwif *hwif; 836 struct pci_dev *pdev; 837 int err; 838 839 if (!hwdev || !temp) 840 return -EINVAL; 841 842 hwif = hwdev->hwif; 843 pdev = hwif->pdev; 844 845 temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif); 846 temp_key.template_id = tmpl_idx; 847 848 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL, 849 &temp_key, sizeof(temp_key), 850 &temp_key, &out_size); 851 if (err || !out_size || temp_key.status) { 852 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n", 853 err, temp_key.status, out_size); 854 return -EINVAL; 855 } 856 857 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE); 858 859 return 0; 860 } 861 862 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id, 863 u8 type) 864 { 865 struct hinic_rss_engine_type rss_engine = { 0 }; 866 struct hinic_hwdev *hwdev = nic_dev->hwdev; 867 struct hinic_hwif *hwif = hwdev->hwif; 868 struct pci_dev *pdev = hwif->pdev; 869 u16 out_size = sizeof(rss_engine); 870 int err; 871 872 rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif); 873 rss_engine.hash_engine = type; 874 rss_engine.template_id = template_id; 875 876 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE, 877 &rss_engine, sizeof(rss_engine), 878 &rss_engine, &out_size); 879 if (err || !out_size || rss_engine.status) { 880 dev_err(&pdev->dev, 881 "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 882 err, rss_engine.status, out_size); 883 return -EINVAL; 884 } 885 886 return 0; 887 } 888 889 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type) 890 { 891 struct hinic_rss_engine_type hash_type = { 0 }; 892 struct hinic_hwdev *hwdev = nic_dev->hwdev; 893 u16 out_size = sizeof(hash_type); 894 struct hinic_hwif *hwif; 895 struct pci_dev *pdev; 896 int err; 897 898 if (!hwdev || !type) 899 return -EINVAL; 900 901 hwif = hwdev->hwif; 902 pdev = hwif->pdev; 903 904 hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif); 905 hash_type.template_id = tmpl_idx; 906 907 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE, 908 &hash_type, sizeof(hash_type), 909 &hash_type, &out_size); 910 if (err || !out_size || hash_type.status) { 911 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n", 912 err, hash_type.status, out_size); 913 return -EINVAL; 914 } 915 916 *type = hash_type.hash_engine; 917 return 0; 918 } 919 920 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id) 921 { 922 struct hinic_hwdev *hwdev = nic_dev->hwdev; 923 struct hinic_rss_config rss_cfg = { 0 }; 924 struct hinic_hwif *hwif = hwdev->hwif; 925 struct pci_dev *pdev = hwif->pdev; 926 u16 out_size = sizeof(rss_cfg); 927 int err; 928 929 rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif); 930 rss_cfg.rss_en = rss_en; 931 rss_cfg.template_id = template_id; 932 rss_cfg.rq_priority_number = 0; 933 934 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG, 935 &rss_cfg, sizeof(rss_cfg), 936 &rss_cfg, &out_size); 937 if (err || !out_size || rss_cfg.status) { 938 dev_err(&pdev->dev, 939 "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n", 940 err, rss_cfg.status, out_size); 941 return -EINVAL; 942 } 943 944 return 0; 945 } 946 947 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx) 948 { 949 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 950 struct hinic_hwdev *hwdev = nic_dev->hwdev; 951 struct hinic_hwif *hwif = hwdev->hwif; 952 u16 out_size = sizeof(template_mgmt); 953 struct pci_dev *pdev = hwif->pdev; 954 int err; 955 956 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 957 template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC; 958 959 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 960 &template_mgmt, sizeof(template_mgmt), 961 &template_mgmt, &out_size); 962 if (err || !out_size || template_mgmt.status) { 963 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n", 964 err, template_mgmt.status, out_size); 965 return -EINVAL; 966 } 967 968 *tmpl_idx = template_mgmt.template_id; 969 970 return 0; 971 } 972 973 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx) 974 { 975 struct hinic_rss_template_mgmt template_mgmt = { 0 }; 976 struct hinic_hwdev *hwdev = nic_dev->hwdev; 977 struct hinic_hwif *hwif = hwdev->hwif; 978 u16 out_size = sizeof(template_mgmt); 979 struct pci_dev *pdev = hwif->pdev; 980 int err; 981 982 template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif); 983 template_mgmt.template_id = tmpl_idx; 984 template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE; 985 986 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR, 987 &template_mgmt, sizeof(template_mgmt), 988 &template_mgmt, &out_size); 989 if (err || !out_size || template_mgmt.status) { 990 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n", 991 err, template_mgmt.status, out_size); 992 return -EINVAL; 993 } 994 995 return 0; 996 } 997 998 int hinic_get_vport_stats(struct hinic_dev *nic_dev, 999 struct hinic_vport_stats *stats) 1000 { 1001 struct hinic_cmd_vport_stats vport_stats = { 0 }; 1002 struct hinic_port_stats_info stats_info = { 0 }; 1003 struct hinic_hwdev *hwdev = nic_dev->hwdev; 1004 struct hinic_hwif *hwif = hwdev->hwif; 1005 u16 out_size = sizeof(vport_stats); 1006 struct pci_dev *pdev = hwif->pdev; 1007 int err; 1008 1009 stats_info.stats_version = HINIC_PORT_STATS_VERSION; 1010 stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif); 1011 stats_info.stats_size = sizeof(vport_stats); 1012 1013 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT, 1014 &stats_info, sizeof(stats_info), 1015 &vport_stats, &out_size); 1016 if (err || !out_size || vport_stats.status) { 1017 dev_err(&pdev->dev, 1018 "Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n", 1019 err, vport_stats.status, out_size); 1020 return -EFAULT; 1021 } 1022 1023 memcpy(stats, &vport_stats.stats, sizeof(*stats)); 1024 return 0; 1025 } 1026 1027 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev, 1028 struct hinic_phy_port_stats *stats) 1029 { 1030 struct hinic_port_stats_info stats_info = { 0 }; 1031 struct hinic_hwdev *hwdev = nic_dev->hwdev; 1032 struct hinic_hwif *hwif = hwdev->hwif; 1033 struct hinic_port_stats *port_stats; 1034 u16 out_size = sizeof(*port_stats); 1035 struct pci_dev *pdev = hwif->pdev; 1036 int err; 1037 1038 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); 1039 if (!port_stats) 1040 return -ENOMEM; 1041 1042 stats_info.stats_version = HINIC_PORT_STATS_VERSION; 1043 stats_info.stats_size = sizeof(*port_stats); 1044 1045 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS, 1046 &stats_info, sizeof(stats_info), 1047 port_stats, &out_size); 1048 if (err || !out_size || port_stats->status) { 1049 dev_err(&pdev->dev, 1050 "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n", 1051 err, port_stats->status, out_size); 1052 err = -EINVAL; 1053 goto out; 1054 } 1055 1056 memcpy(stats, &port_stats->stats, sizeof(*stats)); 1057 1058 out: 1059 kfree(port_stats); 1060 1061 return err; 1062 } 1063 1064 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver) 1065 { 1066 struct hinic_hwdev *hwdev = nic_dev->hwdev; 1067 struct hinic_version_info up_ver = {0}; 1068 u16 out_size = sizeof(up_ver); 1069 struct hinic_hwif *hwif; 1070 struct pci_dev *pdev; 1071 int err; 1072 1073 if (!hwdev) 1074 return -EINVAL; 1075 1076 hwif = hwdev->hwif; 1077 pdev = hwif->pdev; 1078 1079 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION, 1080 &up_ver, sizeof(up_ver), &up_ver, 1081 &out_size); 1082 if (err || !out_size || up_ver.status) { 1083 dev_err(&pdev->dev, 1084 "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n", 1085 err, up_ver.status, out_size); 1086 return -EINVAL; 1087 } 1088 1089 snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver); 1090 1091 return 0; 1092 } 1093 1094 int hinic_get_link_mode(struct hinic_hwdev *hwdev, 1095 struct hinic_link_mode_cmd *link_mode) 1096 { 1097 u16 out_size; 1098 int err; 1099 1100 if (!hwdev || !link_mode) 1101 return -EINVAL; 1102 1103 link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1104 out_size = sizeof(*link_mode); 1105 1106 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE, 1107 link_mode, sizeof(*link_mode), 1108 link_mode, &out_size); 1109 if (err || !out_size || link_mode->status) { 1110 dev_err(&hwdev->hwif->pdev->dev, 1111 "Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x\n", 1112 err, link_mode->status, out_size); 1113 return -EIO; 1114 } 1115 1116 return 0; 1117 } 1118 1119 int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable) 1120 { 1121 struct hinic_set_autoneg_cmd autoneg = {0}; 1122 u16 out_size = sizeof(autoneg); 1123 int err; 1124 1125 if (!hwdev) 1126 return -EINVAL; 1127 1128 autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1129 autoneg.enable = enable; 1130 1131 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_AUTONEG, 1132 &autoneg, sizeof(autoneg), 1133 &autoneg, &out_size); 1134 if (err || !out_size || autoneg.status) { 1135 dev_err(&hwdev->hwif->pdev->dev, "Failed to %s autoneg, err: %d, status: 0x%x, out size: 0x%x\n", 1136 enable ? "enable" : "disable", err, autoneg.status, 1137 out_size); 1138 return -EIO; 1139 } 1140 1141 return 0; 1142 } 1143 1144 int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed) 1145 { 1146 struct hinic_speed_cmd speed_info = {0}; 1147 u16 out_size = sizeof(speed_info); 1148 int err; 1149 1150 if (!hwdev) 1151 return -EINVAL; 1152 1153 speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1154 speed_info.speed = speed; 1155 1156 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_SPEED, 1157 &speed_info, sizeof(speed_info), 1158 &speed_info, &out_size); 1159 if (err || !out_size || speed_info.status) { 1160 dev_err(&hwdev->hwif->pdev->dev, 1161 "Failed to set speed, err: %d, status: 0x%x, out size: 0x%x\n", 1162 err, speed_info.status, out_size); 1163 return -EIO; 1164 } 1165 1166 return 0; 1167 } 1168 1169 int hinic_set_link_settings(struct hinic_hwdev *hwdev, 1170 struct hinic_link_ksettings_info *info) 1171 { 1172 u16 out_size = sizeof(*info); 1173 int err; 1174 1175 err = hinic_hilink_msg_cmd(hwdev, HINIC_HILINK_CMD_SET_LINK_SETTINGS, 1176 info, sizeof(*info), info, &out_size); 1177 if ((info->status != HINIC_MGMT_CMD_UNSUPPORTED && 1178 info->status) || err || !out_size) { 1179 dev_err(&hwdev->hwif->pdev->dev, 1180 "Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n", 1181 err, info->status, out_size); 1182 return -EFAULT; 1183 } 1184 1185 return info->status; 1186 } 1187 1188 int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev, 1189 struct hinic_pause_config *pause_info) 1190 { 1191 u16 out_size = sizeof(*pause_info); 1192 int err; 1193 1194 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1195 1196 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO, 1197 pause_info, sizeof(*pause_info), 1198 pause_info, &out_size); 1199 if (err || !out_size || pause_info->status) { 1200 dev_err(&hwdev->hwif->pdev->dev, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n", 1201 err, pause_info->status, out_size); 1202 return -EIO; 1203 } 1204 1205 return 0; 1206 } 1207 1208 int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev, 1209 struct hinic_pause_config *pause_info) 1210 { 1211 u16 out_size = sizeof(*pause_info); 1212 int err; 1213 1214 pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1215 1216 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO, 1217 pause_info, sizeof(*pause_info), 1218 pause_info, &out_size); 1219 if (err || !out_size || pause_info->status) { 1220 dev_err(&hwdev->hwif->pdev->dev, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x\n", 1221 err, pause_info->status, out_size); 1222 return -EIO; 1223 } 1224 1225 return 0; 1226 } 1227 1228 int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap) 1229 { 1230 struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg; 1231 struct hinic_set_pfc pfc = {0}; 1232 u16 out_size = sizeof(pfc); 1233 int err; 1234 1235 if (HINIC_IS_VF(hwdev->hwif)) 1236 return 0; 1237 1238 mutex_lock(&nic_cfg->cfg_mutex); 1239 1240 pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif); 1241 pfc.pfc_bitmap = pfc_bitmap; 1242 pfc.pfc_en = pfc_en; 1243 1244 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC, 1245 &pfc, sizeof(pfc), &pfc, &out_size); 1246 if (err || pfc.status || !out_size) { 1247 dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n", 1248 pfc_en ? "enable" : "disable", err, pfc.status, 1249 out_size); 1250 mutex_unlock(&nic_cfg->cfg_mutex); 1251 return -EIO; 1252 } 1253 1254 /* pause settings is opposite from pfc */ 1255 nic_cfg->rx_pause = pfc_en ? 0 : 1; 1256 nic_cfg->tx_pause = pfc_en ? 0 : 1; 1257 1258 mutex_unlock(&nic_cfg->cfg_mutex); 1259 1260 return 0; 1261 } 1262 1263 int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable) 1264 { 1265 struct hinic_port_loopback lb = {0}; 1266 u16 out_size = sizeof(lb); 1267 int err; 1268 1269 lb.mode = mode; 1270 lb.en = enable; 1271 1272 if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) { 1273 dev_err(&hwdev->hwif->pdev->dev, 1274 "Invalid loopback mode %d to set\n", mode); 1275 return -EINVAL; 1276 } 1277 1278 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE, 1279 &lb, sizeof(lb), &lb, &out_size); 1280 if (err || !out_size || lb.status) { 1281 dev_err(&hwdev->hwif->pdev->dev, 1282 "Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n", 1283 mode, enable, err, lb.status, out_size); 1284 return -EIO; 1285 } 1286 1287 return 0; 1288 } 1289 1290 static int _set_led_status(struct hinic_hwdev *hwdev, u8 port, 1291 enum hinic_led_type type, 1292 enum hinic_led_mode mode, u8 reset) 1293 { 1294 struct hinic_led_info led_info = {0}; 1295 u16 out_size = sizeof(led_info); 1296 struct hinic_pfhwdev *pfhwdev; 1297 int err; 1298 1299 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); 1300 1301 led_info.port = port; 1302 led_info.reset = reset; 1303 1304 led_info.type = type; 1305 led_info.mode = mode; 1306 1307 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, 1308 HINIC_COMM_CMD_SET_LED_STATUS, 1309 &led_info, sizeof(led_info), 1310 &led_info, &out_size, HINIC_MGMT_MSG_SYNC); 1311 if (err || led_info.status || !out_size) { 1312 dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n", 1313 err, led_info.status, out_size); 1314 return -EIO; 1315 } 1316 1317 return 0; 1318 } 1319 1320 int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port, 1321 enum hinic_led_type type, enum hinic_led_mode mode) 1322 { 1323 if (!hwdev) 1324 return -EINVAL; 1325 1326 return _set_led_status(hwdev, port, type, mode, 0); 1327 } 1328 1329 int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port) 1330 { 1331 int err; 1332 1333 if (!hwdev) 1334 return -EINVAL; 1335 1336 err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID, 1337 HINIC_LED_MODE_INVALID, 1); 1338 if (err) 1339 dev_err(&hwdev->hwif->pdev->dev, 1340 "Failed to reset led status\n"); 1341 1342 return err; 1343 } 1344 1345 static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev) 1346 { 1347 struct hinic_cmd_get_light_module_abs sfp_abs = {0}; 1348 u16 out_size = sizeof(sfp_abs); 1349 u8 port_id = hwdev->port_id; 1350 int err; 1351 1352 sfp_abs.port_id = port_id; 1353 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS, 1354 &sfp_abs, sizeof(sfp_abs), &sfp_abs, 1355 &out_size); 1356 if (sfp_abs.status || err || !out_size) { 1357 dev_err(&hwdev->hwif->pdev->dev, 1358 "Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n", 1359 port_id, err, sfp_abs.status, out_size); 1360 return true; 1361 } 1362 1363 return ((sfp_abs.abs_status == 0) ? false : true); 1364 } 1365 1366 int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len) 1367 { 1368 struct hinic_cmd_get_std_sfp_info sfp_info = {0}; 1369 u16 out_size = sizeof(sfp_info); 1370 u8 port_id; 1371 int err; 1372 1373 if (!hwdev || !data || !len) 1374 return -EINVAL; 1375 1376 port_id = hwdev->port_id; 1377 1378 if (hinic_if_sfp_absent(hwdev)) 1379 return -ENXIO; 1380 1381 sfp_info.port_id = port_id; 1382 err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO, 1383 &sfp_info, sizeof(sfp_info), &sfp_info, 1384 &out_size); 1385 if (sfp_info.status || err || !out_size) { 1386 dev_err(&hwdev->hwif->pdev->dev, 1387 "Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n", 1388 port_id, err, sfp_info.status, out_size); 1389 return -EIO; 1390 } 1391 1392 *len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE); 1393 memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE); 1394 1395 return 0; 1396 } 1397 1398 int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1) 1399 { 1400 u8 sfp_data[STD_SFP_INFO_MAX_SIZE]; 1401 u16 len; 1402 int err; 1403 1404 if (hinic_if_sfp_absent(hwdev)) 1405 return -ENXIO; 1406 1407 err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len); 1408 if (err) 1409 return err; 1410 1411 *data0 = sfp_data[0]; 1412 *data1 = sfp_data[1]; 1413 1414 return 0; 1415 } 1416