]> git.dujemihanovic.xyz Git - linux.git/commitdiff
bnxt_en: Fix occasional ethtool -t loopback test failures
authorMichael Chan <michael.chan@broadcom.com>
Sun, 20 Feb 2022 09:05:49 +0000 (04:05 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sun, 20 Feb 2022 13:47:14 +0000 (13:47 +0000)
In the current code, we setup the port to PHY or MAC loopback mode
and then transmit a test broadcast packet for the loopback test.  This
scheme fails sometime if the port is shared with management firmware
that can also send packets.  The driver may receive the management
firmware's packet and the test will fail when the contents don't
match the test packet.

Change the test packet to use it's own MAC address as the destination
and setup the port to only receive it's own MAC address.  This should
filter out other packets sent by management firmware.

Fixes: 91725d89b97a ("bnxt_en: Add PHY loopback to ethtool self-test.")
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: Edwin Peer <edwin.peer@broadcom.com>
Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
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
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index 23bbb1c5812dfcf0c509955d304bca7013f5be2a..785436f6dd24462cad7b7101877f17e3d4422d80 100644 (file)
@@ -8639,6 +8639,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
        vnic->uc_filter_count = 1;
 
        vnic->rx_mask = 0;
+       if (test_bit(BNXT_STATE_HALF_OPEN, &bp->state))
+               goto skip_rx_mask;
+
        if (bp->dev->flags & IFF_BROADCAST)
                vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
 
@@ -8659,6 +8662,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
        if (rc)
                goto err_out;
 
+skip_rx_mask:
        rc = bnxt_hwrm_set_coal(bp);
        if (rc)
                netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n",
@@ -10335,8 +10339,10 @@ int bnxt_half_open_nic(struct bnxt *bp)
                netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
                goto half_open_err;
        }
+       set_bit(BNXT_STATE_HALF_OPEN, &bp->state);
        rc = bnxt_init_nic(bp, true);
        if (rc) {
+               clear_bit(BNXT_STATE_HALF_OPEN, &bp->state);
                netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc);
                goto half_open_err;
        }
@@ -10357,6 +10363,7 @@ void bnxt_half_close_nic(struct bnxt *bp)
        bnxt_hwrm_resource_free(bp, false, true);
        bnxt_free_skbs(bp);
        bnxt_free_mem(bp, true);
+       clear_bit(BNXT_STATE_HALF_OPEN, &bp->state);
 }
 
 void bnxt_reenable_sriov(struct bnxt *bp)
index 440dfeb4948bc67fe3f3d7036471b21b3075b4f7..666fc1e7a7d2f5efef820f6e627d7b20ef925ad9 100644 (file)
@@ -1921,6 +1921,7 @@ struct bnxt {
 #define BNXT_STATE_RECOVER             12
 #define BNXT_STATE_FW_NON_FATAL_COND   13
 #define BNXT_STATE_FW_ACTIVATE_RESET   14
+#define BNXT_STATE_HALF_OPEN           15      /* For offline ethtool tests */
 
 #define BNXT_NO_FW_ACCESS(bp)                                  \
        (test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) ||    \
index a85b18858b3240aa433c782dc1e07e2c317eb9ce..8aaa2335f848aa627dc3ef7bb182e87acd1c9995 100644 (file)
@@ -3458,7 +3458,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
        if (!skb)
                return -ENOMEM;
        data = skb_put(skb, pkt_size);
-       eth_broadcast_addr(data);
+       ether_addr_copy(&data[i], bp->dev->dev_addr);
        i += ETH_ALEN;
        ether_addr_copy(&data[i], bp->dev->dev_addr);
        i += ETH_ALEN;