Skip to content

Commit

Permalink
forcedeth: restart tx/rx
Browse files Browse the repository at this point in the history
This patch fixes the issue where the transmitter and receiver must be
restarted when applying new changes to certain registers.

Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Ayaz Abdulla authored and Jeff Garzik committed Feb 6, 2008
1 parent 47eaa26 commit b2976d2
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions drivers/net/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit b2976d2

Please sign in to comment.