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

Commit b2976d23 authored by Ayaz Abdulla's avatar Ayaz Abdulla Committed by Jeff Garzik
Browse files

forcedeth: restart tx/rx



This patch fixes the issue where the transmitter and receiver must be
restarted when applying new changes to certain registers.

Signed-off-by: default avatarAyaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 47eaa267
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -624,6 +624,9 @@ union ring_type {
#define NV_MSI_X_VECTOR_TX    0x1
#define NV_MSI_X_VECTOR_OTHER 0x2

#define NV_RESTART_TX         0x1
#define NV_RESTART_RX         0x2

/* statistics */
struct nv_ethtool_str {
	char name[ETH_GSTRING_LEN];
@@ -2767,6 +2770,7 @@ static int nv_update_linkspeed(struct net_device *dev)
	int mii_status;
	int retval = 0;
	u32 control_1000, status_1000, phyreg, pause_flags, txreg;
	u32 txrxFlags = 0;

	/* BMSR_LSTATUS is latched, read it twice:
	 * we want the current value.
@@ -2862,6 +2866,16 @@ static int nv_update_linkspeed(struct net_device *dev)
	np->duplex = newdup;
	np->linkspeed = newls;

	/* The transmitter and receiver must be restarted for safe update */
	if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START) {
		txrxFlags |= NV_RESTART_TX;
		nv_stop_tx(dev);
	}
	if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
		txrxFlags |= NV_RESTART_RX;
		nv_stop_rx(dev);
	}

	if (np->gigabit == PHY_GIGABIT) {
		phyreg = readl(base + NvRegRandomSeed);
		phyreg &= ~(0x3FF00);
@@ -2950,6 +2964,11 @@ static int nv_update_linkspeed(struct net_device *dev)
	}
	nv_update_pause(dev, pause_flags);

	if (txrxFlags & NV_RESTART_TX)
		nv_start_tx(dev);
	if (txrxFlags & NV_RESTART_RX)
		nv_start_rx(dev);

	return retval;
}