aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAyaz Abdulla <aabdulla@nvidia.com>2008-02-04 15:13:59 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-06 06:41:14 -0500
commitb2976d23a15aac11e8e77a496108b9f4040fac4d (patch)
treef5ac3f3007795411969047233591f0b364db65cd /drivers
parent47eaa267a5db1729d238f977364e297b8963e115 (diff)
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: Ayaz Abdulla <aabdulla@nvidia.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/forcedeth.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 36342230a6de..6e47b1103cd2 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -624,6 +624,9 @@ union ring_type {
624#define NV_MSI_X_VECTOR_TX 0x1 624#define NV_MSI_X_VECTOR_TX 0x1
625#define NV_MSI_X_VECTOR_OTHER 0x2 625#define NV_MSI_X_VECTOR_OTHER 0x2
626 626
627#define NV_RESTART_TX 0x1
628#define NV_RESTART_RX 0x2
629
627/* statistics */ 630/* statistics */
628struct nv_ethtool_str { 631struct nv_ethtool_str {
629 char name[ETH_GSTRING_LEN]; 632 char name[ETH_GSTRING_LEN];
@@ -2767,6 +2770,7 @@ static int nv_update_linkspeed(struct net_device *dev)
2767 int mii_status; 2770 int mii_status;
2768 int retval = 0; 2771 int retval = 0;
2769 u32 control_1000, status_1000, phyreg, pause_flags, txreg; 2772 u32 control_1000, status_1000, phyreg, pause_flags, txreg;
2773 u32 txrxFlags = 0;
2770 2774
2771 /* BMSR_LSTATUS is latched, read it twice: 2775 /* BMSR_LSTATUS is latched, read it twice:
2772 * we want the current value. 2776 * we want the current value.
@@ -2862,6 +2866,16 @@ set_speed:
2862 np->duplex = newdup; 2866 np->duplex = newdup;
2863 np->linkspeed = newls; 2867 np->linkspeed = newls;
2864 2868
2869 /* The transmitter and receiver must be restarted for safe update */
2870 if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START) {
2871 txrxFlags |= NV_RESTART_TX;
2872 nv_stop_tx(dev);
2873 }
2874 if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
2875 txrxFlags |= NV_RESTART_RX;
2876 nv_stop_rx(dev);
2877 }
2878
2865 if (np->gigabit == PHY_GIGABIT) { 2879 if (np->gigabit == PHY_GIGABIT) {
2866 phyreg = readl(base + NvRegRandomSeed); 2880 phyreg = readl(base + NvRegRandomSeed);
2867 phyreg &= ~(0x3FF00); 2881 phyreg &= ~(0x3FF00);
@@ -2950,6 +2964,11 @@ set_speed:
2950 } 2964 }
2951 nv_update_pause(dev, pause_flags); 2965 nv_update_pause(dev, pause_flags);
2952 2966
2967 if (txrxFlags & NV_RESTART_TX)
2968 nv_start_tx(dev);
2969 if (txrxFlags & NV_RESTART_RX)
2970 nv_start_rx(dev);
2971
2953 return retval; 2972 return retval;
2954} 2973}
2955 2974