aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-10-26 07:24:02 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-26 19:16:25 -0400
commit5ccdcecb72692d46d7a9264e62751241c7eca559 (patch)
treec82d7487a41fed230234578f1ddbe1b35ea59e5e /drivers/net/e1000e
parentca15df58b1b98f073393eef3704674b45d1cb474 (diff)
e1000e: allow for swflag to be held over consecutive PHY accesses
PCH-based parts (82577/82578) and some ICH8-based parts (82566) need to hold the swflag (sw/fw/hw hardware semaphore) over consecutive PHY accesses in order to perform sw-driven PHY configuration during initialization to workaround known hardware issues (see follow-on patch). This patch provides new PHY read/write functions (and function pointers) that will allow accessing the PHY registers assuming the swflag has already been acquired. The actual PHY register access code has moved into helper functions that are called with a flag indicating whether or not the swflag has already been acquired and acquires/releases it if not. The functions called from within the updated PHY access functions had to be updated to assume the swflag was already acquired, and other functions that called those functions were also updated to acquire/release the swflag. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r--drivers/net/e1000e/e1000.h12
-rw-r--r--drivers/net/e1000e/hw.h2
-rw-r--r--drivers/net/e1000e/ich8lan.c4
-rw-r--r--drivers/net/e1000e/phy.c469
4 files changed, 346 insertions, 141 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 981936c1fb46..405a144ebcad 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -519,9 +519,13 @@ extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
519extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); 519extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
520extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); 520extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
521extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); 521extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
522extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
523 u16 *data);
522extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw); 524extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
523extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active); 525extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
524extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); 526extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
527extern s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
528 u16 data);
525extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw); 529extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
526extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw); 530extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
527extern s32 e1000e_get_cfg_done(struct e1000_hw *hw); 531extern s32 e1000e_get_cfg_done(struct e1000_hw *hw);
@@ -538,7 +542,11 @@ extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
538extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); 542extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
539extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); 543extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
540extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); 544extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
545extern s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
546 u16 data);
541extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); 547extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
548extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
549 u16 *data);
542extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, 550extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
543 u32 usec_interval, bool *success); 551 u32 usec_interval, bool *success);
544extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); 552extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
@@ -546,7 +554,11 @@ extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
546extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); 554extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
547extern s32 e1000e_check_downshift(struct e1000_hw *hw); 555extern s32 e1000e_check_downshift(struct e1000_hw *hw);
548extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); 556extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
557extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
558 u16 *data);
549extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); 559extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
560extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
561 u16 data);
550extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); 562extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
551extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); 563extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
552extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); 564extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index fd44d9f90769..7b05cf47f7f5 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -764,11 +764,13 @@ struct e1000_phy_operations {
764 s32 (*get_cable_length)(struct e1000_hw *); 764 s32 (*get_cable_length)(struct e1000_hw *);
765 s32 (*get_phy_info)(struct e1000_hw *); 765 s32 (*get_phy_info)(struct e1000_hw *);
766 s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *); 766 s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
767 s32 (*read_phy_reg_locked)(struct e1000_hw *, u32, u16 *);
767 void (*release_phy)(struct e1000_hw *); 768 void (*release_phy)(struct e1000_hw *);
768 s32 (*reset_phy)(struct e1000_hw *); 769 s32 (*reset_phy)(struct e1000_hw *);
769 s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); 770 s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
770 s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); 771 s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
771 s32 (*write_phy_reg)(struct e1000_hw *, u32, u16); 772 s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
773 s32 (*write_phy_reg_locked)(struct e1000_hw *, u32, u16);
772 s32 (*cfg_on_link_up)(struct e1000_hw *); 774 s32 (*cfg_on_link_up)(struct e1000_hw *);
773}; 775};
774 776
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index aaaaf2ca4084..b6388b9535fd 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -250,9 +250,11 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
250 250
251 phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan; 251 phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
252 phy->ops.read_phy_reg = e1000_read_phy_reg_hv; 252 phy->ops.read_phy_reg = e1000_read_phy_reg_hv;
253 phy->ops.read_phy_reg_locked = e1000_read_phy_reg_hv_locked;
253 phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan; 254 phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan;
254 phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; 255 phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan;
255 phy->ops.write_phy_reg = e1000_write_phy_reg_hv; 256 phy->ops.write_phy_reg = e1000_write_phy_reg_hv;
257 phy->ops.write_phy_reg_locked = e1000_write_phy_reg_hv_locked;
256 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 258 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
257 259
258 phy->id = e1000_phy_unknown; 260 phy->id = e1000_phy_unknown;
@@ -313,6 +315,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
313 case IGP03E1000_E_PHY_ID: 315 case IGP03E1000_E_PHY_ID:
314 phy->type = e1000_phy_igp_3; 316 phy->type = e1000_phy_igp_3;
315 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; 317 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
318 phy->ops.read_phy_reg_locked = e1000e_read_phy_reg_igp_locked;
319 phy->ops.write_phy_reg_locked = e1000e_write_phy_reg_igp_locked;
316 break; 320 break;
317 case IFE_E_PHY_ID: 321 case IFE_E_PHY_ID:
318 case IFE_PLUS_E_PHY_ID: 322 case IFE_PLUS_E_PHY_ID:
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 994401fd0664..f9d33ab05e97 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -164,16 +164,25 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw)
164 * MDIC mode. No harm in trying again in this case since 164 * MDIC mode. No harm in trying again in this case since
165 * the PHY ID is unknown at this point anyway 165 * the PHY ID is unknown at this point anyway
166 */ 166 */
167 ret_val = phy->ops.acquire_phy(hw);
168 if (ret_val)
169 goto out;
167 ret_val = e1000_set_mdio_slow_mode_hv(hw, true); 170 ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
168 if (ret_val) 171 if (ret_val)
169 goto out; 172 goto out;
173 phy->ops.release_phy(hw);
170 174
171 retry_count++; 175 retry_count++;
172 } 176 }
173out: 177out:
174 /* Revert to MDIO fast mode, if applicable */ 178 /* Revert to MDIO fast mode, if applicable */
175 if (retry_count) 179 if (retry_count) {
180 ret_val = phy->ops.acquire_phy(hw);
181 if (ret_val)
182 return ret_val;
176 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 183 ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
184 phy->ops.release_phy(hw);
185 }
177 186
178 return ret_val; 187 return ret_val;
179} 188}
@@ -354,94 +363,173 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
354} 363}
355 364
356/** 365/**
357 * e1000e_read_phy_reg_igp - Read igp PHY register 366 * __e1000e_read_phy_reg_igp - Read igp PHY register
358 * @hw: pointer to the HW structure 367 * @hw: pointer to the HW structure
359 * @offset: register offset to be read 368 * @offset: register offset to be read
360 * @data: pointer to the read data 369 * @data: pointer to the read data
370 * @locked: semaphore has already been acquired or not
361 * 371 *
362 * Acquires semaphore, if necessary, then reads the PHY register at offset 372 * Acquires semaphore, if necessary, then reads the PHY register at offset
363 * and storing the retrieved information in data. Release any acquired 373 * and stores the retrieved information in data. Release any acquired
364 * semaphores before exiting. 374 * semaphores before exiting.
365 **/ 375 **/
366s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) 376static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
377 bool locked)
367{ 378{
368 s32 ret_val; 379 s32 ret_val = 0;
369 380
370 ret_val = hw->phy.ops.acquire_phy(hw); 381 if (!locked) {
371 if (ret_val) 382 if (!(hw->phy.ops.acquire_phy))
372 return ret_val; 383 goto out;
384
385 ret_val = hw->phy.ops.acquire_phy(hw);
386 if (ret_val)
387 goto out;
388 }
373 389
374 if (offset > MAX_PHY_MULTI_PAGE_REG) { 390 if (offset > MAX_PHY_MULTI_PAGE_REG) {
375 ret_val = e1000e_write_phy_reg_mdic(hw, 391 ret_val = e1000e_write_phy_reg_mdic(hw,
376 IGP01E1000_PHY_PAGE_SELECT, 392 IGP01E1000_PHY_PAGE_SELECT,
377 (u16)offset); 393 (u16)offset);
378 if (ret_val) { 394 if (ret_val)
379 hw->phy.ops.release_phy(hw); 395 goto release;
380 return ret_val;
381 }
382 } 396 }
383 397
384 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 398 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
385 data); 399 data);
386
387 hw->phy.ops.release_phy(hw);
388 400
401release:
402 if (!locked)
403 hw->phy.ops.release_phy(hw);
404out:
389 return ret_val; 405 return ret_val;
390} 406}
391 407
392/** 408/**
409 * e1000e_read_phy_reg_igp - Read igp PHY register
410 * @hw: pointer to the HW structure
411 * @offset: register offset to be read
412 * @data: pointer to the read data
413 *
414 * Acquires semaphore then reads the PHY register at offset and stores the
415 * retrieved information in data.
416 * Release the acquired semaphore before exiting.
417 **/
418s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
419{
420 return __e1000e_read_phy_reg_igp(hw, offset, data, false);
421}
422
423/**
424 * e1000e_read_phy_reg_igp_locked - Read igp PHY register
425 * @hw: pointer to the HW structure
426 * @offset: register offset to be read
427 * @data: pointer to the read data
428 *
429 * Reads the PHY register at offset and stores the retrieved information
430 * in data. Assumes semaphore already acquired.
431 **/
432s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
433{
434 return __e1000e_read_phy_reg_igp(hw, offset, data, true);
435}
436
437/**
393 * e1000e_write_phy_reg_igp - Write igp PHY register 438 * e1000e_write_phy_reg_igp - Write igp PHY register
394 * @hw: pointer to the HW structure 439 * @hw: pointer to the HW structure
395 * @offset: register offset to write to 440 * @offset: register offset to write to
396 * @data: data to write at register offset 441 * @data: data to write at register offset
442 * @locked: semaphore has already been acquired or not
397 * 443 *
398 * Acquires semaphore, if necessary, then writes the data to PHY register 444 * Acquires semaphore, if necessary, then writes the data to PHY register
399 * at the offset. Release any acquired semaphores before exiting. 445 * at the offset. Release any acquired semaphores before exiting.
400 **/ 446 **/
401s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) 447static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
448 bool locked)
402{ 449{
403 s32 ret_val; 450 s32 ret_val = 0;
404 451
405 ret_val = hw->phy.ops.acquire_phy(hw); 452 if (!locked) {
406 if (ret_val) 453 if (!(hw->phy.ops.acquire_phy))
407 return ret_val; 454 goto out;
455
456 ret_val = hw->phy.ops.acquire_phy(hw);
457 if (ret_val)
458 goto out;
459 }
408 460
409 if (offset > MAX_PHY_MULTI_PAGE_REG) { 461 if (offset > MAX_PHY_MULTI_PAGE_REG) {
410 ret_val = e1000e_write_phy_reg_mdic(hw, 462 ret_val = e1000e_write_phy_reg_mdic(hw,
411 IGP01E1000_PHY_PAGE_SELECT, 463 IGP01E1000_PHY_PAGE_SELECT,
412 (u16)offset); 464 (u16)offset);
413 if (ret_val) { 465 if (ret_val)
414 hw->phy.ops.release_phy(hw); 466 goto release;
415 return ret_val;
416 }
417 } 467 }
418 468
419 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 469 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
420 data); 470 data);
421 471
422 hw->phy.ops.release_phy(hw); 472release:
473 if (!locked)
474 hw->phy.ops.release_phy(hw);
423 475
476out:
424 return ret_val; 477 return ret_val;
425} 478}
426 479
427/** 480/**
428 * e1000e_read_kmrn_reg - Read kumeran register 481 * e1000e_write_phy_reg_igp - Write igp PHY register
482 * @hw: pointer to the HW structure
483 * @offset: register offset to write to
484 * @data: data to write at register offset
485 *
486 * Acquires semaphore then writes the data to PHY register
487 * at the offset. Release any acquired semaphores before exiting.
488 **/
489s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
490{
491 return __e1000e_write_phy_reg_igp(hw, offset, data, false);
492}
493
494/**
495 * e1000e_write_phy_reg_igp_locked - Write igp PHY register
496 * @hw: pointer to the HW structure
497 * @offset: register offset to write to
498 * @data: data to write at register offset
499 *
500 * Writes the data to PHY register at the offset.
501 * Assumes semaphore already acquired.
502 **/
503s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
504{
505 return __e1000e_write_phy_reg_igp(hw, offset, data, true);
506}
507
508/**
509 * __e1000_read_kmrn_reg - Read kumeran register
429 * @hw: pointer to the HW structure 510 * @hw: pointer to the HW structure
430 * @offset: register offset to be read 511 * @offset: register offset to be read
431 * @data: pointer to the read data 512 * @data: pointer to the read data
513 * @locked: semaphore has already been acquired or not
432 * 514 *
433 * Acquires semaphore, if necessary. Then reads the PHY register at offset 515 * Acquires semaphore, if necessary. Then reads the PHY register at offset
434 * using the kumeran interface. The information retrieved is stored in data. 516 * using the kumeran interface. The information retrieved is stored in data.
435 * Release any acquired semaphores before exiting. 517 * Release any acquired semaphores before exiting.
436 **/ 518 **/
437s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) 519static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
520 bool locked)
438{ 521{
439 u32 kmrnctrlsta; 522 u32 kmrnctrlsta;
440 s32 ret_val; 523 s32 ret_val = 0;
441 524
442 ret_val = hw->phy.ops.acquire_phy(hw); 525 if (!locked) {
443 if (ret_val) 526 if (!(hw->phy.ops.acquire_phy))
444 return ret_val; 527 goto out;
528
529 ret_val = hw->phy.ops.acquire_phy(hw);
530 if (ret_val)
531 goto out;
532 }
445 533
446 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 534 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
447 E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; 535 E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
@@ -452,41 +540,111 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
452 kmrnctrlsta = er32(KMRNCTRLSTA); 540 kmrnctrlsta = er32(KMRNCTRLSTA);
453 *data = (u16)kmrnctrlsta; 541 *data = (u16)kmrnctrlsta;
454 542
455 hw->phy.ops.release_phy(hw); 543 if (!locked)
544 hw->phy.ops.release_phy(hw);
456 545
546out:
457 return ret_val; 547 return ret_val;
458} 548}
459 549
460/** 550/**
461 * e1000e_write_kmrn_reg - Write kumeran register 551 * e1000e_read_kmrn_reg - Read kumeran register
552 * @hw: pointer to the HW structure
553 * @offset: register offset to be read
554 * @data: pointer to the read data
555 *
556 * Acquires semaphore then reads the PHY register at offset using the
557 * kumeran interface. The information retrieved is stored in data.
558 * Release the acquired semaphore before exiting.
559 **/
560s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
561{
562 return __e1000_read_kmrn_reg(hw, offset, data, false);
563}
564
565/**
566 * e1000_read_kmrn_reg_locked - Read kumeran register
567 * @hw: pointer to the HW structure
568 * @offset: register offset to be read
569 * @data: pointer to the read data
570 *
571 * Reads the PHY register at offset using the kumeran interface. The
572 * information retrieved is stored in data.
573 * Assumes semaphore already acquired.
574 **/
575s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
576{
577 return __e1000_read_kmrn_reg(hw, offset, data, true);
578}
579
580/**
581 * __e1000_write_kmrn_reg - Write kumeran register
462 * @hw: pointer to the HW structure 582 * @hw: pointer to the HW structure
463 * @offset: register offset to write to 583 * @offset: register offset to write to
464 * @data: data to write at register offset 584 * @data: data to write at register offset
585 * @locked: semaphore has already been acquired or not
465 * 586 *
466 * Acquires semaphore, if necessary. Then write the data to PHY register 587 * Acquires semaphore, if necessary. Then write the data to PHY register
467 * at the offset using the kumeran interface. Release any acquired semaphores 588 * at the offset using the kumeran interface. Release any acquired semaphores
468 * before exiting. 589 * before exiting.
469 **/ 590 **/
470s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) 591static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
592 bool locked)
471{ 593{
472 u32 kmrnctrlsta; 594 u32 kmrnctrlsta;
473 s32 ret_val; 595 s32 ret_val = 0;
474 596
475 ret_val = hw->phy.ops.acquire_phy(hw); 597 if (!locked) {
476 if (ret_val) 598 if (!(hw->phy.ops.acquire_phy))
477 return ret_val; 599 goto out;
600
601 ret_val = hw->phy.ops.acquire_phy(hw);
602 if (ret_val)
603 goto out;
604 }
478 605
479 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 606 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
480 E1000_KMRNCTRLSTA_OFFSET) | data; 607 E1000_KMRNCTRLSTA_OFFSET) | data;
481 ew32(KMRNCTRLSTA, kmrnctrlsta); 608 ew32(KMRNCTRLSTA, kmrnctrlsta);
482 609
483 udelay(2); 610 udelay(2);
484 hw->phy.ops.release_phy(hw);
485 611
612 if (!locked)
613 hw->phy.ops.release_phy(hw);
614
615out:
486 return ret_val; 616 return ret_val;
487} 617}
488 618
489/** 619/**
620 * e1000e_write_kmrn_reg - Write kumeran register
621 * @hw: pointer to the HW structure
622 * @offset: register offset to write to
623 * @data: data to write at register offset
624 *
625 * Acquires semaphore then writes the data to the PHY register at the offset
626 * using the kumeran interface. Release the acquired semaphore before exiting.
627 **/
628s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
629{
630 return __e1000_write_kmrn_reg(hw, offset, data, false);
631}
632
633/**
634 * e1000_write_kmrn_reg_locked - Write kumeran register
635 * @hw: pointer to the HW structure
636 * @offset: register offset to write to
637 * @data: data to write at register offset
638 *
639 * Write the data to PHY register at the offset using the kumeran interface.
640 * Assumes semaphore already acquired.
641 **/
642s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
643{
644 return __e1000_write_kmrn_reg(hw, offset, data, true);
645}
646
647/**
490 * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link 648 * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
491 * @hw: pointer to the HW structure 649 * @hw: pointer to the HW structure
492 * 650 *
@@ -2105,6 +2263,10 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2105 u32 page = offset >> IGP_PAGE_SHIFT; 2263 u32 page = offset >> IGP_PAGE_SHIFT;
2106 u32 page_shift = 0; 2264 u32 page_shift = 0;
2107 2265
2266 ret_val = hw->phy.ops.acquire_phy(hw);
2267 if (ret_val)
2268 return ret_val;
2269
2108 /* Page 800 works differently than the rest so it has its own func */ 2270 /* Page 800 works differently than the rest so it has its own func */
2109 if (page == BM_WUC_PAGE) { 2271 if (page == BM_WUC_PAGE) {
2110 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2272 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
@@ -2112,10 +2274,6 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2112 goto out; 2274 goto out;
2113 } 2275 }
2114 2276
2115 ret_val = hw->phy.ops.acquire_phy(hw);
2116 if (ret_val)
2117 goto out;
2118
2119 hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); 2277 hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2120 2278
2121 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2279 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2135,18 +2293,15 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2135 /* Page is shifted left, PHY expects (page x 32) */ 2293 /* Page is shifted left, PHY expects (page x 32) */
2136 ret_val = e1000e_write_phy_reg_mdic(hw, page_select, 2294 ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2137 (page << page_shift)); 2295 (page << page_shift));
2138 if (ret_val) { 2296 if (ret_val)
2139 hw->phy.ops.release_phy(hw);
2140 goto out; 2297 goto out;
2141 }
2142 } 2298 }
2143 2299
2144 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2300 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2145 data); 2301 data);
2146 2302
2147 hw->phy.ops.release_phy(hw);
2148
2149out: 2303out:
2304 hw->phy.ops.release_phy(hw);
2150 return ret_val; 2305 return ret_val;
2151} 2306}
2152 2307
@@ -2167,6 +2322,10 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2167 u32 page = offset >> IGP_PAGE_SHIFT; 2322 u32 page = offset >> IGP_PAGE_SHIFT;
2168 u32 page_shift = 0; 2323 u32 page_shift = 0;
2169 2324
2325 ret_val = hw->phy.ops.acquire_phy(hw);
2326 if (ret_val)
2327 return ret_val;
2328
2170 /* Page 800 works differently than the rest so it has its own func */ 2329 /* Page 800 works differently than the rest so it has its own func */
2171 if (page == BM_WUC_PAGE) { 2330 if (page == BM_WUC_PAGE) {
2172 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2331 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
@@ -2174,10 +2333,6 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2174 goto out; 2333 goto out;
2175 } 2334 }
2176 2335
2177 ret_val = hw->phy.ops.acquire_phy(hw);
2178 if (ret_val)
2179 goto out;
2180
2181 hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); 2336 hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2182 2337
2183 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2338 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2197,17 +2352,14 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2197 /* Page is shifted left, PHY expects (page x 32) */ 2352 /* Page is shifted left, PHY expects (page x 32) */
2198 ret_val = e1000e_write_phy_reg_mdic(hw, page_select, 2353 ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2199 (page << page_shift)); 2354 (page << page_shift));
2200 if (ret_val) { 2355 if (ret_val)
2201 hw->phy.ops.release_phy(hw);
2202 goto out; 2356 goto out;
2203 }
2204 } 2357 }
2205 2358
2206 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2359 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2207 data); 2360 data);
2208 hw->phy.ops.release_phy(hw);
2209
2210out: 2361out:
2362 hw->phy.ops.release_phy(hw);
2211 return ret_val; 2363 return ret_val;
2212} 2364}
2213 2365
@@ -2226,17 +2378,17 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
2226 s32 ret_val; 2378 s32 ret_val;
2227 u16 page = (u16)(offset >> IGP_PAGE_SHIFT); 2379 u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2228 2380
2381 ret_val = hw->phy.ops.acquire_phy(hw);
2382 if (ret_val)
2383 return ret_val;
2384
2229 /* Page 800 works differently than the rest so it has its own func */ 2385 /* Page 800 works differently than the rest so it has its own func */
2230 if (page == BM_WUC_PAGE) { 2386 if (page == BM_WUC_PAGE) {
2231 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2387 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2232 true); 2388 true);
2233 return ret_val; 2389 goto out;
2234 } 2390 }
2235 2391
2236 ret_val = hw->phy.ops.acquire_phy(hw);
2237 if (ret_val)
2238 return ret_val;
2239
2240 hw->phy.addr = 1; 2392 hw->phy.addr = 1;
2241 2393
2242 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2394 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2245,16 +2397,14 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
2245 ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, 2397 ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2246 page); 2398 page);
2247 2399
2248 if (ret_val) { 2400 if (ret_val)
2249 hw->phy.ops.release_phy(hw); 2401 goto out;
2250 return ret_val;
2251 }
2252 } 2402 }
2253 2403
2254 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2404 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2255 data); 2405 data);
2406out:
2256 hw->phy.ops.release_phy(hw); 2407 hw->phy.ops.release_phy(hw);
2257
2258 return ret_val; 2408 return ret_val;
2259} 2409}
2260 2410
@@ -2272,17 +2422,17 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2272 s32 ret_val; 2422 s32 ret_val;
2273 u16 page = (u16)(offset >> IGP_PAGE_SHIFT); 2423 u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2274 2424
2425 ret_val = hw->phy.ops.acquire_phy(hw);
2426 if (ret_val)
2427 return ret_val;
2428
2275 /* Page 800 works differently than the rest so it has its own func */ 2429 /* Page 800 works differently than the rest so it has its own func */
2276 if (page == BM_WUC_PAGE) { 2430 if (page == BM_WUC_PAGE) {
2277 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2431 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2278 false); 2432 false);
2279 return ret_val; 2433 goto out;
2280 } 2434 }
2281 2435
2282 ret_val = hw->phy.ops.acquire_phy(hw);
2283 if (ret_val)
2284 return ret_val;
2285
2286 hw->phy.addr = 1; 2436 hw->phy.addr = 1;
2287 2437
2288 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2438 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2290,17 +2440,15 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2290 ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, 2440 ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2291 page); 2441 page);
2292 2442
2293 if (ret_val) { 2443 if (ret_val)
2294 hw->phy.ops.release_phy(hw); 2444 goto out;
2295 return ret_val;
2296 }
2297 } 2445 }
2298 2446
2299 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2447 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2300 data); 2448 data);
2301 2449
2450out:
2302 hw->phy.ops.release_phy(hw); 2451 hw->phy.ops.release_phy(hw);
2303
2304 return ret_val; 2452 return ret_val;
2305} 2453}
2306 2454
@@ -2320,6 +2468,8 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2320 * 3) Write the address using the address opcode (0x11) 2468 * 3) Write the address using the address opcode (0x11)
2321 * 4) Read or write the data using the data opcode (0x12) 2469 * 4) Read or write the data using the data opcode (0x12)
2322 * 5) Restore 769_17.2 to its original value 2470 * 5) Restore 769_17.2 to its original value
2471 *
2472 * Assumes semaphore already acquired.
2323 **/ 2473 **/
2324static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, 2474static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2325 u16 *data, bool read) 2475 u16 *data, bool read)
@@ -2327,20 +2477,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2327 s32 ret_val; 2477 s32 ret_val;
2328 u16 reg = BM_PHY_REG_NUM(offset); 2478 u16 reg = BM_PHY_REG_NUM(offset);
2329 u16 phy_reg = 0; 2479 u16 phy_reg = 0;
2330 u8 phy_acquired = 1;
2331
2332 2480
2333 /* Gig must be disabled for MDIO accesses to page 800 */ 2481 /* Gig must be disabled for MDIO accesses to page 800 */
2334 if ((hw->mac.type == e1000_pchlan) && 2482 if ((hw->mac.type == e1000_pchlan) &&
2335 (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) 2483 (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
2336 hw_dbg(hw, "Attempting to access page 800 while gig enabled\n"); 2484 hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
2337 2485
2338 ret_val = hw->phy.ops.acquire_phy(hw);
2339 if (ret_val) {
2340 phy_acquired = 0;
2341 goto out;
2342 }
2343
2344 /* All operations in this function are phy address 1 */ 2486 /* All operations in this function are phy address 1 */
2345 hw->phy.addr = 1; 2487 hw->phy.addr = 1;
2346 2488
@@ -2397,8 +2539,6 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2397 ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); 2539 ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
2398 2540
2399out: 2541out:
2400 if (phy_acquired == 1)
2401 hw->phy.ops.release_phy(hw);
2402 return ret_val; 2542 return ret_val;
2403} 2543}
2404 2544
@@ -2439,52 +2579,63 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
2439 return 0; 2579 return 0;
2440} 2580}
2441 2581
2582/**
2583 * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
2584 * @hw: pointer to the HW structure
2585 * @slow: true for slow mode, false for normal mode
2586 *
2587 * Assumes semaphore already acquired.
2588 **/
2442s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) 2589s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
2443{ 2590{
2444 s32 ret_val = 0; 2591 s32 ret_val = 0;
2445 u16 data = 0; 2592 u16 data = 0;
2446 2593
2447 ret_val = hw->phy.ops.acquire_phy(hw);
2448 if (ret_val)
2449 return ret_val;
2450
2451 /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ 2594 /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
2452 hw->phy.addr = 1; 2595 hw->phy.addr = 1;
2453 ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 2596 ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
2454 (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); 2597 (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
2455 if (ret_val) { 2598 if (ret_val)
2456 hw->phy.ops.release_phy(hw); 2599 goto out;
2457 return ret_val; 2600
2458 }
2459 ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, 2601 ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
2460 (0x2180 | (slow << 10))); 2602 (0x2180 | (slow << 10)));
2603 if (ret_val)
2604 goto out;
2461 2605
2462 /* dummy read when reverting to fast mode - throw away result */ 2606 /* dummy read when reverting to fast mode - throw away result */
2463 if (!slow) 2607 if (!slow)
2464 e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); 2608 ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
2465
2466 hw->phy.ops.release_phy(hw);
2467 2609
2610out:
2468 return ret_val; 2611 return ret_val;
2469} 2612}
2470 2613
2471/** 2614/**
2472 * e1000_read_phy_reg_hv - Read HV PHY register 2615 * __e1000_read_phy_reg_hv - Read HV PHY register
2473 * @hw: pointer to the HW structure 2616 * @hw: pointer to the HW structure
2474 * @offset: register offset to be read 2617 * @offset: register offset to be read
2475 * @data: pointer to the read data 2618 * @data: pointer to the read data
2619 * @locked: semaphore has already been acquired or not
2476 * 2620 *
2477 * Acquires semaphore, if necessary, then reads the PHY register at offset 2621 * Acquires semaphore, if necessary, then reads the PHY register at offset
2478 * and storing the retrieved information in data. Release any acquired 2622 * and stores the retrieved information in data. Release any acquired
2479 * semaphore before exiting. 2623 * semaphore before exiting.
2480 **/ 2624 **/
2481s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) 2625static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
2626 bool locked)
2482{ 2627{
2483 s32 ret_val; 2628 s32 ret_val;
2484 u16 page = BM_PHY_REG_PAGE(offset); 2629 u16 page = BM_PHY_REG_PAGE(offset);
2485 u16 reg = BM_PHY_REG_NUM(offset); 2630 u16 reg = BM_PHY_REG_NUM(offset);
2486 bool in_slow_mode = false; 2631 bool in_slow_mode = false;
2487 2632
2633 if (!locked) {
2634 ret_val = hw->phy.ops.acquire_phy(hw);
2635 if (ret_val)
2636 return ret_val;
2637 }
2638
2488 /* Workaround failure in MDIO access while cable is disconnected */ 2639 /* Workaround failure in MDIO access while cable is disconnected */
2489 if ((hw->phy.type == e1000_phy_82577) && 2640 if ((hw->phy.type == e1000_phy_82577) &&
2490 !(er32(STATUS) & E1000_STATUS_LU)) { 2641 !(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2508,10 +2659,6 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2508 goto out; 2659 goto out;
2509 } 2660 }
2510 2661
2511 ret_val = hw->phy.ops.acquire_phy(hw);
2512 if (ret_val)
2513 goto out;
2514
2515 hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); 2662 hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2516 2663
2517 if (page == HV_INTC_FC_PAGE_START) 2664 if (page == HV_INTC_FC_PAGE_START)
@@ -2529,42 +2676,76 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2529 ret_val = e1000e_write_phy_reg_mdic(hw, 2676 ret_val = e1000e_write_phy_reg_mdic(hw,
2530 IGP01E1000_PHY_PAGE_SELECT, 2677 IGP01E1000_PHY_PAGE_SELECT,
2531 (page << IGP_PAGE_SHIFT)); 2678 (page << IGP_PAGE_SHIFT));
2532 if (ret_val) {
2533 hw->phy.ops.release_phy(hw);
2534 goto out;
2535 }
2536 hw->phy.addr = phy_addr; 2679 hw->phy.addr = phy_addr;
2537 } 2680 }
2538 } 2681 }
2539 2682
2540 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2683 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2541 data); 2684 data);
2542 hw->phy.ops.release_phy(hw);
2543
2544out: 2685out:
2545 /* Revert to MDIO fast mode, if applicable */ 2686 /* Revert to MDIO fast mode, if applicable */
2546 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) 2687 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
2547 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 2688 ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
2548 2689
2690 if (!locked)
2691 hw->phy.ops.release_phy(hw);
2692
2549 return ret_val; 2693 return ret_val;
2550} 2694}
2551 2695
2552/** 2696/**
2553 * e1000_write_phy_reg_hv - Write HV PHY register 2697 * e1000_read_phy_reg_hv - Read HV PHY register
2698 * @hw: pointer to the HW structure
2699 * @offset: register offset to be read
2700 * @data: pointer to the read data
2701 *
2702 * Acquires semaphore then reads the PHY register at offset and stores
2703 * the retrieved information in data. Release the acquired semaphore
2704 * before exiting.
2705 **/
2706s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2707{
2708 return __e1000_read_phy_reg_hv(hw, offset, data, false);
2709}
2710
2711/**
2712 * e1000_read_phy_reg_hv_locked - Read HV PHY register
2713 * @hw: pointer to the HW structure
2714 * @offset: register offset to be read
2715 * @data: pointer to the read data
2716 *
2717 * Reads the PHY register at offset and stores the retrieved information
2718 * in data. Assumes semaphore already acquired.
2719 **/
2720s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
2721{
2722 return __e1000_read_phy_reg_hv(hw, offset, data, true);
2723}
2724
2725/**
2726 * __e1000_write_phy_reg_hv - Write HV PHY register
2554 * @hw: pointer to the HW structure 2727 * @hw: pointer to the HW structure
2555 * @offset: register offset to write to 2728 * @offset: register offset to write to
2556 * @data: data to write at register offset 2729 * @data: data to write at register offset
2730 * @locked: semaphore has already been acquired or not
2557 * 2731 *
2558 * Acquires semaphore, if necessary, then writes the data to PHY register 2732 * Acquires semaphore, if necessary, then writes the data to PHY register
2559 * at the offset. Release any acquired semaphores before exiting. 2733 * at the offset. Release any acquired semaphores before exiting.
2560 **/ 2734 **/
2561s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) 2735static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
2736 bool locked)
2562{ 2737{
2563 s32 ret_val; 2738 s32 ret_val;
2564 u16 page = BM_PHY_REG_PAGE(offset); 2739 u16 page = BM_PHY_REG_PAGE(offset);
2565 u16 reg = BM_PHY_REG_NUM(offset); 2740 u16 reg = BM_PHY_REG_NUM(offset);
2566 bool in_slow_mode = false; 2741 bool in_slow_mode = false;
2567 2742
2743 if (!locked) {
2744 ret_val = hw->phy.ops.acquire_phy(hw);
2745 if (ret_val)
2746 return ret_val;
2747 }
2748
2568 /* Workaround failure in MDIO access while cable is disconnected */ 2749 /* Workaround failure in MDIO access while cable is disconnected */
2569 if ((hw->phy.type == e1000_phy_82577) && 2750 if ((hw->phy.type == e1000_phy_82577) &&
2570 !(er32(STATUS) & E1000_STATUS_LU)) { 2751 !(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2588,10 +2769,6 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2588 goto out; 2769 goto out;
2589 } 2770 }
2590 2771
2591 ret_val = hw->phy.ops.acquire_phy(hw);
2592 if (ret_val)
2593 goto out;
2594
2595 hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); 2772 hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2596 2773
2597 if (page == HV_INTC_FC_PAGE_START) 2774 if (page == HV_INTC_FC_PAGE_START)
@@ -2607,15 +2784,10 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2607 ((MAX_PHY_REG_ADDRESS & reg) == 0) && 2784 ((MAX_PHY_REG_ADDRESS & reg) == 0) &&
2608 (data & (1 << 11))) { 2785 (data & (1 << 11))) {
2609 u16 data2 = 0x7EFF; 2786 u16 data2 = 0x7EFF;
2610 hw->phy.ops.release_phy(hw);
2611 ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, 2787 ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
2612 &data2, false); 2788 &data2, false);
2613 if (ret_val) 2789 if (ret_val)
2614 goto out; 2790 goto out;
2615
2616 ret_val = hw->phy.ops.acquire_phy(hw);
2617 if (ret_val)
2618 goto out;
2619 } 2791 }
2620 2792
2621 if (reg > MAX_PHY_MULTI_PAGE_REG) { 2793 if (reg > MAX_PHY_MULTI_PAGE_REG) {
@@ -2630,27 +2802,53 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2630 ret_val = e1000e_write_phy_reg_mdic(hw, 2802 ret_val = e1000e_write_phy_reg_mdic(hw,
2631 IGP01E1000_PHY_PAGE_SELECT, 2803 IGP01E1000_PHY_PAGE_SELECT,
2632 (page << IGP_PAGE_SHIFT)); 2804 (page << IGP_PAGE_SHIFT));
2633 if (ret_val) {
2634 hw->phy.ops.release_phy(hw);
2635 goto out;
2636 }
2637 hw->phy.addr = phy_addr; 2805 hw->phy.addr = phy_addr;
2638 } 2806 }
2639 } 2807 }
2640 2808
2641 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2809 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2642 data); 2810 data);
2643 hw->phy.ops.release_phy(hw);
2644 2811
2645out: 2812out:
2646 /* Revert to MDIO fast mode, if applicable */ 2813 /* Revert to MDIO fast mode, if applicable */
2647 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) 2814 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
2648 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 2815 ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
2649 2816
2817 if (!locked)
2818 hw->phy.ops.release_phy(hw);
2819
2650 return ret_val; 2820 return ret_val;
2651} 2821}
2652 2822
2653/** 2823/**
2824 * e1000_write_phy_reg_hv - Write HV PHY register
2825 * @hw: pointer to the HW structure
2826 * @offset: register offset to write to
2827 * @data: data to write at register offset
2828 *
2829 * Acquires semaphore then writes the data to PHY register at the offset.
2830 * Release the acquired semaphores before exiting.
2831 **/
2832s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2833{
2834 return __e1000_write_phy_reg_hv(hw, offset, data, false);
2835}
2836
2837/**
2838 * e1000_write_phy_reg_hv_locked - Write HV PHY register
2839 * @hw: pointer to the HW structure
2840 * @offset: register offset to write to
2841 * @data: data to write at register offset
2842 *
2843 * Writes the data to PHY register at the offset. Assumes semaphore
2844 * already acquired.
2845 **/
2846s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
2847{
2848 return __e1000_write_phy_reg_hv(hw, offset, data, true);
2849}
2850
2851/**
2654 * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page 2852 * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
2655 * @page: page to be accessed 2853 * @page: page to be accessed
2656 **/ 2854 **/
@@ -2671,10 +2869,9 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page)
2671 * @data: pointer to the data to be read or written 2869 * @data: pointer to the data to be read or written
2672 * @read: determines if operation is read or written 2870 * @read: determines if operation is read or written
2673 * 2871 *
2674 * Acquires semaphore, if necessary, then reads the PHY register at offset 2872 * Reads the PHY register at offset and stores the retreived information
2675 * and storing the retreived information in data. Release any acquired 2873 * in data. Assumes semaphore already acquired. Note that the procedure
2676 * semaphores before exiting. Note that the procedure to read these regs 2874 * to read these regs uses the address port and data port to read/write.
2677 * uses the address port and data port to read/write.
2678 **/ 2875 **/
2679static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, 2876static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2680 u16 *data, bool read) 2877 u16 *data, bool read)
@@ -2682,20 +2879,12 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2682 s32 ret_val; 2879 s32 ret_val;
2683 u32 addr_reg = 0; 2880 u32 addr_reg = 0;
2684 u32 data_reg = 0; 2881 u32 data_reg = 0;
2685 u8 phy_acquired = 1;
2686 2882
2687 /* This takes care of the difference with desktop vs mobile phy */ 2883 /* This takes care of the difference with desktop vs mobile phy */
2688 addr_reg = (hw->phy.type == e1000_phy_82578) ? 2884 addr_reg = (hw->phy.type == e1000_phy_82578) ?
2689 I82578_ADDR_REG : I82577_ADDR_REG; 2885 I82578_ADDR_REG : I82577_ADDR_REG;
2690 data_reg = addr_reg + 1; 2886 data_reg = addr_reg + 1;
2691 2887
2692 ret_val = hw->phy.ops.acquire_phy(hw);
2693 if (ret_val) {
2694 hw_dbg(hw, "Could not acquire PHY\n");
2695 phy_acquired = 0;
2696 goto out;
2697 }
2698
2699 /* All operations in this function are phy address 2 */ 2888 /* All operations in this function are phy address 2 */
2700 hw->phy.addr = 2; 2889 hw->phy.addr = 2;
2701 2890
@@ -2718,8 +2907,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2718 } 2907 }
2719 2908
2720out: 2909out:
2721 if (phy_acquired == 1)
2722 hw->phy.ops.release_phy(hw);
2723 return ret_val; 2910 return ret_val;
2724} 2911}
2725 2912