aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000e/phy.c')
-rw-r--r--drivers/net/e1000e/phy.c476
1 files changed, 328 insertions, 148 deletions
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 994401fd0664..03175b3a2c9e 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -95,13 +95,6 @@ static const u16 e1000_igp_2_cable_length_table[] =
95/* BM PHY Copper Specific Control 1 */ 95/* BM PHY Copper Specific Control 1 */
96#define BM_CS_CTRL1 16 96#define BM_CS_CTRL1 16
97 97
98/* BM PHY Copper Specific Status */
99#define BM_CS_STATUS 17
100#define BM_CS_STATUS_LINK_UP 0x0400
101#define BM_CS_STATUS_RESOLVED 0x0800
102#define BM_CS_STATUS_SPEED_MASK 0xC000
103#define BM_CS_STATUS_SPEED_1000 0x8000
104
105#define HV_MUX_DATA_CTRL PHY_REG(776, 16) 98#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
106#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400 99#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
107#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004 100#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
@@ -164,16 +157,25 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw)
164 * MDIC mode. No harm in trying again in this case since 157 * MDIC mode. No harm in trying again in this case since
165 * the PHY ID is unknown at this point anyway 158 * the PHY ID is unknown at this point anyway
166 */ 159 */
160 ret_val = phy->ops.acquire_phy(hw);
161 if (ret_val)
162 goto out;
167 ret_val = e1000_set_mdio_slow_mode_hv(hw, true); 163 ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
168 if (ret_val) 164 if (ret_val)
169 goto out; 165 goto out;
166 phy->ops.release_phy(hw);
170 167
171 retry_count++; 168 retry_count++;
172 } 169 }
173out: 170out:
174 /* Revert to MDIO fast mode, if applicable */ 171 /* Revert to MDIO fast mode, if applicable */
175 if (retry_count) 172 if (retry_count) {
173 ret_val = phy->ops.acquire_phy(hw);
174 if (ret_val)
175 return ret_val;
176 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 176 ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
177 phy->ops.release_phy(hw);
178 }
177 179
178 return ret_val; 180 return ret_val;
179} 181}
@@ -354,94 +356,173 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
354} 356}
355 357
356/** 358/**
357 * e1000e_read_phy_reg_igp - Read igp PHY register 359 * __e1000e_read_phy_reg_igp - Read igp PHY register
358 * @hw: pointer to the HW structure 360 * @hw: pointer to the HW structure
359 * @offset: register offset to be read 361 * @offset: register offset to be read
360 * @data: pointer to the read data 362 * @data: pointer to the read data
363 * @locked: semaphore has already been acquired or not
361 * 364 *
362 * Acquires semaphore, if necessary, then reads the PHY register at offset 365 * Acquires semaphore, if necessary, then reads the PHY register at offset
363 * and storing the retrieved information in data. Release any acquired 366 * and stores the retrieved information in data. Release any acquired
364 * semaphores before exiting. 367 * semaphores before exiting.
365 **/ 368 **/
366s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) 369static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
370 bool locked)
367{ 371{
368 s32 ret_val; 372 s32 ret_val = 0;
369 373
370 ret_val = hw->phy.ops.acquire_phy(hw); 374 if (!locked) {
371 if (ret_val) 375 if (!(hw->phy.ops.acquire_phy))
372 return ret_val; 376 goto out;
377
378 ret_val = hw->phy.ops.acquire_phy(hw);
379 if (ret_val)
380 goto out;
381 }
373 382
374 if (offset > MAX_PHY_MULTI_PAGE_REG) { 383 if (offset > MAX_PHY_MULTI_PAGE_REG) {
375 ret_val = e1000e_write_phy_reg_mdic(hw, 384 ret_val = e1000e_write_phy_reg_mdic(hw,
376 IGP01E1000_PHY_PAGE_SELECT, 385 IGP01E1000_PHY_PAGE_SELECT,
377 (u16)offset); 386 (u16)offset);
378 if (ret_val) { 387 if (ret_val)
379 hw->phy.ops.release_phy(hw); 388 goto release;
380 return ret_val;
381 }
382 } 389 }
383 390
384 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 391 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
385 data); 392 data);
386
387 hw->phy.ops.release_phy(hw);
388 393
394release:
395 if (!locked)
396 hw->phy.ops.release_phy(hw);
397out:
389 return ret_val; 398 return ret_val;
390} 399}
391 400
392/** 401/**
402 * e1000e_read_phy_reg_igp - Read igp PHY register
403 * @hw: pointer to the HW structure
404 * @offset: register offset to be read
405 * @data: pointer to the read data
406 *
407 * Acquires semaphore then reads the PHY register at offset and stores the
408 * retrieved information in data.
409 * Release the acquired semaphore before exiting.
410 **/
411s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
412{
413 return __e1000e_read_phy_reg_igp(hw, offset, data, false);
414}
415
416/**
417 * e1000e_read_phy_reg_igp_locked - Read igp PHY register
418 * @hw: pointer to the HW structure
419 * @offset: register offset to be read
420 * @data: pointer to the read data
421 *
422 * Reads the PHY register at offset and stores the retrieved information
423 * in data. Assumes semaphore already acquired.
424 **/
425s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data)
426{
427 return __e1000e_read_phy_reg_igp(hw, offset, data, true);
428}
429
430/**
393 * e1000e_write_phy_reg_igp - Write igp PHY register 431 * e1000e_write_phy_reg_igp - Write igp PHY register
394 * @hw: pointer to the HW structure 432 * @hw: pointer to the HW structure
395 * @offset: register offset to write to 433 * @offset: register offset to write to
396 * @data: data to write at register offset 434 * @data: data to write at register offset
435 * @locked: semaphore has already been acquired or not
397 * 436 *
398 * Acquires semaphore, if necessary, then writes the data to PHY register 437 * Acquires semaphore, if necessary, then writes the data to PHY register
399 * at the offset. Release any acquired semaphores before exiting. 438 * at the offset. Release any acquired semaphores before exiting.
400 **/ 439 **/
401s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) 440static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
441 bool locked)
402{ 442{
403 s32 ret_val; 443 s32 ret_val = 0;
404 444
405 ret_val = hw->phy.ops.acquire_phy(hw); 445 if (!locked) {
406 if (ret_val) 446 if (!(hw->phy.ops.acquire_phy))
407 return ret_val; 447 goto out;
448
449 ret_val = hw->phy.ops.acquire_phy(hw);
450 if (ret_val)
451 goto out;
452 }
408 453
409 if (offset > MAX_PHY_MULTI_PAGE_REG) { 454 if (offset > MAX_PHY_MULTI_PAGE_REG) {
410 ret_val = e1000e_write_phy_reg_mdic(hw, 455 ret_val = e1000e_write_phy_reg_mdic(hw,
411 IGP01E1000_PHY_PAGE_SELECT, 456 IGP01E1000_PHY_PAGE_SELECT,
412 (u16)offset); 457 (u16)offset);
413 if (ret_val) { 458 if (ret_val)
414 hw->phy.ops.release_phy(hw); 459 goto release;
415 return ret_val;
416 }
417 } 460 }
418 461
419 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 462 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
420 data); 463 data);
421 464
422 hw->phy.ops.release_phy(hw); 465release:
466 if (!locked)
467 hw->phy.ops.release_phy(hw);
423 468
469out:
424 return ret_val; 470 return ret_val;
425} 471}
426 472
427/** 473/**
428 * e1000e_read_kmrn_reg - Read kumeran register 474 * e1000e_write_phy_reg_igp - Write igp PHY register
475 * @hw: pointer to the HW structure
476 * @offset: register offset to write to
477 * @data: data to write at register offset
478 *
479 * Acquires semaphore then writes the data to PHY register
480 * at the offset. Release any acquired semaphores before exiting.
481 **/
482s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
483{
484 return __e1000e_write_phy_reg_igp(hw, offset, data, false);
485}
486
487/**
488 * e1000e_write_phy_reg_igp_locked - Write igp PHY register
489 * @hw: pointer to the HW structure
490 * @offset: register offset to write to
491 * @data: data to write at register offset
492 *
493 * Writes the data to PHY register at the offset.
494 * Assumes semaphore already acquired.
495 **/
496s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data)
497{
498 return __e1000e_write_phy_reg_igp(hw, offset, data, true);
499}
500
501/**
502 * __e1000_read_kmrn_reg - Read kumeran register
429 * @hw: pointer to the HW structure 503 * @hw: pointer to the HW structure
430 * @offset: register offset to be read 504 * @offset: register offset to be read
431 * @data: pointer to the read data 505 * @data: pointer to the read data
506 * @locked: semaphore has already been acquired or not
432 * 507 *
433 * Acquires semaphore, if necessary. Then reads the PHY register at offset 508 * Acquires semaphore, if necessary. Then reads the PHY register at offset
434 * using the kumeran interface. The information retrieved is stored in data. 509 * using the kumeran interface. The information retrieved is stored in data.
435 * Release any acquired semaphores before exiting. 510 * Release any acquired semaphores before exiting.
436 **/ 511 **/
437s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) 512static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
513 bool locked)
438{ 514{
439 u32 kmrnctrlsta; 515 u32 kmrnctrlsta;
440 s32 ret_val; 516 s32 ret_val = 0;
441 517
442 ret_val = hw->phy.ops.acquire_phy(hw); 518 if (!locked) {
443 if (ret_val) 519 if (!(hw->phy.ops.acquire_phy))
444 return ret_val; 520 goto out;
521
522 ret_val = hw->phy.ops.acquire_phy(hw);
523 if (ret_val)
524 goto out;
525 }
445 526
446 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 527 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
447 E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; 528 E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
@@ -452,41 +533,111 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
452 kmrnctrlsta = er32(KMRNCTRLSTA); 533 kmrnctrlsta = er32(KMRNCTRLSTA);
453 *data = (u16)kmrnctrlsta; 534 *data = (u16)kmrnctrlsta;
454 535
455 hw->phy.ops.release_phy(hw); 536 if (!locked)
537 hw->phy.ops.release_phy(hw);
456 538
539out:
457 return ret_val; 540 return ret_val;
458} 541}
459 542
460/** 543/**
461 * e1000e_write_kmrn_reg - Write kumeran register 544 * e1000e_read_kmrn_reg - Read kumeran register
545 * @hw: pointer to the HW structure
546 * @offset: register offset to be read
547 * @data: pointer to the read data
548 *
549 * Acquires semaphore then reads the PHY register at offset using the
550 * kumeran interface. The information retrieved is stored in data.
551 * Release the acquired semaphore before exiting.
552 **/
553s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
554{
555 return __e1000_read_kmrn_reg(hw, offset, data, false);
556}
557
558/**
559 * e1000e_read_kmrn_reg_locked - Read kumeran register
560 * @hw: pointer to the HW structure
561 * @offset: register offset to be read
562 * @data: pointer to the read data
563 *
564 * Reads the PHY register at offset using the kumeran interface. The
565 * information retrieved is stored in data.
566 * Assumes semaphore already acquired.
567 **/
568s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
569{
570 return __e1000_read_kmrn_reg(hw, offset, data, true);
571}
572
573/**
574 * __e1000_write_kmrn_reg - Write kumeran register
462 * @hw: pointer to the HW structure 575 * @hw: pointer to the HW structure
463 * @offset: register offset to write to 576 * @offset: register offset to write to
464 * @data: data to write at register offset 577 * @data: data to write at register offset
578 * @locked: semaphore has already been acquired or not
465 * 579 *
466 * Acquires semaphore, if necessary. Then write the data to PHY register 580 * Acquires semaphore, if necessary. Then write the data to PHY register
467 * at the offset using the kumeran interface. Release any acquired semaphores 581 * at the offset using the kumeran interface. Release any acquired semaphores
468 * before exiting. 582 * before exiting.
469 **/ 583 **/
470s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) 584static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
585 bool locked)
471{ 586{
472 u32 kmrnctrlsta; 587 u32 kmrnctrlsta;
473 s32 ret_val; 588 s32 ret_val = 0;
474 589
475 ret_val = hw->phy.ops.acquire_phy(hw); 590 if (!locked) {
476 if (ret_val) 591 if (!(hw->phy.ops.acquire_phy))
477 return ret_val; 592 goto out;
593
594 ret_val = hw->phy.ops.acquire_phy(hw);
595 if (ret_val)
596 goto out;
597 }
478 598
479 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & 599 kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
480 E1000_KMRNCTRLSTA_OFFSET) | data; 600 E1000_KMRNCTRLSTA_OFFSET) | data;
481 ew32(KMRNCTRLSTA, kmrnctrlsta); 601 ew32(KMRNCTRLSTA, kmrnctrlsta);
482 602
483 udelay(2); 603 udelay(2);
484 hw->phy.ops.release_phy(hw);
485 604
605 if (!locked)
606 hw->phy.ops.release_phy(hw);
607
608out:
486 return ret_val; 609 return ret_val;
487} 610}
488 611
489/** 612/**
613 * e1000e_write_kmrn_reg - Write kumeran register
614 * @hw: pointer to the HW structure
615 * @offset: register offset to write to
616 * @data: data to write at register offset
617 *
618 * Acquires semaphore then writes the data to the PHY register at the offset
619 * using the kumeran interface. Release the acquired semaphore before exiting.
620 **/
621s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
622{
623 return __e1000_write_kmrn_reg(hw, offset, data, false);
624}
625
626/**
627 * e1000e_write_kmrn_reg_locked - Write kumeran register
628 * @hw: pointer to the HW structure
629 * @offset: register offset to write to
630 * @data: data to write at register offset
631 *
632 * Write the data to PHY register at the offset using the kumeran interface.
633 * Assumes semaphore already acquired.
634 **/
635s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
636{
637 return __e1000_write_kmrn_reg(hw, offset, data, true);
638}
639
640/**
490 * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link 641 * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
491 * @hw: pointer to the HW structure 642 * @hw: pointer to the HW structure
492 * 643 *
@@ -2105,6 +2256,10 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2105 u32 page = offset >> IGP_PAGE_SHIFT; 2256 u32 page = offset >> IGP_PAGE_SHIFT;
2106 u32 page_shift = 0; 2257 u32 page_shift = 0;
2107 2258
2259 ret_val = hw->phy.ops.acquire_phy(hw);
2260 if (ret_val)
2261 return ret_val;
2262
2108 /* Page 800 works differently than the rest so it has its own func */ 2263 /* Page 800 works differently than the rest so it has its own func */
2109 if (page == BM_WUC_PAGE) { 2264 if (page == BM_WUC_PAGE) {
2110 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2265 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
@@ -2112,10 +2267,6 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
2112 goto out; 2267 goto out;
2113 } 2268 }
2114 2269
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); 2270 hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2120 2271
2121 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2272 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2135,18 +2286,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) */ 2286 /* Page is shifted left, PHY expects (page x 32) */
2136 ret_val = e1000e_write_phy_reg_mdic(hw, page_select, 2287 ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2137 (page << page_shift)); 2288 (page << page_shift));
2138 if (ret_val) { 2289 if (ret_val)
2139 hw->phy.ops.release_phy(hw);
2140 goto out; 2290 goto out;
2141 }
2142 } 2291 }
2143 2292
2144 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2293 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2145 data); 2294 data);
2146 2295
2147 hw->phy.ops.release_phy(hw);
2148
2149out: 2296out:
2297 hw->phy.ops.release_phy(hw);
2150 return ret_val; 2298 return ret_val;
2151} 2299}
2152 2300
@@ -2167,6 +2315,10 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2167 u32 page = offset >> IGP_PAGE_SHIFT; 2315 u32 page = offset >> IGP_PAGE_SHIFT;
2168 u32 page_shift = 0; 2316 u32 page_shift = 0;
2169 2317
2318 ret_val = hw->phy.ops.acquire_phy(hw);
2319 if (ret_val)
2320 return ret_val;
2321
2170 /* Page 800 works differently than the rest so it has its own func */ 2322 /* Page 800 works differently than the rest so it has its own func */
2171 if (page == BM_WUC_PAGE) { 2323 if (page == BM_WUC_PAGE) {
2172 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2324 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
@@ -2174,10 +2326,6 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
2174 goto out; 2326 goto out;
2175 } 2327 }
2176 2328
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); 2329 hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
2182 2330
2183 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2331 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2197,17 +2345,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) */ 2345 /* Page is shifted left, PHY expects (page x 32) */
2198 ret_val = e1000e_write_phy_reg_mdic(hw, page_select, 2346 ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
2199 (page << page_shift)); 2347 (page << page_shift));
2200 if (ret_val) { 2348 if (ret_val)
2201 hw->phy.ops.release_phy(hw);
2202 goto out; 2349 goto out;
2203 }
2204 } 2350 }
2205 2351
2206 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2352 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2207 data); 2353 data);
2208 hw->phy.ops.release_phy(hw);
2209
2210out: 2354out:
2355 hw->phy.ops.release_phy(hw);
2211 return ret_val; 2356 return ret_val;
2212} 2357}
2213 2358
@@ -2226,17 +2371,17 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
2226 s32 ret_val; 2371 s32 ret_val;
2227 u16 page = (u16)(offset >> IGP_PAGE_SHIFT); 2372 u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2228 2373
2374 ret_val = hw->phy.ops.acquire_phy(hw);
2375 if (ret_val)
2376 return ret_val;
2377
2229 /* Page 800 works differently than the rest so it has its own func */ 2378 /* Page 800 works differently than the rest so it has its own func */
2230 if (page == BM_WUC_PAGE) { 2379 if (page == BM_WUC_PAGE) {
2231 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, 2380 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
2232 true); 2381 true);
2233 return ret_val; 2382 goto out;
2234 } 2383 }
2235 2384
2236 ret_val = hw->phy.ops.acquire_phy(hw);
2237 if (ret_val)
2238 return ret_val;
2239
2240 hw->phy.addr = 1; 2385 hw->phy.addr = 1;
2241 2386
2242 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2387 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2245,16 +2390,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, 2390 ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2246 page); 2391 page);
2247 2392
2248 if (ret_val) { 2393 if (ret_val)
2249 hw->phy.ops.release_phy(hw); 2394 goto out;
2250 return ret_val;
2251 }
2252 } 2395 }
2253 2396
2254 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2397 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2255 data); 2398 data);
2399out:
2256 hw->phy.ops.release_phy(hw); 2400 hw->phy.ops.release_phy(hw);
2257
2258 return ret_val; 2401 return ret_val;
2259} 2402}
2260 2403
@@ -2272,17 +2415,17 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
2272 s32 ret_val; 2415 s32 ret_val;
2273 u16 page = (u16)(offset >> IGP_PAGE_SHIFT); 2416 u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
2274 2417
2418 ret_val = hw->phy.ops.acquire_phy(hw);
2419 if (ret_val)
2420 return ret_val;
2421
2275 /* Page 800 works differently than the rest so it has its own func */ 2422 /* Page 800 works differently than the rest so it has its own func */
2276 if (page == BM_WUC_PAGE) { 2423 if (page == BM_WUC_PAGE) {
2277 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, 2424 ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
2278 false); 2425 false);
2279 return ret_val; 2426 goto out;
2280 } 2427 }
2281 2428
2282 ret_val = hw->phy.ops.acquire_phy(hw);
2283 if (ret_val)
2284 return ret_val;
2285
2286 hw->phy.addr = 1; 2429 hw->phy.addr = 1;
2287 2430
2288 if (offset > MAX_PHY_MULTI_PAGE_REG) { 2431 if (offset > MAX_PHY_MULTI_PAGE_REG) {
@@ -2290,17 +2433,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, 2433 ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
2291 page); 2434 page);
2292 2435
2293 if (ret_val) { 2436 if (ret_val)
2294 hw->phy.ops.release_phy(hw); 2437 goto out;
2295 return ret_val;
2296 }
2297 } 2438 }
2298 2439
2299 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 2440 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
2300 data); 2441 data);
2301 2442
2443out:
2302 hw->phy.ops.release_phy(hw); 2444 hw->phy.ops.release_phy(hw);
2303
2304 return ret_val; 2445 return ret_val;
2305} 2446}
2306 2447
@@ -2320,6 +2461,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) 2461 * 3) Write the address using the address opcode (0x11)
2321 * 4) Read or write the data using the data opcode (0x12) 2462 * 4) Read or write the data using the data opcode (0x12)
2322 * 5) Restore 769_17.2 to its original value 2463 * 5) Restore 769_17.2 to its original value
2464 *
2465 * Assumes semaphore already acquired.
2323 **/ 2466 **/
2324static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, 2467static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2325 u16 *data, bool read) 2468 u16 *data, bool read)
@@ -2327,20 +2470,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
2327 s32 ret_val; 2470 s32 ret_val;
2328 u16 reg = BM_PHY_REG_NUM(offset); 2471 u16 reg = BM_PHY_REG_NUM(offset);
2329 u16 phy_reg = 0; 2472 u16 phy_reg = 0;
2330 u8 phy_acquired = 1;
2331
2332 2473
2333 /* Gig must be disabled for MDIO accesses to page 800 */ 2474 /* Gig must be disabled for MDIO accesses to page 800 */
2334 if ((hw->mac.type == e1000_pchlan) && 2475 if ((hw->mac.type == e1000_pchlan) &&
2335 (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) 2476 (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
2336 hw_dbg(hw, "Attempting to access page 800 while gig enabled\n"); 2477 hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
2337 2478
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 */ 2479 /* All operations in this function are phy address 1 */
2345 hw->phy.addr = 1; 2480 hw->phy.addr = 1;
2346 2481
@@ -2397,8 +2532,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); 2532 ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
2398 2533
2399out: 2534out:
2400 if (phy_acquired == 1)
2401 hw->phy.ops.release_phy(hw);
2402 return ret_val; 2535 return ret_val;
2403} 2536}
2404 2537
@@ -2439,52 +2572,63 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
2439 return 0; 2572 return 0;
2440} 2573}
2441 2574
2575/**
2576 * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
2577 * @hw: pointer to the HW structure
2578 * @slow: true for slow mode, false for normal mode
2579 *
2580 * Assumes semaphore already acquired.
2581 **/
2442s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) 2582s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
2443{ 2583{
2444 s32 ret_val = 0; 2584 s32 ret_val = 0;
2445 u16 data = 0; 2585 u16 data = 0;
2446 2586
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 */ 2587 /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
2452 hw->phy.addr = 1; 2588 hw->phy.addr = 1;
2453 ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 2589 ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
2454 (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); 2590 (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
2455 if (ret_val) { 2591 if (ret_val)
2456 hw->phy.ops.release_phy(hw); 2592 goto out;
2457 return ret_val; 2593
2458 }
2459 ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, 2594 ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
2460 (0x2180 | (slow << 10))); 2595 (0x2180 | (slow << 10)));
2596 if (ret_val)
2597 goto out;
2461 2598
2462 /* dummy read when reverting to fast mode - throw away result */ 2599 /* dummy read when reverting to fast mode - throw away result */
2463 if (!slow) 2600 if (!slow)
2464 e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); 2601 ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
2465
2466 hw->phy.ops.release_phy(hw);
2467 2602
2603out:
2468 return ret_val; 2604 return ret_val;
2469} 2605}
2470 2606
2471/** 2607/**
2472 * e1000_read_phy_reg_hv - Read HV PHY register 2608 * __e1000_read_phy_reg_hv - Read HV PHY register
2473 * @hw: pointer to the HW structure 2609 * @hw: pointer to the HW structure
2474 * @offset: register offset to be read 2610 * @offset: register offset to be read
2475 * @data: pointer to the read data 2611 * @data: pointer to the read data
2612 * @locked: semaphore has already been acquired or not
2476 * 2613 *
2477 * Acquires semaphore, if necessary, then reads the PHY register at offset 2614 * Acquires semaphore, if necessary, then reads the PHY register at offset
2478 * and storing the retrieved information in data. Release any acquired 2615 * and stores the retrieved information in data. Release any acquired
2479 * semaphore before exiting. 2616 * semaphore before exiting.
2480 **/ 2617 **/
2481s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) 2618static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
2619 bool locked)
2482{ 2620{
2483 s32 ret_val; 2621 s32 ret_val;
2484 u16 page = BM_PHY_REG_PAGE(offset); 2622 u16 page = BM_PHY_REG_PAGE(offset);
2485 u16 reg = BM_PHY_REG_NUM(offset); 2623 u16 reg = BM_PHY_REG_NUM(offset);
2486 bool in_slow_mode = false; 2624 bool in_slow_mode = false;
2487 2625
2626 if (!locked) {
2627 ret_val = hw->phy.ops.acquire_phy(hw);
2628 if (ret_val)
2629 return ret_val;
2630 }
2631
2488 /* Workaround failure in MDIO access while cable is disconnected */ 2632 /* Workaround failure in MDIO access while cable is disconnected */
2489 if ((hw->phy.type == e1000_phy_82577) && 2633 if ((hw->phy.type == e1000_phy_82577) &&
2490 !(er32(STATUS) & E1000_STATUS_LU)) { 2634 !(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2508,10 +2652,6 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2508 goto out; 2652 goto out;
2509 } 2653 }
2510 2654
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); 2655 hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2516 2656
2517 if (page == HV_INTC_FC_PAGE_START) 2657 if (page == HV_INTC_FC_PAGE_START)
@@ -2529,42 +2669,76 @@ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2529 ret_val = e1000e_write_phy_reg_mdic(hw, 2669 ret_val = e1000e_write_phy_reg_mdic(hw,
2530 IGP01E1000_PHY_PAGE_SELECT, 2670 IGP01E1000_PHY_PAGE_SELECT,
2531 (page << IGP_PAGE_SHIFT)); 2671 (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; 2672 hw->phy.addr = phy_addr;
2537 } 2673 }
2538 } 2674 }
2539 2675
2540 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2676 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2541 data); 2677 data);
2542 hw->phy.ops.release_phy(hw);
2543
2544out: 2678out:
2545 /* Revert to MDIO fast mode, if applicable */ 2679 /* Revert to MDIO fast mode, if applicable */
2546 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) 2680 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
2547 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 2681 ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
2548 2682
2683 if (!locked)
2684 hw->phy.ops.release_phy(hw);
2685
2549 return ret_val; 2686 return ret_val;
2550} 2687}
2551 2688
2552/** 2689/**
2553 * e1000_write_phy_reg_hv - Write HV PHY register 2690 * e1000_read_phy_reg_hv - Read HV PHY register
2691 * @hw: pointer to the HW structure
2692 * @offset: register offset to be read
2693 * @data: pointer to the read data
2694 *
2695 * Acquires semaphore then reads the PHY register at offset and stores
2696 * the retrieved information in data. Release the acquired semaphore
2697 * before exiting.
2698 **/
2699s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
2700{
2701 return __e1000_read_phy_reg_hv(hw, offset, data, false);
2702}
2703
2704/**
2705 * e1000_read_phy_reg_hv_locked - Read HV PHY register
2706 * @hw: pointer to the HW structure
2707 * @offset: register offset to be read
2708 * @data: pointer to the read data
2709 *
2710 * Reads the PHY register at offset and stores the retrieved information
2711 * in data. Assumes semaphore already acquired.
2712 **/
2713s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data)
2714{
2715 return __e1000_read_phy_reg_hv(hw, offset, data, true);
2716}
2717
2718/**
2719 * __e1000_write_phy_reg_hv - Write HV PHY register
2554 * @hw: pointer to the HW structure 2720 * @hw: pointer to the HW structure
2555 * @offset: register offset to write to 2721 * @offset: register offset to write to
2556 * @data: data to write at register offset 2722 * @data: data to write at register offset
2723 * @locked: semaphore has already been acquired or not
2557 * 2724 *
2558 * Acquires semaphore, if necessary, then writes the data to PHY register 2725 * Acquires semaphore, if necessary, then writes the data to PHY register
2559 * at the offset. Release any acquired semaphores before exiting. 2726 * at the offset. Release any acquired semaphores before exiting.
2560 **/ 2727 **/
2561s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) 2728static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
2729 bool locked)
2562{ 2730{
2563 s32 ret_val; 2731 s32 ret_val;
2564 u16 page = BM_PHY_REG_PAGE(offset); 2732 u16 page = BM_PHY_REG_PAGE(offset);
2565 u16 reg = BM_PHY_REG_NUM(offset); 2733 u16 reg = BM_PHY_REG_NUM(offset);
2566 bool in_slow_mode = false; 2734 bool in_slow_mode = false;
2567 2735
2736 if (!locked) {
2737 ret_val = hw->phy.ops.acquire_phy(hw);
2738 if (ret_val)
2739 return ret_val;
2740 }
2741
2568 /* Workaround failure in MDIO access while cable is disconnected */ 2742 /* Workaround failure in MDIO access while cable is disconnected */
2569 if ((hw->phy.type == e1000_phy_82577) && 2743 if ((hw->phy.type == e1000_phy_82577) &&
2570 !(er32(STATUS) & E1000_STATUS_LU)) { 2744 !(er32(STATUS) & E1000_STATUS_LU)) {
@@ -2588,10 +2762,6 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2588 goto out; 2762 goto out;
2589 } 2763 }
2590 2764
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); 2765 hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
2596 2766
2597 if (page == HV_INTC_FC_PAGE_START) 2767 if (page == HV_INTC_FC_PAGE_START)
@@ -2607,15 +2777,10 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2607 ((MAX_PHY_REG_ADDRESS & reg) == 0) && 2777 ((MAX_PHY_REG_ADDRESS & reg) == 0) &&
2608 (data & (1 << 11))) { 2778 (data & (1 << 11))) {
2609 u16 data2 = 0x7EFF; 2779 u16 data2 = 0x7EFF;
2610 hw->phy.ops.release_phy(hw);
2611 ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, 2780 ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
2612 &data2, false); 2781 &data2, false);
2613 if (ret_val) 2782 if (ret_val)
2614 goto out; 2783 goto out;
2615
2616 ret_val = hw->phy.ops.acquire_phy(hw);
2617 if (ret_val)
2618 goto out;
2619 } 2784 }
2620 2785
2621 if (reg > MAX_PHY_MULTI_PAGE_REG) { 2786 if (reg > MAX_PHY_MULTI_PAGE_REG) {
@@ -2630,27 +2795,53 @@ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2630 ret_val = e1000e_write_phy_reg_mdic(hw, 2795 ret_val = e1000e_write_phy_reg_mdic(hw,
2631 IGP01E1000_PHY_PAGE_SELECT, 2796 IGP01E1000_PHY_PAGE_SELECT,
2632 (page << IGP_PAGE_SHIFT)); 2797 (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; 2798 hw->phy.addr = phy_addr;
2638 } 2799 }
2639 } 2800 }
2640 2801
2641 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, 2802 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
2642 data); 2803 data);
2643 hw->phy.ops.release_phy(hw);
2644 2804
2645out: 2805out:
2646 /* Revert to MDIO fast mode, if applicable */ 2806 /* Revert to MDIO fast mode, if applicable */
2647 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) 2807 if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
2648 ret_val = e1000_set_mdio_slow_mode_hv(hw, false); 2808 ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
2649 2809
2810 if (!locked)
2811 hw->phy.ops.release_phy(hw);
2812
2650 return ret_val; 2813 return ret_val;
2651} 2814}
2652 2815
2653/** 2816/**
2817 * e1000_write_phy_reg_hv - Write HV PHY register
2818 * @hw: pointer to the HW structure
2819 * @offset: register offset to write to
2820 * @data: data to write at register offset
2821 *
2822 * Acquires semaphore then writes the data to PHY register at the offset.
2823 * Release the acquired semaphores before exiting.
2824 **/
2825s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
2826{
2827 return __e1000_write_phy_reg_hv(hw, offset, data, false);
2828}
2829
2830/**
2831 * e1000_write_phy_reg_hv_locked - Write HV PHY register
2832 * @hw: pointer to the HW structure
2833 * @offset: register offset to write to
2834 * @data: data to write at register offset
2835 *
2836 * Writes the data to PHY register at the offset. Assumes semaphore
2837 * already acquired.
2838 **/
2839s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data)
2840{
2841 return __e1000_write_phy_reg_hv(hw, offset, data, true);
2842}
2843
2844/**
2654 * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page 2845 * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
2655 * @page: page to be accessed 2846 * @page: page to be accessed
2656 **/ 2847 **/
@@ -2671,10 +2862,9 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page)
2671 * @data: pointer to the data to be read or written 2862 * @data: pointer to the data to be read or written
2672 * @read: determines if operation is read or written 2863 * @read: determines if operation is read or written
2673 * 2864 *
2674 * Acquires semaphore, if necessary, then reads the PHY register at offset 2865 * Reads the PHY register at offset and stores the retreived information
2675 * and storing the retreived information in data. Release any acquired 2866 * in data. Assumes semaphore already acquired. Note that the procedure
2676 * semaphores before exiting. Note that the procedure to read these regs 2867 * 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 **/ 2868 **/
2679static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, 2869static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2680 u16 *data, bool read) 2870 u16 *data, bool read)
@@ -2682,20 +2872,12 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2682 s32 ret_val; 2872 s32 ret_val;
2683 u32 addr_reg = 0; 2873 u32 addr_reg = 0;
2684 u32 data_reg = 0; 2874 u32 data_reg = 0;
2685 u8 phy_acquired = 1;
2686 2875
2687 /* This takes care of the difference with desktop vs mobile phy */ 2876 /* This takes care of the difference with desktop vs mobile phy */
2688 addr_reg = (hw->phy.type == e1000_phy_82578) ? 2877 addr_reg = (hw->phy.type == e1000_phy_82578) ?
2689 I82578_ADDR_REG : I82577_ADDR_REG; 2878 I82578_ADDR_REG : I82577_ADDR_REG;
2690 data_reg = addr_reg + 1; 2879 data_reg = addr_reg + 1;
2691 2880
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 */ 2881 /* All operations in this function are phy address 2 */
2700 hw->phy.addr = 2; 2882 hw->phy.addr = 2;
2701 2883
@@ -2718,8 +2900,6 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
2718 } 2900 }
2719 2901
2720out: 2902out:
2721 if (phy_acquired == 1)
2722 hw->phy.ops.release_phy(hw);
2723 return ret_val; 2903 return ret_val;
2724} 2904}
2725 2905