staging: vt6655: always keep abyCurrentNetAddr aligned to 2
[cascardo/linux.git] / drivers / staging / vt6655 / srom.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * File: srom.c
20  *
21  * Purpose:Implement functions to access eeprom
22  *
23  * Author: Jerry Chen
24  *
25  * Date: Jan 29, 2003
26  *
27  * Functions:
28  *      SROMbyReadEmbedded - Embedded read eeprom via MAC
29  *      SROMbWriteEmbedded - Embedded write eeprom via MAC
30  *      SROMvRegBitsOn - Set Bits On in eeprom
31  *      SROMvRegBitsOff - Clear Bits Off in eeprom
32  *      SROMbIsRegBitsOn - Test if Bits On in eeprom
33  *      SROMbIsRegBitsOff - Test if Bits Off in eeprom
34  *      SROMvReadAllContents - Read all contents in eeprom
35  *      SROMvWriteAllContents - Write all contents in eeprom
36  *      SROMvReadEtherAddress - Read Ethernet Address in eeprom
37  *      SROMvWriteEtherAddress - Write Ethernet Address in eeprom
38  *      SROMvReadSubSysVenId - Read Sub_VID and Sub_SysId in eeprom
39  *      SROMbAutoLoad - Auto Load eeprom to MAC register
40  *
41  * Revision History:
42  *
43  */
44
45 #include "upc.h"
46 #include "tmacro.h"
47 #include "mac.h"
48 #include "srom.h"
49
50 /*---------------------  Static Definitions -------------------------*/
51
52 /*---------------------  Static Classes  ----------------------------*/
53
54 /*---------------------  Static Variables  --------------------------*/
55
56 /*---------------------  Static Functions  --------------------------*/
57
58 /*---------------------  Export Variables  --------------------------*/
59
60 /*---------------------  Export Functions  --------------------------*/
61
62 /*
63  * Description: Read a byte from EEPROM, by MAC I2C
64  *
65  * Parameters:
66  *  In:
67  *      dwIoBase        - I/O base address
68  *      byContntOffset  - address of EEPROM
69  *  Out:
70  *      none
71  *
72  * Return Value: data read
73  *
74  */
75 unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset)
76 {
77         unsigned short wDelay, wNoACK;
78         unsigned char byWait;
79         unsigned char byData;
80         unsigned char byOrg;
81
82         byData = 0xFF;
83         VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
84         /* turn off hardware retry for getting NACK */
85         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY)));
86         for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) {
87                 VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID);
88                 VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset);
89
90                 /* issue read command */
91                 VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR);
92                 /* wait DONE be set */
93                 for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
94                         VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
95                         if (byWait & (I2MCSR_DONE | I2MCSR_NACK))
96                                 break;
97                         PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
98                 }
99                 if ((wDelay < W_MAX_TIMEOUT) &&
100                     (!(byWait & I2MCSR_NACK))) {
101                         break;
102                 }
103         }
104         VNSvInPortB(dwIoBase + MAC_REG_I2MDIPT, &byData);
105         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
106         return byData;
107 }
108
109 /*
110  * Description: Write a byte to EEPROM, by MAC I2C
111  *
112  * Parameters:
113  *  In:
114  *      dwIoBase        - I/O base address
115  *      byContntOffset  - address of EEPROM
116  *      wData           - data to write
117  *  Out:
118  *      none
119  *
120  * Return Value: true if succeeded; false if failed.
121  *
122  */
123 bool SROMbWriteEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byData)
124 {
125         unsigned short wDelay, wNoACK;
126         unsigned char byWait;
127
128         unsigned char byOrg;
129
130         VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
131         /* turn off hardware retry for getting NACK */
132         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY)));
133         for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) {
134                 VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID);
135                 VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset);
136                 VNSvOutPortB(dwIoBase + MAC_REG_I2MDOPT, byData);
137
138                 /* issue write command */
139                 VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMW);
140                 /* wait DONE be set */
141                 for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
142                         VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
143                         if (byWait & (I2MCSR_DONE | I2MCSR_NACK))
144                                 break;
145                         PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
146                 }
147
148                 if ((wDelay < W_MAX_TIMEOUT) &&
149                     (!(byWait & I2MCSR_NACK))) {
150                         break;
151                 }
152         }
153         if (wNoACK == W_MAX_I2CRETRY) {
154                 VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
155                 return false;
156         }
157         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
158         return true;
159 }
160
161 /*
162  * Description: Turn bits on in eeprom
163  *
164  * Parameters:
165  *  In:
166  *      dwIoBase        - I/O base address
167  *      byContntOffset  - address of EEPROM
168  *      byBits          - bits to turn on
169  *  Out:
170  *      none
171  *
172  * Return Value: none
173  *
174  */
175 void SROMvRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits)
176 {
177         unsigned char byOrgData;
178
179         byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
180         SROMbWriteEmbedded(dwIoBase, byContntOffset, (unsigned char)(byOrgData | byBits));
181 }
182
183 /*
184  * Description: Turn bits off in eeprom
185  *
186  * Parameters:
187  *  In:
188  *      dwIoBase        - I/O base address
189  *      byContntOffset  - address of EEPROM
190  *      byBits          - bits to turn off
191  *  Out:
192  *      none
193  *
194  */
195 void SROMvRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits)
196 {
197         unsigned char byOrgData;
198
199         byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
200         SROMbWriteEmbedded(dwIoBase, byContntOffset, (unsigned char)(byOrgData & (~byBits)));
201 }
202
203 /*
204  * Description: Test if bits on in eeprom
205  *
206  * Parameters:
207  *  In:
208  *      dwIoBase        - I/O base address
209  *      byContntOffset  - address of EEPROM
210  *      byTestBits      - bits to test
211  *  Out:
212  *      none
213  *
214  * Return Value: true if all test bits on; otherwise false
215  *
216  */
217 bool SROMbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
218 {
219         unsigned char byOrgData;
220
221         byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
222         return (byOrgData & byTestBits) == byTestBits;
223 }
224
225 /*
226  * Description: Test if bits off in eeprom
227  *
228  * Parameters:
229  *  In:
230  *      dwIoBase        - I/O base address
231  *      byContntOffset  - address of EEPROM
232  *      byTestBits      - bits to test
233  *  Out:
234  *      none
235  *
236  * Return Value: true if all test bits off; otherwise false
237  *
238  */
239 bool SROMbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
240 {
241         unsigned char byOrgData;
242
243         byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
244         return !(byOrgData & byTestBits);
245 }
246
247 /*
248  * Description: Read all contents of eeprom to buffer
249  *
250  * Parameters:
251  *  In:
252  *      dwIoBase        - I/O base address
253  *  Out:
254  *      pbyEepromRegs   - EEPROM content Buffer
255  *
256  * Return Value: none
257  *
258  */
259 void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs)
260 {
261         int     ii;
262
263         /* ii = Rom Address */
264         for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
265                 *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase, (unsigned char)ii);
266                 pbyEepromRegs++;
267         }
268 }
269
270 /*
271  * Description: Write all contents of buffer to eeprom
272  *
273  * Parameters:
274  *  In:
275  *      dwIoBase        - I/O base address
276  *      pbyEepromRegs   - EEPROM content Buffer
277  *  Out:
278  *      none
279  *
280  * Return Value: none
281  *
282  */
283 void SROMvWriteAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs)
284 {
285         int     ii;
286
287         /* ii = Rom Address */
288         for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
289                 SROMbWriteEmbedded(dwIoBase, (unsigned char)ii, *pbyEepromRegs);
290                 pbyEepromRegs++;
291         }
292 }
293
294 /*
295  * Description: Read Ethernet Address from eeprom to buffer
296  *
297  * Parameters:
298  *  In:
299  *      dwIoBase        - I/O base address
300  *  Out:
301  *      pbyEtherAddress - Ethernet Address buffer
302  *
303  * Return Value: none
304  *
305  */
306 void SROMvReadEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress)
307 {
308         unsigned char ii;
309
310         /* ii = Rom Address */
311         for (ii = 0; ii < ETH_ALEN; ii++) {
312                 *pbyEtherAddress = SROMbyReadEmbedded(dwIoBase, ii);
313                 pbyEtherAddress++;
314         }
315 }
316
317 /*
318  * Description: Write Ethernet Address from buffer to eeprom
319  *
320  * Parameters:
321  *  In:
322  *      dwIoBase        - I/O base address
323  *      pbyEtherAddress - Ethernet Address buffer
324  *  Out:
325  *      none
326  *
327  * Return Value: none
328  *
329  */
330 void SROMvWriteEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress)
331 {
332         unsigned char ii;
333
334         /* ii = Rom Address */
335         for (ii = 0; ii < ETH_ALEN; ii++) {
336                 SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress);
337                 pbyEtherAddress++;
338         }
339 }
340
341 /*
342  * Description: Read Sub_VID and Sub_SysId from eeprom to buffer
343  *
344  * Parameters:
345  *  In:
346  *      dwIoBase        - I/O base address
347  *  Out:
348  *      pdwSubSysVenId  - Sub_VID and Sub_SysId read
349  *
350  * Return Value: none
351  *
352  */
353 void SROMvReadSubSysVenId(void __iomem *dwIoBase, unsigned long *pdwSubSysVenId)
354 {
355         unsigned char *pbyData;
356
357         pbyData = (unsigned char *)pdwSubSysVenId;
358         /* sub vendor */
359         *pbyData = SROMbyReadEmbedded(dwIoBase, 6);
360         *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7);
361         /* sub system */
362         *(pbyData+2) = SROMbyReadEmbedded(dwIoBase, 8);
363         *(pbyData+3) = SROMbyReadEmbedded(dwIoBase, 9);
364 }
365
366 /*
367  * Description: Auto Load EEPROM to MAC register
368  *
369  * Parameters:
370  *  In:
371  *      dwIoBase        - I/O base address
372  *  Out:
373  *      none
374  *
375  * Return Value: true if success; otherwise false
376  *
377  */
378 bool SROMbAutoLoad(void __iomem *dwIoBase)
379 {
380         unsigned char byWait;
381         int     ii;
382
383         unsigned char byOrg;
384
385         VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg);
386         /* turn on hardware retry */
387         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY));
388
389         MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD);
390
391         /* ii = Rom Address */
392         for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
393                 MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT);
394                 VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
395                 if (!(byWait & I2MCSR_AUTOLD))
396                         break;
397         }
398
399         VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg);
400
401         if (ii == EEP_MAX_CONTEXT_SIZE)
402                 return false;
403         return true;
404 }