aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-11-05 18:52:10 -0500
committerJeff Garzik <jeff@garzik.org>2007-11-10 04:25:08 -0500
commitaf043aa54fd45774e61979d1748616c2a67f0da8 (patch)
treeee4df2ee14195776b537f4509e3049c0ae729661 /drivers
parentab5adecb2d02f3688719dfb5936a82833fcc3955 (diff)
sky2: longer PHY delay
Increse phy delay and handle I/O errors. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 706884ae8fcd..eaab3d87dcf3 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -156,7 +156,7 @@ static const char *yukon2_name[] = {
156 156
157static void sky2_set_multicast(struct net_device *dev); 157static void sky2_set_multicast(struct net_device *dev);
158 158
159/* Access to external PHY */ 159/* Access to PHY via serial interconnect */
160static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) 160static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
161{ 161{
162 int i; 162 int i;
@@ -166,13 +166,22 @@ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
166 GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg)); 166 GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
167 167
168 for (i = 0; i < PHY_RETRIES; i++) { 168 for (i = 0; i < PHY_RETRIES; i++) {
169 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) 169 u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
170 if (ctrl == 0xffff)
171 goto io_error;
172
173 if (!(ctrl & GM_SMI_CT_BUSY))
170 return 0; 174 return 0;
171 udelay(1); 175
176 udelay(10);
172 } 177 }
173 178
174 printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name); 179 dev_warn(&hw->pdev->dev,"%s: phy write timeout\n", hw->dev[port]->name);
175 return -ETIMEDOUT; 180 return -ETIMEDOUT;
181
182io_error:
183 dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
184 return -EIO;
176} 185}
177 186
178static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val) 187static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
@@ -183,23 +192,29 @@ static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
183 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); 192 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
184 193
185 for (i = 0; i < PHY_RETRIES; i++) { 194 for (i = 0; i < PHY_RETRIES; i++) {
186 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) { 195 u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
196 if (ctrl == 0xffff)
197 goto io_error;
198
199 if (ctrl & GM_SMI_CT_RD_VAL) {
187 *val = gma_read16(hw, port, GM_SMI_DATA); 200 *val = gma_read16(hw, port, GM_SMI_DATA);
188 return 0; 201 return 0;
189 } 202 }
190 203
191 udelay(1); 204 udelay(10);
192 } 205 }
193 206
207 dev_warn(&hw->pdev->dev, "%s: phy read timeout\n", hw->dev[port]->name);
194 return -ETIMEDOUT; 208 return -ETIMEDOUT;
209io_error:
210 dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
211 return -EIO;
195} 212}
196 213
197static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) 214static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
198{ 215{
199 u16 v; 216 u16 v;
200 217 __gm_phy_read(hw, port, reg, &v);
201 if (__gm_phy_read(hw, port, reg, &v) != 0)
202 printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
203 return v; 218 return v;
204} 219}
205 220