qlcnic: Support spoof check config.
authorRajesh Borundia <rajesh.borundia@qlogic.com>
Thu, 23 May 2013 21:04:25 +0000 (21:04 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 25 May 2013 06:04:53 +0000 (23:04 -0700)
o Add support for spoof check configuration per VF using
  iproute2 tool.

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c

index aeb26a8..1e19671 100644 (file)
@@ -449,6 +449,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
        .ndo_set_vf_tx_rate     = qlcnic_sriov_set_vf_tx_rate,
        .ndo_get_vf_config      = qlcnic_sriov_get_vf_config,
        .ndo_set_vf_vlan        = qlcnic_sriov_set_vf_vlan,
+       .ndo_set_vf_spoofchk    = qlcnic_sriov_set_vf_spoofchk,
 #endif
 };
 
index d85fbb5..9176cb0 100644 (file)
@@ -129,6 +129,7 @@ struct qlcnic_vport {
        u8                      vlan_mode;
        u16                     vlan;
        u8                      qos;
+       bool                    spoofchk;
        u8                      mac[6];
 };
 
@@ -225,6 +226,7 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int);
 int qlcnic_sriov_get_vf_config(struct net_device *, int ,
                               struct ifla_vf_info *);
 int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8);
+int qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool);
 #else
 static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
 static inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
index 196b2d1..6262c71 100644 (file)
@@ -187,6 +187,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
                        }
                        sriov->vf_info[i].vp = vp;
                        vp->max_tx_bw = MAX_BW;
+                       vp->spoofchk = true;
                        random_ether_addr(vp->mac);
                        dev_info(&adapter->pdev->dev,
                                 "MAC Address %pM is configured for VF %d\n",
index 1a66ccd..ee0c1d3 100644 (file)
@@ -580,6 +580,7 @@ static int qlcnic_sriov_set_vf_acl(struct qlcnic_adapter *adapter, u8 func)
        struct qlcnic_cmd_args cmd;
        struct qlcnic_vport *vp;
        int err, id;
+       u8 *mac;
 
        id = qlcnic_sriov_func_to_index(adapter, func);
        if (id < 0)
@@ -591,6 +592,14 @@ static int qlcnic_sriov_set_vf_acl(struct qlcnic_adapter *adapter, u8 func)
                return err;
 
        cmd.req.arg[1] = 0x3 | func << 16;
+       if (vp->spoofchk == true) {
+               mac = vp->mac;
+               cmd.req.arg[2] |= BIT_1 | BIT_3 | BIT_8;
+               cmd.req.arg[4] = mac[5] | mac[4] << 8 | mac[3] << 16 |
+                                mac[2] << 24;
+               cmd.req.arg[5] = mac[1] | mac[0] << 8;
+       }
+
        if (vp->vlan_mode == QLC_PVID_MODE) {
                cmd.req.arg[2] |= BIT_6;
                cmd.req.arg[3] |= vp->vlan << 8;
@@ -1767,6 +1776,7 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev,
        memcpy(&ivi->mac, vp->mac, ETH_ALEN);
        ivi->vlan = vp->vlan;
        ivi->qos = vp->qos;
+       ivi->spoofchk = vp->spoofchk;
        if (vp->max_tx_bw == MAX_BW)
                ivi->tx_rate = 0;
        else
@@ -1775,3 +1785,29 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev,
        ivi->vf = vf;
        return 0;
 }
+
+int qlcnic_sriov_set_vf_spoofchk(struct net_device *netdev, int vf, bool chk)
+{
+       struct qlcnic_adapter *adapter = netdev_priv(netdev);
+       struct qlcnic_sriov *sriov = adapter->ahw->sriov;
+       struct qlcnic_vf_info *vf_info;
+       struct qlcnic_vport *vp;
+
+       if (!qlcnic_sriov_pf_check(adapter))
+               return -EOPNOTSUPP;
+
+       if (vf >= sriov->num_vfs)
+               return -EINVAL;
+
+       vf_info = &sriov->vf_info[vf];
+       vp = vf_info->vp;
+       if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
+               netdev_err(netdev,
+                          "Spoof check change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n",
+                          vf);
+               return -EOPNOTSUPP;
+       }
+
+       vp->spoofchk = chk;
+       return 0;
+}