]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty...
[linux-imx.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_sriov_pf.c
index ee0c1d307966d842d824c3ed64449690946b7d76..eb49cd65378cdcf5feec210a2812d3d09ef8f0cb 100644 (file)
@@ -635,12 +635,12 @@ static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans,
                                           struct qlcnic_cmd_args *cmd)
 {
        struct qlcnic_vf_info *vf = trans->vf;
-       struct qlcnic_adapter *adapter = vf->adapter;
-       int err;
+       struct qlcnic_vport *vp = vf->vp;
+       struct qlcnic_adapter *adapter;
        u16 func = vf->pci_func;
+       int err;
 
-       cmd->rsp.arg[0] = trans->req_hdr->cmd_op;
-       cmd->rsp.arg[0] |= (1 << 16);
+       adapter = vf->adapter;
 
        if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) {
                err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
@@ -650,6 +650,8 @@ static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans,
                                qlcnic_sriov_pf_config_vport(adapter, 0, func);
                }
        } else {
+               if (vp->vlan_mode == QLC_GUEST_VLAN_MODE)
+                       vp->vlan = 0;
                err = qlcnic_sriov_pf_config_vport(adapter, 0, func);
        }
 
@@ -1183,7 +1185,7 @@ static int qlcnic_sriov_pf_get_acl_cmd(struct qlcnic_bc_trans *trans,
        u8 cmd_op, mode = vp->vlan_mode;
 
        cmd_op = trans->req_hdr->cmd_op;
-       cmd->rsp.arg[0] = (cmd_op & 0xffff) | 14 << 16 | 1 << 25;
+       cmd->rsp.arg[0] |= 1 << 25;
 
        switch (mode) {
        case QLC_GUEST_VLAN_MODE:
@@ -1561,6 +1563,7 @@ void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
                                struct qlcnic_vf_info *vf)
 {
        struct net_device *dev = vf->adapter->netdev;
+       struct qlcnic_vport *vp = vf->vp;
 
        if (!test_and_clear_bit(QLC_BC_VF_STATE, &vf->state)) {
                clear_bit(QLC_BC_VF_FLR, &vf->state);
@@ -1573,6 +1576,9 @@ void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
                return;
        }
 
+       if (vp->vlan_mode == QLC_GUEST_VLAN_MODE)
+               vp->vlan = 0;
+
        qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr);
        netdev_info(dev, "FLR received for PCI func %d\n", vf->pci_func);
 }
@@ -1621,13 +1627,15 @@ int qlcnic_sriov_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
-       int i, num_vfs = sriov->num_vfs;
+       int i, num_vfs;
        struct qlcnic_vf_info *vf_info;
        u8 *curr_mac;
 
        if (!qlcnic_sriov_pf_check(adapter))
                return -EOPNOTSUPP;
 
+       num_vfs = sriov->num_vfs;
+
        if (!is_valid_ether_addr(mac) || vf >= num_vfs)
                return -EINVAL;
 
@@ -1741,6 +1749,7 @@ int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf,
 
        switch (vlan) {
        case 4095:
+               vp->vlan = 0;
                vp->vlan_mode = QLC_GUEST_VLAN_MODE;
                break;
        case 0:
@@ -1759,6 +1768,29 @@ int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf,
        return 0;
 }
 
+static inline __u32 qlcnic_sriov_get_vf_vlan(struct qlcnic_adapter *adapter,
+                                            struct qlcnic_vport *vp, int vf)
+{
+       __u32 vlan = 0;
+
+       switch (vp->vlan_mode) {
+       case QLC_PVID_MODE:
+               vlan = vp->vlan;
+               break;
+       case QLC_GUEST_VLAN_MODE:
+               vlan = MAX_VLAN_ID;
+               break;
+       case QLC_NO_VLAN_MODE:
+               vlan = 0;
+               break;
+       default:
+               netdev_info(adapter->netdev, "Invalid VLAN mode = %d for VF %d\n",
+                           vp->vlan_mode, vf);
+       }
+
+       return vlan;
+}
+
 int qlcnic_sriov_get_vf_config(struct net_device *netdev,
                               int vf, struct ifla_vf_info *ivi)
 {
@@ -1774,7 +1806,7 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev,
 
        vp = sriov->vf_info[vf].vp;
        memcpy(&ivi->mac, vp->mac, ETH_ALEN);
-       ivi->vlan = vp->vlan;
+       ivi->vlan = qlcnic_sriov_get_vf_vlan(adapter, vp, vf);
        ivi->qos = vp->qos;
        ivi->spoofchk = vp->spoofchk;
        if (vp->max_tx_bw == MAX_BW)