Add support for `ndo_set_vf_spoofchk' to allow PF control over
its VF spoof-checking configuration.

Signed-off-by: Shahed Shaikh <shahed.sha...@cavium.com>
Signed-off-by: Ariel Elior <ariel.el...@cavium.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h   |  1 +
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c  |  1 +
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 80 ++++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h |  2 +
 4 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 0e508e5..142bc11 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -494,6 +494,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vf,
 int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
 int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
                      __be16 vlan_proto);
+int bnx2x_set_vf_spoofchk(struct net_device *dev, int idx, bool val);
 
 /* select_queue callback */
 u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 71362b7..faf64ba 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13121,6 +13121,7 @@ static int bnx2x_vlan_rx_kill_vid(struct net_device 
*dev, __be16 proto, u16 vid)
        .ndo_set_vf_mac         = bnx2x_set_vf_mac,
        .ndo_set_vf_vlan        = bnx2x_set_vf_vlan,
        .ndo_get_vf_config      = bnx2x_get_vf_config,
+       .ndo_set_vf_spoofchk    = bnx2x_set_vf_spoofchk,
 #endif
 #ifdef NETDEV_FCOE_WWNN
        .ndo_fcoe_get_wwn       = bnx2x_fcoe_get_wwn,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 62da465..2f76b37 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -209,7 +209,10 @@ void bnx2x_vfop_qctor_prep(struct bnx2x *bp,
         */
        __set_bit(BNX2X_Q_FLG_TX_SWITCH, &setup_p->flags);
        __set_bit(BNX2X_Q_FLG_TX_SEC, &setup_p->flags);
-       __set_bit(BNX2X_Q_FLG_ANTI_SPOOF, &setup_p->flags);
+       if (vf->spoofchk)
+               __set_bit(BNX2X_Q_FLG_ANTI_SPOOF, &setup_p->flags);
+       else
+               __clear_bit(BNX2X_Q_FLG_ANTI_SPOOF, &setup_p->flags);
 
        /* Setup-op rx parameters */
        if (test_bit(BNX2X_Q_TYPE_HAS_RX, &q_type)) {
@@ -1269,6 +1272,8 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int 
int_mode_param,
                bnx2x_vf(bp, i, state) = VF_FREE;
                mutex_init(&bnx2x_vf(bp, i, op_mutex));
                bnx2x_vf(bp, i, op_current) = CHANNEL_TLV_NONE;
+               /* enable spoofchk by default */
+               bnx2x_vf(bp, i, spoofchk) = 1;
        }
 
        /* re-read the IGU CAM for VFs - index and abs_vfid must be set */
@@ -2632,7 +2637,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
        ivi->qos = 0;
        ivi->max_tx_rate = 10000; /* always 10G. TBA take from link struct */
        ivi->min_tx_rate = 0;
-       ivi->spoofchk = 1; /*always enabled */
+       ivi->spoofchk = vf->spoofchk ? 1 : 0;
        if (vf->state == VF_ENABLED) {
                /* mac and vlan are in vlan_mac objects */
                if (bnx2x_validate_vf_sp_objs(bp, vf, false)) {
@@ -2950,6 +2955,77 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, 
u16 vlan, u8 qos,
        return rc;
 }
 
+int bnx2x_set_vf_spoofchk(struct net_device *dev, int idx, bool val)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       struct bnx2x_virtf *vf;
+       int i, rc = 0;
+
+       vf = BP_VF(bp, idx);
+       if (!vf)
+               return -EINVAL;
+
+       /* nothing to do */
+       if (vf->spoofchk == val)
+               return 0;
+
+       vf->spoofchk = val ? 1 : 0;
+
+       DP(BNX2X_MSG_IOV, "%s spoofchk for VF %d\n",
+          val ? "enabling" : "disabling", idx);
+
+       /* is vf initialized and queue set up? */
+       if (vf->state != VF_ENABLED ||
+           bnx2x_get_q_logical_state(bp, &bnx2x_leading_vfq(vf, sp_obj)) !=
+           BNX2X_Q_LOGICAL_STATE_ACTIVE)
+               return rc;
+
+       /* User should be able to see error in system logs */
+       if (!bnx2x_validate_vf_sp_objs(bp, vf, true))
+               return -EINVAL;
+
+       /* send queue update ramrods to configure spoofchk */
+       for_each_vfq(vf, i) {
+               struct bnx2x_queue_state_params q_params = {NULL};
+               struct bnx2x_queue_update_params *update_params;
+
+               q_params.q_obj = &bnx2x_vfq(vf, i, sp_obj);
+
+               /* validate the Q is UP */
+               if (bnx2x_get_q_logical_state(bp, q_params.q_obj) !=
+                   BNX2X_Q_LOGICAL_STATE_ACTIVE)
+                       continue;
+
+               __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
+               q_params.cmd = BNX2X_Q_CMD_UPDATE;
+               update_params = &q_params.params.update;
+               __set_bit(BNX2X_Q_UPDATE_ANTI_SPOOF_CHNG,
+                         &update_params->update_flags);
+               if (val) {
+                       __set_bit(BNX2X_Q_UPDATE_ANTI_SPOOF,
+                                 &update_params->update_flags);
+               } else {
+                       __clear_bit(BNX2X_Q_UPDATE_ANTI_SPOOF,
+                                   &update_params->update_flags);
+               }
+
+               /* Update the Queue state */
+               rc = bnx2x_queue_state_change(bp, &q_params);
+               if (rc) {
+                       BNX2X_ERR("Failed to %s spoofchk on VF %d - vfq %d\n",
+                                 val ? "enable" : "disable", idx, i);
+                       goto out;
+               }
+       }
+out:
+       if (!rc)
+               DP(BNX2X_MSG_IOV,
+                  "%s spoofchk for VF[%d]\n", val ? "Enabled" : "Disabled",
+                  idx);
+
+       return rc;
+}
+
 /* crc is the first field in the bulletin board. Compute the crc over the
  * entire bulletin board excluding the crc field itself. Use the length field
  * as the Bulletin Board was posted by a PF with possibly a different version
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index eb814c6..b6ebd92 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -142,6 +142,8 @@ struct bnx2x_virtf {
 
        bool flr_clnup_stage;   /* true during flr cleanup */
        bool malicious;         /* true if FW indicated so, until FLR */
+       /* 1(true) if spoof check is enabled */
+       u8 spoofchk;
 
        /* dma */
        dma_addr_t fw_stat_map;
-- 
1.8.3.1

Reply via email to