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 * SPDX-License-Identifier: BSD-3-Clause
22 * -- End of Copyright Notice --
27 #include "IxEthAcc_p.h"
28 #include "IxEthAccMac_p.h"
29 #include "IxEthAccMii_p.h"
32 PRIVATE UINT32 miiBaseAddressVirt;
33 PRIVATE IxOsalMutex miiAccessLock;
35 PUBLIC UINT32 ixEthAccMiiRetryCount = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
36 PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
38 /* -----------------------------------
39 * private function prototypes
42 ixEthAccMdioCmdWrite(UINT32 mdioCommand);
45 ixEthAccMdioCmdRead(UINT32 *data);
48 ixEthAccMdioStatusRead(UINT32 *data);
52 ixEthAccMdioCmdWrite(UINT32 mdioCommand)
54 REG_WRITE(miiBaseAddressVirt,
55 IX_ETH_ACC_MAC_MDIO_CMD_1,
58 REG_WRITE(miiBaseAddressVirt,
59 IX_ETH_ACC_MAC_MDIO_CMD_2,
60 (mdioCommand >> 8) & 0xff);
62 REG_WRITE(miiBaseAddressVirt,
63 IX_ETH_ACC_MAC_MDIO_CMD_3,
64 (mdioCommand >> 16) & 0xff);
66 REG_WRITE(miiBaseAddressVirt,
67 IX_ETH_ACC_MAC_MDIO_CMD_4,
68 (mdioCommand >> 24) & 0xff);
72 ixEthAccMdioCmdRead(UINT32 *data)
76 REG_READ(miiBaseAddressVirt,
77 IX_ETH_ACC_MAC_MDIO_CMD_1,
80 *data = regval & 0xff;
82 REG_READ(miiBaseAddressVirt,
83 IX_ETH_ACC_MAC_MDIO_CMD_2,
86 *data |= (regval & 0xff) << 8;
88 REG_READ(miiBaseAddressVirt,
89 IX_ETH_ACC_MAC_MDIO_CMD_3,
92 *data |= (regval & 0xff) << 16;
94 REG_READ(miiBaseAddressVirt,
95 IX_ETH_ACC_MAC_MDIO_CMD_4,
98 *data |= (regval & 0xff) << 24;
103 ixEthAccMdioStatusRead(UINT32 *data)
107 REG_READ(miiBaseAddressVirt,
108 IX_ETH_ACC_MAC_MDIO_STS_1,
111 *data = regval & 0xff;
113 REG_READ(miiBaseAddressVirt,
114 IX_ETH_ACC_MAC_MDIO_STS_2,
117 *data |= (regval & 0xff) << 8;
119 REG_READ(miiBaseAddressVirt,
120 IX_ETH_ACC_MAC_MDIO_STS_3,
123 *data |= (regval & 0xff) << 16;
125 REG_READ(miiBaseAddressVirt,
126 IX_ETH_ACC_MAC_MDIO_STS_4,
129 *data |= (regval & 0xff) << 24;
134 /********************************************************************
140 if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
142 return IX_ETH_ACC_FAIL;
145 miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
147 if (miiBaseAddressVirt == 0)
149 ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
150 IX_OSAL_LOG_DEV_STDOUT,
151 "EthAcc: Could not map MII I/O mapped memory\n",
154 return IX_ETH_ACC_FAIL;
157 return IX_ETH_ACC_SUCCESS;
161 ixEthAccMiiUnload(void)
163 IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
165 miiBaseAddressVirt = 0;
168 PUBLIC IxEthAccStatus
169 ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
171 if (retryCount < 1) return IX_ETH_ACC_FAIL;
173 ixEthAccMiiRetryCount = retryCount;
174 ixEthAccMiiAccessTimeout = timeout;
176 return IX_ETH_ACC_SUCCESS;
179 /*********************************************************************
180 * ixEthAccMiiReadRtn - read a 16 bit value from a PHY
183 ixEthAccMiiReadRtn (UINT8 phyAddr,
191 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
193 return (IX_ETH_ACC_FAIL);
196 if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
197 || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
199 return (IX_ETH_ACC_FAIL);
204 return (IX_ETH_ACC_FAIL);
207 ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
208 mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
209 | phyAddr << IX_ETH_ACC_MII_ADDR_SHL;
210 mdioCommand |= IX_ETH_ACC_MII_GO;
212 ixEthAccMdioCmdWrite(mdioCommand);
214 miiTimeout = ixEthAccMiiRetryCount;
219 ixEthAccMdioCmdRead(®val);
221 if((regval & IX_ETH_ACC_MII_GO) == 0x0)
225 /* Sleep for a while */
226 ixOsalSleep(ixEthAccMiiAccessTimeout);
234 ixOsalMutexUnlock(&miiAccessLock);
236 return IX_ETH_ACC_FAIL;
240 ixEthAccMdioStatusRead(®val);
241 if(regval & IX_ETH_ACC_MII_READ_FAIL)
243 ixOsalMutexUnlock(&miiAccessLock);
245 return IX_ETH_ACC_FAIL;
248 *value = regval & 0xffff;
249 ixOsalMutexUnlock(&miiAccessLock);
250 return IX_ETH_ACC_SUCCESS;
255 /*********************************************************************
256 * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
259 ixEthAccMiiWriteRtn (UINT8 phyAddr,
268 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
270 return (IX_ETH_ACC_FAIL);
273 if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
274 || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
276 return (IX_ETH_ACC_FAIL);
279 /* ensure that a PHY is present at this address */
280 if(ixEthAccMiiReadRtn(phyAddr,
281 IX_ETH_ACC_MII_CTRL_REG,
282 &readVal) != IX_ETH_ACC_SUCCESS)
284 return (IX_ETH_ACC_FAIL);
287 ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
288 mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
289 | phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
290 mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;
292 ixEthAccMdioCmdWrite(mdioCommand);
294 miiTimeout = ixEthAccMiiRetryCount;
299 ixEthAccMdioCmdRead(®val);
301 /*The "GO" bit is reset to 0 when the write completes*/
302 if((regval & IX_ETH_ACC_MII_GO) == 0x0)
306 /* Sleep for a while */
307 ixOsalSleep(ixEthAccMiiAccessTimeout);
311 ixOsalMutexUnlock(&miiAccessLock);
314 return IX_ETH_ACC_FAIL;
316 return IX_ETH_ACC_SUCCESS;
320 /*****************************************************************
322 * Phy query functions
326 ixEthAccMiiStatsShow (UINT32 phyAddr)
329 printf("Regisers on PHY at address 0x%x\n", phyAddr);
330 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, ®val);
331 printf(" Control Register : 0x%4.4x\n", regval);
332 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, ®val);
333 printf(" Status Register : 0x%4.4x\n", regval);
334 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, ®val);
335 printf(" PHY ID1 Register : 0x%4.4x\n", regval);
336 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, ®val);
337 printf(" PHY ID2 Register : 0x%4.4x\n", regval);
338 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, ®val);
339 printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
340 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, ®val);
341 printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
342 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, ®val);
343 printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
344 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, ®val);
345 printf(" Auto Neg Next Register : 0x%4.4x\n", regval);
347 return IX_ETH_ACC_SUCCESS;
351 /*****************************************************************
353 * Interface query functions
357 ixEthAccMdioShow (void)
361 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
363 return (IX_ETH_ACC_FAIL);
366 ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
367 ixEthAccMdioCmdRead(®val);
368 ixOsalMutexUnlock(&miiAccessLock);
370 printf("MDIO command register\n");
371 printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31);
372 printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26);
373 printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f);
374 printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f);
376 ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
377 ixEthAccMdioStatusRead(®val);
378 ixOsalMutexUnlock(&miiAccessLock);
380 printf("MDIO status register\n");
381 printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31);
382 printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff);
384 return IX_ETH_ACC_SUCCESS;