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