]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnxt_en: Workaround Nitro A0 RX hardware bug (part 4).
authorPrashant Sreedharan <prashant.sreedharan@broadcom.com>
Mon, 18 Jul 2016 11:15:24 +0000 (07:15 -0400)
committerDhaval Giani <dhaval.giani@oracle.com>
Fri, 20 Jan 2017 17:59:23 +0000 (12:59 -0500)
Orabug: 24567991

Allocate special vnic for dropping packets not matching the RX filters.
First vnic is for normal RX packets and the driver will drop all
packets on the 2nd vnic.

Signed-off-by: Prashant Sreedharan <prashant.sreedharan@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit dc52c6c70e0066e9cef886907f820411bebe8e07)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Signed-off-by: Dhaval Giani <dhaval.giani@oracle.com>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index 36fc7e9a176e59e2c7a33d3a513ce0c1f9e9c697..bba5dee46489b95b4bd78f7921f1ed086b125cc8 100644 (file)
@@ -2414,6 +2414,9 @@ static int bnxt_alloc_vnics(struct bnxt *bp)
                num_vnics += bp->rx_nr_rings;
 #endif
 
+       if (BNXT_CHIP_TYPE_NITRO_A0(bp))
+               num_vnics++;
+
        bp->vnic_info = kcalloc(num_vnics, sizeof(struct bnxt_vnic_info),
                                GFP_KERNEL);
        if (!bp->vnic_info)
@@ -3289,8 +3292,10 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
        struct hwrm_cfa_l2_filter_alloc_output *resp = bp->hwrm_cmd_resp_addr;
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_L2_FILTER_ALLOC, -1, -1);
-       req.flags = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX |
-                               CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST);
+       req.flags = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX);
+       if (!BNXT_CHIP_TYPE_NITRO_A0(bp))
+               req.flags |=
+                       cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST);
        req.dst_id = cpu_to_le16(bp->vnic_info[vnic_id].fw_vnic_id);
        req.enables =
                cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR |
@@ -3409,10 +3414,14 @@ static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
 
                req.hash_type = cpu_to_le32(vnic->hash_type);
 
-               if (vnic->flags & BNXT_VNIC_RSS_FLAG)
-                       max_rings = bp->rx_nr_rings;
-               else
+               if (vnic->flags & BNXT_VNIC_RSS_FLAG) {
+                       if (BNXT_CHIP_TYPE_NITRO_A0(bp))
+                               max_rings = bp->rx_nr_rings - 1;
+                       else
+                               max_rings = bp->rx_nr_rings;
+               } else {
                        max_rings = 1;
+               }
 
                /* Fill the RSS indirection table with ring group ids */
                for (i = 0, j = 0; i < HW_HASH_INDEX_SIZE; i++, j++) {
@@ -3504,13 +3513,19 @@ static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
        u16 def_vlan = 0;
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_CFG, -1, -1);
+
+       req.enables = cpu_to_le32(VNIC_CFG_REQ_ENABLES_DFLT_RING_GRP);
        /* Only RSS support for now TBD: COS & LB */
-       req.enables = cpu_to_le32(VNIC_CFG_REQ_ENABLES_DFLT_RING_GRP |
-                                 VNIC_CFG_REQ_ENABLES_RSS_RULE |
-                                 VNIC_CFG_REQ_ENABLES_MRU);
-       req.rss_rule = cpu_to_le16(vnic->fw_rss_cos_lb_ctx[0]);
+       if (vnic->fw_rss_cos_lb_ctx[0] != INVALID_HW_RING_ID) {
+               req.rss_rule = cpu_to_le16(vnic->fw_rss_cos_lb_ctx[0]);
+               req.enables |= cpu_to_le32(VNIC_CFG_REQ_ENABLES_RSS_RULE |
+                                          VNIC_CFG_REQ_ENABLES_MRU);
+       } else {
+               req.rss_rule = cpu_to_le16(0xffff);
+       }
 
-       if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+       if (BNXT_CHIP_TYPE_NITRO_A0(bp) &&
+           (vnic->fw_rss_cos_lb_ctx[0] != INVALID_HW_RING_ID)) {
                req.cos_rule = cpu_to_le16(vnic->fw_rss_cos_lb_ctx[1]);
                req.enables |= cpu_to_le32(VNIC_CFG_REQ_ENABLES_COS_RULE);
        } else {
@@ -4448,6 +4463,26 @@ static bool bnxt_promisc_ok(struct bnxt *bp)
        return true;
 }
 
+static int bnxt_setup_nitroa0_vnic(struct bnxt *bp)
+{
+       unsigned int rc = 0;
+
+       rc = bnxt_hwrm_vnic_alloc(bp, 1, bp->rx_nr_rings - 1, 1);
+       if (rc) {
+               netdev_err(bp->dev, "Cannot allocate special vnic for NS2 A0: %x\n",
+                          rc);
+               return rc;
+       }
+
+       rc = bnxt_hwrm_vnic_cfg(bp, 1);
+       if (rc) {
+               netdev_err(bp->dev, "Cannot allocate special vnic for NS2 A0: %x\n",
+                          rc);
+               return rc;
+       }
+       return rc;
+}
+
 static int bnxt_cfg_rx_mode(struct bnxt *);
 static bool bnxt_mc_list_updated(struct bnxt *, u32 *);
 
@@ -4537,7 +4572,14 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
        rc = bnxt_hwrm_set_coal(bp);
        if (rc)
                netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n",
-                           rc);
+                               rc);
+
+       if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+               rc = bnxt_setup_nitroa0_vnic(bp);
+               if (rc)
+                       netdev_err(bp->dev, "Special vnic setup failure for NS2 A0 rc: %x\n",
+                                  rc);
+       }
 
        if (BNXT_VF(bp)) {
                bnxt_hwrm_func_qcfg(bp);