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.c469
1 files changed, 328 insertions, 141 deletions
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