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