Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55fd0cf3 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

bnxt_en: Add external loopback test to ethtool selftest.



Add code to detect firmware support for external loopback and the extra
test entry for external loopback.

Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e795892e
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -6337,6 +6337,10 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
		bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
		bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
				 PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK;
				 PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK;
	}
	}
	if (resp->flags & PORT_PHY_QCAPS_RESP_FLAGS_EXTERNAL_LPBK_SUPPORTED) {
		if (bp->test_info)
			bp->test_info->flags |= BNXT_TEST_FL_EXT_LPBK;
	}
	if (resp->supported_speeds_auto_mode)
	if (resp->supported_speeds_auto_mode)
		link_info->support_auto_speeds =
		link_info->support_auto_speeds =
			le16_to_cpu(resp->supported_speeds_auto_mode);
			le16_to_cpu(resp->supported_speeds_auto_mode);
+2 −0
Original line number Original line Diff line number Diff line
@@ -990,6 +990,8 @@ struct bnxt_led_info {


struct bnxt_test_info {
struct bnxt_test_info {
	u8 offline_mask;
	u8 offline_mask;
	u8 flags;
#define BNXT_TEST_FL_EXT_LPBK	0x1
	u16 timeout;
	u16 timeout;
	char string[BNXT_MAX_TEST][ETH_GSTRING_LEN];
	char string[BNXT_MAX_TEST][ETH_GSTRING_LEN];
};
};
+26 −6
Original line number Original line Diff line number Diff line
@@ -2397,7 +2397,7 @@ static int bnxt_disable_an_for_lpbk(struct bnxt *bp,
	return rc;
	return rc;
}
}


static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable)
static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable, bool ext)
{
{
	struct hwrm_port_phy_cfg_input req = {0};
	struct hwrm_port_phy_cfg_input req = {0};


@@ -2405,6 +2405,9 @@ static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable)


	if (enable) {
	if (enable) {
		bnxt_disable_an_for_lpbk(bp, &req);
		bnxt_disable_an_for_lpbk(bp, &req);
		if (ext)
			req.lpbk = PORT_PHY_CFG_REQ_LPBK_EXTERNAL;
		else
			req.lpbk = PORT_PHY_CFG_REQ_LPBK_LOCAL;
			req.lpbk = PORT_PHY_CFG_REQ_LPBK_LOCAL;
	} else {
	} else {
		req.lpbk = PORT_PHY_CFG_REQ_LPBK_NONE;
		req.lpbk = PORT_PHY_CFG_REQ_LPBK_NONE;
@@ -2538,15 +2541,17 @@ static int bnxt_run_fw_tests(struct bnxt *bp, u8 test_mask, u8 *test_results)
	return rc;
	return rc;
}
}


#define BNXT_DRV_TESTS			3
#define BNXT_DRV_TESTS			4
#define BNXT_MACLPBK_TEST_IDX		(bp->num_tests - BNXT_DRV_TESTS)
#define BNXT_MACLPBK_TEST_IDX		(bp->num_tests - BNXT_DRV_TESTS)
#define BNXT_PHYLPBK_TEST_IDX		(BNXT_MACLPBK_TEST_IDX + 1)
#define BNXT_PHYLPBK_TEST_IDX		(BNXT_MACLPBK_TEST_IDX + 1)
#define BNXT_IRQ_TEST_IDX		(BNXT_MACLPBK_TEST_IDX + 2)
#define BNXT_EXTLPBK_TEST_IDX		(BNXT_MACLPBK_TEST_IDX + 2)
#define BNXT_IRQ_TEST_IDX		(BNXT_MACLPBK_TEST_IDX + 3)


static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
			   u64 *buf)
			   u64 *buf)
{
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt *bp = netdev_priv(dev);
	bool do_ext_lpbk = false;
	bool offline = false;
	bool offline = false;
	u8 test_results = 0;
	u8 test_results = 0;
	u8 test_mask = 0;
	u8 test_mask = 0;
@@ -2560,6 +2565,10 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
		return;
		return;
	}
	}


	if ((etest->flags & ETH_TEST_FL_EXTERNAL_LB) &&
	    (bp->test_info->flags & BNXT_TEST_FL_EXT_LPBK))
		do_ext_lpbk = true;

	if (etest->flags & ETH_TEST_FL_OFFLINE) {
	if (etest->flags & ETH_TEST_FL_OFFLINE) {
		if (bp->pf.active_vfs) {
		if (bp->pf.active_vfs) {
			etest->flags |= ETH_TEST_FL_FAILED;
			etest->flags |= ETH_TEST_FL_FAILED;
@@ -2600,13 +2609,22 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
			buf[BNXT_MACLPBK_TEST_IDX] = 0;
			buf[BNXT_MACLPBK_TEST_IDX] = 0;


		bnxt_hwrm_mac_loopback(bp, false);
		bnxt_hwrm_mac_loopback(bp, false);
		bnxt_hwrm_phy_loopback(bp, true);
		bnxt_hwrm_phy_loopback(bp, true, false);
		msleep(1000);
		msleep(1000);
		if (bnxt_run_loopback(bp)) {
		if (bnxt_run_loopback(bp)) {
			buf[BNXT_PHYLPBK_TEST_IDX] = 1;
			buf[BNXT_PHYLPBK_TEST_IDX] = 1;
			etest->flags |= ETH_TEST_FL_FAILED;
			etest->flags |= ETH_TEST_FL_FAILED;
		}
		}
		bnxt_hwrm_phy_loopback(bp, false);
		if (do_ext_lpbk) {
			etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
			bnxt_hwrm_phy_loopback(bp, true, true);
			msleep(1000);
			if (bnxt_run_loopback(bp)) {
				buf[BNXT_EXTLPBK_TEST_IDX] = 1;
				etest->flags |= ETH_TEST_FL_FAILED;
			}
		}
		bnxt_hwrm_phy_loopback(bp, false, false);
		bnxt_half_close_nic(bp);
		bnxt_half_close_nic(bp);
		bnxt_open_nic(bp, false, true);
		bnxt_open_nic(bp, false, true);
	}
	}
@@ -2707,6 +2725,8 @@ void bnxt_ethtool_init(struct bnxt *bp)
			strcpy(str, "Mac loopback test (offline)");
			strcpy(str, "Mac loopback test (offline)");
		} else if (i == BNXT_PHYLPBK_TEST_IDX) {
		} else if (i == BNXT_PHYLPBK_TEST_IDX) {
			strcpy(str, "Phy loopback test (offline)");
			strcpy(str, "Phy loopback test (offline)");
		} else if (i == BNXT_EXTLPBK_TEST_IDX) {
			strcpy(str, "Ext loopback test (offline)");
		} else if (i == BNXT_IRQ_TEST_IDX) {
		} else if (i == BNXT_IRQ_TEST_IDX) {
			strcpy(str, "Interrupt_test (offline)");
			strcpy(str, "Interrupt_test (offline)");
		} else {
		} else {