linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
<<
>>
Prefs
   1/*
   2 * QLogic qlcnic NIC Driver
   3 * Copyright (c) 2009-2013 QLogic Corporation
   4 *
   5 * See LICENSE.qlcnic for copyright and licensing details.
   6 */
   7
   8#include "qlcnic_sriov.h"
   9#include "qlcnic.h"
  10#include <linux/types.h>
  11
  12#define QLCNIC_SRIOV_VF_MAX_MAC 1
  13#define QLC_VF_MIN_TX_RATE      100
  14#define QLC_VF_MAX_TX_RATE      9999
  15
  16static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8);
  17
  18struct qlcnic_sriov_cmd_handler {
  19        int (*fn) (struct qlcnic_bc_trans *, struct qlcnic_cmd_args *);
  20};
  21
  22struct qlcnic_sriov_fw_cmd_handler {
  23        u32 cmd;
  24        int (*fn) (struct qlcnic_bc_trans *, struct qlcnic_cmd_args *);
  25};
  26
  27static int qlcnic_sriov_pf_set_vport_info(struct qlcnic_adapter *adapter,
  28                                          struct qlcnic_info *npar_info,
  29                                          u16 vport_id)
  30{
  31        struct qlcnic_cmd_args cmd;
  32        int err;
  33
  34        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO))
  35                return -ENOMEM;
  36
  37        cmd.req.arg[1] = (vport_id << 16) | 0x1;
  38        cmd.req.arg[2] = npar_info->bit_offsets;
  39        cmd.req.arg[2] |= npar_info->min_tx_bw << 16;
  40        cmd.req.arg[3] = npar_info->max_tx_bw | (npar_info->max_tx_ques << 16);
  41        cmd.req.arg[4] = npar_info->max_tx_mac_filters;
  42        cmd.req.arg[4] |= npar_info->max_rx_mcast_mac_filters << 16;
  43        cmd.req.arg[5] = npar_info->max_rx_ucast_mac_filters |
  44                         (npar_info->max_rx_ip_addr << 16);
  45        cmd.req.arg[6] = npar_info->max_rx_lro_flow |
  46                         (npar_info->max_rx_status_rings << 16);
  47        cmd.req.arg[7] = npar_info->max_rx_buf_rings |
  48                         (npar_info->max_rx_ques << 16);
  49        cmd.req.arg[8] = npar_info->max_tx_vlan_keys;
  50        cmd.req.arg[8] |= npar_info->max_local_ipv6_addrs << 16;
  51        cmd.req.arg[9] = npar_info->max_remote_ipv6_addrs;
  52
  53        err = qlcnic_issue_cmd(adapter, &cmd);
  54        if (err)
  55                dev_err(&adapter->pdev->dev,
  56                        "Failed to set vport info, err=%d\n", err);
  57
  58        qlcnic_free_mbx_args(&cmd);
  59        return err;
  60}
  61
  62static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter,
  63                                         struct qlcnic_info *info, u16 func)
  64{
  65        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
  66        struct qlcnic_resources *res = &sriov->ff_max;
  67        u32 temp, num_vf_macs, num_vfs, max;
  68        int ret = -EIO, vpid, id;
  69        struct qlcnic_vport *vp;
  70
  71        vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
  72        if (vpid < 0)
  73                return -EINVAL;
  74
  75        num_vfs = sriov->num_vfs;
  76        max = num_vfs + 1;
  77        info->bit_offsets = 0xffff;
  78        info->max_tx_ques = res->num_tx_queues / max;
  79        info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters;
  80        num_vf_macs = QLCNIC_SRIOV_VF_MAX_MAC;
  81
  82        if (adapter->ahw->pci_func == func) {
  83                temp = res->num_rx_mcast_mac_filters - (num_vfs * num_vf_macs);
  84                info->max_rx_ucast_mac_filters = temp;
  85                temp = res->num_tx_mac_filters - (num_vfs * num_vf_macs);
  86                info->max_tx_mac_filters = temp;
  87                info->min_tx_bw = 0;
  88                info->max_tx_bw = MAX_BW;
  89        } else {
  90                id = qlcnic_sriov_func_to_index(adapter, func);
  91                if (id < 0)
  92                        return id;
  93                vp = sriov->vf_info[id].vp;
  94                info->min_tx_bw = vp->min_tx_bw;
  95                info->max_tx_bw = vp->max_tx_bw;
  96                info->max_rx_ucast_mac_filters = num_vf_macs;
  97                info->max_tx_mac_filters = num_vf_macs;
  98        }
  99
 100        info->max_rx_ip_addr = res->num_destip / max;
 101        info->max_rx_status_rings = res->num_rx_status_rings / max;
 102        info->max_rx_buf_rings = res->num_rx_buf_rings / max;
 103        info->max_rx_ques = res->num_rx_queues / max;
 104        info->max_rx_lro_flow = res->num_lro_flows_supported / max;
 105        info->max_tx_vlan_keys = res->num_txvlan_keys;
 106        info->max_local_ipv6_addrs = res->max_local_ipv6_addrs;
 107        info->max_remote_ipv6_addrs = res->max_remote_ipv6_addrs;
 108
 109        ret = qlcnic_sriov_pf_set_vport_info(adapter, info, vpid);
 110        if (ret)
 111                return ret;
 112
 113        return 0;
 114}
 115
 116static void qlcnic_sriov_pf_set_ff_max_res(struct qlcnic_adapter *adapter,
 117                                           struct qlcnic_info *info)
 118{
 119        struct qlcnic_resources *ff_max = &adapter->ahw->sriov->ff_max;
 120
 121        ff_max->num_tx_mac_filters = info->max_tx_mac_filters;
 122        ff_max->num_rx_ucast_mac_filters = info->max_rx_ucast_mac_filters;
 123        ff_max->num_rx_mcast_mac_filters = info->max_rx_mcast_mac_filters;
 124        ff_max->num_txvlan_keys = info->max_tx_vlan_keys;
 125        ff_max->num_rx_queues = info->max_rx_ques;
 126        ff_max->num_tx_queues = info->max_tx_ques;
 127        ff_max->num_lro_flows_supported = info->max_rx_lro_flow;
 128        ff_max->num_destip = info->max_rx_ip_addr;
 129        ff_max->num_rx_buf_rings = info->max_rx_buf_rings;
 130        ff_max->num_rx_status_rings = info->max_rx_status_rings;
 131        ff_max->max_remote_ipv6_addrs = info->max_remote_ipv6_addrs;
 132        ff_max->max_local_ipv6_addrs = info->max_local_ipv6_addrs;
 133}
 134
 135static int qlcnic_sriov_get_pf_info(struct qlcnic_adapter *adapter,
 136                                    struct qlcnic_info *npar_info)
 137{
 138        int err;
 139        struct qlcnic_cmd_args cmd;
 140
 141        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO))
 142                return -ENOMEM;
 143
 144        cmd.req.arg[1] = 0x2;
 145        err = qlcnic_issue_cmd(adapter, &cmd);
 146        if (err) {
 147                dev_err(&adapter->pdev->dev,
 148                        "Failed to get PF info, err=%d\n", err);
 149                goto out;
 150        }
 151
 152        npar_info->total_pf = cmd.rsp.arg[2] & 0xff;
 153        npar_info->total_rss_engines = (cmd.rsp.arg[2] >> 8) & 0xff;
 154        npar_info->max_vports = MSW(cmd.rsp.arg[2]);
 155        npar_info->max_tx_ques =  LSW(cmd.rsp.arg[3]);
 156        npar_info->max_tx_mac_filters = MSW(cmd.rsp.arg[3]);
 157        npar_info->max_rx_mcast_mac_filters = LSW(cmd.rsp.arg[4]);
 158        npar_info->max_rx_ucast_mac_filters = MSW(cmd.rsp.arg[4]);
 159        npar_info->max_rx_ip_addr = LSW(cmd.rsp.arg[5]);
 160        npar_info->max_rx_lro_flow = MSW(cmd.rsp.arg[5]);
 161        npar_info->max_rx_status_rings = LSW(cmd.rsp.arg[6]);
 162        npar_info->max_rx_buf_rings = MSW(cmd.rsp.arg[6]);
 163        npar_info->max_rx_ques = LSW(cmd.rsp.arg[7]);
 164        npar_info->max_tx_vlan_keys = MSW(cmd.rsp.arg[7]);
 165        npar_info->max_local_ipv6_addrs = LSW(cmd.rsp.arg[8]);
 166        npar_info->max_remote_ipv6_addrs = MSW(cmd.rsp.arg[8]);
 167
 168        qlcnic_sriov_pf_set_ff_max_res(adapter, npar_info);
 169        dev_info(&adapter->pdev->dev,
 170                 "\n\ttotal_pf: %d,\n"
 171                 "\n\ttotal_rss_engines: %d max_vports: %d max_tx_ques %d,\n"
 172                 "\tmax_tx_mac_filters: %d max_rx_mcast_mac_filters: %d,\n"
 173                 "\tmax_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d,\n"
 174                 "\tmax_rx_lro_flow: %d max_rx_status_rings: %d,\n"
 175                 "\tmax_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d\n"
 176                 "\tmax_local_ipv6_addrs: %d, max_remote_ipv6_addrs: %d\n",
 177                 npar_info->total_pf, npar_info->total_rss_engines,
 178                 npar_info->max_vports, npar_info->max_tx_ques,
 179                 npar_info->max_tx_mac_filters,
 180                 npar_info->max_rx_mcast_mac_filters,
 181                 npar_info->max_rx_ucast_mac_filters, npar_info->max_rx_ip_addr,
 182                 npar_info->max_rx_lro_flow, npar_info->max_rx_status_rings,
 183                 npar_info->max_rx_buf_rings, npar_info->max_rx_ques,
 184                 npar_info->max_tx_vlan_keys, npar_info->max_local_ipv6_addrs,
 185                 npar_info->max_remote_ipv6_addrs);
 186
 187out:
 188        qlcnic_free_mbx_args(&cmd);
 189        return err;
 190}
 191
 192static void qlcnic_sriov_pf_reset_vport_handle(struct qlcnic_adapter *adapter,
 193                                               u8 func)
 194{
 195        struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
 196        struct qlcnic_vport *vp;
 197        int index;
 198
 199        if (adapter->ahw->pci_func == func) {
 200                sriov->vp_handle = 0;
 201        } else {
 202                index = qlcnic_sriov_func_to_index(adapter, func);
 203                if (index < 0)
 204                        return;
 205                vp = sriov->vf_info[index].vp;
 206                vp->handle = 0;
 207        }
 208}
 209
 210static void qlcnic_sriov_pf_set_vport_handle(struct qlcnic_adapter *adapter,
 211                                             u16 vport_handle, u8 func)
 212{
 213        struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
 214        struct qlcnic_vport *vp;
 215        int index;
 216
 217        if (adapter->ahw->pci_func == func) {
 218                sriov->vp_handle = vport_handle;
 219        } else {
 220                index = qlcnic_sriov_func_to_index(adapter, func);
 221                if (index < 0)
 222                        return;
 223                vp = sriov->vf_info[index].vp;
 224                vp->handle = vport_handle;
 225        }
 226}
 227
 228static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *adapter,
 229                                            u8 func)
 230{
 231        struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
 232        struct qlcnic_vf_info *vf_info;
 233        int index;
 234
 235        if (adapter->ahw->pci_func == func) {
 236                return sriov->vp_handle;
 237        } else {
 238                index = qlcnic_sriov_func_to_index(adapter, func);
 239                if (index >= 0) {
 240                        vf_info = &sriov->vf_info[index];
 241                        return vf_info->vp->handle;
 242                }
 243        }
 244
 245        return -EINVAL;
 246}
 247
 248static int qlcnic_sriov_pf_config_vport(struct qlcnic_adapter *adapter,
 249                                        u8 flag, u16 func)
 250{
 251        struct qlcnic_cmd_args cmd;
 252        int ret;
 253        int vpid;
 254
 255        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_VPORT))
 256                return -ENOMEM;
 257
 258        if (flag) {
 259                cmd.req.arg[3] = func << 8;
 260        } else {
 261                vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
 262                if (vpid < 0) {
 263                        ret = -EINVAL;
 264                        goto out;
 265                }
 266                cmd.req.arg[3] = ((vpid & 0xffff) << 8) | 1;
 267        }
 268
 269        ret = qlcnic_issue_cmd(adapter, &cmd);
 270        if (ret) {
 271                dev_err(&adapter->pdev->dev,
 272                        "Failed %s vport, err %d for func 0x%x\n",
 273                        (flag ? "enable" : "disable"), ret, func);
 274                goto out;
 275        }
 276
 277        if (flag) {
 278                vpid = cmd.rsp.arg[2] & 0xffff;
 279                qlcnic_sriov_pf_set_vport_handle(adapter, vpid, func);
 280        } else {
 281                qlcnic_sriov_pf_reset_vport_handle(adapter, func);
 282        }
 283
 284out:
 285        qlcnic_free_mbx_args(&cmd);
 286        return ret;
 287}
 288
 289static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter,
 290                                              u8 enable)
 291{
 292        struct qlcnic_cmd_args cmd;
 293        int err;
 294
 295        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
 296        if (err)
 297                return err;
 298
 299        cmd.req.arg[1] = 0x4;
 300        if (enable)
 301                cmd.req.arg[1] |= BIT_16;
 302
 303        err = qlcnic_issue_cmd(adapter, &cmd);
 304        if (err)
 305                dev_err(&adapter->pdev->dev,
 306                        "Failed to configure VLAN filtering, err=%d\n", err);
 307
 308        qlcnic_free_mbx_args(&cmd);
 309        return err;
 310}
 311
 312static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter,
 313                                       u8 func, u8 enable)
 314{
 315        struct qlcnic_cmd_args cmd;
 316        int err = -EIO;
 317
 318        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH))
 319                return -ENOMEM;
 320
 321        cmd.req.arg[0] |= (3 << 29);
 322        cmd.req.arg[1] = ((func & 0xf) << 2) | BIT_6 | BIT_1;
 323        if (enable)
 324                cmd.req.arg[1] |= BIT_0;
 325
 326        err = qlcnic_issue_cmd(adapter, &cmd);
 327
 328        if (err != QLCNIC_RCODE_SUCCESS) {
 329                dev_err(&adapter->pdev->dev,
 330                        "Failed to enable sriov eswitch%d\n", err);
 331                err = -EIO;
 332        }
 333
 334        qlcnic_free_mbx_args(&cmd);
 335        return err;
 336}
 337
 338static void qlcnic_sriov_pf_del_flr_queue(struct qlcnic_adapter *adapter)
 339{
 340        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
 341        struct qlcnic_back_channel *bc = &sriov->bc;
 342        int i;
 343
 344        for (i = 0; i < sriov->num_vfs; i++)
 345                cancel_work_sync(&sriov->vf_info[i].flr_work);
 346
 347        destroy_workqueue(bc->bc_flr_wq);
 348}
 349
 350static int qlcnic_sriov_pf_create_flr_queue(struct qlcnic_adapter *adapter)
 351{
 352        struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc;
 353        struct workqueue_struct *wq;
 354
 355        wq = create_singlethread_workqueue("qlcnic-flr");
 356        if (wq == NULL) {
 357                dev_err(&adapter->pdev->dev, "Cannot create FLR workqueue\n");
 358                return -ENOMEM;
 359        }
 360
 361        bc->bc_flr_wq =  wq;
 362        return 0;
 363}
 364
 365void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter)
 366{
 367        u8 func = adapter->ahw->pci_func;
 368
 369        if (!qlcnic_sriov_enable_check(adapter))
 370                return;
 371
 372        qlcnic_sriov_pf_del_flr_queue(adapter);
 373        qlcnic_sriov_cfg_bc_intr(adapter, 0);
 374        qlcnic_sriov_pf_config_vport(adapter, 0, func);
 375        qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
 376        qlcnic_sriov_pf_cfg_vlan_filtering(adapter, 0);
 377        __qlcnic_sriov_cleanup(adapter);
 378        adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
 379        clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
 380}
 381
 382void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter)
 383{
 384        if (!qlcnic_sriov_pf_check(adapter))
 385                return;
 386
 387        if (!qlcnic_sriov_enable_check(adapter))
 388                return;
 389
 390        pci_disable_sriov(adapter->pdev);
 391        netdev_info(adapter->netdev,
 392                    "SR-IOV is disabled successfully on port %d\n",
 393                    adapter->portnum);
 394}
 395
 396static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter)
 397{
 398        struct net_device *netdev = adapter->netdev;
 399
 400        rtnl_lock();
 401        if (netif_running(netdev))
 402                __qlcnic_down(adapter, netdev);
 403
 404        qlcnic_sriov_pf_disable(adapter);
 405
 406        qlcnic_sriov_pf_cleanup(adapter);
 407
 408        /* After disabling SRIOV re-init the driver in default mode
 409           configure opmode based on op_mode of function
 410         */
 411        if (qlcnic_83xx_configure_opmode(adapter)) {
 412                rtnl_unlock();
 413                return -EIO;
 414        }
 415
 416        if (netif_running(netdev))
 417                __qlcnic_up(adapter, netdev);
 418
 419        rtnl_unlock();
 420        return 0;
 421}
 422
 423static int qlcnic_sriov_pf_init(struct qlcnic_adapter *adapter)
 424{
 425        struct qlcnic_hardware_context *ahw = adapter->ahw;
 426        struct qlcnic_info nic_info, pf_info, vp_info;
 427        int err;
 428        u8 func = ahw->pci_func;
 429
 430        if (!qlcnic_sriov_enable_check(adapter))
 431                return 0;
 432
 433        err = qlcnic_sriov_pf_cfg_vlan_filtering(adapter, 1);
 434        if (err)
 435                return err;
 436
 437        err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1);
 438        if (err)
 439                goto disable_vlan_filtering;
 440
 441        err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
 442        if (err)
 443                goto disable_eswitch;
 444
 445        err = qlcnic_sriov_get_pf_info(adapter, &pf_info);
 446        if (err)
 447                goto delete_vport;
 448
 449        err = qlcnic_get_nic_info(adapter, &nic_info, func);
 450        if (err)
 451                goto delete_vport;
 452
 453        err = qlcnic_sriov_pf_cal_res_limit(adapter, &vp_info, func);
 454        if (err)
 455                goto delete_vport;
 456
 457        err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
 458        if (err)
 459                goto delete_vport;
 460
 461        ahw->physical_port = (u8) nic_info.phys_port;
 462        ahw->switch_mode = nic_info.switch_mode;
 463        ahw->max_mtu = nic_info.max_mtu;
 464        ahw->capabilities = nic_info.capabilities;
 465        ahw->nic_mode = QLC_83XX_SRIOV_MODE;
 466        return err;
 467
 468delete_vport:
 469        qlcnic_sriov_pf_config_vport(adapter, 0, func);
 470
 471disable_eswitch:
 472        qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
 473
 474disable_vlan_filtering:
 475        qlcnic_sriov_pf_cfg_vlan_filtering(adapter, 0);
 476
 477        return err;
 478}
 479
 480static int qlcnic_sriov_pf_enable(struct qlcnic_adapter *adapter, int num_vfs)
 481{
 482        int err;
 483
 484        if (!qlcnic_sriov_enable_check(adapter))
 485                return 0;
 486
 487        err = pci_enable_sriov(adapter->pdev, num_vfs);
 488        if (err)
 489                qlcnic_sriov_pf_cleanup(adapter);
 490
 491        return err;
 492}
 493
 494static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter,
 495                                     int num_vfs)
 496{
 497        int err = 0;
 498
 499        set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
 500        adapter->ahw->op_mode = QLCNIC_SRIOV_PF_FUNC;
 501
 502        err = qlcnic_sriov_init(adapter, num_vfs);
 503        if (err)
 504                goto clear_op_mode;
 505
 506        err = qlcnic_sriov_pf_create_flr_queue(adapter);
 507        if (err)
 508                goto sriov_cleanup;
 509
 510        err = qlcnic_sriov_pf_init(adapter);
 511        if (err)
 512                goto del_flr_queue;
 513
 514        err = qlcnic_sriov_pf_enable(adapter, num_vfs);
 515        return err;
 516
 517del_flr_queue:
 518        qlcnic_sriov_pf_del_flr_queue(adapter);
 519
 520sriov_cleanup:
 521        __qlcnic_sriov_cleanup(adapter);
 522
 523clear_op_mode:
 524        clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
 525        adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
 526        return err;
 527}
 528
 529static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs)
 530{
 531        struct net_device *netdev = adapter->netdev;
 532        int err;
 533
 534        if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
 535                netdev_err(netdev,
 536                           "SR-IOV cannot be enabled, when legacy interrupts are enabled\n");
 537                return -EIO;
 538        }
 539
 540        rtnl_lock();
 541        if (netif_running(netdev))
 542                __qlcnic_down(adapter, netdev);
 543
 544        err = __qlcnic_pci_sriov_enable(adapter, num_vfs);
 545        if (err) {
 546                netdev_info(netdev, "Failed to enable SR-IOV on port %d\n",
 547                            adapter->portnum);
 548
 549                err = -EIO;
 550                if (qlcnic_83xx_configure_opmode(adapter))
 551                        goto error;
 552        } else {
 553                netdev_info(netdev,
 554                            "SR-IOV is enabled successfully on port %d\n",
 555                            adapter->portnum);
 556                /* Return number of vfs enabled */
 557                err = num_vfs;
 558        }
 559        if (netif_running(netdev))
 560                __qlcnic_up(adapter, netdev);
 561
 562error:
 563        rtnl_unlock();
 564        return err;
 565}
 566
 567int qlcnic_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
 568{
 569        struct qlcnic_adapter *adapter = pci_get_drvdata(dev);
 570        int err;
 571
 572        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 573                return -EBUSY;
 574
 575        if (num_vfs == 0)
 576                err = qlcnic_pci_sriov_disable(adapter);
 577        else
 578                err = qlcnic_pci_sriov_enable(adapter, num_vfs);
 579
 580        clear_bit(__QLCNIC_RESETTING, &adapter->state);
 581        return err;
 582}
 583
 584static int qlcnic_sriov_set_vf_acl(struct qlcnic_adapter *adapter, u8 func)
 585{
 586        struct qlcnic_cmd_args cmd;
 587        struct qlcnic_vport *vp;
 588        int err, id;
 589        u8 *mac;
 590
 591        id = qlcnic_sriov_func_to_index(adapter, func);
 592        if (id < 0)
 593                return id;
 594
 595        vp = adapter->ahw->sriov->vf_info[id].vp;
 596        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
 597        if (err)
 598                return err;
 599
 600        cmd.req.arg[1] = 0x3 | func << 16;
 601        if (vp->spoofchk == true) {
 602                mac = vp->mac;
 603                cmd.req.arg[2] |= BIT_1 | BIT_3 | BIT_8;
 604                cmd.req.arg[4] = mac[5] | mac[4] << 8 | mac[3] << 16 |
 605                                 mac[2] << 24;
 606                cmd.req.arg[5] = mac[1] | mac[0] << 8;
 607        }
 608
 609        if (vp->vlan_mode == QLC_PVID_MODE) {
 610                cmd.req.arg[2] |= BIT_6;
 611                cmd.req.arg[3] |= vp->vlan << 8;
 612        }
 613
 614        err = qlcnic_issue_cmd(adapter, &cmd);
 615        if (err)
 616                dev_err(&adapter->pdev->dev, "Failed to set ACL, err=%d\n",
 617                        err);
 618
 619        qlcnic_free_mbx_args(&cmd);
 620        return err;
 621}
 622
 623static int qlcnic_sriov_set_vf_vport_info(struct qlcnic_adapter *adapter,
 624                                          u16 func)
 625{
 626        struct qlcnic_info defvp_info;
 627        int err;
 628
 629        err = qlcnic_sriov_pf_cal_res_limit(adapter, &defvp_info, func);
 630        if (err)
 631                return -EIO;
 632
 633        err = qlcnic_sriov_set_vf_acl(adapter, func);
 634        if (err)
 635                return err;
 636
 637        return 0;
 638}
 639
 640static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans,
 641                                           struct qlcnic_cmd_args *cmd)
 642{
 643        struct qlcnic_vf_info *vf = trans->vf;
 644        struct qlcnic_vport *vp = vf->vp;
 645        struct qlcnic_adapter *adapter;
 646        u16 func = vf->pci_func;
 647        int err;
 648
 649        adapter = vf->adapter;
 650
 651        if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) {
 652                err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
 653                if (!err) {
 654                        err = qlcnic_sriov_set_vf_vport_info(adapter, func);
 655                        if (err)
 656                                qlcnic_sriov_pf_config_vport(adapter, 0, func);
 657                }
 658        } else {
 659                if (vp->vlan_mode == QLC_GUEST_VLAN_MODE)
 660                        vp->vlan = 0;
 661                err = qlcnic_sriov_pf_config_vport(adapter, 0, func);
 662        }
 663
 664        if (err)
 665                goto err_out;
 666
 667        cmd->rsp.arg[0] |= (1 << 25);
 668
 669        if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
 670                set_bit(QLC_BC_VF_STATE, &vf->state);
 671        else
 672                clear_bit(QLC_BC_VF_STATE, &vf->state);
 673
 674        return err;
 675
 676err_out:
 677        cmd->rsp.arg[0] |= (2 << 25);
 678        return err;
 679}
 680
 681static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter,
 682                                       struct qlcnic_vport *vp,
 683                                       u16 func, u16 vlan, u8 op)
 684{
 685        struct qlcnic_cmd_args cmd;
 686        struct qlcnic_macvlan_mbx mv;
 687        u8 *addr;
 688        int err;
 689        u32 *buf;
 690        int vpid;
 691
 692        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN))
 693                return -ENOMEM;
 694
 695        vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
 696        if (vpid < 0) {
 697                err = -EINVAL;
 698                goto out;
 699        }
 700
 701        if (vlan)
 702                op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
 703                      QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL);
 704
 705        cmd.req.arg[1] = op | (1 << 8) | (3 << 6);
 706        cmd.req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31;
 707
 708        addr = vp->mac;
 709        mv.vlan = vlan;
 710        mv.mac_addr0 = addr[0];
 711        mv.mac_addr1 = addr[1];
 712        mv.mac_addr2 = addr[2];
 713        mv.mac_addr3 = addr[3];
 714        mv.mac_addr4 = addr[4];
 715        mv.mac_addr5 = addr[5];
 716        buf = &cmd.req.arg[2];
 717        memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
 718
 719        err = qlcnic_issue_cmd(adapter, &cmd);
 720
 721        if (err)
 722                dev_err(&adapter->pdev->dev,
 723                        "MAC-VLAN %s to CAM failed, err=%d.\n",
 724                        ((op == 1) ? "add " : "delete "), err);
 725
 726out:
 727        qlcnic_free_mbx_args(&cmd);
 728        return err;
 729}
 730
 731static int qlcnic_sriov_validate_create_rx_ctx(struct qlcnic_cmd_args *cmd)
 732{
 733        if ((cmd->req.arg[0] >> 29) != 0x3)
 734                return -EINVAL;
 735
 736        return 0;
 737}
 738
 739static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran,
 740                                             struct qlcnic_cmd_args *cmd)
 741{
 742        struct qlcnic_vf_info *vf = tran->vf;
 743        struct qlcnic_adapter *adapter = vf->adapter;
 744        struct qlcnic_rcv_mbx_out *mbx_out;
 745        int err;
 746        u16 vlan;
 747
 748        err = qlcnic_sriov_validate_create_rx_ctx(cmd);
 749        if (err) {
 750                cmd->rsp.arg[0] |= (0x6 << 25);
 751                return err;
 752        }
 753
 754        cmd->req.arg[6] = vf->vp->handle;
 755        err = qlcnic_issue_cmd(adapter, cmd);
 756
 757        vlan = vf->vp->vlan;
 758        if (!err) {
 759                mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1];
 760                vf->rx_ctx_id = mbx_out->ctx_id;
 761                qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
 762                                            vlan, QLCNIC_MAC_ADD);
 763        } else {
 764                vf->rx_ctx_id = 0;
 765        }
 766
 767        return err;
 768}
 769
 770static int qlcnic_sriov_pf_mac_address_cmd(struct qlcnic_bc_trans *trans,
 771                                           struct qlcnic_cmd_args *cmd)
 772{
 773        struct qlcnic_vf_info *vf = trans->vf;
 774        u8 type, *mac;
 775
 776        type = cmd->req.arg[1];
 777        switch (type) {
 778        case QLCNIC_SET_STATION_MAC:
 779        case QLCNIC_SET_FAC_DEF_MAC:
 780                cmd->rsp.arg[0] = (2 << 25);
 781                break;
 782        case QLCNIC_GET_CURRENT_MAC:
 783                cmd->rsp.arg[0] = (1 << 25);
 784                mac = vf->vp->mac;
 785                cmd->rsp.arg[2] = mac[1] | ((mac[0] << 8) & 0xff00);
 786                cmd->rsp.arg[1] = mac[5] | ((mac[4] << 8) & 0xff00) |
 787                                  ((mac[3]) << 16 & 0xff0000) |
 788                                  ((mac[2]) << 24 & 0xff000000);
 789        }
 790
 791        return 0;
 792}
 793
 794static int qlcnic_sriov_validate_create_tx_ctx(struct qlcnic_cmd_args *cmd)
 795{
 796        if ((cmd->req.arg[0] >> 29) != 0x3)
 797                return -EINVAL;
 798
 799        return 0;
 800}
 801
 802static int qlcnic_sriov_pf_create_tx_ctx_cmd(struct qlcnic_bc_trans *trans,
 803                                             struct qlcnic_cmd_args *cmd)
 804{
 805        struct qlcnic_vf_info *vf = trans->vf;
 806        struct qlcnic_adapter *adapter = vf->adapter;
 807        struct qlcnic_tx_mbx_out *mbx_out;
 808        int err;
 809
 810        err = qlcnic_sriov_validate_create_tx_ctx(cmd);
 811        if (err) {
 812                cmd->rsp.arg[0] |= (0x6 << 25);
 813                return err;
 814        }
 815
 816        cmd->req.arg[5] |= vf->vp->handle << 16;
 817        err = qlcnic_issue_cmd(adapter, cmd);
 818        if (!err) {
 819                mbx_out = (struct qlcnic_tx_mbx_out *)&cmd->rsp.arg[2];
 820                vf->tx_ctx_id = mbx_out->ctx_id;
 821        } else {
 822                vf->tx_ctx_id = 0;
 823        }
 824
 825        return err;
 826}
 827
 828static int qlcnic_sriov_validate_del_rx_ctx(struct qlcnic_vf_info *vf,
 829                                            struct qlcnic_cmd_args *cmd)
 830{
 831        if ((cmd->req.arg[0] >> 29) != 0x3)
 832                return -EINVAL;
 833
 834        if ((cmd->req.arg[1] & 0xffff) != vf->rx_ctx_id)
 835                return -EINVAL;
 836
 837        return 0;
 838}
 839
 840static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans,
 841                                          struct qlcnic_cmd_args *cmd)
 842{
 843        struct qlcnic_vf_info *vf = trans->vf;
 844        struct qlcnic_adapter *adapter = vf->adapter;
 845        int err;
 846        u16 vlan;
 847
 848        err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd);
 849        if (err) {
 850                cmd->rsp.arg[0] |= (0x6 << 25);
 851                return err;
 852        }
 853
 854        vlan = vf->vp->vlan;
 855        qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
 856                                    vlan, QLCNIC_MAC_DEL);
 857        cmd->req.arg[1] |= vf->vp->handle << 16;
 858        err = qlcnic_issue_cmd(adapter, cmd);
 859
 860        if (!err)
 861                vf->rx_ctx_id = 0;
 862
 863        return err;
 864}
 865
 866static int qlcnic_sriov_validate_del_tx_ctx(struct qlcnic_vf_info *vf,
 867                                            struct qlcnic_cmd_args *cmd)
 868{
 869        if ((cmd->req.arg[0] >> 29) != 0x3)
 870                return -EINVAL;
 871
 872        if ((cmd->req.arg[1] & 0xffff) != vf->tx_ctx_id)
 873                return -EINVAL;
 874
 875        return 0;
 876}
 877
 878static int qlcnic_sriov_pf_del_tx_ctx_cmd(struct qlcnic_bc_trans *trans,
 879                                          struct qlcnic_cmd_args *cmd)
 880{
 881        struct qlcnic_vf_info *vf = trans->vf;
 882        struct qlcnic_adapter *adapter = vf->adapter;
 883        int err;
 884
 885        err = qlcnic_sriov_validate_del_tx_ctx(vf, cmd);
 886        if (err) {
 887                cmd->rsp.arg[0] |= (0x6 << 25);
 888                return err;
 889        }
 890
 891        cmd->req.arg[1] |= vf->vp->handle << 16;
 892        err = qlcnic_issue_cmd(adapter, cmd);
 893
 894        if (!err)
 895                vf->tx_ctx_id = 0;
 896
 897        return err;
 898}
 899
 900static int qlcnic_sriov_validate_cfg_lro(struct qlcnic_vf_info *vf,
 901                                         struct qlcnic_cmd_args *cmd)
 902{
 903        if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
 904                return -EINVAL;
 905
 906        return 0;
 907}
 908
 909static int qlcnic_sriov_pf_cfg_lro_cmd(struct qlcnic_bc_trans *trans,
 910                                       struct qlcnic_cmd_args *cmd)
 911{
 912        struct qlcnic_vf_info *vf = trans->vf;
 913        struct qlcnic_adapter *adapter = vf->adapter;
 914        int err;
 915
 916        err = qlcnic_sriov_validate_cfg_lro(vf, cmd);
 917        if (err) {
 918                cmd->rsp.arg[0] |= (0x6 << 25);
 919                return err;
 920        }
 921
 922        err = qlcnic_issue_cmd(adapter, cmd);
 923        return err;
 924}
 925
 926static int qlcnic_sriov_pf_cfg_ip_cmd(struct qlcnic_bc_trans *trans,
 927                                      struct qlcnic_cmd_args *cmd)
 928{
 929        struct qlcnic_vf_info *vf = trans->vf;
 930        struct qlcnic_adapter *adapter = vf->adapter;
 931        int err = -EIO;
 932        u8 op;
 933
 934        op =  cmd->req.arg[1] & 0xff;
 935
 936        cmd->req.arg[1] |= vf->vp->handle << 16;
 937        cmd->req.arg[1] |= BIT_31;
 938
 939        err = qlcnic_issue_cmd(adapter, cmd);
 940        return err;
 941}
 942
 943static int qlcnic_sriov_validate_cfg_intrpt(struct qlcnic_vf_info *vf,
 944                                            struct qlcnic_cmd_args *cmd)
 945{
 946        if (((cmd->req.arg[1] >> 8) & 0xff) != vf->pci_func)
 947                return -EINVAL;
 948
 949        if (!(cmd->req.arg[1] & BIT_16))
 950                return -EINVAL;
 951
 952        if ((cmd->req.arg[1] & 0xff) != 0x1)
 953                return -EINVAL;
 954
 955        return 0;
 956}
 957
 958static int qlcnic_sriov_pf_cfg_intrpt_cmd(struct qlcnic_bc_trans *trans,
 959                                          struct qlcnic_cmd_args *cmd)
 960{
 961        struct qlcnic_vf_info *vf = trans->vf;
 962        struct qlcnic_adapter *adapter = vf->adapter;
 963        int err;
 964
 965        err = qlcnic_sriov_validate_cfg_intrpt(vf, cmd);
 966        if (err)
 967                cmd->rsp.arg[0] |= (0x6 << 25);
 968        else
 969                err = qlcnic_issue_cmd(adapter, cmd);
 970
 971        return err;
 972}
 973
 974static int qlcnic_sriov_validate_mtu(struct qlcnic_adapter *adapter,
 975                                     struct qlcnic_vf_info *vf,
 976                                     struct qlcnic_cmd_args *cmd)
 977{
 978        if (cmd->req.arg[1] != vf->rx_ctx_id)
 979                return -EINVAL;
 980
 981        if (cmd->req.arg[2] > adapter->ahw->max_mtu)
 982                return -EINVAL;
 983
 984        return 0;
 985}
 986
 987static int qlcnic_sriov_pf_set_mtu_cmd(struct qlcnic_bc_trans *trans,
 988                                       struct qlcnic_cmd_args *cmd)
 989{
 990        struct qlcnic_vf_info *vf = trans->vf;
 991        struct qlcnic_adapter *adapter = vf->adapter;
 992        int err;
 993
 994        err = qlcnic_sriov_validate_mtu(adapter, vf, cmd);
 995        if (err)
 996                cmd->rsp.arg[0] |= (0x6 << 25);
 997        else
 998                err = qlcnic_issue_cmd(adapter, cmd);
 999
1000        return err;
1001}
1002
1003static int qlcnic_sriov_validate_get_nic_info(struct qlcnic_vf_info *vf,
1004                                              struct qlcnic_cmd_args *cmd)
1005{
1006        if (cmd->req.arg[1] & BIT_31) {
1007                if (((cmd->req.arg[1] >> 16) & 0x7fff) != vf->pci_func)
1008                        return -EINVAL;
1009        } else {
1010                cmd->req.arg[1] |= vf->vp->handle << 16;
1011        }
1012
1013        return 0;
1014}
1015
1016static int qlcnic_sriov_pf_get_nic_info_cmd(struct qlcnic_bc_trans *trans,
1017                                            struct qlcnic_cmd_args *cmd)
1018{
1019        struct qlcnic_vf_info *vf = trans->vf;
1020        struct qlcnic_adapter *adapter = vf->adapter;
1021        int err;
1022
1023        err = qlcnic_sriov_validate_get_nic_info(vf, cmd);
1024        if (err) {
1025                cmd->rsp.arg[0] |= (0x6 << 25);
1026                return err;
1027        }
1028
1029        err = qlcnic_issue_cmd(adapter, cmd);
1030        return err;
1031}
1032
1033static int qlcnic_sriov_validate_cfg_rss(struct qlcnic_vf_info *vf,
1034                                         struct qlcnic_cmd_args *cmd)
1035{
1036        if (cmd->req.arg[1] != vf->rx_ctx_id)
1037                return -EINVAL;
1038
1039        return 0;
1040}
1041
1042static int qlcnic_sriov_pf_cfg_rss_cmd(struct qlcnic_bc_trans *trans,
1043                                       struct qlcnic_cmd_args *cmd)
1044{
1045        struct qlcnic_vf_info *vf = trans->vf;
1046        struct qlcnic_adapter *adapter = vf->adapter;
1047        int err;
1048
1049        err = qlcnic_sriov_validate_cfg_rss(vf, cmd);
1050        if (err)
1051                cmd->rsp.arg[0] |= (0x6 << 25);
1052        else
1053                err = qlcnic_issue_cmd(adapter, cmd);
1054
1055        return err;
1056}
1057
1058static int qlcnic_sriov_validate_cfg_intrcoal(struct qlcnic_adapter *adapter,
1059                                              struct qlcnic_vf_info *vf,
1060                                              struct qlcnic_cmd_args *cmd)
1061{
1062        struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
1063        u16 ctx_id, pkts, time;
1064
1065        ctx_id = cmd->req.arg[1] >> 16;
1066        pkts = cmd->req.arg[2] & 0xffff;
1067        time = cmd->req.arg[2] >> 16;
1068
1069        if (ctx_id != vf->rx_ctx_id)
1070                return -EINVAL;
1071        if (pkts > coal->rx_packets)
1072                return -EINVAL;
1073        if (time < coal->rx_time_us)
1074                return -EINVAL;
1075
1076        return 0;
1077}
1078
1079static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran,
1080                                            struct qlcnic_cmd_args *cmd)
1081{
1082        struct qlcnic_vf_info *vf = tran->vf;
1083        struct qlcnic_adapter *adapter = vf->adapter;
1084        int err;
1085
1086        err = qlcnic_sriov_validate_cfg_intrcoal(adapter, vf, cmd);
1087        if (err) {
1088                cmd->rsp.arg[0] |= (0x6 << 25);
1089                return err;
1090        }
1091
1092        err = qlcnic_issue_cmd(adapter, cmd);
1093        return err;
1094}
1095
1096static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter,
1097                                             struct qlcnic_vf_info *vf,
1098                                             struct qlcnic_cmd_args *cmd)
1099{
1100        struct qlcnic_macvlan_mbx *macvlan;
1101        struct qlcnic_vport *vp = vf->vp;
1102        u8 op, new_op;
1103
1104        if (!(cmd->req.arg[1] & BIT_8))
1105                return -EINVAL;
1106
1107        cmd->req.arg[1] |= (vf->vp->handle << 16);
1108        cmd->req.arg[1] |= BIT_31;
1109
1110        macvlan = (struct qlcnic_macvlan_mbx *)&cmd->req.arg[2];
1111        if (!(macvlan->mac_addr0 & BIT_0)) {
1112                dev_err(&adapter->pdev->dev,
1113                        "MAC address change is not allowed from VF %d",
1114                        vf->pci_func);
1115                return -EINVAL;
1116        }
1117
1118        if (vp->vlan_mode == QLC_PVID_MODE) {
1119                op = cmd->req.arg[1] & 0x7;
1120                cmd->req.arg[1] &= ~0x7;
1121                new_op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
1122                         QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
1123                cmd->req.arg[3] |= vp->vlan << 16;
1124                cmd->req.arg[1] |= new_op;
1125        }
1126
1127        return 0;
1128}
1129
1130static int qlcnic_sriov_pf_cfg_macvlan_cmd(struct qlcnic_bc_trans *trans,
1131                                           struct qlcnic_cmd_args *cmd)
1132{
1133        struct qlcnic_vf_info *vf = trans->vf;
1134        struct qlcnic_adapter *adapter = vf->adapter;
1135        int err;
1136
1137        err = qlcnic_sriov_validate_cfg_macvlan(adapter, vf, cmd);
1138        if (err) {
1139                cmd->rsp.arg[0] |= (0x6 << 25);
1140                return err;
1141        }
1142
1143        err = qlcnic_issue_cmd(adapter, cmd);
1144        return err;
1145}
1146
1147static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf,
1148                                           struct qlcnic_cmd_args *cmd)
1149{
1150        if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
1151                return -EINVAL;
1152
1153        return 0;
1154}
1155
1156static int qlcnic_sriov_pf_linkevent_cmd(struct qlcnic_bc_trans *trans,
1157                                         struct qlcnic_cmd_args *cmd)
1158{
1159        struct qlcnic_vf_info *vf = trans->vf;
1160        struct qlcnic_adapter *adapter = vf->adapter;
1161        int err;
1162
1163        err = qlcnic_sriov_validate_linkevent(vf, cmd);
1164        if (err) {
1165                cmd->rsp.arg[0] |= (0x6 << 25);
1166                return err;
1167        }
1168
1169        err = qlcnic_issue_cmd(adapter, cmd);
1170        return err;
1171}
1172
1173static int qlcnic_sriov_pf_cfg_promisc_cmd(struct qlcnic_bc_trans *trans,
1174                                           struct qlcnic_cmd_args *cmd)
1175{
1176        struct qlcnic_vf_info *vf = trans->vf;
1177        struct qlcnic_adapter *adapter = vf->adapter;
1178        int err;
1179
1180        cmd->req.arg[1] |= vf->vp->handle << 16;
1181        cmd->req.arg[1] |= BIT_31;
1182        err = qlcnic_issue_cmd(adapter, cmd);
1183        return err;
1184}
1185
1186static int qlcnic_sriov_pf_get_acl_cmd(struct qlcnic_bc_trans *trans,
1187                                       struct qlcnic_cmd_args *cmd)
1188{
1189        struct qlcnic_vf_info *vf = trans->vf;
1190        struct qlcnic_vport *vp = vf->vp;
1191        u8 cmd_op, mode = vp->vlan_mode;
1192        struct qlcnic_adapter *adapter;
1193
1194        adapter = vf->adapter;
1195
1196        cmd_op = trans->req_hdr->cmd_op;
1197        cmd->rsp.arg[0] |= 1 << 25;
1198
1199        /* For 84xx adapter in case of PVID , PFD should send vlan mode as
1200         * QLC_NO_VLAN_MODE to VFD which is zero in mailbox response
1201         */
1202        if (qlcnic_84xx_check(adapter) && mode == QLC_PVID_MODE)
1203                return 0;
1204
1205        switch (mode) {
1206        case QLC_GUEST_VLAN_MODE:
1207                cmd->rsp.arg[1] = mode | 1 << 8;
1208                cmd->rsp.arg[2] = 1 << 16;
1209                break;
1210        case QLC_PVID_MODE:
1211                cmd->rsp.arg[1] = mode | 1 << 8 | vp->vlan << 16;
1212                break;
1213        }
1214
1215        return 0;
1216}
1217
1218static int qlcnic_sriov_pf_del_guest_vlan(struct qlcnic_adapter *adapter,
1219                                          struct qlcnic_vf_info *vf)
1220
1221{
1222        struct qlcnic_vport *vp = vf->vp;
1223
1224        if (!vp->vlan)
1225                return -EINVAL;
1226
1227        if (!vf->rx_ctx_id) {
1228                vp->vlan = 0;
1229                return 0;
1230        }
1231
1232        qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1233                                    vp->vlan, QLCNIC_MAC_DEL);
1234        vp->vlan = 0;
1235        qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1236                                    0, QLCNIC_MAC_ADD);
1237        return 0;
1238}
1239
1240static int qlcnic_sriov_pf_add_guest_vlan(struct qlcnic_adapter *adapter,
1241                                          struct qlcnic_vf_info *vf,
1242                                          struct qlcnic_cmd_args *cmd)
1243{
1244        struct qlcnic_vport *vp = vf->vp;
1245        int err = -EIO;
1246
1247        if (vp->vlan)
1248                return err;
1249
1250        if (!vf->rx_ctx_id) {
1251                vp->vlan = cmd->req.arg[1] >> 16;
1252                return 0;
1253        }
1254
1255        err = qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1256                                          0, QLCNIC_MAC_DEL);
1257        if (err)
1258                return err;
1259
1260        vp->vlan = cmd->req.arg[1] >> 16;
1261        err = qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1262                                          vp->vlan, QLCNIC_MAC_ADD);
1263
1264        if (err) {
1265                qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1266                                            0, QLCNIC_MAC_ADD);
1267                vp->vlan = 0;
1268        }
1269
1270        return err;
1271}
1272
1273static int qlcnic_sriov_pf_cfg_guest_vlan_cmd(struct qlcnic_bc_trans *tran,
1274                                              struct qlcnic_cmd_args *cmd)
1275{
1276        struct qlcnic_vf_info  *vf = tran->vf;
1277        struct qlcnic_adapter *adapter =  vf->adapter;
1278        struct qlcnic_vport *vp = vf->vp;
1279        int err = -EIO;
1280        u8 op;
1281
1282        if (vp->vlan_mode != QLC_GUEST_VLAN_MODE) {
1283                cmd->rsp.arg[0] |= 2 << 25;
1284                return err;
1285        }
1286
1287        op = cmd->req.arg[1] & 0xf;
1288
1289        if (op)
1290                err = qlcnic_sriov_pf_add_guest_vlan(adapter, vf, cmd);
1291        else
1292                err = qlcnic_sriov_pf_del_guest_vlan(adapter, vf);
1293
1294        cmd->rsp.arg[0] |= err ? 2 << 25 : 1 << 25;
1295        return err;
1296}
1297
1298static const int qlcnic_pf_passthru_supp_cmds[] = {
1299        QLCNIC_CMD_GET_STATISTICS,
1300        QLCNIC_CMD_GET_PORT_CONFIG,
1301        QLCNIC_CMD_GET_LINK_STATUS,
1302        QLCNIC_CMD_DCB_QUERY_CAP,
1303        QLCNIC_CMD_DCB_QUERY_PARAM,
1304        QLCNIC_CMD_INIT_NIC_FUNC,
1305        QLCNIC_CMD_STOP_NIC_FUNC,
1306};
1307
1308static const struct qlcnic_sriov_cmd_handler qlcnic_pf_bc_cmd_hdlr[] = {
1309        [QLCNIC_BC_CMD_CHANNEL_INIT] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1310        [QLCNIC_BC_CMD_CHANNEL_TERM] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1311        [QLCNIC_BC_CMD_GET_ACL] = {&qlcnic_sriov_pf_get_acl_cmd},
1312        [QLCNIC_BC_CMD_CFG_GUEST_VLAN]  = {&qlcnic_sriov_pf_cfg_guest_vlan_cmd},
1313};
1314
1315static const struct qlcnic_sriov_fw_cmd_handler qlcnic_pf_fw_cmd_hdlr[] = {
1316        {QLCNIC_CMD_CREATE_RX_CTX, qlcnic_sriov_pf_create_rx_ctx_cmd},
1317        {QLCNIC_CMD_CREATE_TX_CTX, qlcnic_sriov_pf_create_tx_ctx_cmd},
1318        {QLCNIC_CMD_MAC_ADDRESS, qlcnic_sriov_pf_mac_address_cmd},
1319        {QLCNIC_CMD_DESTROY_RX_CTX, qlcnic_sriov_pf_del_rx_ctx_cmd},
1320        {QLCNIC_CMD_DESTROY_TX_CTX, qlcnic_sriov_pf_del_tx_ctx_cmd},
1321        {QLCNIC_CMD_CONFIGURE_HW_LRO, qlcnic_sriov_pf_cfg_lro_cmd},
1322        {QLCNIC_CMD_CONFIGURE_IP_ADDR, qlcnic_sriov_pf_cfg_ip_cmd},
1323        {QLCNIC_CMD_CONFIG_INTRPT, qlcnic_sriov_pf_cfg_intrpt_cmd},
1324        {QLCNIC_CMD_SET_MTU, qlcnic_sriov_pf_set_mtu_cmd},
1325        {QLCNIC_CMD_GET_NIC_INFO, qlcnic_sriov_pf_get_nic_info_cmd},
1326        {QLCNIC_CMD_CONFIGURE_RSS, qlcnic_sriov_pf_cfg_rss_cmd},
1327        {QLCNIC_CMD_CONFIG_INTR_COAL, qlcnic_sriov_pf_cfg_intrcoal_cmd},
1328        {QLCNIC_CMD_CONFIG_MAC_VLAN, qlcnic_sriov_pf_cfg_macvlan_cmd},
1329        {QLCNIC_CMD_GET_LINK_EVENT, qlcnic_sriov_pf_linkevent_cmd},
1330        {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, qlcnic_sriov_pf_cfg_promisc_cmd},
1331};
1332
1333void qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *adapter,
1334                                    struct qlcnic_bc_trans *trans,
1335                                    struct qlcnic_cmd_args *cmd)
1336{
1337        u8 size, cmd_op;
1338
1339        cmd_op = trans->req_hdr->cmd_op;
1340
1341        if (trans->req_hdr->op_type == QLC_BC_CMD) {
1342                size = ARRAY_SIZE(qlcnic_pf_bc_cmd_hdlr);
1343                if (cmd_op < size) {
1344                        qlcnic_pf_bc_cmd_hdlr[cmd_op].fn(trans, cmd);
1345                        return;
1346                }
1347        } else {
1348                int i;
1349                size = ARRAY_SIZE(qlcnic_pf_fw_cmd_hdlr);
1350                for (i = 0; i < size; i++) {
1351                        if (cmd_op == qlcnic_pf_fw_cmd_hdlr[i].cmd) {
1352                                qlcnic_pf_fw_cmd_hdlr[i].fn(trans, cmd);
1353                                return;
1354                        }
1355                }
1356
1357                size = ARRAY_SIZE(qlcnic_pf_passthru_supp_cmds);
1358                for (i = 0; i < size; i++) {
1359                        if (cmd_op == qlcnic_pf_passthru_supp_cmds[i]) {
1360                                qlcnic_issue_cmd(adapter, cmd);
1361                                return;
1362                        }
1363                }
1364        }
1365
1366        cmd->rsp.arg[0] |= (0x9 << 25);
1367}
1368
1369void qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *adapter,
1370                                             u32 *int_id)
1371{
1372        u16 vpid;
1373
1374        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1375                                                adapter->ahw->pci_func);
1376        *int_id |= vpid;
1377}
1378
1379void qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *adapter,
1380                                           u32 *int_id)
1381{
1382        u16 vpid;
1383
1384        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1385                                                adapter->ahw->pci_func);
1386        *int_id |= vpid << 16;
1387}
1388
1389void qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *adapter,
1390                                              u32 *int_id)
1391{
1392        int vpid;
1393
1394        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1395                                                adapter->ahw->pci_func);
1396        *int_id |= vpid << 16;
1397}
1398
1399void qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *adapter,
1400                                           u32 *int_id)
1401{
1402        u16 vpid;
1403
1404        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1405                                                adapter->ahw->pci_func);
1406        *int_id |= vpid << 16;
1407}
1408
1409void qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1410                                        u32 *int_id)
1411{
1412        u16 vpid;
1413
1414        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1415                                                adapter->ahw->pci_func);
1416        *int_id |= (vpid << 16) | BIT_31;
1417}
1418
1419void qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1420                                       u32 *int_id)
1421{
1422        u16 vpid;
1423
1424        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1425                                                adapter->ahw->pci_func);
1426        *int_id |= (vpid << 16) | BIT_31;
1427}
1428
1429void qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
1430                                        u32 *int_id)
1431{
1432        u16 vpid;
1433
1434        vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1435                                                adapter->ahw->pci_func);
1436        *int_id |= (vpid << 16) | BIT_31;
1437}
1438
1439static void qlcnic_sriov_del_rx_ctx(struct qlcnic_adapter *adapter,
1440                                    struct qlcnic_vf_info *vf)
1441{
1442        struct qlcnic_cmd_args cmd;
1443        int vpid;
1444
1445        if (!vf->rx_ctx_id)
1446                return;
1447
1448        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1449                return;
1450
1451        vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func);
1452        if (vpid >= 0) {
1453                cmd.req.arg[1] = vf->rx_ctx_id | (vpid & 0xffff) << 16;
1454                if (qlcnic_issue_cmd(adapter, &cmd))
1455                        dev_err(&adapter->pdev->dev,
1456                                "Failed to delete Tx ctx in firmware for func 0x%x\n",
1457                                vf->pci_func);
1458                else
1459                        vf->rx_ctx_id = 0;
1460        }
1461
1462        qlcnic_free_mbx_args(&cmd);
1463}
1464
1465static void qlcnic_sriov_del_tx_ctx(struct qlcnic_adapter *adapter,
1466                                    struct qlcnic_vf_info *vf)
1467{
1468        struct qlcnic_cmd_args cmd;
1469        int vpid;
1470
1471        if (!vf->tx_ctx_id)
1472                return;
1473
1474        if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1475                return;
1476
1477        vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func);
1478        if (vpid >= 0) {
1479                cmd.req.arg[1] |= vf->tx_ctx_id | (vpid & 0xffff) << 16;
1480                if (qlcnic_issue_cmd(adapter, &cmd))
1481                        dev_err(&adapter->pdev->dev,
1482                                "Failed to delete Tx ctx in firmware for func 0x%x\n",
1483                                vf->pci_func);
1484                else
1485                        vf->tx_ctx_id = 0;
1486        }
1487
1488        qlcnic_free_mbx_args(&cmd);
1489}
1490
1491static int qlcnic_sriov_add_act_list_irqsave(struct qlcnic_sriov *sriov,
1492                                             struct qlcnic_vf_info *vf,
1493                                             struct qlcnic_bc_trans *trans)
1494{
1495        struct qlcnic_trans_list *t_list = &vf->rcv_act;
1496        unsigned long flag;
1497
1498        spin_lock_irqsave(&t_list->lock, flag);
1499
1500        __qlcnic_sriov_add_act_list(sriov, vf, trans);
1501
1502        spin_unlock_irqrestore(&t_list->lock, flag);
1503        return 0;
1504}
1505
1506static void __qlcnic_sriov_process_flr(struct qlcnic_vf_info *vf)
1507{
1508        struct qlcnic_adapter *adapter = vf->adapter;
1509
1510        qlcnic_sriov_cleanup_list(&vf->rcv_pend);
1511        cancel_work_sync(&vf->trans_work);
1512        qlcnic_sriov_cleanup_list(&vf->rcv_act);
1513
1514        if (test_bit(QLC_BC_VF_SOFT_FLR, &vf->state)) {
1515                qlcnic_sriov_del_tx_ctx(adapter, vf);
1516                qlcnic_sriov_del_rx_ctx(adapter, vf);
1517        }
1518
1519        qlcnic_sriov_pf_config_vport(adapter, 0, vf->pci_func);
1520
1521        clear_bit(QLC_BC_VF_FLR, &vf->state);
1522        if (test_bit(QLC_BC_VF_SOFT_FLR, &vf->state)) {
1523                qlcnic_sriov_add_act_list_irqsave(adapter->ahw->sriov, vf,
1524                                                  vf->flr_trans);
1525                clear_bit(QLC_BC_VF_SOFT_FLR, &vf->state);
1526                vf->flr_trans = NULL;
1527        }
1528}
1529
1530static void qlcnic_sriov_pf_process_flr(struct work_struct *work)
1531{
1532        struct qlcnic_vf_info *vf;
1533
1534        vf = container_of(work, struct qlcnic_vf_info, flr_work);
1535        __qlcnic_sriov_process_flr(vf);
1536        return;
1537}
1538
1539static void qlcnic_sriov_schedule_flr(struct qlcnic_sriov *sriov,
1540                                      struct qlcnic_vf_info *vf,
1541                                      work_func_t func)
1542{
1543        if (test_bit(__QLCNIC_RESETTING, &vf->adapter->state))
1544                return;
1545
1546        INIT_WORK(&vf->flr_work, func);
1547        queue_work(sriov->bc.bc_flr_wq, &vf->flr_work);
1548}
1549
1550static void qlcnic_sriov_handle_soft_flr(struct qlcnic_adapter *adapter,
1551                                         struct qlcnic_bc_trans *trans,
1552                                         struct qlcnic_vf_info *vf)
1553{
1554        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1555
1556        set_bit(QLC_BC_VF_FLR, &vf->state);
1557        clear_bit(QLC_BC_VF_STATE, &vf->state);
1558        set_bit(QLC_BC_VF_SOFT_FLR, &vf->state);
1559        vf->flr_trans = trans;
1560        qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr);
1561        netdev_info(adapter->netdev, "Software FLR for PCI func %d\n",
1562                    vf->pci_func);
1563}
1564
1565bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *adapter,
1566                                 struct qlcnic_bc_trans *trans,
1567                                 struct qlcnic_vf_info *vf)
1568{
1569        struct qlcnic_bc_hdr *hdr = trans->req_hdr;
1570
1571        if ((hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) &&
1572            (hdr->op_type == QLC_BC_CMD) &&
1573             test_bit(QLC_BC_VF_STATE, &vf->state)) {
1574                qlcnic_sriov_handle_soft_flr(adapter, trans, vf);
1575                return true;
1576        }
1577
1578        return false;
1579}
1580
1581void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
1582                                struct qlcnic_vf_info *vf)
1583{
1584        struct net_device *dev = vf->adapter->netdev;
1585        struct qlcnic_vport *vp = vf->vp;
1586
1587        if (!test_and_clear_bit(QLC_BC_VF_STATE, &vf->state)) {
1588                clear_bit(QLC_BC_VF_FLR, &vf->state);
1589                return;
1590        }
1591
1592        if (test_and_set_bit(QLC_BC_VF_FLR, &vf->state)) {
1593                netdev_info(dev, "FLR for PCI func %d in progress\n",
1594                            vf->pci_func);
1595                return;
1596        }
1597
1598        if (vp->vlan_mode == QLC_GUEST_VLAN_MODE)
1599                vp->vlan = 0;
1600
1601        qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr);
1602        netdev_info(dev, "FLR received for PCI func %d\n", vf->pci_func);
1603}
1604
1605void qlcnic_sriov_pf_reset(struct qlcnic_adapter *adapter)
1606{
1607        struct qlcnic_hardware_context *ahw = adapter->ahw;
1608        struct qlcnic_sriov *sriov = ahw->sriov;
1609        struct qlcnic_vf_info *vf;
1610        u16 num_vfs = sriov->num_vfs;
1611        int i;
1612
1613        for (i = 0; i < num_vfs; i++) {
1614                vf = &sriov->vf_info[i];
1615                vf->rx_ctx_id = 0;
1616                vf->tx_ctx_id = 0;
1617                cancel_work_sync(&vf->flr_work);
1618                __qlcnic_sriov_process_flr(vf);
1619                clear_bit(QLC_BC_VF_STATE, &vf->state);
1620        }
1621
1622        qlcnic_sriov_pf_reset_vport_handle(adapter, ahw->pci_func);
1623        QLCWRX(ahw, QLCNIC_MBX_INTR_ENBL, (ahw->num_msix - 1) << 8);
1624}
1625
1626int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *adapter)
1627{
1628        struct qlcnic_hardware_context *ahw = adapter->ahw;
1629        int err;
1630
1631        if (!qlcnic_sriov_enable_check(adapter))
1632                return 0;
1633
1634        ahw->op_mode = QLCNIC_SRIOV_PF_FUNC;
1635
1636        err = qlcnic_sriov_pf_init(adapter);
1637        if (err)
1638                return err;
1639
1640        dev_info(&adapter->pdev->dev, "%s: op_mode %d\n",
1641                 __func__, ahw->op_mode);
1642        return err;
1643}
1644
1645int qlcnic_sriov_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
1646{
1647        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1648        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1649        int i, num_vfs;
1650        struct qlcnic_vf_info *vf_info;
1651        u8 *curr_mac;
1652
1653        if (!qlcnic_sriov_pf_check(adapter))
1654                return -EOPNOTSUPP;
1655
1656        num_vfs = sriov->num_vfs;
1657
1658        if (!is_valid_ether_addr(mac) || vf >= num_vfs)
1659                return -EINVAL;
1660
1661        if (ether_addr_equal(adapter->mac_addr, mac)) {
1662                netdev_err(netdev, "MAC address is already in use by the PF\n");
1663                return -EINVAL;
1664        }
1665
1666        for (i = 0; i < num_vfs; i++) {
1667                vf_info = &sriov->vf_info[i];
1668                if (ether_addr_equal(vf_info->vp->mac, mac)) {
1669                        netdev_err(netdev,
1670                                   "MAC address is already in use by VF %d\n",
1671                                   i);
1672                        return -EINVAL;
1673                }
1674        }
1675
1676        vf_info = &sriov->vf_info[vf];
1677        curr_mac = vf_info->vp->mac;
1678
1679        if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
1680                netdev_err(netdev,
1681                           "MAC address change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n",
1682                           vf);
1683                return -EOPNOTSUPP;
1684        }
1685
1686        memcpy(curr_mac, mac, netdev->addr_len);
1687        netdev_info(netdev, "MAC Address %pM  is configured for VF %d\n",
1688                    mac, vf);
1689        return 0;
1690}
1691
1692int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate)
1693{
1694        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1695        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1696        struct qlcnic_vf_info *vf_info;
1697        struct qlcnic_info nic_info;
1698        struct qlcnic_vport *vp;
1699        u16 vpid;
1700
1701        if (!qlcnic_sriov_pf_check(adapter))
1702                return -EOPNOTSUPP;
1703
1704        if (vf >= sriov->num_vfs)
1705                return -EINVAL;
1706
1707        if (tx_rate >= 10000 || tx_rate < 100) {
1708                netdev_err(netdev,
1709                           "Invalid Tx rate, allowed range is [%d - %d]",
1710                           QLC_VF_MIN_TX_RATE, QLC_VF_MAX_TX_RATE);
1711                return -EINVAL;
1712        }
1713
1714        if (tx_rate == 0)
1715                tx_rate = 10000;
1716
1717        vf_info = &sriov->vf_info[vf];
1718        vp = vf_info->vp;
1719        vpid = vp->handle;
1720
1721        if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
1722                if (qlcnic_sriov_get_vf_vport_info(adapter, &nic_info, vpid))
1723                        return -EIO;
1724
1725                nic_info.max_tx_bw = tx_rate / 100;
1726                nic_info.bit_offsets = BIT_0;
1727
1728                if (qlcnic_sriov_pf_set_vport_info(adapter, &nic_info, vpid))
1729                        return -EIO;
1730        }
1731
1732        vp->max_tx_bw = tx_rate / 100;
1733        netdev_info(netdev,
1734                    "Setting Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n",
1735                    tx_rate, vp->max_tx_bw, vf);
1736        return 0;
1737}
1738
1739int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf,
1740                             u16 vlan, u8 qos)
1741{
1742        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1743        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1744        struct qlcnic_vf_info *vf_info;
1745        struct qlcnic_vport *vp;
1746
1747        if (!qlcnic_sriov_pf_check(adapter))
1748                return -EOPNOTSUPP;
1749
1750        if (vf >= sriov->num_vfs || qos > 7)
1751                return -EINVAL;
1752
1753        if (vlan > MAX_VLAN_ID) {
1754                netdev_err(netdev,
1755                           "Invalid VLAN ID, allowed range is [0 - %d]\n",
1756                           MAX_VLAN_ID);
1757                return -EINVAL;
1758        }
1759
1760        vf_info = &sriov->vf_info[vf];
1761        vp = vf_info->vp;
1762        if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
1763                netdev_err(netdev,
1764                           "VLAN change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n",
1765                           vf);
1766                return -EOPNOTSUPP;
1767        }
1768
1769        switch (vlan) {
1770        case 4095:
1771                vp->vlan = 0;
1772                vp->vlan_mode = QLC_GUEST_VLAN_MODE;
1773                break;
1774        case 0:
1775                vp->vlan_mode = QLC_NO_VLAN_MODE;
1776                vp->vlan = 0;
1777                vp->qos = 0;
1778                break;
1779        default:
1780                vp->vlan_mode = QLC_PVID_MODE;
1781                vp->vlan = vlan;
1782                vp->qos = qos;
1783        }
1784
1785        netdev_info(netdev, "Setting VLAN %d, QoS %d, for VF %d\n",
1786                    vlan, qos, vf);
1787        return 0;
1788}
1789
1790static __u32 qlcnic_sriov_get_vf_vlan(struct qlcnic_adapter *adapter,
1791                                      struct qlcnic_vport *vp, int vf)
1792{
1793        __u32 vlan = 0;
1794
1795        switch (vp->vlan_mode) {
1796        case QLC_PVID_MODE:
1797                vlan = vp->vlan;
1798                break;
1799        case QLC_GUEST_VLAN_MODE:
1800                vlan = MAX_VLAN_ID;
1801                break;
1802        case QLC_NO_VLAN_MODE:
1803                vlan = 0;
1804                break;
1805        default:
1806                netdev_info(adapter->netdev, "Invalid VLAN mode = %d for VF %d\n",
1807                            vp->vlan_mode, vf);
1808        }
1809
1810        return vlan;
1811}
1812
1813int qlcnic_sriov_get_vf_config(struct net_device *netdev,
1814                               int vf, struct ifla_vf_info *ivi)
1815{
1816        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1817        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1818        struct qlcnic_vport *vp;
1819
1820        if (!qlcnic_sriov_pf_check(adapter))
1821                return -EOPNOTSUPP;
1822
1823        if (vf >= sriov->num_vfs)
1824                return -EINVAL;
1825
1826        vp = sriov->vf_info[vf].vp;
1827        memcpy(&ivi->mac, vp->mac, ETH_ALEN);
1828        ivi->vlan = qlcnic_sriov_get_vf_vlan(adapter, vp, vf);
1829        ivi->qos = vp->qos;
1830        ivi->spoofchk = vp->spoofchk;
1831        if (vp->max_tx_bw == MAX_BW)
1832                ivi->tx_rate = 0;
1833        else
1834                ivi->tx_rate = vp->max_tx_bw * 100;
1835
1836        ivi->vf = vf;
1837        return 0;
1838}
1839
1840int qlcnic_sriov_set_vf_spoofchk(struct net_device *netdev, int vf, bool chk)
1841{
1842        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1843        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1844        struct qlcnic_vf_info *vf_info;
1845        struct qlcnic_vport *vp;
1846
1847        if (!qlcnic_sriov_pf_check(adapter))
1848                return -EOPNOTSUPP;
1849
1850        if (vf >= sriov->num_vfs)
1851                return -EINVAL;
1852
1853        vf_info = &sriov->vf_info[vf];
1854        vp = vf_info->vp;
1855        if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
1856                netdev_err(netdev,
1857                           "Spoof check change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n",
1858                           vf);
1859                return -EOPNOTSUPP;
1860        }
1861
1862        vp->spoofchk = chk;
1863        return 0;
1864}
1865