root/drivers/net/ethernet/huawei/hinic/hinic_port.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. change_mac
  2. hinic_port_add_mac
  3. hinic_port_del_mac
  4. hinic_port_get_mac
  5. hinic_port_set_mtu
  6. hinic_port_add_vlan
  7. hinic_port_del_vlan
  8. hinic_port_set_rx_mode
  9. hinic_port_link_state
  10. hinic_port_set_state
  11. hinic_port_set_func_state
  12. hinic_port_get_cap
  13. hinic_port_set_tso
  14. hinic_set_rx_csum_offload
  15. hinic_set_rx_vlan_offload
  16. hinic_set_max_qnum
  17. hinic_set_rx_lro
  18. hinic_set_rx_lro_timer
  19. hinic_set_rx_lro_state
  20. hinic_rss_set_indir_tbl
  21. hinic_rss_get_indir_tbl
  22. hinic_set_rss_type
  23. hinic_get_rss_type
  24. hinic_rss_set_template_tbl
  25. hinic_rss_get_template_tbl
  26. hinic_rss_set_hash_engine
  27. hinic_rss_get_hash_engine
  28. hinic_rss_cfg
  29. hinic_rss_template_alloc
  30. hinic_rss_template_free
  31. hinic_get_vport_stats
  32. hinic_get_phy_port_stats
  33. hinic_get_mgmt_version

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Huawei HiNIC PCI Express Linux driver
   4  * Copyright(c) 2017 Huawei Technologies Co., Ltd
   5  */
   6 
   7 #include <linux/types.h>
   8 #include <linux/netdevice.h>
   9 #include <linux/etherdevice.h>
  10 #include <linux/if_vlan.h>
  11 #include <linux/pci.h>
  12 #include <linux/device.h>
  13 #include <linux/errno.h>
  14 
  15 #include "hinic_hw_if.h"
  16 #include "hinic_hw_dev.h"
  17 #include "hinic_port.h"
  18 #include "hinic_dev.h"
  19 
  20 #define HINIC_MIN_MTU_SIZE              256
  21 #define HINIC_MAX_JUMBO_FRAME_SIZE      15872
  22 
  23 enum mac_op {
  24         MAC_DEL,
  25         MAC_SET,
  26 };
  27 
  28 /**
  29  * change_mac - change(add or delete) mac address
  30  * @nic_dev: nic device
  31  * @addr: mac address
  32  * @vlan_id: vlan number to set with the mac
  33  * @op: add or delete the mac
  34  *
  35  * Return 0 - Success, negative - Failure
  36  **/
  37 static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
  38                       u16 vlan_id, enum mac_op op)
  39 {
  40         struct net_device *netdev = nic_dev->netdev;
  41         struct hinic_hwdev *hwdev = nic_dev->hwdev;
  42         struct hinic_port_mac_cmd port_mac_cmd;
  43         struct hinic_hwif *hwif = hwdev->hwif;
  44         struct pci_dev *pdev = hwif->pdev;
  45         enum hinic_port_cmd cmd;
  46         u16 out_size;
  47         int err;
  48 
  49         if (vlan_id >= VLAN_N_VID) {
  50                 netif_err(nic_dev, drv, netdev, "Invalid VLAN number\n");
  51                 return -EINVAL;
  52         }
  53 
  54         if (op == MAC_SET)
  55                 cmd = HINIC_PORT_CMD_SET_MAC;
  56         else
  57                 cmd = HINIC_PORT_CMD_DEL_MAC;
  58 
  59         port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
  60         port_mac_cmd.vlan_id = vlan_id;
  61         memcpy(port_mac_cmd.mac, addr, ETH_ALEN);
  62 
  63         err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
  64                                  sizeof(port_mac_cmd),
  65                                  &port_mac_cmd, &out_size);
  66         if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
  67                 dev_err(&pdev->dev, "Failed to change MAC, ret = %d\n",
  68                         port_mac_cmd.status);
  69                 return -EFAULT;
  70         }
  71 
  72         return 0;
  73 }
  74 
  75 /**
  76  * hinic_port_add_mac - add mac address
  77  * @nic_dev: nic device
  78  * @addr: mac address
  79  * @vlan_id: vlan number to set with the mac
  80  *
  81  * Return 0 - Success, negative - Failure
  82  **/
  83 int hinic_port_add_mac(struct hinic_dev *nic_dev,
  84                        const u8 *addr, u16 vlan_id)
  85 {
  86         return change_mac(nic_dev, addr, vlan_id, MAC_SET);
  87 }
  88 
  89 /**
  90  * hinic_port_del_mac - remove mac address
  91  * @nic_dev: nic device
  92  * @addr: mac address
  93  * @vlan_id: vlan number that is connected to the mac
  94  *
  95  * Return 0 - Success, negative - Failure
  96  **/
  97 int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
  98                        u16 vlan_id)
  99 {
 100         return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
 101 }
 102 
 103 /**
 104  * hinic_port_get_mac - get the mac address of the nic device
 105  * @nic_dev: nic device
 106  * @addr: returned mac address
 107  *
 108  * Return 0 - Success, negative - Failure
 109  **/
 110 int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
 111 {
 112         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 113         struct hinic_port_mac_cmd port_mac_cmd;
 114         struct hinic_hwif *hwif = hwdev->hwif;
 115         struct pci_dev *pdev = hwif->pdev;
 116         u16 out_size;
 117         int err;
 118 
 119         port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
 120 
 121         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
 122                                  &port_mac_cmd, sizeof(port_mac_cmd),
 123                                  &port_mac_cmd, &out_size);
 124         if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
 125                 dev_err(&pdev->dev, "Failed to get mac, ret = %d\n",
 126                         port_mac_cmd.status);
 127                 return -EFAULT;
 128         }
 129 
 130         memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
 131         return 0;
 132 }
 133 
 134 /**
 135  * hinic_port_set_mtu - set mtu
 136  * @nic_dev: nic device
 137  * @new_mtu: new mtu
 138  *
 139  * Return 0 - Success, negative - Failure
 140  **/
 141 int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
 142 {
 143         struct net_device *netdev = nic_dev->netdev;
 144         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 145         struct hinic_port_mtu_cmd port_mtu_cmd;
 146         struct hinic_hwif *hwif = hwdev->hwif;
 147         struct pci_dev *pdev = hwif->pdev;
 148         int err, max_frame;
 149         u16 out_size;
 150 
 151         if (new_mtu < HINIC_MIN_MTU_SIZE) {
 152                 netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size");
 153                 return -EINVAL;
 154         }
 155 
 156         max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 157         if (max_frame > HINIC_MAX_JUMBO_FRAME_SIZE) {
 158                 netif_err(nic_dev, drv, netdev, "mtu > MAX MTU size");
 159                 return -EINVAL;
 160         }
 161 
 162         port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
 163         port_mtu_cmd.mtu = new_mtu;
 164 
 165         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
 166                                  &port_mtu_cmd, sizeof(port_mtu_cmd),
 167                                  &port_mtu_cmd, &out_size);
 168         if (err || (out_size != sizeof(port_mtu_cmd)) || port_mtu_cmd.status) {
 169                 dev_err(&pdev->dev, "Failed to set mtu, ret = %d\n",
 170                         port_mtu_cmd.status);
 171                 return -EFAULT;
 172         }
 173 
 174         return 0;
 175 }
 176 
 177 /**
 178  * hinic_port_add_vlan - add vlan to the nic device
 179  * @nic_dev: nic device
 180  * @vlan_id: the vlan number to add
 181  *
 182  * Return 0 - Success, negative - Failure
 183  **/
 184 int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
 185 {
 186         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 187         struct hinic_port_vlan_cmd port_vlan_cmd;
 188 
 189         port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
 190         port_vlan_cmd.vlan_id = vlan_id;
 191 
 192         return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
 193                                   &port_vlan_cmd, sizeof(port_vlan_cmd),
 194                                   NULL, NULL);
 195 }
 196 
 197 /**
 198  * hinic_port_del_vlan - delete vlan from the nic device
 199  * @nic_dev: nic device
 200  * @vlan_id: the vlan number to delete
 201  *
 202  * Return 0 - Success, negative - Failure
 203  **/
 204 int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
 205 {
 206         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 207         struct hinic_port_vlan_cmd port_vlan_cmd;
 208 
 209         port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
 210         port_vlan_cmd.vlan_id = vlan_id;
 211 
 212         return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
 213                                  &port_vlan_cmd, sizeof(port_vlan_cmd),
 214                                  NULL, NULL);
 215 }
 216 
 217 /**
 218  * hinic_port_set_rx_mode - set rx mode in the nic device
 219  * @nic_dev: nic device
 220  * @rx_mode: the rx mode to set
 221  *
 222  * Return 0 - Success, negative - Failure
 223  **/
 224 int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
 225 {
 226         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 227         struct hinic_port_rx_mode_cmd rx_mode_cmd;
 228 
 229         rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
 230         rx_mode_cmd.rx_mode = rx_mode;
 231 
 232         return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
 233                                   &rx_mode_cmd, sizeof(rx_mode_cmd),
 234                                   NULL, NULL);
 235 }
 236 
 237 /**
 238  * hinic_port_link_state - get the link state
 239  * @nic_dev: nic device
 240  * @link_state: the returned link state
 241  *
 242  * Return 0 - Success, negative - Failure
 243  **/
 244 int hinic_port_link_state(struct hinic_dev *nic_dev,
 245                           enum hinic_port_link_state *link_state)
 246 {
 247         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 248         struct hinic_hwif *hwif = hwdev->hwif;
 249         struct hinic_port_link_cmd link_cmd;
 250         struct pci_dev *pdev = hwif->pdev;
 251         u16 out_size;
 252         int err;
 253 
 254         if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
 255                 dev_err(&pdev->dev, "unsupported PCI Function type\n");
 256                 return -EINVAL;
 257         }
 258 
 259         link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
 260 
 261         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
 262                                  &link_cmd, sizeof(link_cmd),
 263                                  &link_cmd, &out_size);
 264         if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) {
 265                 dev_err(&pdev->dev, "Failed to get link state, ret = %d\n",
 266                         link_cmd.status);
 267                 return -EINVAL;
 268         }
 269 
 270         *link_state = link_cmd.state;
 271         return 0;
 272 }
 273 
 274 /**
 275  * hinic_port_set_state - set port state
 276  * @nic_dev: nic device
 277  * @state: the state to set
 278  *
 279  * Return 0 - Success, negative - Failure
 280  **/
 281 int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
 282 {
 283         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 284         struct hinic_port_state_cmd port_state;
 285         struct hinic_hwif *hwif = hwdev->hwif;
 286         struct pci_dev *pdev = hwif->pdev;
 287         u16 out_size;
 288         int err;
 289 
 290         if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
 291                 dev_err(&pdev->dev, "unsupported PCI Function type\n");
 292                 return -EINVAL;
 293         }
 294 
 295         port_state.state = state;
 296 
 297         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE,
 298                                  &port_state, sizeof(port_state),
 299                                  &port_state, &out_size);
 300         if (err || (out_size != sizeof(port_state)) || port_state.status) {
 301                 dev_err(&pdev->dev, "Failed to set port state, ret = %d\n",
 302                         port_state.status);
 303                 return -EFAULT;
 304         }
 305 
 306         return 0;
 307 }
 308 
 309 /**
 310  * hinic_port_set_func_state- set func device state
 311  * @nic_dev: nic device
 312  * @state: the state to set
 313  *
 314  * Return 0 - Success, negative - Failure
 315  **/
 316 int hinic_port_set_func_state(struct hinic_dev *nic_dev,
 317                               enum hinic_func_port_state state)
 318 {
 319         struct hinic_port_func_state_cmd func_state;
 320         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 321         struct hinic_hwif *hwif = hwdev->hwif;
 322         struct pci_dev *pdev = hwif->pdev;
 323         u16 out_size;
 324         int err;
 325 
 326         func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
 327         func_state.state = state;
 328 
 329         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE,
 330                                  &func_state, sizeof(func_state),
 331                                  &func_state, &out_size);
 332         if (err || (out_size != sizeof(func_state)) || func_state.status) {
 333                 dev_err(&pdev->dev, "Failed to set port func state, ret = %d\n",
 334                         func_state.status);
 335                 return -EFAULT;
 336         }
 337 
 338         return 0;
 339 }
 340 
 341 /**
 342  * hinic_port_get_cap - get port capabilities
 343  * @nic_dev: nic device
 344  * @port_cap: returned port capabilities
 345  *
 346  * Return 0 - Success, negative - Failure
 347  **/
 348 int hinic_port_get_cap(struct hinic_dev *nic_dev,
 349                        struct hinic_port_cap *port_cap)
 350 {
 351         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 352         struct hinic_hwif *hwif = hwdev->hwif;
 353         struct pci_dev *pdev = hwif->pdev;
 354         u16 out_size;
 355         int err;
 356 
 357         port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif);
 358 
 359         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP,
 360                                  port_cap, sizeof(*port_cap),
 361                                  port_cap, &out_size);
 362         if (err || (out_size != sizeof(*port_cap)) || port_cap->status) {
 363                 dev_err(&pdev->dev,
 364                         "Failed to get port capabilities, ret = %d\n",
 365                         port_cap->status);
 366                 return -EINVAL;
 367         }
 368 
 369         return 0;
 370 }
 371 
 372 /**
 373  * hinic_port_set_tso - set port tso configuration
 374  * @nic_dev: nic device
 375  * @state: the tso state to set
 376  *
 377  * Return 0 - Success, negative - Failure
 378  **/
 379 int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
 380 {
 381         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 382         struct hinic_hwif *hwif = hwdev->hwif;
 383         struct hinic_tso_config tso_cfg = {0};
 384         struct pci_dev *pdev = hwif->pdev;
 385         u16 out_size;
 386         int err;
 387 
 388         tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 389         tso_cfg.tso_en = state;
 390 
 391         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO,
 392                                  &tso_cfg, sizeof(tso_cfg),
 393                                  &tso_cfg, &out_size);
 394         if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
 395                 dev_err(&pdev->dev,
 396                         "Failed to set port tso, ret = %d\n",
 397                         tso_cfg.status);
 398                 return -EINVAL;
 399         }
 400 
 401         return 0;
 402 }
 403 
 404 int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
 405 {
 406         struct hinic_checksum_offload rx_csum_cfg = {0};
 407         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 408         struct hinic_hwif *hwif;
 409         struct pci_dev *pdev;
 410         u16 out_size;
 411         int err;
 412 
 413         if (!hwdev)
 414                 return -EINVAL;
 415 
 416         hwif = hwdev->hwif;
 417         pdev = hwif->pdev;
 418         rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 419         rx_csum_cfg.rx_csum_offload = en;
 420 
 421         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
 422                                  &rx_csum_cfg, sizeof(rx_csum_cfg),
 423                                  &rx_csum_cfg, &out_size);
 424         if (err || !out_size || rx_csum_cfg.status) {
 425                 dev_err(&pdev->dev,
 426                         "Failed to set rx csum offload, ret = %d\n",
 427                         rx_csum_cfg.status);
 428                 return -EINVAL;
 429         }
 430 
 431         return 0;
 432 }
 433 
 434 int hinic_set_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         hwif = hwdev->hwif;
 447         pdev = hwif->pdev;
 448         vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 449         vlan_cfg.vlan_rx_offload = en;
 450 
 451         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
 452                                  &vlan_cfg, sizeof(vlan_cfg),
 453                                  &vlan_cfg, &out_size);
 454         if (err || !out_size || vlan_cfg.status) {
 455                 dev_err(&pdev->dev,
 456                         "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
 457                         err, vlan_cfg.status, out_size);
 458                 return -EINVAL;
 459         }
 460 
 461         return 0;
 462 }
 463 
 464 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
 465 {
 466         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 467         struct hinic_hwif *hwif = hwdev->hwif;
 468         struct pci_dev *pdev = hwif->pdev;
 469         struct hinic_rq_num rq_num = { 0 };
 470         u16 out_size = sizeof(rq_num);
 471         int err;
 472 
 473         rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 474         rq_num.num_rqs = num_rqs;
 475         rq_num.rq_depth = ilog2(HINIC_SQ_DEPTH);
 476 
 477         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
 478                                  &rq_num, sizeof(rq_num),
 479                                  &rq_num, &out_size);
 480         if (err || !out_size || rq_num.status) {
 481                 dev_err(&pdev->dev,
 482                         "Failed to rxq number, ret = %d\n",
 483                         rq_num.status);
 484                 return -EINVAL;
 485         }
 486 
 487         return 0;
 488 }
 489 
 490 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
 491                             u8 max_wqe_num)
 492 {
 493         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 494         struct hinic_hwif *hwif = hwdev->hwif;
 495         struct hinic_lro_config lro_cfg = { 0 };
 496         struct pci_dev *pdev = hwif->pdev;
 497         u16 out_size = sizeof(lro_cfg);
 498         int err;
 499 
 500         lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 501         lro_cfg.lro_ipv4_en = ipv4_en;
 502         lro_cfg.lro_ipv6_en = ipv6_en;
 503         lro_cfg.lro_max_wqe_num = max_wqe_num;
 504 
 505         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
 506                                  &lro_cfg, sizeof(lro_cfg),
 507                                  &lro_cfg, &out_size);
 508         if (err || !out_size || lro_cfg.status) {
 509                 dev_err(&pdev->dev,
 510                         "Failed to set lro offload, ret = %d\n",
 511                         lro_cfg.status);
 512                 return -EINVAL;
 513         }
 514 
 515         return 0;
 516 }
 517 
 518 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
 519 {
 520         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 521         struct hinic_lro_timer lro_timer = { 0 };
 522         struct hinic_hwif *hwif = hwdev->hwif;
 523         struct pci_dev *pdev = hwif->pdev;
 524         u16 out_size = sizeof(lro_timer);
 525         int err;
 526 
 527         lro_timer.status = 0;
 528         lro_timer.type = 0;
 529         lro_timer.enable = 1;
 530         lro_timer.timer = timer_value;
 531 
 532         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
 533                                  &lro_timer, sizeof(lro_timer),
 534                                  &lro_timer, &out_size);
 535         if (lro_timer.status == 0xFF) {
 536                 /* For this case, we think status (0xFF) is OK */
 537                 lro_timer.status = 0;
 538                 dev_dbg(&pdev->dev,
 539                         "Set lro timer not supported by the current FW version, it will be 1ms default\n");
 540         }
 541 
 542         if (err || !out_size || lro_timer.status) {
 543                 dev_err(&pdev->dev,
 544                         "Failed to set lro timer, ret = %d\n",
 545                         lro_timer.status);
 546 
 547                 return -EINVAL;
 548         }
 549 
 550         return 0;
 551 }
 552 
 553 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
 554                            u32 lro_timer, u32 wqe_num)
 555 {
 556         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 557         u8 ipv4_en;
 558         u8 ipv6_en;
 559         int err;
 560 
 561         if (!hwdev)
 562                 return -EINVAL;
 563 
 564         ipv4_en = lro_en ? 1 : 0;
 565         ipv6_en = lro_en ? 1 : 0;
 566 
 567         err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
 568         if (err)
 569                 return err;
 570 
 571         err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
 572         if (err)
 573                 return err;
 574 
 575         return 0;
 576 }
 577 
 578 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
 579                             const u32 *indir_table)
 580 {
 581         struct hinic_rss_indirect_tbl *indir_tbl;
 582         struct hinic_func_to_io *func_to_io;
 583         struct hinic_cmdq_buf cmd_buf;
 584         struct hinic_hwdev *hwdev;
 585         struct hinic_hwif *hwif;
 586         struct pci_dev *pdev;
 587         u32 indir_size;
 588         u64 out_param;
 589         int err, i;
 590         u32 *temp;
 591 
 592         hwdev = nic_dev->hwdev;
 593         func_to_io = &hwdev->func_to_io;
 594         hwif = hwdev->hwif;
 595         pdev = hwif->pdev;
 596 
 597         err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
 598         if (err) {
 599                 dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
 600                 return err;
 601         }
 602 
 603         cmd_buf.size = sizeof(*indir_tbl);
 604 
 605         indir_tbl = cmd_buf.buf;
 606         indir_tbl->group_index = cpu_to_be32(tmpl_idx);
 607 
 608         for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
 609                 indir_tbl->entry[i] = indir_table[i];
 610 
 611                 if (0x3 == (i & 0x3)) {
 612                         temp = (u32 *)&indir_tbl->entry[i - 3];
 613                         *temp = cpu_to_be32(*temp);
 614                 }
 615         }
 616 
 617         /* cfg the rss indirect table by command queue */
 618         indir_size = HINIC_RSS_INDIR_SIZE / 2;
 619         indir_tbl->offset = 0;
 620         indir_tbl->size = cpu_to_be32(indir_size);
 621 
 622         err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
 623                                      HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
 624                                      &cmd_buf, &out_param);
 625         if (err || out_param != 0) {
 626                 dev_err(&pdev->dev, "Failed to set rss indir table\n");
 627                 err = -EFAULT;
 628                 goto free_buf;
 629         }
 630 
 631         indir_tbl->offset = cpu_to_be32(indir_size);
 632         indir_tbl->size = cpu_to_be32(indir_size);
 633         memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);
 634 
 635         err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
 636                                      HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
 637                                      &cmd_buf, &out_param);
 638         if (err || out_param != 0) {
 639                 dev_err(&pdev->dev, "Failed to set rss indir table\n");
 640                 err = -EFAULT;
 641         }
 642 
 643 free_buf:
 644         hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
 645 
 646         return err;
 647 }
 648 
 649 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
 650                             u32 *indir_table)
 651 {
 652         struct hinic_rss_indir_table rss_cfg = { 0 };
 653         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 654         struct hinic_hwif *hwif = hwdev->hwif;
 655         struct pci_dev *pdev = hwif->pdev;
 656         u16 out_size = sizeof(rss_cfg);
 657         int err = 0, i;
 658 
 659         rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 660         rss_cfg.template_id = tmpl_idx;
 661 
 662         err = hinic_port_msg_cmd(hwdev,
 663                                  HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
 664                                  &rss_cfg, sizeof(rss_cfg), &rss_cfg,
 665                                  &out_size);
 666         if (err || !out_size || rss_cfg.status) {
 667                 dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
 668                         err, rss_cfg.status, out_size);
 669                 return -EINVAL;
 670         }
 671 
 672         hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
 673         for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
 674                 indir_table[i] = rss_cfg.indir[i];
 675 
 676         return 0;
 677 }
 678 
 679 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
 680                        struct hinic_rss_type rss_type)
 681 {
 682         struct hinic_rss_context_tbl *ctx_tbl;
 683         struct hinic_func_to_io *func_to_io;
 684         struct hinic_cmdq_buf cmd_buf;
 685         struct hinic_hwdev *hwdev;
 686         struct hinic_hwif *hwif;
 687         struct pci_dev *pdev;
 688         u64 out_param;
 689         u32 ctx = 0;
 690         int err;
 691 
 692         hwdev = nic_dev->hwdev;
 693         func_to_io = &hwdev->func_to_io;
 694         hwif = hwdev->hwif;
 695         pdev = hwif->pdev;
 696 
 697         err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
 698         if (err) {
 699                 dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
 700                 return -ENOMEM;
 701         }
 702 
 703         ctx |=  HINIC_RSS_TYPE_SET(1, VALID) |
 704                 HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
 705                 HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
 706                 HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
 707                 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
 708                 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
 709                 HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
 710                 HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
 711                 HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
 712 
 713         cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
 714 
 715         ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
 716         ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
 717         ctx_tbl->offset = 0;
 718         ctx_tbl->size = sizeof(u32);
 719         ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
 720         ctx_tbl->rsvd = 0;
 721         ctx_tbl->ctx = cpu_to_be32(ctx);
 722 
 723         /* cfg the rss context table by command queue */
 724         err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
 725                                      HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
 726                                      &cmd_buf, &out_param);
 727 
 728         hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
 729 
 730         if (err || out_param != 0) {
 731                 dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
 732                         err);
 733                 return -EFAULT;
 734         }
 735 
 736         return 0;
 737 }
 738 
 739 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
 740                        struct hinic_rss_type *rss_type)
 741 {
 742         struct hinic_rss_context_table ctx_tbl = { 0 };
 743         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 744         struct hinic_hwif *hwif;
 745         struct pci_dev *pdev;
 746         u16 out_size = sizeof(ctx_tbl);
 747         int err;
 748 
 749         if (!hwdev || !rss_type)
 750                 return -EINVAL;
 751 
 752         hwif = hwdev->hwif;
 753         pdev = hwif->pdev;
 754 
 755         ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 756         ctx_tbl.template_id = tmpl_idx;
 757 
 758         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
 759                                  &ctx_tbl, sizeof(ctx_tbl),
 760                                  &ctx_tbl, &out_size);
 761         if (err || !out_size || ctx_tbl.status) {
 762                 dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
 763                         err, ctx_tbl.status, out_size);
 764                 return -EINVAL;
 765         }
 766 
 767         rss_type->ipv4          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
 768         rss_type->ipv6          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
 769         rss_type->ipv6_ext      = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
 770         rss_type->tcp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
 771         rss_type->tcp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
 772         rss_type->tcp_ipv6_ext  = HINIC_RSS_TYPE_GET(ctx_tbl.context,
 773                                                      TCP_IPV6_EXT);
 774         rss_type->udp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
 775         rss_type->udp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
 776 
 777         return 0;
 778 }
 779 
 780 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
 781                                const u8 *temp)
 782 {
 783         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 784         struct hinic_hwif *hwif = hwdev->hwif;
 785         struct hinic_rss_key rss_key = { 0 };
 786         struct pci_dev *pdev = hwif->pdev;
 787         u16 out_size;
 788         int err;
 789 
 790         rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 791         rss_key.template_id = template_id;
 792         memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);
 793 
 794         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
 795                                  &rss_key, sizeof(rss_key),
 796                                  &rss_key, &out_size);
 797         if (err || !out_size || rss_key.status) {
 798                 dev_err(&pdev->dev,
 799                         "Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
 800                         err, rss_key.status, out_size);
 801                 return -EINVAL;
 802         }
 803 
 804         return 0;
 805 }
 806 
 807 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
 808                                u8 *temp)
 809 {
 810         struct hinic_rss_template_key temp_key = { 0 };
 811         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 812         struct hinic_hwif *hwif;
 813         struct pci_dev *pdev;
 814         u16 out_size = sizeof(temp_key);
 815         int err;
 816 
 817         if (!hwdev || !temp)
 818                 return -EINVAL;
 819 
 820         hwif = hwdev->hwif;
 821         pdev = hwif->pdev;
 822 
 823         temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 824         temp_key.template_id = tmpl_idx;
 825 
 826         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
 827                                  &temp_key, sizeof(temp_key),
 828                                  &temp_key, &out_size);
 829         if (err || !out_size || temp_key.status) {
 830                 dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
 831                         err, temp_key.status, out_size);
 832                 return -EINVAL;
 833         }
 834 
 835         memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
 836 
 837         return 0;
 838 }
 839 
 840 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
 841                               u8 type)
 842 {
 843         struct hinic_rss_engine_type rss_engine = { 0 };
 844         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 845         struct hinic_hwif *hwif = hwdev->hwif;
 846         struct pci_dev *pdev = hwif->pdev;
 847         u16 out_size;
 848         int err;
 849 
 850         rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 851         rss_engine.hash_engine = type;
 852         rss_engine.template_id = template_id;
 853 
 854         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
 855                                  &rss_engine, sizeof(rss_engine),
 856                                  &rss_engine, &out_size);
 857         if (err || !out_size || rss_engine.status) {
 858                 dev_err(&pdev->dev,
 859                         "Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
 860                         err, rss_engine.status, out_size);
 861                 return -EINVAL;
 862         }
 863 
 864         return 0;
 865 }
 866 
 867 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
 868 {
 869         struct hinic_rss_engine_type hash_type = { 0 };
 870         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 871         struct hinic_hwif *hwif;
 872         struct pci_dev *pdev;
 873         u16 out_size = sizeof(hash_type);
 874         int err;
 875 
 876         if (!hwdev || !type)
 877                 return -EINVAL;
 878 
 879         hwif = hwdev->hwif;
 880         pdev = hwif->pdev;
 881 
 882         hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 883         hash_type.template_id = tmpl_idx;
 884 
 885         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
 886                                  &hash_type, sizeof(hash_type),
 887                                  &hash_type, &out_size);
 888         if (err || !out_size || hash_type.status) {
 889                 dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
 890                         err, hash_type.status, out_size);
 891                 return -EINVAL;
 892         }
 893 
 894         *type = hash_type.hash_engine;
 895         return 0;
 896 }
 897 
 898 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
 899 {
 900         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 901         struct hinic_rss_config rss_cfg = { 0 };
 902         struct hinic_hwif *hwif = hwdev->hwif;
 903         struct pci_dev *pdev = hwif->pdev;
 904         u16 out_size;
 905         int err;
 906 
 907         rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 908         rss_cfg.rss_en = rss_en;
 909         rss_cfg.template_id = template_id;
 910         rss_cfg.rq_priority_number = 0;
 911 
 912         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
 913                                  &rss_cfg, sizeof(rss_cfg),
 914                                  &rss_cfg, &out_size);
 915         if (err || !out_size || rss_cfg.status) {
 916                 dev_err(&pdev->dev,
 917                         "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
 918                         err, rss_cfg.status, out_size);
 919                 return -EINVAL;
 920         }
 921 
 922         return 0;
 923 }
 924 
 925 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
 926 {
 927         struct hinic_rss_template_mgmt template_mgmt = { 0 };
 928         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 929         struct hinic_hwif *hwif = hwdev->hwif;
 930         struct pci_dev *pdev = hwif->pdev;
 931         u16 out_size;
 932         int err;
 933 
 934         template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 935         template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
 936 
 937         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
 938                                  &template_mgmt, sizeof(template_mgmt),
 939                                  &template_mgmt, &out_size);
 940         if (err || !out_size || template_mgmt.status) {
 941                 dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
 942                         err, template_mgmt.status, out_size);
 943                 return -EINVAL;
 944         }
 945 
 946         *tmpl_idx = template_mgmt.template_id;
 947 
 948         return 0;
 949 }
 950 
 951 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
 952 {
 953         struct hinic_rss_template_mgmt template_mgmt = { 0 };
 954         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 955         struct hinic_hwif *hwif = hwdev->hwif;
 956         struct pci_dev *pdev = hwif->pdev;
 957         u16 out_size;
 958         int err;
 959 
 960         template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 961         template_mgmt.template_id = tmpl_idx;
 962         template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
 963 
 964         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
 965                                  &template_mgmt, sizeof(template_mgmt),
 966                                  &template_mgmt, &out_size);
 967         if (err || !out_size || template_mgmt.status) {
 968                 dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
 969                         err, template_mgmt.status, out_size);
 970                 return -EINVAL;
 971         }
 972 
 973         return 0;
 974 }
 975 
 976 int hinic_get_vport_stats(struct hinic_dev *nic_dev,
 977                           struct hinic_vport_stats *stats)
 978 {
 979         struct hinic_cmd_vport_stats vport_stats = { 0 };
 980         struct hinic_port_stats_info stats_info = { 0 };
 981         struct hinic_hwdev *hwdev = nic_dev->hwdev;
 982         struct hinic_hwif *hwif = hwdev->hwif;
 983         u16 out_size = sizeof(vport_stats);
 984         struct pci_dev *pdev = hwif->pdev;
 985         int err;
 986 
 987         stats_info.stats_version = HINIC_PORT_STATS_VERSION;
 988         stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
 989         stats_info.stats_size = sizeof(vport_stats);
 990 
 991         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
 992                                  &stats_info, sizeof(stats_info),
 993                                  &vport_stats, &out_size);
 994         if (err || !out_size || vport_stats.status) {
 995                 dev_err(&pdev->dev,
 996                         "Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
 997                         err, vport_stats.status, out_size);
 998                 return -EFAULT;
 999         }
1000 
1001         memcpy(stats, &vport_stats.stats, sizeof(*stats));
1002         return 0;
1003 }
1004 
1005 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
1006                              struct hinic_phy_port_stats *stats)
1007 {
1008         struct hinic_port_stats_info stats_info = { 0 };
1009         struct hinic_hwdev *hwdev = nic_dev->hwdev;
1010         struct hinic_hwif *hwif = hwdev->hwif;
1011         struct hinic_port_stats *port_stats;
1012         u16 out_size = sizeof(*port_stats);
1013         struct pci_dev *pdev = hwif->pdev;
1014         int err;
1015 
1016         port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1017         if (!port_stats)
1018                 return -ENOMEM;
1019 
1020         stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1021         stats_info.stats_size = sizeof(*port_stats);
1022 
1023         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
1024                                  &stats_info, sizeof(stats_info),
1025                                  port_stats, &out_size);
1026         if (err || !out_size || port_stats->status) {
1027                 dev_err(&pdev->dev,
1028                         "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1029                         err, port_stats->status, out_size);
1030                 err = -EINVAL;
1031                 goto out;
1032         }
1033 
1034         memcpy(stats, &port_stats->stats, sizeof(*stats));
1035 
1036 out:
1037         kfree(port_stats);
1038 
1039         return err;
1040 }
1041 
1042 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
1043 {
1044         struct hinic_hwdev *hwdev = nic_dev->hwdev;
1045         struct hinic_version_info up_ver = {0};
1046         struct hinic_hwif *hwif;
1047         struct pci_dev *pdev;
1048         u16 out_size;
1049         int err;
1050 
1051         if (!hwdev)
1052                 return -EINVAL;
1053 
1054         hwif = hwdev->hwif;
1055         pdev = hwif->pdev;
1056 
1057         err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1058                                  &up_ver, sizeof(up_ver), &up_ver,
1059                                  &out_size);
1060         if (err || !out_size || up_ver.status) {
1061                 dev_err(&pdev->dev,
1062                         "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1063                         err, up_ver.status, out_size);
1064                 return -EINVAL;
1065         }
1066 
1067         snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
1068 
1069         return 0;
1070 }

/* [<][>][^][v][top][bottom][index][help] */