bnxt_en: Setup multicast properly after resetting device.
authorMichael Chan <michael.chan@broadcom.com>
Wed, 4 May 2016 20:56:44 +0000 (16:56 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 May 2016 21:11:38 +0000 (17:11 -0400)
The multicast/all-multicast internal flags are not properly restored
after device reset.  This could lead to unreliable multicast operations
after an ethtool configuration change for example.

Call bnxt_mc_list_updated() and setup the vnic->mask in bnxt_init_chip()
to fix the issue.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index f33ff205a0ea98aba515cbb66658f783526e9316..9d4e8e113fe18f564060d48a6e686f5a4c79dadd 100644 (file)
@@ -4042,9 +4042,11 @@ static int bnxt_alloc_rfs_vnics(struct bnxt *bp)
 }
 
 static int bnxt_cfg_rx_mode(struct bnxt *);
+static bool bnxt_mc_list_updated(struct bnxt *, u32 *);
 
 static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
 {
+       struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
        int rc = 0;
 
        if (irq_re_init) {
@@ -4100,13 +4102,22 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
                netdev_err(bp->dev, "HWRM vnic filter failure rc: %x\n", rc);
                goto err_out;
        }
-       bp->vnic_info[0].uc_filter_count = 1;
+       vnic->uc_filter_count = 1;
 
-       bp->vnic_info[0].rx_mask = CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
+       vnic->rx_mask = CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
 
        if ((bp->dev->flags & IFF_PROMISC) && BNXT_PF(bp))
-               bp->vnic_info[0].rx_mask |=
-                               CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
+               vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
+
+       if (bp->dev->flags & IFF_ALLMULTI) {
+               vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
+               vnic->mc_list_count = 0;
+       } else {
+               u32 mask = 0;
+
+               bnxt_mc_list_updated(bp, &mask);
+               vnic->rx_mask |= mask;
+       }
 
        rc = bnxt_cfg_rx_mode(bp);
        if (rc)