diff options
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 85 | ||||
-rw-r--r-- | drivers/net/igb/e1000_phy.c | 97 | ||||
-rw-r--r-- | drivers/net/igb/e1000_phy.h | 2 |
3 files changed, 119 insertions, 65 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 65b900028bca..78971815bbce 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -277,45 +277,23 @@ static void igb_release_phy_82575(struct e1000_hw *hw) | |||
277 | static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, | 277 | static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, |
278 | u16 *data) | 278 | u16 *data) |
279 | { | 279 | { |
280 | struct e1000_phy_info *phy = &hw->phy; | 280 | s32 ret_val = -E1000_ERR_PARAM; |
281 | u32 i, i2ccmd = 0; | ||
282 | 281 | ||
283 | if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) { | 282 | if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) { |
284 | hw_dbg("PHY Address %u is out of range\n", offset); | 283 | hw_dbg("PHY Address %u is out of range\n", offset); |
285 | return -E1000_ERR_PARAM; | 284 | goto out; |
286 | } | 285 | } |
287 | 286 | ||
288 | /* | 287 | ret_val = hw->phy.ops.acquire(hw); |
289 | * Set up Op-code, Phy Address, and register address in the I2CCMD | 288 | if (ret_val) |
290 | * register. The MAC will take care of interfacing with the | 289 | goto out; |
291 | * PHY to retrieve the desired data. | ||
292 | */ | ||
293 | i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
294 | (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | | ||
295 | (E1000_I2CCMD_OPCODE_READ)); | ||
296 | 290 | ||
297 | wr32(E1000_I2CCMD, i2ccmd); | 291 | ret_val = igb_read_phy_reg_i2c(hw, offset, data); |
298 | 292 | ||
299 | /* Poll the ready bit to see if the I2C read completed */ | 293 | hw->phy.ops.release(hw); |
300 | for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { | ||
301 | udelay(50); | ||
302 | i2ccmd = rd32(E1000_I2CCMD); | ||
303 | if (i2ccmd & E1000_I2CCMD_READY) | ||
304 | break; | ||
305 | } | ||
306 | if (!(i2ccmd & E1000_I2CCMD_READY)) { | ||
307 | hw_dbg("I2CCMD Read did not complete\n"); | ||
308 | return -E1000_ERR_PHY; | ||
309 | } | ||
310 | if (i2ccmd & E1000_I2CCMD_ERROR) { | ||
311 | hw_dbg("I2CCMD Error bit set\n"); | ||
312 | return -E1000_ERR_PHY; | ||
313 | } | ||
314 | |||
315 | /* Need to byte-swap the 16-bit value. */ | ||
316 | *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00); | ||
317 | 294 | ||
318 | return 0; | 295 | out: |
296 | return ret_val; | ||
319 | } | 297 | } |
320 | 298 | ||
321 | /** | 299 | /** |
@@ -330,47 +308,24 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, | |||
330 | static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, | 308 | static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, |
331 | u16 data) | 309 | u16 data) |
332 | { | 310 | { |
333 | struct e1000_phy_info *phy = &hw->phy; | 311 | s32 ret_val = -E1000_ERR_PARAM; |
334 | u32 i, i2ccmd = 0; | 312 | |
335 | u16 phy_data_swapped; | ||
336 | 313 | ||
337 | if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) { | 314 | if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) { |
338 | hw_dbg("PHY Address %d is out of range\n", offset); | 315 | hw_dbg("PHY Address %d is out of range\n", offset); |
339 | return -E1000_ERR_PARAM; | 316 | goto out; |
340 | } | 317 | } |
341 | 318 | ||
342 | /* Swap the data bytes for the I2C interface */ | 319 | ret_val = hw->phy.ops.acquire(hw); |
343 | phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); | 320 | if (ret_val) |
321 | goto out; | ||
344 | 322 | ||
345 | /* | 323 | ret_val = igb_write_phy_reg_i2c(hw, offset, data); |
346 | * Set up Op-code, Phy Address, and register address in the I2CCMD | ||
347 | * register. The MAC will take care of interfacing with the | ||
348 | * PHY to retrieve the desired data. | ||
349 | */ | ||
350 | i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
351 | (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | | ||
352 | E1000_I2CCMD_OPCODE_WRITE | | ||
353 | phy_data_swapped); | ||
354 | |||
355 | wr32(E1000_I2CCMD, i2ccmd); | ||
356 | |||
357 | /* Poll the ready bit to see if the I2C read completed */ | ||
358 | for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { | ||
359 | udelay(50); | ||
360 | i2ccmd = rd32(E1000_I2CCMD); | ||
361 | if (i2ccmd & E1000_I2CCMD_READY) | ||
362 | break; | ||
363 | } | ||
364 | if (!(i2ccmd & E1000_I2CCMD_READY)) { | ||
365 | hw_dbg("I2CCMD Write did not complete\n"); | ||
366 | return -E1000_ERR_PHY; | ||
367 | } | ||
368 | if (i2ccmd & E1000_I2CCMD_ERROR) { | ||
369 | hw_dbg("I2CCMD Error bit set\n"); | ||
370 | return -E1000_ERR_PHY; | ||
371 | } | ||
372 | 324 | ||
373 | return 0; | 325 | hw->phy.ops.release(hw); |
326 | |||
327 | out: | ||
328 | return ret_val; | ||
374 | } | 329 | } |
375 | 330 | ||
376 | /** | 331 | /** |
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index ee460600e74b..d4c928ccb294 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c | |||
@@ -239,6 +239,103 @@ out: | |||
239 | } | 239 | } |
240 | 240 | ||
241 | /** | 241 | /** |
242 | * igb_read_phy_reg_i2c - Read PHY register using i2c | ||
243 | * @hw: pointer to the HW structure | ||
244 | * @offset: register offset to be read | ||
245 | * @data: pointer to the read data | ||
246 | * | ||
247 | * Reads the PHY register at offset using the i2c interface and stores the | ||
248 | * retrieved information in data. | ||
249 | **/ | ||
250 | s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data) | ||
251 | { | ||
252 | struct e1000_phy_info *phy = &hw->phy; | ||
253 | u32 i, i2ccmd = 0; | ||
254 | |||
255 | |||
256 | /* | ||
257 | * Set up Op-code, Phy Address, and register address in the I2CCMD | ||
258 | * register. The MAC will take care of interfacing with the | ||
259 | * PHY to retrieve the desired data. | ||
260 | */ | ||
261 | i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
262 | (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | | ||
263 | (E1000_I2CCMD_OPCODE_READ)); | ||
264 | |||
265 | wr32(E1000_I2CCMD, i2ccmd); | ||
266 | |||
267 | /* Poll the ready bit to see if the I2C read completed */ | ||
268 | for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { | ||
269 | udelay(50); | ||
270 | i2ccmd = rd32(E1000_I2CCMD); | ||
271 | if (i2ccmd & E1000_I2CCMD_READY) | ||
272 | break; | ||
273 | } | ||
274 | if (!(i2ccmd & E1000_I2CCMD_READY)) { | ||
275 | hw_dbg("I2CCMD Read did not complete\n"); | ||
276 | return -E1000_ERR_PHY; | ||
277 | } | ||
278 | if (i2ccmd & E1000_I2CCMD_ERROR) { | ||
279 | hw_dbg("I2CCMD Error bit set\n"); | ||
280 | return -E1000_ERR_PHY; | ||
281 | } | ||
282 | |||
283 | /* Need to byte-swap the 16-bit value. */ | ||
284 | *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * igb_write_phy_reg_i2c - Write PHY register using i2c | ||
291 | * @hw: pointer to the HW structure | ||
292 | * @offset: register offset to write to | ||
293 | * @data: data to write at register offset | ||
294 | * | ||
295 | * Writes the data to PHY register at the offset using the i2c interface. | ||
296 | **/ | ||
297 | s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) | ||
298 | { | ||
299 | struct e1000_phy_info *phy = &hw->phy; | ||
300 | u32 i, i2ccmd = 0; | ||
301 | u16 phy_data_swapped; | ||
302 | |||
303 | |||
304 | /* Swap the data bytes for the I2C interface */ | ||
305 | phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); | ||
306 | |||
307 | /* | ||
308 | * Set up Op-code, Phy Address, and register address in the I2CCMD | ||
309 | * register. The MAC will take care of interfacing with the | ||
310 | * PHY to retrieve the desired data. | ||
311 | */ | ||
312 | i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
313 | (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | | ||
314 | E1000_I2CCMD_OPCODE_WRITE | | ||
315 | phy_data_swapped); | ||
316 | |||
317 | wr32(E1000_I2CCMD, i2ccmd); | ||
318 | |||
319 | /* Poll the ready bit to see if the I2C read completed */ | ||
320 | for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { | ||
321 | udelay(50); | ||
322 | i2ccmd = rd32(E1000_I2CCMD); | ||
323 | if (i2ccmd & E1000_I2CCMD_READY) | ||
324 | break; | ||
325 | } | ||
326 | if (!(i2ccmd & E1000_I2CCMD_READY)) { | ||
327 | hw_dbg("I2CCMD Write did not complete\n"); | ||
328 | return -E1000_ERR_PHY; | ||
329 | } | ||
330 | if (i2ccmd & E1000_I2CCMD_ERROR) { | ||
331 | hw_dbg("I2CCMD Error bit set\n"); | ||
332 | return -E1000_ERR_PHY; | ||
333 | } | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | /** | ||
242 | * igb_read_phy_reg_igp - Read igp PHY register | 339 | * igb_read_phy_reg_igp - Read igp PHY register |
243 | * @hw: pointer to the HW structure | 340 | * @hw: pointer to the HW structure |
244 | * @offset: register offset to be read | 341 | * @offset: register offset to be read |
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h index ebe4b616db8a..4c49803eeed9 100644 --- a/drivers/net/igb/e1000_phy.h +++ b/drivers/net/igb/e1000_phy.h | |||
@@ -61,6 +61,8 @@ s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); | |||
61 | s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, | 61 | s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, |
62 | u32 usec_interval, bool *success); | 62 | u32 usec_interval, bool *success); |
63 | s32 igb_phy_init_script_igp3(struct e1000_hw *hw); | 63 | s32 igb_phy_init_script_igp3(struct e1000_hw *hw); |
64 | s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); | ||
65 | s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); | ||
64 | 66 | ||
65 | /* IGP01E1000 Specific Registers */ | 67 | /* IGP01E1000 Specific Registers */ |
66 | #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ | 68 | #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ |