dpdk/drivers/net/hinic/base/hinic_pmd_niccfg.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
   3 */
   4
   5#include "hinic_compat.h"
   6#include "hinic_pmd_hwdev.h"
   7#include "hinic_pmd_hwif.h"
   8#include "hinic_pmd_eqs.h"
   9#include "hinic_pmd_wq.h"
  10#include "hinic_pmd_mgmt.h"
  11#include "hinic_pmd_cmdq.h"
  12#include "hinic_pmd_niccfg.h"
  13#include "hinic_pmd_mbox.h"
  14
  15#define l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in,              \
  16                               in_size, buf_out, out_size)      \
  17        hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, cmd,     \
  18                        buf_in, in_size,                        \
  19                        buf_out, out_size, 0)
  20
  21/**
  22 * hinic_init_function_table - Initialize function table.
  23 *
  24 * @param hwdev
  25 *   The hardware interface of a nic device.
  26 * @param rx_buf_sz
  27 *   Receive buffer size.
  28 *
  29 * @return
  30 *   0 on success.
  31 *   negative error value otherwise.
  32 */
  33int hinic_init_function_table(void *hwdev, u16 rx_buf_sz)
  34{
  35        struct hinic_function_table function_table;
  36        u16 out_size = sizeof(function_table);
  37        int err;
  38
  39        if (!hwdev) {
  40                PMD_DRV_LOG(ERR, "Hwdev is NULL");
  41                return -EINVAL;
  42        }
  43
  44        memset(&function_table, 0, sizeof(function_table));
  45        function_table.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
  46        function_table.func_id = hinic_global_func_id(hwdev);
  47        function_table.mtu = 0x3FFF;    /* default, max mtu */
  48        function_table.rx_wqe_buf_size = rx_buf_sz;
  49
  50        err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
  51                                     HINIC_PORT_CMD_INIT_FUNC,
  52                                     &function_table, sizeof(function_table),
  53                                     &function_table, &out_size, 0);
  54        if (err || function_table.mgmt_msg_head.status || !out_size) {
  55                PMD_DRV_LOG(ERR,
  56                        "Failed to init func table, err: %d, status: 0x%x, out size: 0x%x",
  57                        err, function_table.mgmt_msg_head.status, out_size);
  58                return -EIO;
  59        }
  60
  61        return 0;
  62}
  63
  64/**
  65 * hinic_get_base_qpn - Get global queue number.
  66 *
  67 * @param hwdev
  68 *   The hardware interface of a nic device.
  69 * @param global_qpn
  70 *   Global queue number.
  71 *
  72 * @return
  73 *   0 on success.
  74 *   negative error value otherwise.
  75 */
  76int hinic_get_base_qpn(void *hwdev, u16 *global_qpn)
  77{
  78        struct hinic_cmd_qpn cmd_qpn;
  79        u16 out_size = sizeof(cmd_qpn);
  80        int err;
  81
  82        if (!hwdev || !global_qpn) {
  83                PMD_DRV_LOG(ERR, "Hwdev or global_qpn is NULL");
  84                return -EINVAL;
  85        }
  86
  87        memset(&cmd_qpn, 0, sizeof(cmd_qpn));
  88        cmd_qpn.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
  89        cmd_qpn.func_id = hinic_global_func_id(hwdev);
  90
  91        err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
  92                                     HINIC_PORT_CMD_GET_GLOBAL_QPN,
  93                                     &cmd_qpn, sizeof(cmd_qpn), &cmd_qpn,
  94                                     &out_size, 0);
  95        if (err || !out_size || cmd_qpn.mgmt_msg_head.status) {
  96                PMD_DRV_LOG(ERR,
  97                        "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x",
  98                        err, cmd_qpn.mgmt_msg_head.status, out_size);
  99                return -EIO;
 100        }
 101
 102        *global_qpn = cmd_qpn.base_qpn;
 103
 104        return 0;
 105}
 106
 107/**
 108 * hinic_set_mac - Init mac_vlan table in NIC.
 109 *
 110 * @param hwdev
 111 *   The hardware interface of a nic device.
 112 * @param mac_addr
 113 *   MAC address.
 114 * @param vlan_id
 115 *   Set 0 for mac_vlan table initialization.
 116 * @param func_id
 117 *   Global function id of NIC.
 118 *
 119 * @return
 120 *   0 on success.
 121 *   negative error value otherwise.
 122 */
 123int hinic_set_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id)
 124{
 125        struct hinic_port_mac_set mac_info;
 126        u16 out_size = sizeof(mac_info);
 127        int err;
 128
 129        if (!hwdev || !mac_addr) {
 130                PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
 131                return -EINVAL;
 132        }
 133
 134        memset(&mac_info, 0, sizeof(mac_info));
 135        mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 136        mac_info.func_id = func_id;
 137        mac_info.vlan_id = vlan_id;
 138        memmove(mac_info.mac, mac_addr, ETH_ALEN);
 139
 140        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_MAC, &mac_info,
 141                                     sizeof(mac_info), &mac_info, &out_size);
 142        if (err || !out_size || (mac_info.mgmt_msg_head.status &&
 143            mac_info.mgmt_msg_head.status != HINIC_PF_SET_VF_ALREADY)) {
 144                PMD_DRV_LOG(ERR, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x",
 145                        err, mac_info.mgmt_msg_head.status, out_size);
 146                return -EIO;
 147        }
 148
 149        if (mac_info.mgmt_msg_head.status == HINIC_PF_SET_VF_ALREADY) {
 150                PMD_DRV_LOG(WARNING, "PF has already set vf mac, Ignore set operation.");
 151                return HINIC_PF_SET_VF_ALREADY;
 152        }
 153
 154        return 0;
 155}
 156
 157/**
 158 * hinic_del_mac - Uninit mac_vlan table in NIC.
 159 *
 160 * @param hwdev
 161 *   The hardware interface of a nic device.
 162 * @param mac_addr
 163 *   MAC address.
 164 * @param vlan_id
 165 *   Set 0 for mac_vlan table initialization.
 166 * @param func_id
 167 *   Global function id of NIC.
 168 *
 169 * @return
 170 *   0 on success.
 171 *   negative error value otherwise.
 172 */
 173int hinic_del_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id)
 174{
 175        struct hinic_port_mac_set mac_info;
 176        u16 out_size = sizeof(mac_info);
 177        int err;
 178
 179        if (!hwdev || !mac_addr) {
 180                PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
 181                return -EINVAL;
 182        }
 183
 184        if (vlan_id >= VLAN_N_VID) {
 185                PMD_DRV_LOG(ERR, "Invalid VLAN number");
 186                return -EINVAL;
 187        }
 188
 189        memset(&mac_info, 0, sizeof(mac_info));
 190        mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 191        mac_info.func_id = func_id;
 192        mac_info.vlan_id = vlan_id;
 193        memmove(mac_info.mac, mac_addr, ETH_ALEN);
 194
 195        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_DEL_MAC, &mac_info,
 196                                     sizeof(mac_info), &mac_info, &out_size);
 197        if (err || !out_size || (mac_info.mgmt_msg_head.status &&
 198                mac_info.mgmt_msg_head.status != HINIC_PF_SET_VF_ALREADY)) {
 199                PMD_DRV_LOG(ERR, "Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x",
 200                        err, mac_info.mgmt_msg_head.status, out_size);
 201                return -EIO;
 202        }
 203        if (mac_info.mgmt_msg_head.status == HINIC_PF_SET_VF_ALREADY) {
 204                PMD_DRV_LOG(WARNING, "PF has already set vf mac, Ignore delete operation.");
 205                return HINIC_PF_SET_VF_ALREADY;
 206        }
 207
 208        return 0;
 209}
 210
 211/**
 212 * hinic_get_default_mac - Get default mac address from hardware.
 213 *
 214 * @param hwdev
 215 *   The hardware interface of a nic device.
 216 * @param mac_addr
 217 *   MAC address.
 218 *
 219 * @return
 220 *   0 on success.
 221 *   negative error value otherwise.
 222 */
 223int hinic_get_default_mac(void *hwdev, u8 *mac_addr)
 224{
 225        struct hinic_port_mac_set mac_info;
 226        u16 out_size = sizeof(mac_info);
 227        int err;
 228
 229        if (!hwdev || !mac_addr) {
 230                PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
 231                return -EINVAL;
 232        }
 233
 234        memset(&mac_info, 0, sizeof(mac_info));
 235        mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 236        mac_info.func_id = hinic_global_func_id(hwdev);
 237
 238        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_MAC,
 239                                     &mac_info, sizeof(mac_info),
 240                                     &mac_info, &out_size);
 241        if (err || !out_size || mac_info.mgmt_msg_head.status) {
 242                PMD_DRV_LOG(ERR, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x",
 243                        err, mac_info.mgmt_msg_head.status, out_size);
 244                return -EIO;
 245        }
 246
 247        memmove(mac_addr, mac_info.mac, ETH_ALEN);
 248
 249        return 0;
 250}
 251
 252/**
 253*  hinic_update_mac - Update mac address to hardware.
 254*
 255* @param hwdev
 256*   The hardware interface of a nic device.
 257* @param old_mac
 258*   Old mac address.
 259* @param new_mac
 260*   New mac address.
 261* @param vlan_id
 262*   Set 0 for mac_vlan table initialization.
 263* @param func_id
 264*   Global function id of NIC.
 265*
 266* @return
 267*   0 on success.
 268*   negative error value otherwise.
 269*/
 270int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
 271                     u16 func_id)
 272{
 273        struct hinic_port_mac_update mac_info;
 274        u16 out_size = sizeof(mac_info);
 275        int err;
 276
 277        if (!hwdev || !old_mac || !new_mac) {
 278                PMD_DRV_LOG(ERR, "Hwdev, old_mac or new_mac is NULL");
 279                return -EINVAL;
 280        }
 281
 282        memset(&mac_info, 0, sizeof(mac_info));
 283        mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 284        mac_info.func_id = func_id;
 285        mac_info.vlan_id = vlan_id;
 286        memcpy(mac_info.old_mac, old_mac, ETH_ALEN);
 287        memcpy(mac_info.new_mac, new_mac, ETH_ALEN);
 288
 289        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UPDATE_MAC,
 290                                     &mac_info, sizeof(mac_info),
 291                                     &mac_info, &out_size);
 292        if (err || !out_size ||
 293            (mac_info.mgmt_msg_head.status &&
 294             mac_info.mgmt_msg_head.status != HINIC_PF_SET_VF_ALREADY)) {
 295                PMD_DRV_LOG(ERR, "Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x",
 296                            err, mac_info.mgmt_msg_head.status, out_size);
 297                return -EIO;
 298        }
 299        if (mac_info.mgmt_msg_head.status == HINIC_PF_SET_VF_ALREADY) {
 300                PMD_DRV_LOG(WARNING, "PF has already set vf mac, Ignore update operation");
 301                return HINIC_PF_SET_VF_ALREADY;
 302        }
 303
 304        return 0;
 305}
 306
 307/**
 308 * hinic_set_port_mtu -  Set MTU to port.
 309 *
 310 * @param hwdev
 311 *   The hardware interface of a nic device.
 312 * @param new_mtu
 313 *   MTU size.
 314 *
 315 * @return
 316 *   0 on success.
 317 *   negative error value otherwise.
 318 */
 319int hinic_set_port_mtu(void *hwdev, u32 new_mtu)
 320{
 321        struct hinic_mtu mtu_info;
 322        u16 out_size = sizeof(mtu_info);
 323        int err;
 324
 325        if (!hwdev) {
 326                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 327                return -EINVAL;
 328        }
 329
 330        memset(&mtu_info, 0, sizeof(mtu_info));
 331        mtu_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 332        mtu_info.func_id = hinic_global_func_id(hwdev);
 333        mtu_info.mtu = new_mtu;
 334
 335        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
 336                                     &mtu_info, sizeof(mtu_info),
 337                                     &mtu_info, &out_size);
 338        if (err || !out_size || mtu_info.mgmt_msg_head.status) {
 339                PMD_DRV_LOG(ERR, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x",
 340                        err, mtu_info.mgmt_msg_head.status, out_size);
 341                return -EIO;
 342        }
 343
 344        return 0;
 345}
 346
 347/**
 348 * hinic_add_remove_vlan - Add or remove vlan id to vlan elb table.
 349 *
 350 * @param hwdev
 351 *   The hardware interface of a nic device.
 352 * @param vlan_id
 353 *   Vlan id.
 354 * @param func_id
 355 *   Global function id of NIC.
 356 * @param add
 357 *   Add or remove operation.
 358 *
 359 * @return
 360 *   0 on success.
 361 *   negative error value otherwise.
 362 */
 363int hinic_add_remove_vlan(void *hwdev, u16 vlan_id, u16 func_id, bool add)
 364{
 365        struct hinic_vlan_config vlan_info;
 366        u16 out_size = sizeof(vlan_info);
 367        u8 cmd;
 368        int err;
 369
 370        if (!hwdev) {
 371                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 372                return -EINVAL;
 373        }
 374
 375        cmd = add ? HINIC_PORT_CMD_ADD_VLAN : HINIC_PORT_CMD_DEL_VLAN;
 376
 377        memset(&vlan_info, 0, sizeof(vlan_info));
 378        vlan_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 379        vlan_info.func_id = func_id;
 380        vlan_info.vlan_id = vlan_id;
 381
 382        err = l2nic_msg_to_mgmt_sync(hwdev, cmd, &vlan_info, sizeof(vlan_info),
 383                                     &vlan_info, &out_size);
 384        if (err || !out_size || vlan_info.mgmt_msg_head.status) {
 385                PMD_DRV_LOG(ERR,
 386                        "Failed to %s vlan, err: %d, status: 0x%x, out size: 0x%x",
 387                        add ? "add" : "remove", err,
 388                        vlan_info.mgmt_msg_head.status, out_size);
 389                return -EIO;
 390        }
 391
 392        return 0;
 393}
 394
 395/**
 396 * hinic_config_vlan_filter - Enable or Disable vlan filter.
 397 *
 398 * @param hwdev
 399 *   The hardware interface of a nic device.
 400 * @param vlan_filter_ctrl
 401 *   Enable or Disable.
 402 *
 403 * @return
 404 *   0 on success.
 405 *   negative error value otherwise.
 406 */
 407int hinic_config_vlan_filter(void *hwdev, u32 vlan_filter_ctrl)
 408{
 409        struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
 410        struct hinic_vlan_filter vlan_filter;
 411        u16 out_size = sizeof(vlan_filter);
 412        int err;
 413
 414        if (!hwdev)
 415                return -EINVAL;
 416
 417        memset(&vlan_filter, 0, sizeof(vlan_filter));
 418        vlan_filter.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 419        vlan_filter.func_id = hinic_global_func_id(nic_hwdev);
 420        vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl;
 421
 422        err = l2nic_msg_to_mgmt_sync(nic_hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER,
 423                                     &vlan_filter, sizeof(vlan_filter),
 424                                     &vlan_filter, &out_size);
 425        if (vlan_filter.mgmt_msg_head.status == HINIC_MGMT_CMD_UNSUPPORTED) {
 426                err = HINIC_MGMT_CMD_UNSUPPORTED;
 427        } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
 428                (HINIC_IS_VF(nic_hwdev))) {
 429                err = HINIC_MGMT_CMD_UNSUPPORTED;
 430        } else if (err || !out_size || vlan_filter.mgmt_msg_head.status) {
 431                PMD_DRV_LOG(ERR,
 432                        "Failed to config vlan filter, vlan_filter_ctrl: 0x%x, err: %d, status: 0x%x, out size: 0x%x",
 433                        vlan_filter_ctrl, err,
 434                        vlan_filter.mgmt_msg_head.status, out_size);
 435                err = -EIO;
 436        }
 437
 438        return err;
 439}
 440
 441/**
 442 * hinic_set_rx_vlan_offload - Enable or Disable vlan offload.
 443 *
 444 * @param hwdev
 445 *   The hardware interface of a nic device.
 446 * @param en
 447 *   Enable or Disable.
 448 *
 449 * @return
 450 *   0 on success.
 451 *   negative error value otherwise.
 452 */
 453int hinic_set_rx_vlan_offload(void *hwdev, u8 en)
 454{
 455        struct hinic_vlan_offload vlan_cfg;
 456        u16 out_size = sizeof(vlan_cfg);
 457        int err;
 458
 459        if (!hwdev) {
 460                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 461                return -EINVAL;
 462        }
 463
 464        memset(&vlan_cfg, 0, sizeof(vlan_cfg));
 465        vlan_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 466        vlan_cfg.func_id = hinic_global_func_id(hwdev);
 467        vlan_cfg.vlan_rx_offload = en;
 468
 469        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
 470                                     &vlan_cfg, sizeof(vlan_cfg),
 471                                     &vlan_cfg, &out_size);
 472        if (err || !out_size || vlan_cfg.mgmt_msg_head.status) {
 473                PMD_DRV_LOG(ERR,
 474                        "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x",
 475                        err, vlan_cfg.mgmt_msg_head.status, out_size);
 476                return -EIO;
 477        }
 478
 479        return 0;
 480}
 481
 482/**
 483 * hinic_get_link_status - Get link status from hardware.
 484 *
 485 * @param hwdev
 486 *   The hardware interface of a nic device.
 487 * @param link_state
 488 *   Link status.
 489 *
 490 * @return
 491 *   0 on success.
 492 *   negative error value otherwise.
 493 */
 494int hinic_get_link_status(void *hwdev, u8 *link_state)
 495{
 496        struct hinic_get_link get_link;
 497        u16 out_size = sizeof(get_link);
 498        int err;
 499
 500        if (!hwdev || !link_state) {
 501                PMD_DRV_LOG(ERR, "Hwdev or link_state is NULL");
 502                return -EINVAL;
 503        }
 504
 505        memset(&get_link, 0, sizeof(get_link));
 506        get_link.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 507        get_link.func_id = hinic_global_func_id(hwdev);
 508
 509        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
 510                                     &get_link, sizeof(get_link),
 511                                     &get_link, &out_size);
 512        if (err || !out_size || get_link.mgmt_msg_head.status) {
 513                PMD_DRV_LOG(ERR, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x",
 514                        err, get_link.mgmt_msg_head.status, out_size);
 515                return -EIO;
 516        }
 517
 518        *link_state = get_link.link_status;
 519
 520        return 0;
 521}
 522
 523/**
 524 * hinic_set_vport_enable - Notify firmware that driver is ready or not.
 525 *
 526 * @param hwdev
 527 *   The hardware interface of a nic device.
 528 * @param enable
 529 *   1: driver is ready; 0: driver is not ok.
 530 *
 531 * @return
 532 *   0 on success.
 533 *   negative error value otherwise.
 534 */
 535int hinic_set_vport_enable(void *hwdev, bool enable)
 536{
 537        struct hinic_vport_state en_state;
 538        u16 out_size = sizeof(en_state);
 539        int err;
 540
 541        if (!hwdev) {
 542                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 543                return -EINVAL;
 544        }
 545
 546        memset(&en_state, 0, sizeof(en_state));
 547        en_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 548        en_state.func_id = hinic_global_func_id(hwdev);
 549        en_state.state = (enable ? 1 : 0);
 550
 551        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_VPORT_ENABLE,
 552                                     &en_state, sizeof(en_state),
 553                                     &en_state, &out_size);
 554        if (err || !out_size || en_state.mgmt_msg_head.status) {
 555                PMD_DRV_LOG(ERR, "Failed to set vport state, err: %d, status: 0x%x, out size: 0x%x",
 556                        err, en_state.mgmt_msg_head.status, out_size);
 557                return -EIO;
 558        }
 559
 560        return 0;
 561}
 562
 563/**
 564 * hinic_set_port_enable - Open MAG to receive packets.
 565 *
 566 * @param hwdev
 567 *   The hardware interface of a nic device.
 568 * @param enable
 569 *   1: open MAG; 0: close MAG.
 570 *
 571 * @return
 572 *   0 on success.
 573 *   negative error value otherwise.
 574 */
 575int hinic_set_port_enable(void *hwdev, bool enable)
 576{
 577        struct hinic_port_state en_state;
 578        u16 out_size = sizeof(en_state);
 579        int err;
 580
 581        if (!hwdev) {
 582                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 583                return -EINVAL;
 584        }
 585
 586        if (HINIC_IS_VF((struct hinic_hwdev *)hwdev))
 587                return 0;
 588
 589        memset(&en_state, 0, sizeof(en_state));
 590        en_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 591        en_state.state = (enable ? HINIC_PORT_ENABLE : HINIC_PORT_DISABLE);
 592
 593        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PORT_ENABLE,
 594                                     &en_state, sizeof(en_state),
 595                                     &en_state, &out_size);
 596        if (err || !out_size || en_state.mgmt_msg_head.status) {
 597                PMD_DRV_LOG(ERR, "Failed to set phy port state, err: %d, status: 0x%x, out size: 0x%x",
 598                        err, en_state.mgmt_msg_head.status, out_size);
 599                return -EIO;
 600        }
 601
 602        return 0;
 603}
 604
 605int hinic_get_port_info(void *hwdev, struct nic_port_info *port_info)
 606{
 607        struct hinic_port_info port_msg;
 608        u16 out_size = sizeof(port_msg);
 609        int err;
 610
 611        if (!hwdev || !port_info) {
 612                PMD_DRV_LOG(ERR, "Hwdev or port_info is NULL");
 613                return -EINVAL;
 614        }
 615
 616        memset(&port_msg, 0, sizeof(port_msg));
 617        port_msg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 618        port_msg.func_id = hinic_global_func_id(hwdev);
 619
 620        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PORT_INFO,
 621                                     &port_msg, sizeof(port_msg),
 622                                     &port_msg, &out_size);
 623        if (err || !out_size || port_msg.mgmt_msg_head.status) {
 624                PMD_DRV_LOG(ERR,
 625                        "Failed to get port info, err: %d, status: 0x%x, out size: 0x%x",
 626                        err, port_msg.mgmt_msg_head.status, out_size);
 627                return -EIO;
 628        }
 629
 630        port_info->autoneg_cap = port_msg.autoneg_cap;
 631        port_info->autoneg_state = port_msg.autoneg_state;
 632        port_info->duplex = port_msg.duplex;
 633        port_info->port_type = port_msg.port_type;
 634        port_info->speed = port_msg.speed;
 635
 636        return 0;
 637}
 638
 639int hinic_set_pause_config(void *hwdev, struct nic_pause_config nic_pause)
 640{
 641        struct hinic_pause_config pause_info;
 642        u16 out_size = sizeof(pause_info);
 643        int err;
 644
 645        if (!hwdev) {
 646                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 647                return -EINVAL;
 648        }
 649
 650        memset(&pause_info, 0, sizeof(pause_info));
 651        pause_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 652        pause_info.func_id = hinic_global_func_id(hwdev);
 653        pause_info.auto_neg = nic_pause.auto_neg;
 654        pause_info.rx_pause = nic_pause.rx_pause;
 655        pause_info.tx_pause = nic_pause.tx_pause;
 656
 657        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
 658                                     &pause_info, sizeof(pause_info),
 659                                     &pause_info, &out_size);
 660        if (err || !out_size || pause_info.mgmt_msg_head.status) {
 661                PMD_DRV_LOG(ERR, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x",
 662                        err, pause_info.mgmt_msg_head.status, out_size);
 663                return -EIO;
 664        }
 665
 666        return 0;
 667}
 668
 669int hinic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
 670{
 671        struct hinic_pause_config pause_info;
 672        u16 out_size = sizeof(pause_info);
 673        int err;
 674
 675        if (!hwdev || !nic_pause)
 676                return -EINVAL;
 677
 678        memset(&pause_info, 0, sizeof(pause_info));
 679        pause_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 680        pause_info.func_id = hinic_global_func_id(hwdev);
 681
 682        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
 683                                     &pause_info, sizeof(pause_info),
 684                                     &pause_info, &out_size);
 685        if (err || !out_size || pause_info.mgmt_msg_head.status) {
 686                PMD_DRV_LOG(ERR, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n",
 687                        err, pause_info.mgmt_msg_head.status, out_size);
 688                return -EIO;
 689        }
 690
 691        nic_pause->auto_neg = pause_info.auto_neg;
 692        nic_pause->rx_pause = pause_info.rx_pause;
 693        nic_pause->tx_pause = pause_info.tx_pause;
 694
 695        return 0;
 696}
 697
 698int hinic_dcb_set_ets(void *hwdev, u8 *up_tc, u8 *pg_bw,
 699                      u8 *pgid, u8 *up_bw, u8 *prio)
 700{
 701        struct hinic_up_ets_cfg ets;
 702        u16 out_size = sizeof(ets);
 703        u16 up_bw_t = 0;
 704        u8 pg_bw_t = 0;
 705        int i, err;
 706
 707        if (!hwdev || !up_tc || !pg_bw || !pgid || !up_bw || !prio) {
 708                PMD_DRV_LOG(ERR, "Hwdev, up_tc, pg_bw, pgid, up_bw or prio is NULL");
 709                return -EINVAL;
 710        }
 711
 712        for (i = 0; i < HINIC_DCB_TC_MAX; i++) {
 713                up_bw_t += *(up_bw + i);
 714                pg_bw_t += *(pg_bw + i);
 715
 716                if (*(up_tc + i) > HINIC_DCB_TC_MAX) {
 717                        PMD_DRV_LOG(ERR, "Invalid up %d mapping tc: %d", i,
 718                                *(up_tc + i));
 719                        return -EINVAL;
 720                }
 721        }
 722
 723        if (pg_bw_t != 100 || (up_bw_t % 100) != 0) {
 724                PMD_DRV_LOG(ERR,
 725                        "Invalid pg_bw: %d or up_bw: %d", pg_bw_t, up_bw_t);
 726                return -EINVAL;
 727        }
 728
 729        memset(&ets, 0, sizeof(ets));
 730        ets.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 731        ets.port_id = 0;        /* reserved */
 732        memcpy(ets.up_tc, up_tc, HINIC_DCB_TC_MAX);
 733        memcpy(ets.pg_bw, pg_bw, HINIC_DCB_UP_MAX);
 734        memcpy(ets.pgid, pgid, HINIC_DCB_UP_MAX);
 735        memcpy(ets.up_bw, up_bw, HINIC_DCB_UP_MAX);
 736        memcpy(ets.prio, prio, HINIC_DCB_UP_MAX);
 737
 738        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_ETS,
 739                                     &ets, sizeof(ets), &ets, &out_size);
 740        if (err || ets.mgmt_msg_head.status || !out_size) {
 741                PMD_DRV_LOG(ERR,
 742                        "Failed to set ets, err: %d, status: 0x%x, out size: 0x%x",
 743                        err, ets.mgmt_msg_head.status, out_size);
 744                return -EIO;
 745        }
 746
 747        return 0;
 748}
 749
 750int hinic_get_vport_stats(void *hwdev, struct hinic_vport_stats *stats)
 751{
 752        struct hinic_port_stats_info vport_stats_cmd;
 753        struct hinic_cmd_vport_stats vport_stats_rsp;
 754        u16 out_size = sizeof(vport_stats_rsp);
 755        int err;
 756
 757        if (!hwdev || !stats) {
 758                PMD_DRV_LOG(ERR, "Hwdev or stats is NULL");
 759                return -EINVAL;
 760        }
 761
 762        memset(&vport_stats_rsp, 0, sizeof(vport_stats_rsp));
 763        memset(&vport_stats_cmd, 0, sizeof(vport_stats_cmd));
 764        vport_stats_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 765        vport_stats_cmd.stats_version = HINIC_PORT_STATS_VERSION;
 766        vport_stats_cmd.func_id = hinic_global_func_id(hwdev);
 767        vport_stats_cmd.stats_size = sizeof(vport_stats_rsp);
 768
 769        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
 770                                     &vport_stats_cmd, sizeof(vport_stats_cmd),
 771                                     &vport_stats_rsp, &out_size);
 772        if (err || !out_size || vport_stats_rsp.mgmt_msg_head.status) {
 773                PMD_DRV_LOG(ERR,
 774                        "Get vport stats from fw failed, err: %d, status: 0x%x, out size: 0x%x",
 775                        err, vport_stats_rsp.mgmt_msg_head.status, out_size);
 776                return -EIO;
 777        }
 778
 779        memcpy(stats, &vport_stats_rsp.stats, sizeof(*stats));
 780
 781        return 0;
 782}
 783
 784int hinic_get_phy_port_stats(void *hwdev, struct hinic_phy_port_stats *stats)
 785{
 786        struct hinic_port_stats_info port_stats_cmd;
 787        struct hinic_port_stats port_stats_rsp;
 788        u16 out_size = sizeof(port_stats_rsp);
 789        int err;
 790
 791        if (!hwdev || !stats) {
 792                PMD_DRV_LOG(ERR, "Hwdev or stats is NULL");
 793                return -EINVAL;
 794        }
 795
 796        memset(&port_stats_rsp, 0, sizeof(port_stats_rsp));
 797        memset(&port_stats_cmd, 0, sizeof(port_stats_cmd));
 798        port_stats_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 799        port_stats_cmd.stats_version = HINIC_PORT_STATS_VERSION;
 800        port_stats_cmd.stats_size = sizeof(port_stats_rsp);
 801
 802        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
 803                                     &port_stats_cmd, sizeof(port_stats_cmd),
 804                                     &port_stats_rsp, &out_size);
 805        if (err || !out_size || port_stats_rsp.mgmt_msg_head.status) {
 806                PMD_DRV_LOG(ERR,
 807                        "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x",
 808                        err, port_stats_rsp.mgmt_msg_head.status, out_size);
 809                return -EIO;
 810        }
 811
 812        memcpy(stats, &port_stats_rsp.stats, sizeof(*stats));
 813
 814        return 0;
 815}
 816
 817int hinic_set_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type rss_type)
 818{
 819        struct nic_rss_context_tbl *ctx_tbl;
 820        struct hinic_cmd_buf *cmd_buf;
 821        u32 ctx = 0;
 822        u64 out_param;
 823        int err;
 824
 825        if (!hwdev) {
 826                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 827                return -EINVAL;
 828        }
 829
 830        cmd_buf = hinic_alloc_cmd_buf(hwdev);
 831        if (!cmd_buf) {
 832                PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
 833                return -ENOMEM;
 834        }
 835
 836        ctx |= HINIC_RSS_TYPE_SET(1, VALID) |
 837                HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
 838                HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
 839                HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
 840                HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
 841                HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
 842                HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
 843                HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
 844                HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
 845
 846        cmd_buf->size = sizeof(struct nic_rss_context_tbl);
 847
 848        ctx_tbl = (struct nic_rss_context_tbl *)cmd_buf->buf;
 849        ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
 850        ctx_tbl->offset = 0;
 851        ctx_tbl->size = sizeof(u32);
 852        ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
 853        ctx_tbl->rsvd = 0;
 854        ctx_tbl->ctx = cpu_to_be32(ctx);
 855
 856        /* cfg the rss context table by command queue */
 857        err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
 858                                     HINIC_MOD_L2NIC,
 859                                     HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
 860                                     cmd_buf, &out_param, 0);
 861
 862        hinic_free_cmd_buf(hwdev, cmd_buf);
 863
 864        if (err || out_param != 0) {
 865                PMD_DRV_LOG(ERR, "Failed to set rss context table");
 866                return -EIO;
 867        }
 868
 869        return 0;
 870}
 871
 872int hinic_get_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type *rss_type)
 873{
 874        struct hinic_rss_context_table ctx_tbl;
 875        u16 out_size = sizeof(ctx_tbl);
 876        int err;
 877
 878        if (!hwdev || !rss_type) {
 879                PMD_DRV_LOG(ERR, "Hwdev or rss_type is NULL");
 880                return -EINVAL;
 881        }
 882
 883        ctx_tbl.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 884        ctx_tbl.func_id = hinic_global_func_id(hwdev);
 885        ctx_tbl.template_id = (u8)tmpl_idx;
 886
 887        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
 888                                     &ctx_tbl, sizeof(ctx_tbl),
 889                                     &ctx_tbl, &out_size);
 890        if (err || !out_size || ctx_tbl.mgmt_msg_head.status) {
 891                PMD_DRV_LOG(ERR,
 892                        "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x",
 893                        err, ctx_tbl.mgmt_msg_head.status, out_size);
 894                return -EIO;
 895        }
 896
 897        rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
 898        rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
 899        rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
 900        rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
 901        rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
 902        rss_type->tcp_ipv6_ext =
 903                        HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6_EXT);
 904        rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
 905        rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
 906
 907        return 0;
 908}
 909
 910int hinic_rss_set_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp)
 911{
 912        struct hinic_rss_template_key temp_key;
 913        u16 out_size = sizeof(temp_key);
 914        int err;
 915
 916        if (!hwdev || !temp) {
 917                PMD_DRV_LOG(ERR, "Hwdev or temp is NULL");
 918                return -EINVAL;
 919        }
 920
 921        memset(&temp_key, 0, sizeof(temp_key));
 922        temp_key.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 923        temp_key.func_id = hinic_global_func_id(hwdev);
 924        temp_key.template_id = (u8)tmpl_idx;
 925        memcpy(temp_key.key, temp, HINIC_RSS_KEY_SIZE);
 926
 927        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
 928                                     &temp_key, sizeof(temp_key),
 929                                     &temp_key, &out_size);
 930        if (err || !out_size || temp_key.mgmt_msg_head.status) {
 931                PMD_DRV_LOG(ERR,
 932                        "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x",
 933                        err, temp_key.mgmt_msg_head.status, out_size);
 934                return -EIO;
 935        }
 936
 937        return 0;
 938}
 939
 940int hinic_rss_get_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp)
 941{
 942        struct hinic_rss_template_key temp_key;
 943        u16 out_size = sizeof(temp_key);
 944        int err;
 945
 946        if (!hwdev || !temp) {
 947                PMD_DRV_LOG(ERR, "Hwdev or temp is NULL");
 948                return -EINVAL;
 949        }
 950
 951        memset(&temp_key, 0, sizeof(temp_key));
 952        temp_key.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 953        temp_key.func_id = hinic_global_func_id(hwdev);
 954        temp_key.template_id = (u8)tmpl_idx;
 955
 956        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
 957                                     &temp_key, sizeof(temp_key),
 958                                     &temp_key, &out_size);
 959        if (err || !out_size || temp_key.mgmt_msg_head.status) {
 960                PMD_DRV_LOG(ERR, "Failed to get hash key, err: %d, status: 0x%x, out size: 0x%x",
 961                        err, temp_key.mgmt_msg_head.status, out_size);
 962                return -EIO;
 963        }
 964
 965        memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
 966
 967        return 0;
 968}
 969
 970/**
 971 * hinic_rss_set_hash_engine - Init rss hash function.
 972 *
 973 * @param hwdev
 974 *   The hardware interface of a nic device.
 975 * @param tmpl_idx
 976 *   Index of rss template from NIC.
 977 * @param type
 978 *   Hash function, such as Toeplitz or XOR.
 979 *
 980 * @return
 981 *   0 on success.
 982 *   negative error value otherwise.
 983 */
 984int hinic_rss_set_hash_engine(void *hwdev, u8 tmpl_idx, u8 type)
 985{
 986        struct hinic_rss_engine_type hash_type;
 987        u16 out_size = sizeof(hash_type);
 988        int err;
 989
 990        if (!hwdev) {
 991                PMD_DRV_LOG(ERR, "Hwdev is NULL");
 992                return -EINVAL;
 993        }
 994
 995        memset(&hash_type, 0, sizeof(hash_type));
 996        hash_type.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
 997        hash_type.func_id = hinic_global_func_id(hwdev);
 998        hash_type.hash_engine = type;
 999        hash_type.template_id = tmpl_idx;
1000
1001        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
1002                                     &hash_type, sizeof(hash_type),
1003                                     &hash_type, &out_size);
1004        if (err || !out_size || hash_type.mgmt_msg_head.status) {
1005                PMD_DRV_LOG(ERR, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x",
1006                        err, hash_type.mgmt_msg_head.status, out_size);
1007                return -EIO;
1008        }
1009
1010        return 0;
1011}
1012
1013int hinic_rss_set_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table)
1014{
1015        struct nic_rss_indirect_tbl *indir_tbl;
1016        struct hinic_cmd_buf *cmd_buf;
1017        int i;
1018        u32 *temp;
1019        u32 indir_size;
1020        u64 out_param;
1021        int err;
1022
1023        if (!hwdev || !indir_table) {
1024                PMD_DRV_LOG(ERR, "Hwdev or indir_table is NULL");
1025                return -EINVAL;
1026        }
1027
1028        cmd_buf = hinic_alloc_cmd_buf(hwdev);
1029        if (!cmd_buf) {
1030                PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
1031                return -ENOMEM;
1032        }
1033
1034        cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
1035        indir_tbl = cmd_buf->buf;
1036        indir_tbl->group_index = cpu_to_be32(tmpl_idx);
1037
1038        for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
1039                indir_tbl->entry[i] = (u8)(*(indir_table + i));
1040
1041                if (0x3 == (i & 0x3)) {
1042                        temp = (u32 *)&indir_tbl->entry[i - 3];
1043                        *temp = cpu_to_be32(*temp);
1044                }
1045        }
1046
1047        /* configure the rss indirect table by command queue */
1048        indir_size = HINIC_RSS_INDIR_SIZE / 2;
1049        indir_tbl->offset = 0;
1050        indir_tbl->size = cpu_to_be32(indir_size);
1051
1052        err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
1053                                     HINIC_MOD_L2NIC,
1054                                     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
1055                                     cmd_buf, &out_param, 0);
1056        if (err || out_param != 0) {
1057                PMD_DRV_LOG(ERR, "Failed to set rss indir table");
1058                err = -EIO;
1059                goto free_buf;
1060        }
1061
1062        indir_tbl->offset = cpu_to_be32(indir_size);
1063        indir_tbl->size = cpu_to_be32(indir_size);
1064        memcpy(indir_tbl->entry, &indir_tbl->entry[indir_size], indir_size);
1065
1066        err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
1067                                     HINIC_MOD_L2NIC,
1068                                     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
1069                                     cmd_buf, &out_param, 0);
1070        if (err || out_param != 0) {
1071                PMD_DRV_LOG(ERR, "Failed to set rss indir table");
1072                err = -EIO;
1073        }
1074
1075free_buf:
1076        hinic_free_cmd_buf(hwdev, cmd_buf);
1077
1078        return err;
1079}
1080
1081int hinic_rss_get_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table)
1082{
1083        struct hinic_rss_indir_table rss_cfg;
1084        u16 out_size = sizeof(rss_cfg);
1085        int err = 0, i;
1086
1087        if (!hwdev || !indir_table) {
1088                PMD_DRV_LOG(ERR, "Hwdev or indir_table is NULL");
1089                return -EINVAL;
1090        }
1091
1092        memset(&rss_cfg, 0, sizeof(rss_cfg));
1093        rss_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1094        rss_cfg.func_id = hinic_global_func_id(hwdev);
1095        rss_cfg.template_id = (u8)tmpl_idx;
1096
1097        err = l2nic_msg_to_mgmt_sync(hwdev,
1098                                     HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
1099                                     &rss_cfg, sizeof(rss_cfg), &rss_cfg,
1100                                     &out_size);
1101        if (err || !out_size || rss_cfg.mgmt_msg_head.status) {
1102                PMD_DRV_LOG(ERR, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x",
1103                        err, rss_cfg.mgmt_msg_head.status, out_size);
1104                return -EIO;
1105        }
1106
1107        hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
1108        for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
1109                indir_table[i] = rss_cfg.indir[i];
1110
1111        return 0;
1112}
1113
1114int hinic_rss_cfg(void *hwdev, u8 rss_en, u8 tmpl_idx, u8 tc_num, u8 *prio_tc)
1115{
1116        struct hinic_rss_config rss_cfg;
1117        u16 out_size = sizeof(rss_cfg);
1118        int err;
1119
1120        /* micro code required: number of TC should be power of 2 */
1121        if (!hwdev || !prio_tc || (tc_num & (tc_num - 1))) {
1122                PMD_DRV_LOG(ERR, "Hwdev or prio_tc is NULL, or tc_num: %u Not power of 2",
1123                        tc_num);
1124                return -EINVAL;
1125        }
1126
1127        memset(&rss_cfg, 0, sizeof(rss_cfg));
1128        rss_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1129        rss_cfg.func_id = hinic_global_func_id(hwdev);
1130        rss_cfg.rss_en = rss_en;
1131        rss_cfg.template_id = tmpl_idx;
1132        rss_cfg.rq_priority_number = tc_num ? (u8)ilog2(tc_num) : 0;
1133
1134        memcpy(rss_cfg.prio_tc, prio_tc, HINIC_DCB_UP_MAX);
1135
1136        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_CFG,
1137                                     &rss_cfg, sizeof(rss_cfg), &rss_cfg,
1138                                     &out_size);
1139        if (err || !out_size || rss_cfg.mgmt_msg_head.status) {
1140                PMD_DRV_LOG(ERR, "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x",
1141                        err, rss_cfg.mgmt_msg_head.status, out_size);
1142                return -EIO;
1143        }
1144
1145        return 0;
1146}
1147
1148/**
1149 * hinic_rss_template_alloc - Get rss template id from the chip,
1150 * all functions share 96 templates.
1151 *
1152 * @param hwdev
1153 *   The hardware interface of a nic device.
1154 * @param tmpl_idx
1155 *   Index of rss template from chip.
1156 *
1157 * @return
1158 *   0 on success.
1159 *   negative error value otherwise.
1160 */
1161int hinic_rss_template_alloc(void *hwdev, u8 *tmpl_idx)
1162{
1163        struct hinic_rss_template_mgmt template_mgmt;
1164        u16 out_size = sizeof(template_mgmt);
1165        int err;
1166
1167        if (!hwdev || !tmpl_idx) {
1168                PMD_DRV_LOG(ERR, "Hwdev or tmpl_idx is NULL");
1169                return -EINVAL;
1170        }
1171
1172        memset(&template_mgmt, 0, sizeof(template_mgmt));
1173        template_mgmt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1174        template_mgmt.func_id = hinic_global_func_id(hwdev);
1175        template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
1176
1177        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
1178                                     &template_mgmt, sizeof(template_mgmt),
1179                                     &template_mgmt, &out_size);
1180        if (err || !out_size || template_mgmt.mgmt_msg_head.status) {
1181                PMD_DRV_LOG(ERR, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x",
1182                        err, template_mgmt.mgmt_msg_head.status, out_size);
1183                return -EIO;
1184        }
1185
1186        *tmpl_idx = template_mgmt.template_id;
1187
1188        return 0;
1189}
1190
1191/**
1192 * hinic_rss_template_free - Free rss template id to the chip.
1193 *
1194 * @param hwdev
1195 *   The hardware interface of a nic device.
1196 * @param tmpl_idx
1197 *   Index of rss template from chip.
1198 *
1199 * @return
1200 *   0 on success.
1201 *   negative error value otherwise.
1202 */
1203int hinic_rss_template_free(void *hwdev, u8 tmpl_idx)
1204{
1205        struct hinic_rss_template_mgmt template_mgmt;
1206        u16 out_size = sizeof(template_mgmt);
1207        int err;
1208
1209        if (!hwdev) {
1210                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1211                return -EINVAL;
1212        }
1213
1214        memset(&template_mgmt, 0, sizeof(template_mgmt));
1215        template_mgmt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1216        template_mgmt.func_id = hinic_global_func_id(hwdev);
1217        template_mgmt.template_id = tmpl_idx;
1218        template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
1219
1220        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
1221                                     &template_mgmt, sizeof(template_mgmt),
1222                                     &template_mgmt, &out_size);
1223        if (err || !out_size || template_mgmt.mgmt_msg_head.status) {
1224                PMD_DRV_LOG(ERR, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x",
1225                        err, template_mgmt.mgmt_msg_head.status, out_size);
1226                return -EIO;
1227        }
1228
1229        return 0;
1230}
1231
1232/**
1233 * hinic_set_rx_vhd_mode - Change rx buffer size after initialization.
1234 *
1235 * @param hwdev
1236 *   The hardware interface of a nic device.
1237 * @param vhd_mode
1238 *   Not needed.
1239 * @param rx_buf_sz
1240 *   receive buffer size.
1241 *
1242 * @return
1243 *   0 on success.
1244 *   negative error value otherwise.
1245 */
1246int hinic_set_rx_vhd_mode(void *hwdev, u16 vhd_mode, u16 rx_buf_sz)
1247{
1248        struct hinic_set_vhd_mode vhd_mode_cfg;
1249        u16 out_size = sizeof(vhd_mode_cfg);
1250        int err;
1251
1252        if (!hwdev) {
1253                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1254                return -EINVAL;
1255        }
1256
1257        memset(&vhd_mode_cfg, 0, sizeof(vhd_mode_cfg));
1258
1259        vhd_mode_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1260        vhd_mode_cfg.func_id = hinic_global_func_id(hwdev);
1261        vhd_mode_cfg.vhd_type = vhd_mode;
1262        vhd_mode_cfg.rx_wqe_buffer_size = rx_buf_sz;
1263
1264        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_VHD_CFG,
1265                                     &vhd_mode_cfg, sizeof(vhd_mode_cfg),
1266                                     &vhd_mode_cfg, &out_size);
1267        if (err || !out_size || vhd_mode_cfg.mgmt_msg_head.status) {
1268                PMD_DRV_LOG(ERR,
1269                        "Failed to set vhd mode, err: %d, status: 0x%x, out size: 0x%x",
1270                        err, vhd_mode_cfg.mgmt_msg_head.status, out_size);
1271                return -EIO;
1272        }
1273
1274        return 0;
1275}
1276
1277int hinic_set_rx_mode(void *hwdev, u32 enable)
1278{
1279        struct hinic_rx_mode_config rx_mode_cfg;
1280        u16 out_size = sizeof(rx_mode_cfg);
1281        int err;
1282
1283        if (!hwdev) {
1284                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1285                return -EINVAL;
1286        }
1287
1288        memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
1289        rx_mode_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1290        rx_mode_cfg.func_id = hinic_global_func_id(hwdev);
1291        rx_mode_cfg.rx_mode = enable;
1292
1293        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
1294                                     &rx_mode_cfg, sizeof(rx_mode_cfg),
1295                                     &rx_mode_cfg, &out_size);
1296        if (err || !out_size || rx_mode_cfg.mgmt_msg_head.status) {
1297                PMD_DRV_LOG(ERR, "Failed to set rx mode, err: %d, status: 0x%x, out size: 0x%x",
1298                        err, rx_mode_cfg.mgmt_msg_head.status, out_size);
1299                return -EIO;
1300        }
1301
1302        return 0;
1303}
1304
1305/**
1306 * hinic_get_mgmt_version - Get mgmt module version from chip.
1307 *
1308 * @param hwdev
1309 *   The hardware interface of a nic device.
1310 * @param fw
1311 *   Firmware version.
1312 *
1313 * @return
1314 *   0 on success.
1315 *   negative error value otherwise.
1316 */
1317int hinic_get_mgmt_version(void *hwdev, char *fw)
1318{
1319        struct hinic_version_info fw_ver;
1320        u16 out_size = sizeof(fw_ver);
1321        int err;
1322
1323        if (!hwdev || !fw) {
1324                PMD_DRV_LOG(ERR, "Hwdev or fw is NULL");
1325                return -EINVAL;
1326        }
1327
1328        memset(&fw_ver, 0, sizeof(fw_ver));
1329        fw_ver.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1330
1331        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1332                                     &fw_ver, sizeof(fw_ver), &fw_ver,
1333                                     &out_size);
1334        if (err || !out_size || fw_ver.mgmt_msg_head.status) {
1335                PMD_DRV_LOG(ERR, "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1336                        err, fw_ver.mgmt_msg_head.status, out_size);
1337                return -EIO;
1338        }
1339
1340        snprintf(fw, HINIC_MGMT_VERSION_MAX_LEN, "%s", fw_ver.ver);
1341
1342        return 0;
1343}
1344
1345int hinic_set_rx_csum_offload(void *hwdev, u32 en)
1346{
1347        struct hinic_checksum_offload rx_csum_cfg;
1348        u16 out_size = sizeof(rx_csum_cfg);
1349        int err;
1350
1351        if (!hwdev) {
1352                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1353                return -EINVAL;
1354        }
1355
1356        memset(&rx_csum_cfg, 0, sizeof(rx_csum_cfg));
1357        rx_csum_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1358        rx_csum_cfg.func_id = hinic_global_func_id(hwdev);
1359        rx_csum_cfg.rx_csum_offload = en;
1360
1361        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
1362                                     &rx_csum_cfg, sizeof(rx_csum_cfg),
1363                                     &rx_csum_cfg, &out_size);
1364        if (err || !out_size || rx_csum_cfg.mgmt_msg_head.status) {
1365                PMD_DRV_LOG(ERR,
1366                        "Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x",
1367                        err, rx_csum_cfg.mgmt_msg_head.status, out_size);
1368                return -EIO;
1369        }
1370
1371        return 0;
1372}
1373
1374int hinic_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en, u8 max_wqe_num)
1375{
1376        struct hinic_lro_config lro_cfg;
1377        u16 out_size = sizeof(lro_cfg);
1378        int err;
1379
1380        if (!hwdev) {
1381                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1382                return -EINVAL;
1383        }
1384
1385        memset(&lro_cfg, 0, sizeof(lro_cfg));
1386        lro_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1387        lro_cfg.func_id = hinic_global_func_id(hwdev);
1388        lro_cfg.lro_ipv4_en = ipv4_en;
1389        lro_cfg.lro_ipv6_en = ipv6_en;
1390        lro_cfg.lro_max_wqe_num = max_wqe_num;
1391
1392        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_LRO,
1393                                     &lro_cfg, sizeof(lro_cfg), &lro_cfg,
1394                                     &out_size);
1395        if (err || !out_size || lro_cfg.mgmt_msg_head.status) {
1396                PMD_DRV_LOG(ERR, "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x",
1397                        err, lro_cfg.mgmt_msg_head.status, out_size);
1398                return -EIO;
1399        }
1400
1401        return 0;
1402}
1403
1404int hinic_set_anti_attack(void *hwdev, bool enable)
1405{
1406        struct hinic_port_anti_attack_rate rate;
1407        u16 out_size = sizeof(rate);
1408        int err;
1409
1410        if (!hwdev) {
1411                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1412                return -EINVAL;
1413        }
1414
1415        memset(&rate, 0, sizeof(rate));
1416        rate.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1417        rate.func_id = hinic_global_func_id(hwdev);
1418        rate.enable = enable;
1419        rate.cir = ANTI_ATTACK_DEFAULT_CIR;
1420        rate.xir = ANTI_ATTACK_DEFAULT_XIR;
1421        rate.cbs = ANTI_ATTACK_DEFAULT_CBS;
1422        rate.xbs = ANTI_ATTACK_DEFAULT_XBS;
1423
1424        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_ANTI_ATTACK_RATE,
1425                                     &rate, sizeof(rate), &rate, &out_size);
1426        if (err || !out_size || rate.mgmt_msg_head.status) {
1427                PMD_DRV_LOG(ERR, "Can't %s port Anti-Attack rate limit, err: %d, status: 0x%x, out size: 0x%x",
1428                        (enable ? "enable" : "disable"), err,
1429                        rate.mgmt_msg_head.status, out_size);
1430                return -EIO;
1431        }
1432
1433        return 0;
1434}
1435
1436/* Set autoneg status and restart port link status */
1437int hinic_reset_port_link_cfg(void *hwdev)
1438{
1439        struct hinic_reset_link_cfg reset_cfg;
1440        u16 out_size = sizeof(reset_cfg);
1441        int err;
1442
1443        memset(&reset_cfg, 0, sizeof(reset_cfg));
1444        reset_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1445        reset_cfg.func_id = hinic_global_func_id(hwdev);
1446
1447        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RESET_LINK_CFG,
1448                                     &reset_cfg, sizeof(reset_cfg),
1449                                     &reset_cfg, &out_size);
1450        if (err || !out_size || reset_cfg.mgmt_msg_head.status) {
1451                PMD_DRV_LOG(ERR, "Reset port link configure failed, err: %d, status: 0x%x, out size: 0x%x",
1452                        err, reset_cfg.mgmt_msg_head.status, out_size);
1453                return -EIO;
1454        }
1455
1456        return 0;
1457}
1458
1459/**
1460 * hinic_vf_func_init - Register VF to PF.
1461 *
1462 * @param hwdev
1463 *   The hardware interface of a nic device.
1464 *
1465 * @return
1466 *   0 on success.
1467 *   negative error value otherwise.
1468 */
1469int hinic_vf_func_init(struct hinic_hwdev *hwdev)
1470{
1471        int err, state = 0;
1472
1473        if (!HINIC_IS_VF(hwdev))
1474                return 0;
1475
1476        err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
1477                        HINIC_PORT_CMD_VF_REGISTER, &state, sizeof(state),
1478                        NULL, NULL, 0);
1479        if (err) {
1480                PMD_DRV_LOG(ERR, "Fail to register vf");
1481                return err;
1482        }
1483
1484        return 0;
1485}
1486
1487/**
1488 * hinic_vf_func_free - Unregister VF from PF.
1489 *
1490 * @param hwdev
1491 *   The hardware interface of a nic device.
1492 */
1493void hinic_vf_func_free(struct hinic_hwdev *hwdev)
1494{
1495        int err;
1496
1497        if (hinic_func_type(hwdev) != TYPE_VF)
1498                return;
1499
1500        err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
1501                                HINIC_PORT_CMD_VF_UNREGISTER, &err, sizeof(err),
1502                                NULL, NULL, 0);
1503        if (err)
1504                PMD_DRV_LOG(ERR, "Fail to unregister VF, err: %d", err);
1505}
1506
1507int hinic_set_fast_recycle_mode(void *hwdev, u8 mode)
1508{
1509        struct hinic_fast_recycled_mode fast_recycled_mode;
1510        u16 out_size = sizeof(fast_recycled_mode);
1511        int err;
1512
1513        if (!hwdev) {
1514                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1515                return -EINVAL;
1516        }
1517
1518        memset(&fast_recycled_mode, 0, sizeof(fast_recycled_mode));
1519        fast_recycled_mode.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1520        fast_recycled_mode.func_id = hinic_global_func_id(hwdev);
1521        fast_recycled_mode.fast_recycled_mode = mode;
1522
1523        err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
1524                                     HINIC_MGMT_CMD_FAST_RECYCLE_MODE_SET,
1525                                     &fast_recycled_mode,
1526                                     sizeof(fast_recycled_mode),
1527                                     &fast_recycled_mode, &out_size, 0);
1528        if (err || fast_recycled_mode.mgmt_msg_head.status || !out_size) {
1529                PMD_DRV_LOG(ERR, "Failed to set recycle mode, err: %d, status: 0x%x, out size: 0x%x",
1530                        err, fast_recycled_mode.mgmt_msg_head.status, out_size);
1531                return -EIO;
1532        }
1533
1534        return 0;
1535}
1536
1537int hinic_clear_vport_stats(struct hinic_hwdev *hwdev)
1538{
1539        struct hinic_clear_vport_stats clear_vport_stats;
1540        u16 out_size = sizeof(clear_vport_stats);
1541        int err;
1542
1543        if (!hwdev) {
1544                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1545                return -EINVAL;
1546        }
1547
1548        memset(&clear_vport_stats, 0, sizeof(clear_vport_stats));
1549        clear_vport_stats.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1550        clear_vport_stats.func_id = hinic_global_func_id(hwdev);
1551
1552        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAN_VPORT_STAT,
1553                                     &clear_vport_stats,
1554                                     sizeof(clear_vport_stats),
1555                                     &clear_vport_stats, &out_size);
1556        if (err || !out_size || clear_vport_stats.mgmt_msg_head.status) {
1557                PMD_DRV_LOG(ERR, "Failed to clear vport statistics, err: %d, status: 0x%x, out size: 0x%x",
1558                        err, clear_vport_stats.mgmt_msg_head.status, out_size);
1559                return -EIO;
1560        }
1561
1562        return 0;
1563}
1564
1565int hinic_clear_phy_port_stats(struct hinic_hwdev *hwdev)
1566{
1567        struct hinic_clear_port_stats clear_phy_port_stats;
1568        u16 out_size = sizeof(clear_phy_port_stats);
1569        int err;
1570
1571        if (!hwdev) {
1572                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1573                return -EINVAL;
1574        }
1575
1576        memset(&clear_phy_port_stats, 0, sizeof(clear_phy_port_stats));
1577        clear_phy_port_stats.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1578        clear_phy_port_stats.func_id = hinic_global_func_id(hwdev);
1579
1580        err = l2nic_msg_to_mgmt_sync(hwdev,
1581                                     HINIC_PORT_CMD_CLEAR_PORT_STATISTICS,
1582                                     &clear_phy_port_stats,
1583                                     sizeof(clear_phy_port_stats),
1584                                     &clear_phy_port_stats, &out_size);
1585        if (err || !out_size || clear_phy_port_stats.mgmt_msg_head.status) {
1586                PMD_DRV_LOG(ERR, "Failed to clear phy port statistics, err: %d, status: 0x%x, out size: 0x%x",
1587                        err, clear_phy_port_stats.mgmt_msg_head.status,
1588                        out_size);
1589                return -EIO;
1590        }
1591
1592        return 0;
1593}
1594
1595int hinic_set_link_status_follow(void *hwdev,
1596                                 enum hinic_link_follow_status status)
1597{
1598        struct hinic_set_link_follow follow;
1599        u16 out_size = sizeof(follow);
1600        int err;
1601
1602        if (!hwdev)
1603                return -EINVAL;
1604
1605        if (HINIC_IS_VF((struct hinic_hwdev *)hwdev))
1606                return 0;
1607
1608        if (status >= HINIC_LINK_FOLLOW_STATUS_MAX) {
1609                PMD_DRV_LOG(ERR, "Invalid link follow status: %d", status);
1610                return -EINVAL;
1611        }
1612
1613        memset(&follow, 0, sizeof(follow));
1614        follow.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1615        follow.func_id = hinic_global_func_id(hwdev);
1616        follow.follow_status = status;
1617
1618        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_LINK_FOLLOW,
1619                                     &follow, sizeof(follow),
1620                                     &follow, &out_size);
1621        if ((follow.mgmt_msg_head.status != HINIC_MGMT_CMD_UNSUPPORTED &&
1622             follow.mgmt_msg_head.status) || err || !out_size) {
1623                PMD_DRV_LOG(ERR,
1624                        "Failed to set link status follow phy port status, err: %d, status: 0x%x, out size: 0x%x",
1625                        err, follow.mgmt_msg_head.status, out_size);
1626                return -EIO;
1627        }
1628
1629        return follow.mgmt_msg_head.status;
1630}
1631
1632int hinic_get_link_mode(void *hwdev, u32 *supported, u32 *advertised)
1633{
1634        struct hinic_link_mode_cmd link_mode;
1635        u16 out_size = sizeof(link_mode);
1636        int err;
1637
1638        if (!hwdev || !supported || !advertised)
1639                return -EINVAL;
1640
1641        memset(&link_mode, 0, sizeof(link_mode));
1642        link_mode.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1643        link_mode.func_id = hinic_global_func_id(hwdev);
1644
1645        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
1646                                     &link_mode, sizeof(link_mode),
1647                                     &link_mode, &out_size);
1648        if (err || !out_size || link_mode.mgmt_msg_head.status) {
1649                PMD_DRV_LOG(ERR,
1650                        "Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x",
1651                        err, link_mode.mgmt_msg_head.status, out_size);
1652                return -EIO;
1653        }
1654
1655        *supported = link_mode.supported;
1656        *advertised = link_mode.advertised;
1657
1658        return 0;
1659}
1660
1661/**
1662 * hinic_flush_qp_res - Flush tx && rx chip resources in case of set vport
1663 * fake failed when device start.
1664 *
1665 * @param hwdev
1666 *   The hardware interface of a nic device.
1667 *
1668 * @return
1669 *   0 on success.
1670 *   negative error value otherwise.
1671 */
1672int hinic_flush_qp_res(void *hwdev)
1673{
1674        struct hinic_clear_qp_resource qp_res;
1675        u16 out_size = sizeof(qp_res);
1676        int err;
1677
1678        memset(&qp_res, 0, sizeof(qp_res));
1679        qp_res.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1680        qp_res.func_id = hinic_global_func_id(hwdev);
1681
1682        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAR_QP_RES,
1683                                     &qp_res, sizeof(qp_res), &qp_res,
1684                                     &out_size);
1685        if (err || !out_size || qp_res.mgmt_msg_head.status) {
1686                PMD_DRV_LOG(ERR, "Failed to clear sq resources, err: %d, status: 0x%x, out size: 0x%x",
1687                        err, qp_res.mgmt_msg_head.status, out_size);
1688                return -EIO;
1689        }
1690
1691        return 0;
1692}
1693
1694/**
1695 * hinic_vf_get_default_cos - Get default cos of VF.
1696 *
1697 * @param hwdev
1698 *   The hardware interface of a nic device.
1699 * @param cos_id
1700 *   Cos value.
1701 *
1702 * @return
1703 *   0 on success.
1704 *   negative error value otherwise.
1705 */
1706int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id)
1707{
1708        struct hinic_vf_default_cos vf_cos;
1709        u16 out_size = sizeof(vf_cos);
1710        int err;
1711
1712        memset(&vf_cos, 0, sizeof(vf_cos));
1713        vf_cos.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1714
1715        err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
1716                                     HINIC_PORT_CMD_GET_VF_COS, &vf_cos,
1717                                     sizeof(vf_cos), &vf_cos, &out_size, 0);
1718        if (err || !out_size || vf_cos.mgmt_msg_head.status) {
1719                PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d, status: 0x%x, out size: 0x%x",
1720                        err, vf_cos.mgmt_msg_head.status, out_size);
1721                return -EIO;
1722        }
1723        *cos_id = vf_cos.state.default_cos;
1724
1725        return 0;
1726}
1727
1728/**
1729 * hinic_set_fdir_filter - Set fdir filter for control path
1730 * packet to notify firmware.
1731 *
1732 * @param hwdev
1733 *   The hardware interface of a nic device.
1734 * @param filter_type
1735 *   Packet type to filter.
1736 * @param qid
1737 *   Rx qid to filter.
1738 * @param type_enable
1739 *   The status of pkt type filter.
1740 * @param enable
1741 *   Fdir function Enable or Disable.
1742 * @return
1743 *   0 on success,
1744 *   negative error value otherwise.
1745 */
1746int hinic_set_fdir_filter(void *hwdev, u8 filter_type, u8 qid, u8 type_enable,
1747                          bool enable)
1748{
1749        struct hinic_port_qfilter_info port_filer_cmd;
1750        u16 out_size = sizeof(port_filer_cmd);
1751        int err;
1752
1753        if (!hwdev)
1754                return -EINVAL;
1755
1756        memset(&port_filer_cmd, 0, sizeof(port_filer_cmd));
1757        port_filer_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1758        port_filer_cmd.func_id = hinic_global_func_id(hwdev);
1759        port_filer_cmd.filter_enable = (u8)enable;
1760        port_filer_cmd.filter_type = filter_type;
1761        port_filer_cmd.qid = qid;
1762        port_filer_cmd.filter_type_enable = type_enable;
1763        port_filer_cmd.fdir_flag = 0;
1764
1765        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_Q_FILTER,
1766                        &port_filer_cmd, sizeof(port_filer_cmd),
1767                        &port_filer_cmd, &out_size);
1768        if (err || !out_size || port_filer_cmd.mgmt_msg_head.status) {
1769                PMD_DRV_LOG(ERR, "Set port Q filter failed, err: %d, status: 0x%x, out size: 0x%x, type: 0x%x,"
1770                        " enable: 0x%x, qid: 0x%x, filter_type_enable: 0x%x\n",
1771                        err, port_filer_cmd.mgmt_msg_head.status, out_size,
1772                        filter_type, enable, qid, type_enable);
1773                return -EIO;
1774        }
1775
1776        return 0;
1777}
1778
1779/**
1780 * hinic_set_normal_filter - Set fdir filter for IO path packet.
1781 *
1782 * @param hwdev
1783 *   The hardware interface of a nic device.
1784 * @param qid
1785 *   Rx qid to filter.
1786 * @param normal_type_enable
1787 *   IO path packet function Enable or Disable
1788 * @param key
1789 *   IO path packet filter key value, such as DIP from pkt.
1790 * @param enable
1791 *   Fdir function Enable or Disable.
1792 * @param flag
1793 *   Filter flag, such as dip or others.
1794 * @return
1795 *   0 on success,
1796 *   negative error value otherwise.
1797 */
1798int hinic_set_normal_filter(void *hwdev, u8 qid, u8 normal_type_enable,
1799                                u32 key, bool enable, u8 flag)
1800{
1801        struct hinic_port_qfilter_info port_filer_cmd;
1802        u16 out_size = sizeof(port_filer_cmd);
1803        int err;
1804
1805        if (!hwdev)
1806                return -EINVAL;
1807
1808        memset(&port_filer_cmd, 0, sizeof(port_filer_cmd));
1809        port_filer_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1810        port_filer_cmd.func_id = hinic_global_func_id(hwdev);
1811        port_filer_cmd.filter_enable = (u8)enable;
1812        port_filer_cmd.qid = qid;
1813        port_filer_cmd.normal_type_enable = normal_type_enable;
1814        port_filer_cmd.fdir_flag = flag; /* fdir flag: support dip */
1815        port_filer_cmd.key = key;
1816
1817        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_Q_FILTER,
1818                        &port_filer_cmd, sizeof(port_filer_cmd),
1819                        &port_filer_cmd, &out_size);
1820        if (err || !out_size || port_filer_cmd.mgmt_msg_head.status) {
1821                PMD_DRV_LOG(ERR, "Set normal filter failed, err: %d, status: 0x%x, out size: 0x%x, fdir_flag: 0x%x,"
1822                        " enable: 0x%x, qid: 0x%x, normal_type_enable: 0x%x, key:0x%x\n",
1823                        err, port_filer_cmd.mgmt_msg_head.status, out_size,
1824                        flag, enable, qid, normal_type_enable, key);
1825                return -EIO;
1826        }
1827
1828        return 0;
1829}
1830
1831/**
1832 * hinic_set_fdir_tcam - Set fdir filter for control packet
1833 * by tcam table to notify hardware.
1834 *
1835 * @param hwdev
1836 *   The hardware interface of a nic device.
1837 * @param type_mask
1838 *   Index of TCAM.
1839 * @param filter_rule
1840 *   TCAM rule for control packet, such as lacp or bgp.
1841 * @param filter_action
1842 *   TCAM action for control packet, such as accept or drop.
1843 * @return
1844 *   0 on success,
1845 *   negative error value otherwise.
1846 */
1847int hinic_set_fdir_tcam(void *hwdev, u16 type_mask,
1848                        struct tag_pa_rule *filter_rule,
1849                        struct tag_pa_action *filter_action)
1850{
1851        struct hinic_fdir_tcam_info port_tcam_cmd;
1852        u16 out_size = sizeof(port_tcam_cmd);
1853        int err;
1854
1855        if (!hwdev)
1856                return -EINVAL;
1857
1858        memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
1859        port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1860        port_tcam_cmd.tcam_index = type_mask;
1861        port_tcam_cmd.flag = TCAM_SET;
1862        memcpy((void *)&port_tcam_cmd.filter_rule,
1863                (void *)filter_rule, sizeof(struct tag_pa_rule));
1864        memcpy((void *)&port_tcam_cmd.filter_action,
1865                (void *)filter_action, sizeof(struct tag_pa_action));
1866
1867        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_TCAM_FILTER,
1868                        &port_tcam_cmd, sizeof(port_tcam_cmd),
1869                        &port_tcam_cmd, &out_size);
1870        if (err || !out_size || port_tcam_cmd.mgmt_msg_head.status) {
1871                PMD_DRV_LOG(ERR, "Set tcam table failed, err: %d, status: 0x%x, out size: 0x%x",
1872                        err, port_tcam_cmd.mgmt_msg_head.status, out_size);
1873                return -EIO;
1874        }
1875
1876        return 0;
1877}
1878
1879/**
1880 * hinic_clear_fdir_tcam - Clear fdir filter TCAM table for control packet.
1881 *
1882 * @param hwdev
1883 *   The hardware interface of a nic device.
1884 * @param type_mask
1885 *   Index of TCAM.
1886 * @return
1887 *   0 on success,
1888 *   negative error value otherwise.
1889 */
1890int hinic_clear_fdir_tcam(void *hwdev, u16 type_mask)
1891{
1892        struct hinic_fdir_tcam_info port_tcam_cmd;
1893        u16 out_size = sizeof(port_tcam_cmd);
1894        int err;
1895
1896        if (!hwdev)
1897                return -EINVAL;
1898
1899        memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
1900        port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1901        port_tcam_cmd.tcam_index = type_mask;
1902        port_tcam_cmd.flag = TCAM_CLEAR;
1903
1904        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_TCAM_FILTER,
1905                        &port_tcam_cmd, sizeof(port_tcam_cmd),
1906                        &port_tcam_cmd, &out_size);
1907        if (err || !out_size || port_tcam_cmd.mgmt_msg_head.status) {
1908                PMD_DRV_LOG(ERR, "Clear tcam table failed, err: %d, status: 0x%x, out size: 0x%x",
1909                        err, port_tcam_cmd.mgmt_msg_head.status, out_size);
1910                return -EIO;
1911        }
1912
1913        return 0;
1914}
1915
1916int hinic_add_tcam_rule(void *hwdev, struct tag_tcam_cfg_rule *tcam_rule)
1917{
1918        u16 out_size = sizeof(struct tag_fdir_add_rule_cmd);
1919        struct tag_fdir_add_rule_cmd tcam_cmd;
1920        int err;
1921
1922        if (!hwdev) {
1923                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1924                return -EINVAL;
1925        }
1926
1927        if (tcam_rule->index >= HINIC_MAX_TCAM_RULES_NUM) {
1928                PMD_DRV_LOG(ERR, "Tcam rules num to add is invalid");
1929                return -EINVAL;
1930        }
1931
1932        memset(&tcam_cmd, 0, sizeof(struct tag_fdir_add_rule_cmd));
1933        tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1934        memcpy((void *)&tcam_cmd.rule, (void *)tcam_rule,
1935                sizeof(struct tag_tcam_cfg_rule));
1936
1937        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_ADD_FLOW,
1938                                &tcam_cmd, sizeof(tcam_cmd),
1939                                &tcam_cmd, &out_size);
1940        if (err || tcam_cmd.mgmt_msg_head.status || !out_size) {
1941                PMD_DRV_LOG(ERR,
1942                        "Add tcam rule failed, err: %d, status: 0x%x, out size: 0x%x",
1943                        err, tcam_cmd.mgmt_msg_head.status, out_size);
1944                return -EIO;
1945        }
1946
1947        return 0;
1948}
1949
1950int hinic_del_tcam_rule(void *hwdev, u32 index)
1951{
1952        u16 out_size = sizeof(struct tag_fdir_del_rule_cmd);
1953        struct tag_fdir_del_rule_cmd tcam_cmd;
1954        int err;
1955
1956        if (!hwdev) {
1957                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1958                return -EINVAL;
1959        }
1960
1961        if (index >= HINIC_MAX_TCAM_RULES_NUM) {
1962                PMD_DRV_LOG(ERR, "Tcam rules num to del is invalid");
1963                return -EINVAL;
1964        }
1965
1966        memset(&tcam_cmd, 0, sizeof(struct tag_fdir_del_rule_cmd));
1967        tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1968        tcam_cmd.index_start = index;
1969        tcam_cmd.index_num = 1;
1970
1971        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_DEL_FLOW,
1972                                &tcam_cmd, sizeof(tcam_cmd),
1973                                &tcam_cmd, &out_size);
1974        if (err || tcam_cmd.mgmt_msg_head.status || !out_size) {
1975                PMD_DRV_LOG(ERR,
1976                        "Del tcam rule failed, err: %d, status: 0x%x, out size: 0x%x",
1977                        err, tcam_cmd.mgmt_msg_head.status, out_size);
1978                return -EIO;
1979        }
1980
1981        return 0;
1982}
1983
1984static int hinic_mgmt_tcam_block(void *hwdev, u8 alloc_en,
1985                                u8 block_type, u16 *index)
1986{
1987        struct hinic_cmd_ctrl_tcam_block tcam_block_info;
1988        u16 out_size = sizeof(struct hinic_cmd_ctrl_tcam_block);
1989        struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
1990        int err;
1991
1992        if (!hwdev) {
1993                PMD_DRV_LOG(ERR, "Hwdev is NULL");
1994                return -EINVAL;
1995        }
1996
1997        memset(&tcam_block_info, 0, sizeof(struct hinic_cmd_ctrl_tcam_block));
1998        tcam_block_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1999        tcam_block_info.func_id = hinic_global_func_id(hwdev);
2000        tcam_block_info.alloc_en = alloc_en;
2001        tcam_block_info.tcam_type = block_type;
2002        tcam_block_info.tcam_block_index = *index;
2003
2004        err = l2nic_msg_to_mgmt_sync(hwdev,
2005                                HINIC_PORT_CMD_UP_TC_CTRL_TCAM_BLOCK,
2006                                &tcam_block_info, sizeof(tcam_block_info),
2007                                &tcam_block_info, &out_size);
2008        if (tcam_block_info.mgmt_msg_head.status ==
2009                HINIC_MGMT_CMD_UNSUPPORTED) {
2010                err = HINIC_MGMT_CMD_UNSUPPORTED;
2011                PMD_DRV_LOG(INFO, "Firmware/uP doesn't support alloc or del tcam block");
2012                return err;
2013        } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
2014                        (HINIC_IS_VF(nic_hwdev))) {
2015                err = HINIC_MGMT_CMD_UNSUPPORTED;
2016                PMD_DRV_LOG(INFO, "VF doesn't support alloc and del tcam block.");
2017                return err;
2018        } else if (err || (!out_size) || tcam_block_info.mgmt_msg_head.status) {
2019                PMD_DRV_LOG(ERR,
2020                        "Set tcam block failed, err: %d, status: 0x%x, out size: 0x%x",
2021                        err, tcam_block_info.mgmt_msg_head.status, out_size);
2022                return -EIO;
2023        }
2024
2025        if (alloc_en)
2026                *index = tcam_block_info.tcam_block_index;
2027
2028        return 0;
2029}
2030
2031int hinic_alloc_tcam_block(void *hwdev, u8 block_type, u16 *index)
2032{
2033        return hinic_mgmt_tcam_block(hwdev, HINIC_TCAM_BLOCK_ENABLE,
2034                                block_type, index);
2035}
2036
2037int hinic_free_tcam_block(void *hwdev, u8 block_type, u16 *index)
2038{
2039        return hinic_mgmt_tcam_block(hwdev, HINIC_TCAM_BLOCK_DISABLE,
2040                                block_type, index);
2041}
2042
2043int hinic_flush_tcam_rule(void *hwdev)
2044{
2045        struct hinic_cmd_flush_tcam_rules tcam_flush;
2046        u16 out_size = sizeof(struct hinic_cmd_flush_tcam_rules);
2047        struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
2048        int err;
2049
2050        if (!hwdev) {
2051                PMD_DRV_LOG(ERR, "Hwdev is NULL");
2052                return -EINVAL;
2053        }
2054
2055        memset(&tcam_flush, 0, sizeof(struct hinic_cmd_flush_tcam_rules));
2056        tcam_flush.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
2057        tcam_flush.func_id = hinic_global_func_id(hwdev);
2058
2059        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_FLUSH_TCAM,
2060                        &tcam_flush, sizeof(struct hinic_cmd_flush_tcam_rules),
2061                        &tcam_flush, &out_size);
2062        if (tcam_flush.mgmt_msg_head.status == HINIC_MGMT_CMD_UNSUPPORTED) {
2063                err = HINIC_MGMT_CMD_UNSUPPORTED;
2064                PMD_DRV_LOG(INFO, "Firmware/uP doesn't support flush tcam fdir");
2065        } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
2066                        (HINIC_IS_VF(nic_hwdev))) {
2067                err = HINIC_MGMT_CMD_UNSUPPORTED;
2068                PMD_DRV_LOG(INFO, "VF doesn't support flush tcam fdir");
2069        } else if (err || (!out_size) || tcam_flush.mgmt_msg_head.status) {
2070                PMD_DRV_LOG(ERR,
2071                        "Flush tcam fdir rules failed, err: %d, status: 0x%x, out size: 0x%x",
2072                        err, tcam_flush.mgmt_msg_head.status, out_size);
2073                err = -EIO;
2074        }
2075
2076        return err;
2077}
2078
2079int hinic_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
2080{
2081        struct hinic_port_tcam_info port_tcam_cmd;
2082        u16 out_size = sizeof(port_tcam_cmd);
2083        int err;
2084
2085        if (!hwdev)
2086                return -EINVAL;
2087
2088        memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
2089        port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
2090        port_tcam_cmd.func_id = hinic_global_func_id(hwdev);
2091        port_tcam_cmd.tcam_enable = (u8)enable;
2092
2093        err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_ENABLE,
2094                        &port_tcam_cmd, sizeof(port_tcam_cmd),
2095                        &port_tcam_cmd, &out_size);
2096        if ((port_tcam_cmd.mgmt_msg_head.status != HINIC_MGMT_CMD_UNSUPPORTED &&
2097                port_tcam_cmd.mgmt_msg_head.status) || err || !out_size) {
2098                if (err == HINIC_MBOX_VF_CMD_ERROR &&
2099                        HINIC_IS_VF((struct hinic_hwdev *)hwdev)) {
2100                        err = HINIC_MGMT_CMD_UNSUPPORTED;
2101                        PMD_DRV_LOG(WARNING, "VF doesn't support setting fdir tcam filter");
2102                        return err;
2103                }
2104                PMD_DRV_LOG(ERR, "Set fdir tcam filter failed, err: %d, "
2105                        "status: 0x%x, out size: 0x%x, enable: 0x%x",
2106                        err, port_tcam_cmd.mgmt_msg_head.status, out_size,
2107                        enable);
2108                return -EIO;
2109        }
2110
2111        if (port_tcam_cmd.mgmt_msg_head.status == HINIC_MGMT_CMD_UNSUPPORTED) {
2112                err = HINIC_MGMT_CMD_UNSUPPORTED;
2113                PMD_DRV_LOG(WARNING, "Fw doesn't support setting fdir tcam filter");
2114        }
2115
2116        return err;
2117}
2118
2119
2120