4 * @author Intel Corporation
7 * @brief MII control functions
11 * IXP400 SW Release version 2.0
13 * -- Copyright Notice --
16 * Copyright 2001-2005, Intel Corporation.
17 * All rights reserved.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. Neither the name of the Intel Corporation nor the names of its contributors
29 * may be used to endorse or promote products derived from this software
30 * without specific prior written permission.
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
34 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * -- End of Copyright Notice --
51 #include "IxEthAcc_p.h"
52 #include "IxEthAccMac_p.h"
53 #include "IxEthAccMii_p.h"
56 PRIVATE UINT32 miiBaseAddressVirt
;
57 PRIVATE IxOsalMutex miiAccessLock
;
59 PUBLIC UINT32 ixEthAccMiiRetryCount
= IX_ETH_ACC_MII_TIMEOUT_10TH_SECS
;
60 PUBLIC UINT32 ixEthAccMiiAccessTimeout
= IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS
;
62 /* -----------------------------------
63 * private function prototypes
66 ixEthAccMdioCmdWrite(UINT32 mdioCommand
);
69 ixEthAccMdioCmdRead(UINT32
*data
);
72 ixEthAccMdioStatusRead(UINT32
*data
);
76 ixEthAccMdioCmdWrite(UINT32 mdioCommand
)
78 REG_WRITE(miiBaseAddressVirt
,
79 IX_ETH_ACC_MAC_MDIO_CMD_1
,
82 REG_WRITE(miiBaseAddressVirt
,
83 IX_ETH_ACC_MAC_MDIO_CMD_2
,
84 (mdioCommand
>> 8) & 0xff);
86 REG_WRITE(miiBaseAddressVirt
,
87 IX_ETH_ACC_MAC_MDIO_CMD_3
,
88 (mdioCommand
>> 16) & 0xff);
90 REG_WRITE(miiBaseAddressVirt
,
91 IX_ETH_ACC_MAC_MDIO_CMD_4
,
92 (mdioCommand
>> 24) & 0xff);
96 ixEthAccMdioCmdRead(UINT32
*data
)
100 REG_READ(miiBaseAddressVirt
,
101 IX_ETH_ACC_MAC_MDIO_CMD_1
,
104 *data
= regval
& 0xff;
106 REG_READ(miiBaseAddressVirt
,
107 IX_ETH_ACC_MAC_MDIO_CMD_2
,
110 *data
|= (regval
& 0xff) << 8;
112 REG_READ(miiBaseAddressVirt
,
113 IX_ETH_ACC_MAC_MDIO_CMD_3
,
116 *data
|= (regval
& 0xff) << 16;
118 REG_READ(miiBaseAddressVirt
,
119 IX_ETH_ACC_MAC_MDIO_CMD_4
,
122 *data
|= (regval
& 0xff) << 24;
127 ixEthAccMdioStatusRead(UINT32
*data
)
131 REG_READ(miiBaseAddressVirt
,
132 IX_ETH_ACC_MAC_MDIO_STS_1
,
135 *data
= regval
& 0xff;
137 REG_READ(miiBaseAddressVirt
,
138 IX_ETH_ACC_MAC_MDIO_STS_2
,
141 *data
|= (regval
& 0xff) << 8;
143 REG_READ(miiBaseAddressVirt
,
144 IX_ETH_ACC_MAC_MDIO_STS_3
,
147 *data
|= (regval
& 0xff) << 16;
149 REG_READ(miiBaseAddressVirt
,
150 IX_ETH_ACC_MAC_MDIO_STS_4
,
153 *data
|= (regval
& 0xff) << 24;
158 /********************************************************************
164 if(ixOsalMutexInit(&miiAccessLock
)!= IX_SUCCESS
)
166 return IX_ETH_ACC_FAIL
;
169 miiBaseAddressVirt
= (UINT32
) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE
, IX_OSAL_IXP400_ETHA_MAP_SIZE
);
171 if (miiBaseAddressVirt
== 0)
173 ixOsalLog(IX_OSAL_LOG_LVL_FATAL
,
174 IX_OSAL_LOG_DEV_STDOUT
,
175 "EthAcc: Could not map MII I/O mapped memory\n",
178 return IX_ETH_ACC_FAIL
;
181 return IX_ETH_ACC_SUCCESS
;
185 ixEthAccMiiUnload(void)
187 IX_OSAL_MEM_UNMAP(miiBaseAddressVirt
);
189 miiBaseAddressVirt
= 0;
192 PUBLIC IxEthAccStatus
193 ixEthAccMiiAccessTimeoutSet(UINT32 timeout
, UINT32 retryCount
)
195 if (retryCount
< 1) return IX_ETH_ACC_FAIL
;
197 ixEthAccMiiRetryCount
= retryCount
;
198 ixEthAccMiiAccessTimeout
= timeout
;
200 return IX_ETH_ACC_SUCCESS
;
203 /*********************************************************************
204 * ixEthAccMiiReadRtn - read a 16 bit value from a PHY
207 ixEthAccMiiReadRtn (UINT8 phyAddr
,
215 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
217 return (IX_ETH_ACC_FAIL
);
220 if ((phyAddr
>= IXP425_ETH_ACC_MII_MAX_ADDR
)
221 || (phyReg
>= IXP425_ETH_ACC_MII_MAX_REG
))
223 return (IX_ETH_ACC_FAIL
);
228 return (IX_ETH_ACC_FAIL
);
231 ixOsalMutexLock(&miiAccessLock
, IX_OSAL_WAIT_FOREVER
);
232 mdioCommand
= phyReg
<< IX_ETH_ACC_MII_REG_SHL
233 | phyAddr
<< IX_ETH_ACC_MII_ADDR_SHL
;
234 mdioCommand
|= IX_ETH_ACC_MII_GO
;
236 ixEthAccMdioCmdWrite(mdioCommand
);
238 miiTimeout
= ixEthAccMiiRetryCount
;
243 ixEthAccMdioCmdRead(®val
);
245 if((regval
& IX_ETH_ACC_MII_GO
) == 0x0)
249 /* Sleep for a while */
250 ixOsalSleep(ixEthAccMiiAccessTimeout
);
258 ixOsalMutexUnlock(&miiAccessLock
);
260 return IX_ETH_ACC_FAIL
;
264 ixEthAccMdioStatusRead(®val
);
265 if(regval
& IX_ETH_ACC_MII_READ_FAIL
)
267 ixOsalMutexUnlock(&miiAccessLock
);
269 return IX_ETH_ACC_FAIL
;
272 *value
= regval
& 0xffff;
273 ixOsalMutexUnlock(&miiAccessLock
);
274 return IX_ETH_ACC_SUCCESS
;
279 /*********************************************************************
280 * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
283 ixEthAccMiiWriteRtn (UINT8 phyAddr
,
292 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
294 return (IX_ETH_ACC_FAIL
);
297 if ((phyAddr
>= IXP425_ETH_ACC_MII_MAX_ADDR
)
298 || (phyReg
>= IXP425_ETH_ACC_MII_MAX_REG
))
300 return (IX_ETH_ACC_FAIL
);
303 /* ensure that a PHY is present at this address */
304 if(ixEthAccMiiReadRtn(phyAddr
,
305 IX_ETH_ACC_MII_CTRL_REG
,
306 &readVal
) != IX_ETH_ACC_SUCCESS
)
308 return (IX_ETH_ACC_FAIL
);
311 ixOsalMutexLock(&miiAccessLock
, IX_OSAL_WAIT_FOREVER
);
312 mdioCommand
= phyReg
<< IX_ETH_ACC_MII_REG_SHL
313 | phyAddr
<< IX_ETH_ACC_MII_ADDR_SHL
;
314 mdioCommand
|= IX_ETH_ACC_MII_GO
| IX_ETH_ACC_MII_WRITE
| value
;
316 ixEthAccMdioCmdWrite(mdioCommand
);
318 miiTimeout
= ixEthAccMiiRetryCount
;
323 ixEthAccMdioCmdRead(®val
);
325 /*The "GO" bit is reset to 0 when the write completes*/
326 if((regval
& IX_ETH_ACC_MII_GO
) == 0x0)
330 /* Sleep for a while */
331 ixOsalSleep(ixEthAccMiiAccessTimeout
);
335 ixOsalMutexUnlock(&miiAccessLock
);
338 return IX_ETH_ACC_FAIL
;
340 return IX_ETH_ACC_SUCCESS
;
344 /*****************************************************************
346 * Phy query functions
350 ixEthAccMiiStatsShow (UINT32 phyAddr
)
353 printf("Regisers on PHY at address 0x%x\n", phyAddr
);
354 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_CTRL_REG
, ®val
);
355 printf(" Control Register : 0x%4.4x\n", regval
);
356 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_STAT_REG
, ®val
);
357 printf(" Status Register : 0x%4.4x\n", regval
);
358 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_PHY_ID1_REG
, ®val
);
359 printf(" PHY ID1 Register : 0x%4.4x\n", regval
);
360 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_PHY_ID2_REG
, ®val
);
361 printf(" PHY ID2 Register : 0x%4.4x\n", regval
);
362 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_AN_ADS_REG
, ®val
);
363 printf(" Auto Neg ADS Register : 0x%4.4x\n", regval
);
364 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_AN_PRTN_REG
, ®val
);
365 printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval
);
366 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_AN_EXP_REG
, ®val
);
367 printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval
);
368 ixEthAccMiiReadRtn(phyAddr
, IX_ETH_ACC_MII_AN_NEXT_REG
, ®val
);
369 printf(" Auto Neg Next Register : 0x%4.4x\n", regval
);
371 return IX_ETH_ACC_SUCCESS
;
375 /*****************************************************************
377 * Interface query functions
381 ixEthAccMdioShow (void)
385 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
387 return (IX_ETH_ACC_FAIL
);
390 ixOsalMutexLock(&miiAccessLock
, IX_OSAL_WAIT_FOREVER
);
391 ixEthAccMdioCmdRead(®val
);
392 ixOsalMutexUnlock(&miiAccessLock
);
394 printf("MDIO command register\n");
395 printf(" Go bit : 0x%x\n", (regval
& BIT(31)) >> 31);
396 printf(" MDIO Write : 0x%x\n", (regval
& BIT(26)) >> 26);
397 printf(" PHY address : 0x%x\n", (regval
>> 21) & 0x1f);
398 printf(" Reg address : 0x%x\n", (regval
>> 16) & 0x1f);
400 ixOsalMutexLock(&miiAccessLock
, IX_OSAL_WAIT_FOREVER
);
401 ixEthAccMdioStatusRead(®val
);
402 ixOsalMutexUnlock(&miiAccessLock
);
404 printf("MDIO status register\n");
405 printf(" Read OK : 0x%x\n", (regval
& BIT(31)) >> 31);
406 printf(" Read Data : 0x%x\n", (regval
>> 16) & 0xff);
408 return IX_ETH_ACC_SUCCESS
;