]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm920t/at91rm9200/ks8721.c
3 * Author : Eric Benard (Eukrea Electromatique)
4 * based on dm9161.c which is :
6 * Author : Hamid Ikdoumi (Atmel)
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #include <at91rm9200_net.h>
31 #ifdef CONFIG_DRIVER_ETHER
33 #if defined(CONFIG_CMD_NET)
37 * ks8721_isphyconnected
39 * Reads the 2 PHY ID registers
41 * p_mac - pointer to AT91S_EMAC struct
43 * 1 - if id read successfully
46 unsigned int ks8721_isphyconnected(AT91PS_EMAC p_mac
)
48 unsigned short id1
, id2
;
50 at91rm9200_EmacEnableMDIO(p_mac
);
51 at91rm9200_EmacReadPhy(p_mac
,
52 CONFIG_PHY_ADDRESS
| KS8721_PHYID1
, &id1
);
53 at91rm9200_EmacReadPhy(p_mac
,
54 CONFIG_PHY_ADDRESS
| KS8721_PHYID2
, &id2
);
55 at91rm9200_EmacDisableMDIO(p_mac
);
57 if ((id1
== (KS8721_PHYID_OUI
>> 6)) &&
58 ((id2
>> 10) == (KS8721_PHYID_OUI
& KS8721_LSB_MASK
))) {
59 if ((id2
& KS8721_MODELMASK
) == KS8721BL_MODEL
)
60 printf("Micrel KS8721bL PHY detected : ");
62 printf("Unknown Micrel PHY detected : ");
72 * Link parallel detection status of MAC is checked and set in the
73 * MAC configuration registers
75 * p_mac - pointer to MAC
77 * 1 - if link status set succesfully
78 * 0 - if link status not set
80 unsigned char ks8721_getlinkspeed(AT91PS_EMAC p_mac
)
84 if (!at91rm9200_EmacReadPhy(p_mac
, KS8721_BMSR
, &stat1
))
87 if (!(stat1
& KS8721_LINK_STATUS
)) {
89 printf("Link Down !\n");
93 if (stat1
& KS8721_100BASE_TX_FD
) {
94 /* set Emac for 100BaseTX and Full Duplex */
96 p_mac
->EMAC_CFG
|= AT91C_EMAC_SPD
| AT91C_EMAC_FD
;
100 if (stat1
& KS8721_10BASE_T_FD
) {
101 /* set MII for 10BaseT and Full Duplex */
103 p_mac
->EMAC_CFG
= (p_mac
->EMAC_CFG
&
104 ~(AT91C_EMAC_SPD
| AT91C_EMAC_FD
))
109 if (stat1
& KS8721_100BASE_T4_HD
) {
110 /* set MII for 100BaseTX and Half Duplex */
111 printf("100BT HD\n");
112 p_mac
->EMAC_CFG
= (p_mac
->EMAC_CFG
&
113 ~(AT91C_EMAC_SPD
| AT91C_EMAC_FD
))
118 if (stat1
& KS8721_10BASE_T_HD
) {
119 /* set MII for 10BaseT and Half Duplex */
121 p_mac
->EMAC_CFG
&= ~(AT91C_EMAC_SPD
| AT91C_EMAC_FD
);
131 * MAC starts checking its link by using parallel detection and
132 * Autonegotiation and the same is set in the MAC configuration registers
134 * p_mac - pointer to struct AT91S_EMAC
136 * 1 - if link status set succesfully
137 * 0 - if link status not set
139 unsigned char ks8721_initphy(AT91PS_EMAC p_mac
)
141 unsigned char ret
= 1;
142 unsigned short intvalue
;
144 at91rm9200_EmacEnableMDIO(p_mac
);
146 /* Try another time */
147 if (!ks8721_getlinkspeed(p_mac
))
148 ret
= ks8721_getlinkspeed(p_mac
);
150 /* Disable PHY Interrupts */
152 at91rm9200_EmacWritePhy(p_mac
,
153 CONFIG_PHY_ADDRESS
| KS8721_MDINTR
, &intvalue
);
154 at91rm9200_EmacDisableMDIO(p_mac
);
161 * ks8721_autonegotiate
163 * MAC Autonegotiates with the partner status of same is set in the
164 * MAC configuration registers
166 * dev - pointer to struct net_device
168 * 1 - if link status set successfully
169 * 0 - if link status not set
171 unsigned char ks8721_autonegotiate(AT91PS_EMAC p_mac
, int *status
)
173 unsigned short value
;
174 unsigned short phyanar
;
175 unsigned short phyanalpar
;
177 /* Set ks8721 control register */
178 if (!at91rm9200_EmacReadPhy(p_mac
,
179 CONFIG_PHY_ADDRESS
| KS8721_BMCR
, &value
))
182 /* remove autonegotiation enable */
183 value
&= ~KS8721_AUTONEG
;
184 /* Electrically isolate PHY */
185 value
|= KS8721_ISOLATE
;
186 if (!at91rm9200_EmacWritePhy(p_mac
,
187 CONFIG_PHY_ADDRESS
| KS8721_BMCR
, &value
)) {
191 * Set the Auto_negotiation Advertisement Register
192 * MII advertising for Next page, 100BaseTxFD and HD,
193 * 10BaseTFD and HD, IEEE 802.3
195 phyanar
= KS8721_NP
| KS8721_TX_FDX
| KS8721_TX_HDX
|
196 KS8721_10_FDX
| KS8721_10_HDX
| KS8721_AN_IEEE_802_3
;
197 if (!at91rm9200_EmacWritePhy(p_mac
,
198 CONFIG_PHY_ADDRESS
| KS8721_ANAR
, &phyanar
)) {
201 /* Read the Control Register */
202 if (!at91rm9200_EmacReadPhy(p_mac
,
203 CONFIG_PHY_ADDRESS
| KS8721_BMCR
, &value
)) {
206 value
|= KS8721_SPEED_SELECT
| KS8721_AUTONEG
| KS8721_DUPLEX_MODE
;
207 if (!at91rm9200_EmacWritePhy(p_mac
,
208 CONFIG_PHY_ADDRESS
| KS8721_BMCR
, &value
)) {
211 /* Restart Auto_negotiation */
212 value
|= KS8721_RESTART_AUTONEG
;
213 value
&= ~KS8721_ISOLATE
;
214 if (!at91rm9200_EmacWritePhy(p_mac
,
215 CONFIG_PHY_ADDRESS
| KS8721_BMCR
, &value
)) {
218 /* Check AutoNegotiate complete */
220 at91rm9200_EmacReadPhy(p_mac
,
221 CONFIG_PHY_ADDRESS
| KS8721_BMSR
, &value
);
222 if (!(value
& KS8721_AUTONEG_COMP
))
225 /* Get the AutoNeg Link partner base page */
226 if (!at91rm9200_EmacReadPhy(p_mac
,
227 CONFIG_PHY_ADDRESS
| KS8721_ANLPAR
, &phyanalpar
)) {
231 if ((phyanar
& KS8721_TX_FDX
) && (phyanalpar
& KS8721_TX_FDX
)) {
232 /* Set MII for 100BaseTX and Full Duplex */
233 p_mac
->EMAC_CFG
|= AT91C_EMAC_SPD
| AT91C_EMAC_FD
;
237 if ((phyanar
& KS8721_10_FDX
) && (phyanalpar
& KS8721_10_FDX
)) {
238 /* Set MII for 10BaseT and Full Duplex */
239 p_mac
->EMAC_CFG
= (p_mac
->EMAC_CFG
&
240 ~(AT91C_EMAC_SPD
| AT91C_EMAC_FD
))
247 #endif /* CONFIG_CMD_NET */
249 #endif /* CONFIG_DRIVER_ETHER */