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;