4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
30 #define NGE_DBG NGE_DBG_MII /* debug flag for this code */
33 * The arrays below can be indexed by the MODE bits from the mac2phy
34 * register to determine the current speed/duplex settings.
36 static const int16_t nge_copper_link_speed
[] = {
37 0, /* MII_AUX_STATUS_MODE_NONE */
38 10, /* MII_AUX_STAT0,US_MODE_10 */
39 100, /* MII_AUX_STAT0,US_MODE_100 */
40 1000, /* MII_AUX_STAT0,US_MODE_1000 */
43 static const int8_t nge_copper_link_duplex
[] = {
44 LINK_DUPLEX_UNKNOWN
, /* MII_DUPLEX_NONE */
45 LINK_DUPLEX_HALF
, /* MII_DUPLEX_HALF */
46 LINK_DUPLEX_FULL
, /* MII_DUPLEX_FULL */
50 static uint16_t nge_mii_access(nge_t
*ngep
, nge_regno_t regno
,
51 uint16_t data
, uint32_t cmd
);
52 #pragma inline(nge_mii_access)
55 nge_mii_access(nge_t
*ngep
, nge_regno_t regno
, uint16_t data
, uint32_t cmd
)
59 nge_mdio_adr mdio_adr
;
60 nge_mintr_src intr_src
;
62 NGE_TRACE(("nge_mii_access($%p, 0x%lx, 0x%x, 0x%x)",
63 (void *)ngep
, regno
, data
, cmd
));
66 * Clear the privous interrupt event
68 intr_src
.src_val
= nge_reg_get8(ngep
, NGE_MINTR_SRC
);
69 nge_reg_put8(ngep
, NGE_MINTR_SRC
, intr_src
.src_val
);
72 * Check whether the current operation has been finished
74 mdio_adr
.adr_val
= nge_reg_get16(ngep
, NGE_MDIO_ADR
);
75 for (tries
= 0; tries
< 30; tries
++) {
76 if (mdio_adr
.adr_bits
.mdio_clc
== NGE_CLEAR
)
79 mdio_adr
.adr_val
= nge_reg_get16(ngep
, NGE_MDIO_ADR
);
83 * The current operation can not be finished successfully
84 * The driver should halt the current operation
87 mdio_adr
.adr_bits
.mdio_clc
= NGE_SET
;
88 nge_reg_put16(ngep
, NGE_MDIO_ADR
, mdio_adr
.adr_val
);
93 * Assemble the operation cmd
95 mdio_adr
.adr_bits
.phy_reg
= (uint16_t)regno
;
96 mdio_adr
.adr_bits
.phy_adr
= ngep
->phy_xmii_addr
;
97 mdio_adr
.adr_bits
.mdio_rw
= (cmd
== NGE_MDIO_WRITE
) ? 1 : 0;
100 if (cmd
== NGE_MDIO_WRITE
)
101 nge_reg_put16(ngep
, NGE_MDIO_DATA
, data
);
103 nge_reg_put16(ngep
, NGE_MDIO_ADR
, mdio_adr
.adr_val
);
106 * To check whether the read/write operation is finished
108 for (tries
= 0; tries
< 300; tries
++) {
110 mdio_adr
.adr_val
= nge_reg_get16(ngep
, NGE_MDIO_ADR
);
111 if (mdio_adr
.adr_bits
.mdio_clc
== NGE_CLEAR
)
115 return ((uint16_t)~0);
118 * Read the data from MDIO data register
120 if (cmd
== NGE_MDIO_READ
)
121 mdio_data
= nge_reg_get16(ngep
, NGE_MDIO_DATA
);
124 * To check whether the read/write operation is valid
126 intr_src
.src_val
= nge_reg_get8(ngep
, NGE_MINTR_SRC
);
127 nge_reg_put8(ngep
, NGE_MINTR_SRC
, intr_src
.src_val
);
128 if (intr_src
.src_bits
.mrei
== NGE_SET
)
129 return ((uint16_t)~0);
134 uint16_t nge_mii_get16(nge_t
*ngep
, nge_regno_t regno
);
135 #pragma inline(nge_mii_get16)
138 nge_mii_get16(nge_t
*ngep
, nge_regno_t regno
)
141 return (nge_mii_access(ngep
, regno
, 0, NGE_MDIO_READ
));
144 void nge_mii_put16(nge_t
*ngep
, nge_regno_t regno
, uint16_t data
);
145 #pragma inline(nge_mii_put16)
148 nge_mii_put16(nge_t
*ngep
, nge_regno_t regno
, uint16_t data
)
151 (void) nge_mii_access(ngep
, regno
, data
, NGE_MDIO_WRITE
);
155 * Basic low-level function to probe for a PHY
157 * Returns TRUE if the PHY responds with valid data, FALSE otherwise
160 nge_phy_probe(nge_t
*ngep
)
167 NGE_TRACE(("nge_phy_probe($%p)", (void *)ngep
));
170 * Scan the phys to find the right address
173 * Probe maximum for 32 phy addresses
175 for (i
= 0; i
< NGE_PHY_NUMBER
; i
++) {
176 ngep
->phy_xmii_addr
= i
;
178 * Read the MII_STATUS register twice, in
179 * order to clear any sticky bits (but they should
180 * have been cleared by the RESET, I think).
182 phy_status
= nge_mii_get16(ngep
, MII_STATUS
);
183 phy_status
= nge_mii_get16(ngep
, MII_STATUS
);
184 if (phy_status
!= 0xffff) {
185 phyidh
= nge_mii_get16(ngep
, MII_PHYIDH
);
186 phyidl
= nge_mii_get16(ngep
, MII_PHYIDL
);
188 (((uint32_t)phyidh
<< 16) |(phyidl
& MII_IDL_MASK
));
189 NGE_DEBUG(("nge_phy_probe: status 0x%x, phy id 0x%x",
190 phy_status
, ngep
->phy_id
));
201 * Basic low-level function to powerup the phy and remove the isolation
205 nge_phy_recover(nge_t
*ngep
)
210 NGE_TRACE(("nge_phy_recover($%p)", (void *)ngep
));
211 control
= nge_mii_get16(ngep
, MII_CONTROL
);
212 control
&= ~(MII_CONTROL_PWRDN
| MII_CONTROL_ISOLATE
);
213 nge_mii_put16(ngep
, MII_CONTROL
, control
);
214 for (count
= 0; ++count
< 10; ) {
216 control
= nge_mii_get16(ngep
, MII_CONTROL
);
217 if (BIC(control
, MII_CONTROL_PWRDN
))
224 * Basic low-level function to reset the PHY.
225 * Doesn't incorporate any special-case workarounds.
227 * Returns TRUE on success, FALSE if the RESET bit doesn't clear
230 nge_phy_reset(nge_t
*ngep
)
235 NGE_TRACE(("nge_phy_reset($%p)", (void *)ngep
));
237 ASSERT(mutex_owned(ngep
->genlock
));
240 * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear
242 control
= nge_mii_get16(ngep
, MII_CONTROL
);
243 control
|= MII_CONTROL_RESET
;
244 nge_mii_put16(ngep
, MII_CONTROL
, control
);
245 /* We should wait for 500ms. It's defined in the manual */
246 delay(drv_usectohz(500000));
247 for (count
= 0; ++count
< 10; ) {
249 control
= nge_mii_get16(ngep
, MII_CONTROL
);
250 if (BIC(control
, MII_CONTROL_RESET
))
253 NGE_DEBUG(("nge_phy_reset: FAILED, control now 0x%x", control
));
259 nge_phy_restart(nge_t
*ngep
)
263 if (!nge_phy_recover(ngep
))
265 if (!nge_phy_reset(ngep
))
268 if (MII_PHY_MFG(ngep
->phy_id
) == MII_ID_CICADA
) {
269 if (ngep
->phy_mode
== RGMII_IN
) {
270 mii_reg
= nge_mii_get16(ngep
,
271 MII_CICADA_EXT_CONTROL
);
272 mii_reg
&= ~(MII_CICADA_MODE_SELECT_BITS
273 | MII_CICADA_POWER_SUPPLY_BITS
);
274 mii_reg
|= (MII_CICADA_MODE_SELECT_RGMII
275 | MII_CICADA_POWER_SUPPLY_2_5V
);
276 nge_mii_put16(ngep
, MII_CICADA_EXT_CONTROL
, mii_reg
);
278 mii_reg
= nge_mii_get16(ngep
,
279 MII_CICADA_AUXCTRL_STATUS
);
280 mii_reg
|= MII_CICADA_PIN_PRORITY_SETTING
;
281 nge_mii_put16(ngep
, MII_CICADA_AUXCTRL_STATUS
,
284 mii_reg
= nge_mii_get16(ngep
,
285 MII_CICADA_10BASET_CONTROL
);
286 mii_reg
|= MII_CICADA_DISABLE_ECHO_MODE
;
288 MII_CICADA_10BASET_CONTROL
, mii_reg
);
290 mii_reg
= nge_mii_get16(ngep
,
291 MII_CICADA_BYPASS_CONTROL
);
292 mii_reg
&= (~CICADA_125MHZ_CLOCK_ENABLE
);
293 nge_mii_put16(ngep
, MII_CICADA_BYPASS_CONTROL
, mii_reg
);
301 * Synchronise the (copper) PHY's speed/duplex/autonegotiation capabilities
302 * and advertisements with the required settings as specified by the various
303 * param_* variables that can be poked via the NDD interface.
305 * We always reset the PHY and reprogram *all* the relevant registers,
306 * not just those changed. This should cause the link to go down, and then
307 * back up again once the link is stable and autonegotiation (if enabled)
308 * is complete. We should get a link state change interrupt somewhere along
311 * NOTE: <genlock> must already be held by the caller
314 nge_update_copper(nge_t
*ngep
)
319 boolean_t adv_autoneg
;
321 boolean_t adv_asym_pause
;
322 boolean_t adv_1000fdx
;
323 boolean_t adv_100fdx
;
324 boolean_t adv_100hdx
;
328 NGE_TRACE(("nge_update_copper($%p)", (void *)ngep
));
330 ASSERT(mutex_owned(ngep
->genlock
));
332 NGE_DEBUG(("nge_update_copper: autoneg %d "
333 "pause %d asym_pause %d "
335 "100fdx %d 100hdx %d "
336 "10fdx %d 10hdx %d ",
337 ngep
->param_adv_autoneg
,
338 ngep
->param_adv_pause
, ngep
->param_adv_asym_pause
,
339 ngep
->param_adv_1000fdx
,
340 ngep
->param_adv_100fdx
, ngep
->param_adv_100hdx
,
341 ngep
->param_adv_10fdx
, ngep
->param_adv_10hdx
));
343 control
= anar
= gigctrl
= 0;
346 * PHY settings are normally based on the param_* variables,
347 * but if any loopback mode is in effect, that takes precedence.
349 * NGE supports MAC-internal loopback, PHY-internal loopback,
350 * and External loopback at a variety of speeds (with a special
351 * cable). In all cases, autoneg is turned OFF, full-duplex
352 * is turned ON, and the speed/mastership is forced.
354 switch (ngep
->param_loop_mode
) {
357 adv_pause
= ngep
->param_adv_pause
;
358 adv_autoneg
= ngep
->param_adv_autoneg
;
359 adv_asym_pause
= ngep
->param_adv_asym_pause
;
360 if (ngep
->phy_mode
== MII_IN
) {
361 adv_1000fdx
= ngep
->param_adv_1000fdx
= B_FALSE
;
363 adv_1000fdx
= ngep
->param_adv_1000fdx
;
364 adv_100fdx
= ngep
->param_adv_100fdx
;
365 adv_100hdx
= ngep
->param_adv_100hdx
;
366 adv_10fdx
= ngep
->param_adv_10fdx
;
367 adv_10hdx
= ngep
->param_adv_10hdx
;
371 case NGE_LOOP_EXTERNAL_100
:
372 case NGE_LOOP_EXTERNAL_10
:
373 case NGE_LOOP_INTERNAL_PHY
:
374 adv_autoneg
= adv_pause
= adv_asym_pause
= B_FALSE
;
375 adv_1000fdx
= adv_100fdx
= adv_10fdx
= B_FALSE
;
376 adv_100hdx
= adv_10hdx
= B_FALSE
;
377 ngep
->param_link_duplex
= LINK_DUPLEX_FULL
;
379 switch (ngep
->param_loop_mode
) {
380 case NGE_LOOP_EXTERNAL_100
:
381 ngep
->param_link_speed
= 100;
385 case NGE_LOOP_EXTERNAL_10
:
386 ngep
->param_link_speed
= 10;
390 case NGE_LOOP_INTERNAL_PHY
:
391 ngep
->param_link_speed
= 1000;
392 adv_1000fdx
= B_TRUE
;
397 NGE_DEBUG(("nge_update_copper: autoneg %d "
398 "pause %d asym_pause %d "
400 "100fdx %d 100hdx %d "
401 "10fdx %d 10hdx %d ",
403 adv_pause
, adv_asym_pause
,
405 adv_100fdx
, adv_100hdx
,
406 adv_10fdx
, adv_10hdx
));
409 * We should have at least one technology capability set;
410 * if not, we select a default of 10Mb/s half-duplex
412 if (!adv_1000fdx
&& !adv_100fdx
&& !adv_10fdx
&&
413 !adv_100hdx
&& !adv_10hdx
)
417 * Now transform the adv_* variables into the proper settings
418 * of the PHY registers ...
420 * If autonegotiation is (now) enabled, we want to trigger
421 * a new autonegotiation cycle once the PHY has been
422 * programmed with the capabilities to be advertised.
425 control
|= MII_CONTROL_ANE
|MII_CONTROL_RSAN
;
428 control
|= MII_CONTROL_1000MB
|MII_CONTROL_FDUPLEX
;
430 control
|= MII_CONTROL_100MB
|MII_CONTROL_FDUPLEX
;
432 control
|= MII_CONTROL_100MB
;
434 control
|= MII_CONTROL_FDUPLEX
;
438 { _NOTE(EMPTY
); } /* Can't get here anyway ... */
441 gigctrl
|= MII_1000BT_CTL_ADV_FDX
;
443 anar
|= MII_ABILITY_100BASE_TX_FD
;
445 anar
|= MII_ABILITY_100BASE_TX
;
447 anar
|= MII_ABILITY_10BASE_T_FD
;
449 anar
|= MII_ABILITY_10BASE_T
;
452 anar
|= MII_ABILITY_PAUSE
;
454 anar
|= MII_ABILITY_ASMPAUSE
;
457 * Munge in any other fixed bits we require ...
459 anar
|= MII_AN_SELECTOR_8023
;
462 * Restart the PHY and write the new values.
464 nge_mii_put16(ngep
, MII_AN_ADVERT
, anar
);
465 nge_mii_put16(ngep
, MII_CONTROL
, control
);
466 nge_mii_put16(ngep
, MII_1000BASE_T_CONTROL
, gigctrl
);
467 if (!nge_phy_restart(ngep
))
468 nge_error(ngep
, "nge_update_copper: failed to restart phy");
470 * Loopback bit in control register is not reset sticky
471 * write it after PHY restart.
473 if (ngep
->param_loop_mode
== NGE_LOOP_INTERNAL_PHY
) {
474 control
= nge_mii_get16(ngep
, MII_CONTROL
);
475 control
|= MII_CONTROL_LOOPBACK
;
476 nge_mii_put16(ngep
, MII_CONTROL
, control
);
481 nge_check_copper(nge_t
*ngep
)
484 uint16_t mii_exstatus
;
485 uint16_t mii_excontrol
;
492 nge_mintr_src mintr_src
;
494 speed
= UNKOWN_SPEED
;
495 duplex
= UNKOWN_DUPLEX
;
497 * Read the status from the PHY (which is self-clearing
498 * on read!); also read & clear the main (Ethernet) MAC status
499 * (the relevant bits of this are write-one-to-clear).
501 mii_status
= nge_mii_get16(ngep
, MII_STATUS
);
502 mii_cs
.cs_val
= nge_reg_get32(ngep
, NGE_MII_CS
);
503 mintr_src
.src_val
= nge_reg_get32(ngep
, NGE_MINTR_SRC
);
504 nge_reg_put32(ngep
, NGE_MINTR_SRC
, mintr_src
.src_val
);
506 NGE_DEBUG(("nge_check_copper: link %d/%s, MII status 0x%x "
507 "(was 0x%x)", ngep
->link_state
,
508 UPORDOWN(ngep
->param_link_up
), mii_status
,
509 ngep
->phy_gen_status
));
513 * If the PHY status changed, record the time
515 switch (ngep
->phy_mode
) {
520 * Judge the giga speed by reading control
521 * and status register
523 mii_excontrol
= nge_mii_get16(ngep
,
524 MII_1000BASE_T_CONTROL
);
525 mii_exstatus
= nge_mii_get16(ngep
,
526 MII_1000BASE_T_STATUS
);
527 if ((mii_excontrol
& MII_1000BT_CTL_ADV_FDX
) &&
528 (mii_exstatus
& MII_1000BT_STAT_LP_FDX_CAP
)) {
532 anar
= nge_mii_get16(ngep
, MII_AN_ADVERT
);
533 lpan
= nge_mii_get16(ngep
, MII_AN_LPABLE
);
535 anar
= (anar
& lpan
);
536 if (anar
& MII_100BASET_FD
) {
539 } else if (anar
& MII_100BASET_HD
) {
542 } else if (anar
& MII_10BASET_FD
) {
545 } else if (anar
& MII_10BASET_HD
) {
552 anar
= nge_mii_get16(ngep
, MII_AN_ADVERT
);
553 lpan
= nge_mii_get16(ngep
, MII_AN_LPABLE
);
555 anar
= (anar
& lpan
);
557 if (anar
& MII_100BASET_FD
) {
560 } else if (anar
& MII_100BASET_HD
) {
563 } else if (anar
& MII_10BASET_FD
) {
566 } else if (anar
& MII_10BASET_HD
) {
575 * We will only consider the link UP if all the readings
576 * are consistent and give meaningful results ...
578 linkup
= nge_copper_link_speed
[speed
] > 0;
579 linkup
&= nge_copper_link_duplex
[duplex
] != LINK_DUPLEX_UNKNOWN
;
580 linkup
&= BIS(mii_status
, MII_STATUS_LINKUP
);
581 linkup
&= BIS(mii_cs
.cs_val
, MII_STATUS_LINKUP
);
584 * Record current register values, then reread status
585 * register & loop until it stabilises ...
587 ngep
->phy_gen_status
= mii_status
;
588 mii_status
= nge_mii_get16(ngep
, MII_STATUS
);
589 } while (mii_status
!= ngep
->phy_gen_status
);
591 /* Get the Link Partner Ability */
592 mii_exstatus
= nge_mii_get16(ngep
, MII_1000BASE_T_STATUS
);
593 lpan
= nge_mii_get16(ngep
, MII_AN_LPABLE
);
594 if (mii_exstatus
& MII_1000BT_STAT_LP_FDX_CAP
) {
595 ngep
->param_lp_autoneg
= B_TRUE
;
596 ngep
->param_link_autoneg
= B_TRUE
;
597 ngep
->param_lp_1000fdx
= B_TRUE
;
599 if (mii_exstatus
& MII_1000BT_STAT_LP_HDX_CAP
) {
600 ngep
->param_lp_autoneg
= B_TRUE
;
601 ngep
->param_link_autoneg
= B_TRUE
;
602 ngep
->param_lp_1000hdx
= B_TRUE
;
604 if (lpan
& MII_100BASET_FD
)
605 ngep
->param_lp_100fdx
= B_TRUE
;
606 if (lpan
& MII_100BASET_HD
)
607 ngep
->param_lp_100hdx
= B_TRUE
;
608 if (lpan
& MII_10BASET_FD
)
609 ngep
->param_lp_10fdx
= B_TRUE
;
610 if (lpan
& MII_10BASET_HD
)
611 ngep
->param_lp_10hdx
= B_TRUE
;
612 if (lpan
& MII_LP_ASYM_PAUSE
)
613 ngep
->param_lp_asym_pause
= B_TRUE
;
614 if (lpan
& MII_LP_PAUSE
)
615 ngep
->param_lp_pause
= B_TRUE
;
617 ngep
->param_link_up
= linkup
;
618 ngep
->param_link_speed
= nge_copper_link_speed
[speed
];
619 ngep
->param_link_duplex
= nge_copper_link_duplex
[duplex
];
621 ngep
->param_link_up
= B_FALSE
;
622 ngep
->param_link_speed
= 0;
623 ngep
->param_link_duplex
= LINK_DUPLEX_UNKNOWN
;
625 NGE_DEBUG(("nge_check_copper: link now %s speed %d duplex %d",
626 UPORDOWN(ngep
->param_link_up
),
627 ngep
->param_link_speed
,
628 ngep
->param_link_duplex
));
634 * Because the network chipset embedded in Ck8-04 bridge is only a mac chipset,
635 * the different vendor can use different media(serdes and copper).
636 * To make it easier to extend the driver to support more platforms with ck8-04,
637 * For example, one platform with serdes support,
638 * wrapper phy operation functions.
639 * But now, only supply copper phy operations.
641 static const phys_ops_t copper_ops
= {
648 * Here we have to determine which media we're using (copper or serdes).
649 * Once that's done, we can initialise the physical layer appropriately.
652 nge_phys_init(nge_t
*ngep
)
655 NGE_TRACE(("nge_phys_init($%p)", (void *)ngep
));
657 /* Get the phy type from MAC2PHY register */
658 m2p
.m2p_val
= nge_reg_get32(ngep
, NGE_MAC2PHY
);
659 ngep
->phy_mode
= m2p
.m2p_bits
.in_type
;
660 if ((ngep
->phy_mode
!= RGMII_IN
) && (ngep
->phy_mode
!= MII_IN
)) {
661 ngep
->phy_mode
= RGMII_IN
;
662 m2p
.m2p_bits
.in_type
= RGMII_IN
;
663 nge_reg_put32(ngep
, NGE_MAC2PHY
, m2p
.m2p_val
);
667 * Probe for the type of the PHY.
669 ngep
->phy_xmii_addr
= 1;
670 (void) nge_phy_probe(ngep
);
671 ngep
->chipinfo
.flags
|= CHIP_FLAG_COPPER
;
672 ngep
->physops
= &copper_ops
;
673 (*(ngep
->physops
->phys_restart
))(ngep
);