blob: bfe606f507b326634309b95e73783e251e34ed9a [file] [log] [blame]
Wolfgang Denkba94a1b2006-05-30 15:56:48 +02001/**
2 * @file IxEthAccMii.c
3 *
4 * @author Intel Corporation
5 * @date
6 *
7 * @brief MII control functions
8 *
9 * Design Notes:
10 *
11 * IXP400 SW Release version 2.0
12 *
13 * -- Copyright Notice --
14 *
15 * @par
16 * Copyright 2001-2005, Intel Corporation.
17 * All rights reserved.
18 *
19 * @par
Wolfgang Denkcb3761e2013-07-28 22:12:47 +020020 * SPDX-License-Identifier: BSD-3-Clause
Wolfgang Denkba94a1b2006-05-30 15:56:48 +020021 * @par
22 * -- End of Copyright Notice --
23 */
24
25#include "IxOsal.h"
26#include "IxEthAcc.h"
27#include "IxEthAcc_p.h"
28#include "IxEthAccMac_p.h"
29#include "IxEthAccMii_p.h"
30
31
32PRIVATE UINT32 miiBaseAddressVirt;
33PRIVATE IxOsalMutex miiAccessLock;
34
35PUBLIC UINT32 ixEthAccMiiRetryCount = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
36PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
37
38/* -----------------------------------
39 * private function prototypes
40 */
41PRIVATE void
42ixEthAccMdioCmdWrite(UINT32 mdioCommand);
43
44PRIVATE void
45ixEthAccMdioCmdRead(UINT32 *data);
46
47PRIVATE void
48ixEthAccMdioStatusRead(UINT32 *data);
49
50
51PRIVATE void
52ixEthAccMdioCmdWrite(UINT32 mdioCommand)
53{
54 REG_WRITE(miiBaseAddressVirt,
55 IX_ETH_ACC_MAC_MDIO_CMD_1,
56 mdioCommand & 0xff);
57
58 REG_WRITE(miiBaseAddressVirt,
59 IX_ETH_ACC_MAC_MDIO_CMD_2,
60 (mdioCommand >> 8) & 0xff);
61
62 REG_WRITE(miiBaseAddressVirt,
63 IX_ETH_ACC_MAC_MDIO_CMD_3,
64 (mdioCommand >> 16) & 0xff);
65
66 REG_WRITE(miiBaseAddressVirt,
67 IX_ETH_ACC_MAC_MDIO_CMD_4,
68 (mdioCommand >> 24) & 0xff);
69}
70
71PRIVATE void
72ixEthAccMdioCmdRead(UINT32 *data)
73{
74 UINT32 regval;
75
76 REG_READ(miiBaseAddressVirt,
77 IX_ETH_ACC_MAC_MDIO_CMD_1,
78 regval);
79
80 *data = regval & 0xff;
81
82 REG_READ(miiBaseAddressVirt,
83 IX_ETH_ACC_MAC_MDIO_CMD_2,
84 regval);
85
86 *data |= (regval & 0xff) << 8;
87
88 REG_READ(miiBaseAddressVirt,
89 IX_ETH_ACC_MAC_MDIO_CMD_3,
90 regval);
91
92 *data |= (regval & 0xff) << 16;
93
94 REG_READ(miiBaseAddressVirt,
95 IX_ETH_ACC_MAC_MDIO_CMD_4,
96 regval);
97
98 *data |= (regval & 0xff) << 24;
99
100}
101
102PRIVATE void
103ixEthAccMdioStatusRead(UINT32 *data)
104{
105 UINT32 regval;
106
107 REG_READ(miiBaseAddressVirt,
108 IX_ETH_ACC_MAC_MDIO_STS_1,
109 regval);
110
111 *data = regval & 0xff;
112
113 REG_READ(miiBaseAddressVirt,
114 IX_ETH_ACC_MAC_MDIO_STS_2,
115 regval);
116
117 *data |= (regval & 0xff) << 8;
118
119 REG_READ(miiBaseAddressVirt,
120 IX_ETH_ACC_MAC_MDIO_STS_3,
121 regval);
122
123 *data |= (regval & 0xff) << 16;
124
125 REG_READ(miiBaseAddressVirt,
126 IX_ETH_ACC_MAC_MDIO_STS_4,
127 regval);
128
129 *data |= (regval & 0xff) << 24;
130
131}
132
133
134/********************************************************************
135 * ixEthAccMiiInit
136 */
137IxEthAccStatus
138ixEthAccMiiInit()
139{
140 if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
141 {
142 return IX_ETH_ACC_FAIL;
143 }
144
145 miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
146
147 if (miiBaseAddressVirt == 0)
148 {
149 ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
150 IX_OSAL_LOG_DEV_STDOUT,
151 "EthAcc: Could not map MII I/O mapped memory\n",
152 0, 0, 0, 0, 0, 0);
153
154 return IX_ETH_ACC_FAIL;
155 }
156
157 return IX_ETH_ACC_SUCCESS;
158}
159
160void
161ixEthAccMiiUnload(void)
162{
163 IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
164
165 miiBaseAddressVirt = 0;
166}
167
168PUBLIC IxEthAccStatus
169ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
170{
171 if (retryCount < 1) return IX_ETH_ACC_FAIL;
172
173 ixEthAccMiiRetryCount = retryCount;
174 ixEthAccMiiAccessTimeout = timeout;
175
176 return IX_ETH_ACC_SUCCESS;
177}
178
179/*********************************************************************
180 * ixEthAccMiiReadRtn - read a 16 bit value from a PHY
181 */
182IxEthAccStatus
183ixEthAccMiiReadRtn (UINT8 phyAddr,
184 UINT8 phyReg,
185 UINT16 *value)
186{
187 UINT32 mdioCommand;
188 UINT32 regval;
189 UINT32 miiTimeout;
190
191 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
192 {
193 return (IX_ETH_ACC_FAIL);
194 }
195
196 if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
197 || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
198 {
199 return (IX_ETH_ACC_FAIL);
200 }
201
202 if (value == NULL)
203 {
204 return (IX_ETH_ACC_FAIL);
205 }
206
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;
211
212 ixEthAccMdioCmdWrite(mdioCommand);
213
214 miiTimeout = ixEthAccMiiRetryCount;
215
216 while(miiTimeout)
217 {
218
219 ixEthAccMdioCmdRead(&regval);
220
221 if((regval & IX_ETH_ACC_MII_GO) == 0x0)
222 {
223 break;
224 }
225 /* Sleep for a while */
226 ixOsalSleep(ixEthAccMiiAccessTimeout);
227 miiTimeout--;
228 }
229
230
231
232 if(miiTimeout == 0)
233 {
234 ixOsalMutexUnlock(&miiAccessLock);
235 *value = 0xffff;
236 return IX_ETH_ACC_FAIL;
237 }
238
239
240 ixEthAccMdioStatusRead(&regval);
241 if(regval & IX_ETH_ACC_MII_READ_FAIL)
242 {
243 ixOsalMutexUnlock(&miiAccessLock);
244 *value = 0xffff;
245 return IX_ETH_ACC_FAIL;
246 }
247
248 *value = regval & 0xffff;
249 ixOsalMutexUnlock(&miiAccessLock);
250 return IX_ETH_ACC_SUCCESS;
251
252}
253
254
255/*********************************************************************
256 * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
257 */
258IxEthAccStatus
259ixEthAccMiiWriteRtn (UINT8 phyAddr,
260 UINT8 phyReg,
261 UINT16 value)
262{
263 UINT32 mdioCommand;
264 UINT32 regval;
265 UINT16 readVal;
266 UINT32 miiTimeout;
267
268 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
269 {
270 return (IX_ETH_ACC_FAIL);
271 }
272
273 if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR)
274 || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
275 {
276 return (IX_ETH_ACC_FAIL);
277 }
278
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)
283 {
284 return (IX_ETH_ACC_FAIL);
285 }
286
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;
291
292 ixEthAccMdioCmdWrite(mdioCommand);
293
294 miiTimeout = ixEthAccMiiRetryCount;
295
296 while(miiTimeout)
297 {
298
299 ixEthAccMdioCmdRead(&regval);
300
301 /*The "GO" bit is reset to 0 when the write completes*/
302 if((regval & IX_ETH_ACC_MII_GO) == 0x0)
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200303 {
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200304 break;
305 }
306 /* Sleep for a while */
307 ixOsalSleep(ixEthAccMiiAccessTimeout);
308 miiTimeout--;
309 }
310
311 ixOsalMutexUnlock(&miiAccessLock);
312 if(miiTimeout == 0)
313 {
314 return IX_ETH_ACC_FAIL;
315 }
316 return IX_ETH_ACC_SUCCESS;
317}
318
319
320/*****************************************************************
321 *
322 * Phy query functions
323 *
324 */
325IxEthAccStatus
326ixEthAccMiiStatsShow (UINT32 phyAddr)
327{
328 UINT16 regval;
329 printf("Regisers on PHY at address 0x%x\n", phyAddr);
330 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &regval);
331 printf(" Control Register : 0x%4.4x\n", regval);
332 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, &regval);
333 printf(" Status Register : 0x%4.4x\n", regval);
334 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, &regval);
335 printf(" PHY ID1 Register : 0x%4.4x\n", regval);
336 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, &regval);
337 printf(" PHY ID2 Register : 0x%4.4x\n", regval);
338 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, &regval);
339 printf(" Auto Neg ADS Register : 0x%4.4x\n", regval);
340 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, &regval);
341 printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval);
342 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, &regval);
343 printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval);
344 ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, &regval);
345 printf(" Auto Neg Next Register : 0x%4.4x\n", regval);
346
347 return IX_ETH_ACC_SUCCESS;
348}
349
350
351/*****************************************************************
352 *
353 * Interface query functions
354 *
355 */
356IxEthAccStatus
357ixEthAccMdioShow (void)
358{
359 UINT32 regval;
360
361 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
362 {
363 return (IX_ETH_ACC_FAIL);
364 }
365
366 ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
367 ixEthAccMdioCmdRead(&regval);
368 ixOsalMutexUnlock(&miiAccessLock);
369
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);
375
376 ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
377 ixEthAccMdioStatusRead(&regval);
378 ixOsalMutexUnlock(&miiAccessLock);
379
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);
383
384 return IX_ETH_ACC_SUCCESS;
385}
386