ff843e161b76a4869801357d998b479102af2a8c
[linux-flexiantxendom0-3.2.10.git] / drivers / net / e100 / e100_eeprom.c
1 /*******************************************************************************
2
3   
4   Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
5   
6   This program is free software; you can redistribute it and/or modify it 
7   under the terms of the GNU General Public License as published by the Free 
8   Software Foundation; either version 2 of the License, or (at your option) 
9   any later version.
10   
11   This program is distributed in the hope that it will be useful, but WITHOUT 
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
14   more details.
15   
16   You should have received a copy of the GNU General Public License along with
17   this program; if not, write to the Free Software Foundation, Inc., 59 
18   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19   
20   The full GNU General Public License is included in this distribution in the
21   file called LICENSE.
22   
23   Contact Information:
24   Linux NICS <linux.nics@intel.com>
25   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 *******************************************************************************/
27
28 /**********************************************************************
29 *                                                                     *
30 * INTEL CORPORATION                                                   *
31 *                                                                     *
32 * This software is supplied under the terms of the license included   *
33 * above.  All use of this driver must be in accordance with the terms *
34 * of that license.                                                    *
35 *                                                                     *
36 * Module Name:  e100_eeprom.c                                         *
37 *                                                                     *
38 * Abstract:     This module contains routines to read and write to a  *
39 *               serial EEPROM                                         *
40 *                                                                     *
41 * Environment:  This file is intended to be specific to the Linux     *
42 *               operating system.                                     *
43 *                                                                     *
44 **********************************************************************/
45 #include "e100.h"
46
47 #define CSR_EEPROM_CONTROL_FIELD(bdp) ((bdp)->scb->scb_eprm_cntrl)
48
49 #define CSR_GENERAL_CONTROL2_FIELD(bdp) \
50                    ((bdp)->scb->scb_ext.d102_scb.scb_gen_ctrl2)
51
52 #define EEPROM_STALL_TIME       4
53 #define EEPROM_CHECKSUM         ((u16) 0xBABA)
54 #define EEPROM_MAX_WORD_SIZE    256
55
56 void e100_eeprom_cleanup(struct e100_private *adapter);
57 u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
58 static void e100_eeprom_write_word(struct e100_private *adapter, u16 reg,
59                                    u16 data);
60 void e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,
61                              u16 size);
62 u16 e100_eeprom_size(struct e100_private *adapter);
63 u16 e100_eeprom_read(struct e100_private *adapter, u16 reg);
64
65 static void shift_out_bits(struct e100_private *adapter, u16 data, u16 count);
66 static u16 shift_in_bits(struct e100_private *adapter);
67 static void raise_clock(struct e100_private *adapter, u16 *x);
68 static void lower_clock(struct e100_private *adapter, u16 *x);
69 static u16 eeprom_wait_cmd_done(struct e100_private *adapter);
70 static void eeprom_stand_by(struct e100_private *adapter);
71
72 //----------------------------------------------------------------------------------------
73 // Procedure:   eeprom_set_semaphore
74 //
75 // Description: This function set (write 1) Gamla EEPROM semaphore bit (bit 23 word 0x1C in the CSR).
76 //
77 // Arguments:
78 //      Adapter                 - Adapter context
79 //
80 // Returns:  true if success
81 //           else return false 
82 //
83 //----------------------------------------------------------------------------------------
84
85 inline u8
86 eeprom_set_semaphore(struct e100_private *adapter)
87 {
88         u16 data = 0;
89         unsigned long expiration_time = jiffies + HZ / 100 + 1;
90
91         do {
92                 // Get current value of General Control 2
93                 data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
94
95                 // Set bit 23 word 0x1C in the CSR.
96                 data |= SCB_GCR2_EEPROM_ACCESS_SEMAPHORE;
97                 writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
98
99                 // Check to see if this bit set or not.
100                 data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
101
102                 if (data & SCB_GCR2_EEPROM_ACCESS_SEMAPHORE) {
103                         return true;
104                 }
105
106                 if (time_before(jiffies, expiration_time))
107                         yield();
108                 else
109                         return false;
110
111         } while (true);
112 }
113
114 //----------------------------------------------------------------------------------------
115 // Procedure:   eeprom_reset_semaphore
116 //
117 // Description: This function reset (write 0) Gamla EEPROM semaphore bit 
118 //              (bit 23 word 0x1C in the CSR).
119 //
120 // Arguments:  struct e100_private * adapter - Adapter context
121 //----------------------------------------------------------------------------------------
122
123 inline void
124 eeprom_reset_semaphore(struct e100_private *adapter)
125 {
126         u16 data = 0;
127
128         data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
129         data &= ~(SCB_GCR2_EEPROM_ACCESS_SEMAPHORE);
130         writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
131 }
132
133 //----------------------------------------------------------------------------------------
134 // Procedure:   e100_eeprom_size
135 //
136 // Description: This routine determines the size of the EEPROM.  This value should be
137 //              checked for validity - ie. is it too big or too small.  The size returned
138 //              is then passed to the read/write functions.
139 //
140 // Returns:
141 //      Size of the eeprom, or zero if an error occurred
142 //----------------------------------------------------------------------------------------
143 u16
144 e100_eeprom_size(struct e100_private *adapter)
145 {
146         u16 x, size = 1;        // must be one to accumulate a product
147
148         // if we've already stored this data, read from memory
149         if (adapter->eeprom_size) {
150                 return adapter->eeprom_size;
151         }
152         // otherwise, read from the eeprom
153         // Set EEPROM semaphore.
154         if (adapter->rev_id >= D102_REV_ID) {
155                 if (!eeprom_set_semaphore(adapter))
156                         return 0;
157         }
158         // enable the eeprom by setting EECS.
159         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
160         x &= ~(EEDI | EEDO | EESK);
161         x |= EECS;
162         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
163
164         // write the read opcode
165         shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
166
167         // experiment to discover the size of the eeprom.  request register zero
168         // and wait for the eeprom to tell us it has accepted the entire address.
169         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
170         do {
171                 size *= 2;      // each bit of address doubles eeprom size
172                 x |= EEDO;      // set bit to detect "dummy zero"
173                 x &= ~EEDI;     // address consists of all zeros
174
175                 writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
176                 readw(&(adapter->scb->scb_status));
177                 udelay(EEPROM_STALL_TIME);
178                 raise_clock(adapter, &x);
179                 lower_clock(adapter, &x);
180
181                 // check for "dummy zero"
182                 x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
183                 if (size > EEPROM_MAX_WORD_SIZE) {
184                         size = 0;
185                         break;
186                 }
187         } while (x & EEDO);
188
189         // read in the value requested
190         (void) shift_in_bits(adapter);
191         e100_eeprom_cleanup(adapter);
192
193         // Clear EEPROM Semaphore.
194         if (adapter->rev_id >= D102_REV_ID) {
195                 eeprom_reset_semaphore(adapter);
196         }
197
198         return size;
199 }
200
201 //----------------------------------------------------------------------------------------
202 // Procedure:   eeprom_address_size
203 //
204 // Description: determines the number of bits in an address for the eeprom acceptable
205 //              values are 64, 128, and 256
206 // Arguments: size of the eeprom
207 // Returns: bits in an address for that size eeprom
208 //----------------------------------------------------------------------------------------
209
210 static inline int
211 eeprom_address_size(u16 size)
212 {
213         int isize = size;
214         
215         return (ffs(isize) - 1);
216 }
217
218 //----------------------------------------------------------------------------------------
219 // Procedure:   e100_eeprom_read
220 //
221 // Description: This routine serially reads one word out of the EEPROM.
222 //
223 // Arguments:
224 //      adapter - our adapter context
225 //      reg - EEPROM word to read.
226 //
227 // Returns:
228 //      Contents of EEPROM word (reg).
229 //----------------------------------------------------------------------------------------
230
231 u16
232 e100_eeprom_read(struct e100_private *adapter, u16 reg)
233 {
234         u16 x, data, bits;
235
236         // Set EEPROM semaphore.
237         if (adapter->rev_id >= D102_REV_ID) {
238                 if (!eeprom_set_semaphore(adapter))
239                         return 0;
240         }
241         // eeprom size is initialized to zero
242         if (!adapter->eeprom_size)
243                 adapter->eeprom_size = e100_eeprom_size(adapter);
244
245         bits = eeprom_address_size(adapter->eeprom_size);
246
247         // select EEPROM, reset bits, set EECS
248         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
249
250         x &= ~(EEDI | EEDO | EESK);
251         x |= EECS;
252         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
253
254         // write the read opcode and register number in that order
255         // The opcode is 3bits in length, reg is 'bits' bits long
256         shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
257         shift_out_bits(adapter, reg, bits);
258
259         // Now read the data (16 bits) in from the selected EEPROM word
260         data = shift_in_bits(adapter);
261
262         e100_eeprom_cleanup(adapter);
263
264         // Clear EEPROM Semaphore.
265         if (adapter->rev_id >= D102_REV_ID) {
266                 eeprom_reset_semaphore(adapter);
267         }
268
269         return data;
270 }
271
272 //----------------------------------------------------------------------------------------
273 // Procedure:   shift_out_bits
274 //
275 // Description: This routine shifts data bits out to the EEPROM.
276 //
277 // Arguments:
278 //      data - data to send to the EEPROM.
279 //      count - number of data bits to shift out.
280 //
281 // Returns: (none)
282 //----------------------------------------------------------------------------------------
283
284 static void
285 shift_out_bits(struct e100_private *adapter, u16 data, u16 count)
286 {
287         u16 x, mask;
288
289         mask = 1 << (count - 1);
290         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
291         x &= ~(EEDO | EEDI);
292
293         do {
294                 x &= ~EEDI;
295                 if (data & mask)
296                         x |= EEDI;
297
298                 writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
299                 readw(&(adapter->scb->scb_status)); /* flush command to card */
300                 udelay(EEPROM_STALL_TIME);
301                 raise_clock(adapter, &x);
302                 lower_clock(adapter, &x);
303                 mask = mask >> 1;
304         } while (mask);
305
306         x &= ~EEDI;
307         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
308 }
309
310 //----------------------------------------------------------------------------------------
311 // Procedure:   raise_clock
312 //
313 // Description: This routine raises the EEPROM's clock input (EESK)
314 //
315 // Arguments:
316 //      x - Ptr to the EEPROM control register's current value
317 //
318 // Returns: (none)
319 //----------------------------------------------------------------------------------------
320
321 void
322 raise_clock(struct e100_private *adapter, u16 *x)
323 {
324         *x = *x | EESK;
325         writew(*x, &CSR_EEPROM_CONTROL_FIELD(adapter));
326         readw(&(adapter->scb->scb_status)); /* flush command to card */
327         udelay(EEPROM_STALL_TIME);
328 }
329
330 //----------------------------------------------------------------------------------------
331 // Procedure:   lower_clock
332 //
333 // Description: This routine lower's the EEPROM's clock input (EESK)
334 //
335 // Arguments:
336 //      x - Ptr to the EEPROM control register's current value
337 //
338 // Returns: (none)
339 //----------------------------------------------------------------------------------------
340
341 void
342 lower_clock(struct e100_private *adapter, u16 *x)
343 {
344         *x = *x & ~EESK;
345         writew(*x, &CSR_EEPROM_CONTROL_FIELD(adapter));
346         readw(&(adapter->scb->scb_status)); /* flush command to card */
347         udelay(EEPROM_STALL_TIME);
348 }
349
350 //----------------------------------------------------------------------------------------
351 // Procedure:   shift_in_bits
352 //
353 // Description: This routine shifts data bits in from the EEPROM.
354 //
355 // Arguments:
356 //
357 // Returns:
358 //      The contents of that particular EEPROM word
359 //----------------------------------------------------------------------------------------
360
361 static u16
362 shift_in_bits(struct e100_private *adapter)
363 {
364         u16 x, d, i;
365
366         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
367         x &= ~(EEDO | EEDI);
368         d = 0;
369
370         for (i = 0; i < 16; i++) {
371                 d <<= 1;
372                 raise_clock(adapter, &x);
373
374                 x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
375
376                 x &= ~EEDI;
377                 if (x & EEDO)
378                         d |= 1;
379
380                 lower_clock(adapter, &x);
381         }
382
383         return d;
384 }
385
386 //----------------------------------------------------------------------------------------
387 // Procedure:   e100_eeprom_cleanup
388 //
389 // Description: This routine returns the EEPROM to an idle state
390 //----------------------------------------------------------------------------------------
391
392 void
393 e100_eeprom_cleanup(struct e100_private *adapter)
394 {
395         u16 x;
396
397         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
398
399         x &= ~(EECS | EEDI);
400         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
401
402         raise_clock(adapter, &x);
403         lower_clock(adapter, &x);
404 }
405
406 //**********************************************************************************
407 // Procedure:   e100_eeprom_update_chksum
408 //
409 // Description: Calculates the checksum and writes it to the EEProm. 
410 //              It calculates the checksum accroding to the formula: 
411 //                              Checksum = 0xBABA - (sum of first 63 words).
412 //
413 //-----------------------------------------------------------------------------------
414 u16
415 e100_eeprom_calculate_chksum(struct e100_private *adapter)
416 {
417         u16 idx, xsum_index, checksum = 0;
418
419         // eeprom size is initialized to zero
420         if (!adapter->eeprom_size)
421                 adapter->eeprom_size = e100_eeprom_size(adapter);
422
423         xsum_index = adapter->eeprom_size - 1;
424         for (idx = 0; idx < xsum_index; idx++)
425                 checksum += e100_eeprom_read(adapter, idx);
426
427         checksum = EEPROM_CHECKSUM - checksum;
428         return checksum;
429 }
430
431 //----------------------------------------------------------------------------------------
432 // Procedure:   e100_eeprom_write_word
433 //
434 // Description: This routine writes a word to a specific EEPROM location without.
435 //              taking EEPROM semaphore and updating checksum. 
436 //              Use e100_eeprom_write_block for the EEPROM update
437 // Arguments: reg - The EEPROM word that we are going to write to.
438 //            data - The data (word) that we are going to write to the EEPROM.
439 //----------------------------------------------------------------------------------------
440 static void
441 e100_eeprom_write_word(struct e100_private *adapter, u16 reg, u16 data)
442 {
443         u16 x;
444         u16 bits;
445
446         bits = eeprom_address_size(adapter->eeprom_size);
447
448         /* select EEPROM, mask off ASIC and reset bits, set EECS */
449         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
450         x &= ~(EEDI | EEDO | EESK);
451         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
452         readw(&(adapter->scb->scb_status)); /* flush command to card */
453         udelay(EEPROM_STALL_TIME);
454         x |= EECS;
455         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
456
457         shift_out_bits(adapter, EEPROM_EWEN_OPCODE, 5);
458         shift_out_bits(adapter, reg, (u16) (bits - 2));
459         if (!eeprom_wait_cmd_done(adapter))
460                 return;
461
462         /* write the new word to the EEPROM & send the write opcode the EEPORM */
463         shift_out_bits(adapter, EEPROM_WRITE_OPCODE, 3);
464
465         /* select which word in the EEPROM that we are writing to */
466         shift_out_bits(adapter, reg, bits);
467
468         /* write the data to the selected EEPROM word */
469         shift_out_bits(adapter, data, 16);
470         if (!eeprom_wait_cmd_done(adapter))
471                 return;
472
473         shift_out_bits(adapter, EEPROM_EWDS_OPCODE, 5);
474         shift_out_bits(adapter, reg, (u16) (bits - 2));
475         if (!eeprom_wait_cmd_done(adapter))
476                 return;
477
478         e100_eeprom_cleanup(adapter);
479 }
480
481 //----------------------------------------------------------------------------------------
482 // Procedure:   e100_eeprom_write_block
483 //
484 // Description: This routine writes a block of words starting from specified EEPROM 
485 //              location and updates checksum
486 // Arguments: reg - The EEPROM word that we are going to write to.
487 //            data - The data (word) that we are going to write to the EEPROM.
488 //----------------------------------------------------------------------------------------
489 void
490 e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,
491                         u16 size)
492 {
493         u16 checksum;
494         u16 i;
495
496         if (!adapter->eeprom_size)
497                 adapter->eeprom_size = e100_eeprom_size(adapter);
498
499         // Set EEPROM semaphore.
500         if (adapter->rev_id >= D102_REV_ID) {
501                 if (!eeprom_set_semaphore(adapter))
502                         return;
503         }
504
505         for (i = 0; i < size; i++) {
506                 e100_eeprom_write_word(adapter, start + i, data[i]);
507         }
508         //Update checksum
509         checksum = e100_eeprom_calculate_chksum(adapter);
510         e100_eeprom_write_word(adapter, (adapter->eeprom_size - 1), checksum);
511
512         // Clear EEPROM Semaphore.
513         if (adapter->rev_id >= D102_REV_ID) {
514                 eeprom_reset_semaphore(adapter);
515         }
516 }
517
518 //----------------------------------------------------------------------------------------
519 // Procedure:   eeprom_wait_cmd_done
520 //
521 // Description: This routine waits for the the EEPROM to finish its command.  
522 //                              Specifically, it waits for EEDO (data out) to go high.
523 // Returns:     true - If the command finished
524 //              false - If the command never finished (EEDO stayed low)
525 //----------------------------------------------------------------------------------------
526 static u16
527 eeprom_wait_cmd_done(struct e100_private *adapter)
528 {
529         u16 x;
530         unsigned long expiration_time = jiffies + HZ / 100 + 1;
531
532         eeprom_stand_by(adapter);
533
534         do {
535                 rmb();
536                 x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
537                 if (x & EEDO)
538                         return true;
539                 if (time_before(jiffies, expiration_time))
540                         yield();
541                 else
542                         return false;
543         } while (true);
544 }
545
546 //----------------------------------------------------------------------------------------
547 // Procedure:   eeprom_stand_by
548 //
549 // Description: This routine lowers the EEPROM chip select (EECS) for a few microseconds.
550 //----------------------------------------------------------------------------------------
551 static void
552 eeprom_stand_by(struct e100_private *adapter)
553 {
554         u16 x;
555
556         x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
557         x &= ~(EECS | EESK);
558         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
559         readw(&(adapter->scb->scb_status)); /* flush command to card */
560         udelay(EEPROM_STALL_TIME);
561         x |= EECS;
562         writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
563         readw(&(adapter->scb->scb_status)); /* flush command to card */
564         udelay(EEPROM_STALL_TIME);
565 }