]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxEthAccMii.c
doc: SPI: Add qspi test details on AM43xx
[karo-tx-uboot.git] / drivers / net / npe / IxEthAccMii.c
1 /**
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
20  * SPDX-License-Identifier:     BSD-3-Clause
21  * @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
32 PRIVATE UINT32 miiBaseAddressVirt;
33 PRIVATE IxOsalMutex miiAccessLock;
34
35 PUBLIC UINT32 ixEthAccMiiRetryCount    = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
36 PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
37
38 /* -----------------------------------
39  * private function prototypes
40  */
41 PRIVATE void
42 ixEthAccMdioCmdWrite(UINT32 mdioCommand);
43
44 PRIVATE void
45 ixEthAccMdioCmdRead(UINT32 *data);
46
47 PRIVATE void
48 ixEthAccMdioStatusRead(UINT32 *data);
49
50
51 PRIVATE void
52 ixEthAccMdioCmdWrite(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
71 PRIVATE void
72 ixEthAccMdioCmdRead(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
102 PRIVATE void
103 ixEthAccMdioStatusRead(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  */
137 IxEthAccStatus
138 ixEthAccMiiInit()
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
160 void
161 ixEthAccMiiUnload(void)
162 {
163     IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
164   
165     miiBaseAddressVirt = 0;
166 }
167
168 PUBLIC IxEthAccStatus
169 ixEthAccMiiAccessTimeoutSet(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  */
182 IxEthAccStatus      
183 ixEthAccMiiReadRtn (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  */
258 IxEthAccStatus
259 ixEthAccMiiWriteRtn (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)
303         {                   
304             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  */
325 IxEthAccStatus
326 ixEthAccMiiStatsShow (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  */
356 IxEthAccStatus
357 ixEthAccMdioShow (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