Skip to content

Commit

Permalink
forcedeth: prevent TX timeouts after reboot
Browse files Browse the repository at this point in the history
This complements patch "net-forcedeth: fix TX timeout caused by TX
pause on down link" which ensures that a lock-up sequence is not sent
to the NIC. Present patch ensures that if a NIC is already locked-up,
the driver will recover from it when initializing the device.

It does the equivalent of the following recovery sequence:
 - write NVREG_TX_PAUSEFRAME_ENABLE_V1 to eth1's register
   NvRegTxPauseFrame
 - write NVREG_XMITCTL_START to eth1's register
   NvRegTransmitterControl
 - write 0 to eth1's register NvRegTransmitterControl
(this is at the heart of the "unbricking" sequence mentioned in patch
 "net-forcedeth: fix TX timeout caused by TX pause on down link")

Tested:
 - hardware is MCP55 device id 10de:0373 (rev a3), dual-port
 - reboot a kernel without any of patches mentioned
 - freeze the NIC (details on description for commit "net-forcedeth:
   fix TX timeout caused by TX pause on down link")
 - wait 5mn until ping hangs & TX timeout in dmesg
 - reboot on kernel with present patch
 - host is immediatly operational, no TX timeout

Signed-off-by: David Decotigny <decot@googlers.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
david decotigny authored and David S. Miller committed Aug 30, 2012
1 parent 1ff39eb commit 3f0a1b5
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions drivers/net/ethernet/nvidia/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -5905,11 +5905,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
goto out_error;
}

netif_carrier_off(dev);

/* Some NICs freeze when TX pause is enabled while NIC is
* down, and this stays across warm reboots. The sequence
* below should be enough to recover from that state.
*/
nv_update_pause(dev, 0);
nv_start_tx(dev);
nv_stop_tx(dev);

if (id->driver_data & DEV_HAS_VLAN)
nv_vlan_mode(dev, dev->features);

netif_carrier_off(dev);

dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n",
dev->name, np->phy_oui, np->phyaddr, dev->dev_addr);

Expand Down

0 comments on commit 3f0a1b5

Please sign in to comment.