block: fix warning with calling smp_processor_id() in preemptible section
[pandora-kernel.git] / drivers / staging / brcm80211 / brcmsmac / bcmotp.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/delay.h>
18 #include <linux/kernel.h>
19 #include <linux/string.h>
20 #include <linux/module.h>
21 #include <linux/pci.h>
22 #include <linux/crc-ccitt.h>
23
24 #include <bcmdefs.h>
25 #include <bcmdevs.h>
26 #include <bcmutils.h>
27 #include <aiutils.h>
28 #include <hndsoc.h>
29 #include <sbchipc.h>
30 #include <bcmotp.h>
31
32 /*
33  * There are two different OTP controllers so far:
34  *      1. new IPX OTP controller:      chipc 21, >=23
35  *      2. older HND OTP controller:    chipc 12, 17, 22
36  *
37  * Define BCMHNDOTP to include support for the HND OTP controller.
38  * Define BCMIPXOTP to include support for the IPX OTP controller.
39  *
40  * NOTE 1: More than one may be defined
41  * NOTE 2: If none are defined, the default is to include them all.
42  */
43
44 #if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
45 #define BCMHNDOTP       1
46 #define BCMIPXOTP       1
47 #endif
48
49 #define OTPTYPE_HND(ccrev)      ((ccrev) < 21 || (ccrev) == 22)
50 #define OTPTYPE_IPX(ccrev)      ((ccrev) == 21 || (ccrev) >= 23)
51
52 #define OTPP_TRIES      10000000        /* # of tries for OTPP */
53
54 #ifdef BCMIPXOTP
55 #define MAXNUMRDES              9       /* Maximum OTP redundancy entries */
56 #endif
57
58 /* OTP common function type */
59 typedef int (*otp_status_t) (void *oh);
60 typedef int (*otp_size_t) (void *oh);
61 typedef void *(*otp_init_t) (si_t *sih);
62 typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
63 typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
64                                   uint *wlen);
65 typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
66
67 /* OTP function struct */
68 typedef struct otp_fn_s {
69         otp_size_t size;
70         otp_read_bit_t read_bit;
71         otp_init_t init;
72         otp_read_region_t read_region;
73         otp_nvread_t nvread;
74         otp_status_t status;
75 } otp_fn_t;
76
77 typedef struct {
78         uint ccrev;             /* chipc revision */
79         otp_fn_t *fn;           /* OTP functions */
80         si_t *sih;              /* Saved sb handle */
81
82 #ifdef BCMIPXOTP
83         /* IPX OTP section */
84         u16 wsize;              /* Size of otp in words */
85         u16 rows;               /* Geometry */
86         u16 cols;               /* Geometry */
87         u32 status;             /* Flag bits (lock/prog/rv).
88                                  * (Reflected only when OTP is power cycled)
89                                  */
90         u16 hwbase;             /* hardware subregion offset */
91         u16 hwlim;              /* hardware subregion boundary */
92         u16 swbase;             /* software subregion offset */
93         u16 swlim;              /* software subregion boundary */
94         u16 fbase;              /* fuse subregion offset */
95         u16 flim;               /* fuse subregion boundary */
96         int otpgu_base;         /* offset to General Use Region */
97 #endif                          /* BCMIPXOTP */
98
99 #ifdef BCMHNDOTP
100         /* HND OTP section */
101         uint size;              /* Size of otp in bytes */
102         uint hwprot;            /* Hardware protection bits */
103         uint signvalid;         /* Signature valid bits */
104         int boundary;           /* hw/sw boundary */
105 #endif                          /* BCMHNDOTP */
106 } otpinfo_t;
107
108 static otpinfo_t otpinfo;
109
110 /*
111  * IPX OTP Code
112  *
113  *   Exported functions:
114  *      ipxotp_status()
115  *      ipxotp_size()
116  *      ipxotp_init()
117  *      ipxotp_read_bit()
118  *      ipxotp_read_region()
119  *      ipxotp_nvread()
120  *
121  */
122
123 #ifdef BCMIPXOTP
124
125 #define HWSW_RGN(rgn)           (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
126
127 /* OTP layout */
128 /* CC revs 21, 24 and 27 OTP General Use Region word offset */
129 #define REVA4_OTPGU_BASE        12
130
131 /* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
132 #define REVB8_OTPGU_BASE        20
133
134 /* CC rev 36 OTP General Use Region word offset */
135 #define REV36_OTPGU_BASE        12
136
137 /* Subregion word offsets in General Use region */
138 #define OTPGU_HSB_OFF           0
139 #define OTPGU_SFB_OFF           1
140 #define OTPGU_CI_OFF            2
141 #define OTPGU_P_OFF             3
142 #define OTPGU_SROM_OFF          4
143
144 /* Flag bit offsets in General Use region  */
145 #define OTPGU_HWP_OFF           60
146 #define OTPGU_SWP_OFF           61
147 #define OTPGU_CIP_OFF           62
148 #define OTPGU_FUSEP_OFF         63
149 #define OTPGU_CIP_MSK           0x4000
150 #define OTPGU_P_MSK             0xf000
151 #define OTPGU_P_SHIFT           (OTPGU_HWP_OFF % 16)
152
153 /* OTP Size */
154 #define OTP_SZ_FU_324           ((roundup(324, 8))/8)   /* 324 bits */
155 #define OTP_SZ_FU_288           (288/8) /* 288 bits */
156 #define OTP_SZ_FU_216           (216/8) /* 216 bits */
157 #define OTP_SZ_FU_72            (72/8)  /* 72 bits */
158 #define OTP_SZ_CHECKSUM         (16/8)  /* 16 bits */
159 #define OTP4315_SWREG_SZ        178     /* 178 bytes */
160 #define OTP_SZ_FU_144           (144/8) /* 144 bits */
161
162 static int ipxotp_status(void *oh)
163 {
164         otpinfo_t *oi = (otpinfo_t *) oh;
165         return (int)(oi->status);
166 }
167
168 /* Return size in bytes */
169 static int ipxotp_size(void *oh)
170 {
171         otpinfo_t *oi = (otpinfo_t *) oh;
172         return (int)oi->wsize * 2;
173 }
174
175 static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
176 {
177         otpinfo_t *oi;
178
179         oi = (otpinfo_t *) oh;
180
181         return R_REG(&cc->sromotp[wn]);
182 }
183
184 static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
185 {
186         otpinfo_t *oi = (otpinfo_t *) oh;
187         uint k, row, col;
188         u32 otpp, st;
189
190         row = off / oi->cols;
191         col = off % oi->cols;
192
193         otpp = OTPP_START_BUSY |
194             ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
195             ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
196             ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
197         W_REG(&cc->otpprog, otpp);
198
199         for (k = 0;
200              ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
201              && (k < OTPP_TRIES); k++)
202                 ;
203         if (k >= OTPP_TRIES) {
204                 return 0xffff;
205         }
206         if (st & OTPP_READERR) {
207                 return 0xffff;
208         }
209         st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
210
211         return (int)st;
212 }
213
214 /* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
215  * osizew is oi->wsize (OTP size - GU size) in words
216  */
217 static int ipxotp_max_rgnsz(si_t *sih, int osizew)
218 {
219         int ret = 0;
220
221         switch (sih->chip) {
222         case BCM43224_CHIP_ID:
223         case BCM43225_CHIP_ID:
224                 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
225                 break;
226         case BCM4313_CHIP_ID:
227                 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
228                 break;
229         default:
230                 break;  /* Don't know about this chip */
231         }
232
233         return ret;
234 }
235
236 static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc)
237 {
238         uint k;
239         u32 otpp, st;
240
241         /* record word offset of General Use Region for various chipcommon revs */
242         if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
243             || oi->sih->ccrev == 27) {
244                 oi->otpgu_base = REVA4_OTPGU_BASE;
245         } else if (oi->sih->ccrev == 36) {
246                 /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
247                 if (oi->wsize >= 128)
248                         oi->otpgu_base = REVB8_OTPGU_BASE;
249                 else
250                         oi->otpgu_base = REV36_OTPGU_BASE;
251         } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
252                 oi->otpgu_base = REVB8_OTPGU_BASE;
253         }
254
255         /* First issue an init command so the status is up to date */
256         otpp =
257             OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
258
259         W_REG(&cc->otpprog, otpp);
260         for (k = 0;
261              ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
262              && (k < OTPP_TRIES); k++)
263                 ;
264         if (k >= OTPP_TRIES) {
265                 return;
266         }
267
268         /* Read OTP lock bits and subregion programmed indication bits */
269         oi->status = R_REG(&cc->otpstatus);
270
271         if ((oi->sih->chip == BCM43224_CHIP_ID)
272             || (oi->sih->chip == BCM43225_CHIP_ID)) {
273                 u32 p_bits;
274                 p_bits =
275                     (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
276                      OTPGU_P_MSK)
277                     >> OTPGU_P_SHIFT;
278                 oi->status |= (p_bits << OTPS_GUP_SHIFT);
279         }
280
281         /*
282          * h/w region base and fuse region limit are fixed to the top and
283          * the bottom of the general use region. Everything else can be flexible.
284          */
285         oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
286         oi->hwlim = oi->wsize;
287         if (oi->status & OTPS_GUP_HW) {
288                 oi->hwlim =
289                     ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
290                 oi->swbase = oi->hwlim;
291         } else
292                 oi->swbase = oi->hwbase;
293
294         /* subtract fuse and checksum from beginning */
295         oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
296
297         if (oi->status & OTPS_GUP_SW) {
298                 oi->swlim =
299                     ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
300                 oi->fbase = oi->swlim;
301         } else
302                 oi->fbase = oi->swbase;
303
304         oi->flim = oi->wsize;
305 }
306
307 static void *ipxotp_init(si_t *sih)
308 {
309         uint idx;
310         chipcregs_t *cc;
311         otpinfo_t *oi;
312
313         /* Make sure we're running IPX OTP */
314         if (!OTPTYPE_IPX(sih->ccrev))
315                 return NULL;
316
317         /* Make sure OTP is not disabled */
318         if (ai_is_otp_disabled(sih))
319                 return NULL;
320
321         /* Make sure OTP is powered up */
322         if (!ai_is_otp_powered(sih))
323                 return NULL;
324
325         oi = &otpinfo;
326
327         /* Check for otp size */
328         switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
329         case 0:
330                 /* Nothing there */
331                 return NULL;
332         case 1:         /* 32x64 */
333                 oi->rows = 32;
334                 oi->cols = 64;
335                 oi->wsize = 128;
336                 break;
337         case 2:         /* 64x64 */
338                 oi->rows = 64;
339                 oi->cols = 64;
340                 oi->wsize = 256;
341                 break;
342         case 5:         /* 96x64 */
343                 oi->rows = 96;
344                 oi->cols = 64;
345                 oi->wsize = 384;
346                 break;
347         case 7:         /* 16x64 *//* 1024 bits */
348                 oi->rows = 16;
349                 oi->cols = 64;
350                 oi->wsize = 64;
351                 break;
352         default:
353                 /* Don't know the geometry */
354                 return NULL;
355         }
356
357         /* Retrieve OTP region info */
358         idx = ai_coreidx(sih);
359         cc = ai_setcoreidx(sih, SI_CC_IDX);
360
361         _ipxotp_init(oi, cc);
362
363         ai_setcoreidx(sih, idx);
364
365         return (void *)oi;
366 }
367
368 static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
369 {
370         otpinfo_t *oi = (otpinfo_t *) oh;
371         uint idx;
372         chipcregs_t *cc;
373         uint base, i, sz;
374
375         /* Validate region selection */
376         switch (region) {
377         case OTP_HW_RGN:
378                 sz = (uint) oi->hwlim - oi->hwbase;
379                 if (!(oi->status & OTPS_GUP_HW)) {
380                         *wlen = sz;
381                         return -ENODATA;
382                 }
383                 if (*wlen < sz) {
384                         *wlen = sz;
385                         return -EOVERFLOW;
386                 }
387                 base = oi->hwbase;
388                 break;
389         case OTP_SW_RGN:
390                 sz = ((uint) oi->swlim - oi->swbase);
391                 if (!(oi->status & OTPS_GUP_SW)) {
392                         *wlen = sz;
393                         return -ENODATA;
394                 }
395                 if (*wlen < sz) {
396                         *wlen = sz;
397                         return -EOVERFLOW;
398                 }
399                 base = oi->swbase;
400                 break;
401         case OTP_CI_RGN:
402                 sz = OTPGU_CI_SZ;
403                 if (!(oi->status & OTPS_GUP_CI)) {
404                         *wlen = sz;
405                         return -ENODATA;
406                 }
407                 if (*wlen < sz) {
408                         *wlen = sz;
409                         return -EOVERFLOW;
410                 }
411                 base = oi->otpgu_base + OTPGU_CI_OFF;
412                 break;
413         case OTP_FUSE_RGN:
414                 sz = (uint) oi->flim - oi->fbase;
415                 if (!(oi->status & OTPS_GUP_FUSE)) {
416                         *wlen = sz;
417                         return -ENODATA;
418                 }
419                 if (*wlen < sz) {
420                         *wlen = sz;
421                         return -EOVERFLOW;
422                 }
423                 base = oi->fbase;
424                 break;
425         case OTP_ALL_RGN:
426                 sz = ((uint) oi->flim - oi->hwbase);
427                 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
428                         *wlen = sz;
429                         return -ENODATA;
430                 }
431                 if (*wlen < sz) {
432                         *wlen = sz;
433                         return -EOVERFLOW;
434                 }
435                 base = oi->hwbase;
436                 break;
437         default:
438                 return -EINVAL;
439         }
440
441         idx = ai_coreidx(oi->sih);
442         cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
443
444         /* Read the data */
445         for (i = 0; i < sz; i++)
446                 data[i] = ipxotp_otpr(oh, cc, base + i);
447
448         ai_setcoreidx(oi->sih, idx);
449         *wlen = sz;
450         return 0;
451 }
452
453 static int ipxotp_nvread(void *oh, char *data, uint *len)
454 {
455         return -ENOTSUPP;
456 }
457
458 static otp_fn_t ipxotp_fn = {
459         (otp_size_t) ipxotp_size,
460         (otp_read_bit_t) ipxotp_read_bit,
461
462         (otp_init_t) ipxotp_init,
463         (otp_read_region_t) ipxotp_read_region,
464         (otp_nvread_t) ipxotp_nvread,
465
466         (otp_status_t) ipxotp_status
467 };
468
469 #endif                          /* BCMIPXOTP */
470
471 /*
472  * HND OTP Code
473  *
474  *   Exported functions:
475  *      hndotp_status()
476  *      hndotp_size()
477  *      hndotp_init()
478  *      hndotp_read_bit()
479  *      hndotp_read_region()
480  *      hndotp_nvread()
481  *
482  */
483
484 #ifdef BCMHNDOTP
485
486 /* Fields in otpstatus */
487 #define OTPS_PROGFAIL           0x80000000
488 #define OTPS_PROTECT            0x00000007
489 #define OTPS_HW_PROTECT         0x00000001
490 #define OTPS_SW_PROTECT         0x00000002
491 #define OTPS_CID_PROTECT        0x00000004
492 #define OTPS_RCEV_MSK           0x00003f00
493 #define OTPS_RCEV_SHIFT         8
494
495 /* Fields in the otpcontrol register */
496 #define OTPC_RECWAIT            0xff000000
497 #define OTPC_PROGWAIT           0x00ffff00
498 #define OTPC_PRW_SHIFT          8
499 #define OTPC_MAXFAIL            0x00000038
500 #define OTPC_VSEL               0x00000006
501 #define OTPC_SELVL              0x00000001
502
503 /* OTP regions (Word offsets from otp size) */
504 #define OTP_SWLIM_OFF   (-4)
505 #define OTP_CIDBASE_OFF 0
506 #define OTP_CIDLIM_OFF  4
507
508 /* Predefined OTP words (Word offset from otp size) */
509 #define OTP_BOUNDARY_OFF (-4)
510 #define OTP_HWSIGN_OFF  (-3)
511 #define OTP_SWSIGN_OFF  (-2)
512 #define OTP_CIDSIGN_OFF (-1)
513 #define OTP_CID_OFF     0
514 #define OTP_PKG_OFF     1
515 #define OTP_FID_OFF     2
516 #define OTP_RSV_OFF     3
517 #define OTP_LIM_OFF     4
518 #define OTP_RD_OFF      4       /* Redundancy row starts here */
519 #define OTP_RC0_OFF     28      /* Redundancy control word 1 */
520 #define OTP_RC1_OFF     32      /* Redundancy control word 2 */
521 #define OTP_RC_LIM_OFF  36      /* Redundancy control word end */
522
523 #define OTP_HW_REGION   OTPS_HW_PROTECT
524 #define OTP_SW_REGION   OTPS_SW_PROTECT
525 #define OTP_CID_REGION  OTPS_CID_PROTECT
526
527 #if OTP_HW_REGION != OTP_HW_RGN
528 #error "incompatible OTP_HW_RGN"
529 #endif
530 #if OTP_SW_REGION != OTP_SW_RGN
531 #error "incompatible OTP_SW_RGN"
532 #endif
533 #if OTP_CID_REGION != OTP_CI_RGN
534 #error "incompatible OTP_CI_RGN"
535 #endif
536
537 /* Redundancy entry definitions */
538 #define OTP_RCE_ROW_SZ          6
539 #define OTP_RCE_SIGN_MASK       0x7fff
540 #define OTP_RCE_ROW_MASK        0x3f
541 #define OTP_RCE_BITS            21
542 #define OTP_RCE_SIGN_SZ         15
543 #define OTP_RCE_BIT0            1
544
545 #define OTP_WPR         4
546 #define OTP_SIGNATURE   0x578a
547 #define OTP_MAGIC       0x4e56
548
549 static int hndotp_status(void *oh)
550 {
551         otpinfo_t *oi = (otpinfo_t *) oh;
552         return (int)(oi->hwprot | oi->signvalid);
553 }
554
555 static int hndotp_size(void *oh)
556 {
557         otpinfo_t *oi = (otpinfo_t *) oh;
558         return (int)(oi->size);
559 }
560
561 static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
562 {
563         volatile u16 *ptr;
564
565         ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
566         return R_REG(&ptr[wn]);
567 }
568
569 static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
570 {
571         otpinfo_t *oi = (otpinfo_t *) oh;
572         volatile u16 *ptr;
573
574         ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
575
576         return R_REG(&ptr[(oi->size / 2) + woff]);
577 }
578
579 static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
580 {
581         uint k, row, col;
582         u32 otpp, st;
583
584         row = idx / 65;
585         col = idx % 65;
586
587         otpp = OTPP_START_BUSY | OTPP_READ |
588             ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
589
590         W_REG(&cc->otpprog, otpp);
591         st = R_REG(&cc->otpprog);
592         for (k = 0;
593              ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
594              k++)
595                 st = R_REG(&cc->otpprog);
596
597         if (k >= OTPP_TRIES) {
598                 return 0xffff;
599         }
600         if (st & OTPP_READERR) {
601                 return 0xffff;
602         }
603         st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
604         return (u16) st;
605 }
606
607 static void *hndotp_init(si_t *sih)
608 {
609         uint idx;
610         chipcregs_t *cc;
611         otpinfo_t *oi;
612         u32 cap = 0, clkdiv, otpdiv = 0;
613         void *ret = NULL;
614
615         oi = &otpinfo;
616
617         idx = ai_coreidx(sih);
618
619         /* Check for otp */
620         cc = ai_setcoreidx(sih, SI_CC_IDX);
621         if (cc != NULL) {
622                 cap = R_REG(&cc->capabilities);
623                 if ((cap & CC_CAP_OTPSIZE) == 0) {
624                         /* Nothing there */
625                         goto out;
626                 }
627
628                 if (!((oi->ccrev == 12) || (oi->ccrev == 17)
629                      || (oi->ccrev == 22)))
630                         return NULL;
631
632                 /* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
633                  * 8 row (64 bytes) smaller
634                  */
635                 oi->size =
636                     1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
637                           + CC_CAP_OTPSIZE_BASE);
638                 if (oi->ccrev >= 18)
639                         oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
640
641                 oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
642                 oi->boundary = -1;
643
644                 /* Check the region signature */
645                 if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
646                         oi->signvalid |= OTP_HW_REGION;
647                         oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
648                 }
649
650                 if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
651                         oi->signvalid |= OTP_SW_REGION;
652
653                 if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
654                         oi->signvalid |= OTP_CID_REGION;
655
656                 /* Set OTP clkdiv for stability */
657                 if (oi->ccrev == 22)
658                         otpdiv = 12;
659
660                 if (otpdiv) {
661                         clkdiv = R_REG(&cc->clkdiv);
662                         clkdiv =
663                             (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
664                         W_REG(&cc->clkdiv, clkdiv);
665                 }
666                 udelay(10);
667
668                 ret = (void *)oi;
669         }
670
671  out:                           /* All done */
672         ai_setcoreidx(sih, idx);
673
674         return ret;
675 }
676
677 static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
678 {
679         otpinfo_t *oi = (otpinfo_t *) oh;
680         u32 idx, st;
681         chipcregs_t *cc;
682         int i;
683
684
685         if (region != OTP_HW_REGION) {
686                 /*
687                  * Only support HW region
688                  * (no active chips use HND OTP SW region)
689                  * */
690                 return -ENOTSUPP;
691         }
692
693         /* Region empty? */
694         st = oi->hwprot | oi->signvalid;
695         if ((st & region) == 0)
696                 return -ENODATA;
697
698         *wlen =
699             ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
700
701         idx = ai_coreidx(oi->sih);
702         cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
703
704         for (i = 0; i < (int)*wlen; i++)
705                 data[i] = hndotp_otpr(oh, cc, i);
706
707         ai_setcoreidx(oi->sih, idx);
708
709         return 0;
710 }
711
712 static int hndotp_nvread(void *oh, char *data, uint *len)
713 {
714         int rc = 0;
715         otpinfo_t *oi = (otpinfo_t *) oh;
716         u32 base, bound, lim = 0, st;
717         int i, chunk, gchunks, tsz = 0;
718         u32 idx;
719         chipcregs_t *cc;
720         uint offset;
721         u16 *rawotp = NULL;
722
723         /* save the orig core */
724         idx = ai_coreidx(oi->sih);
725         cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
726
727         st = hndotp_status(oh);
728         if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
729                 rc = -1;
730                 goto out;
731         }
732
733         /* Read the whole otp so we can easily manipulate it */
734         lim = hndotp_size(oh);
735         rawotp = kmalloc(lim, GFP_ATOMIC);
736         if (rawotp == NULL) {
737                 rc = -2;
738                 goto out;
739         }
740         for (i = 0; i < (int)(lim / 2); i++)
741                 rawotp[i] = hndotp_otpr(oh, cc, i);
742
743         if ((st & OTP_HW_REGION) == 0) {
744                 /* This could be a programming failure in the first
745                  * chunk followed by one or more good chunks
746                  */
747                 for (i = 0; i < (int)(lim / 2); i++)
748                         if (rawotp[i] == OTP_MAGIC)
749                                 break;
750
751                 if (i < (int)(lim / 2)) {
752                         base = i;
753                         bound = (i * 2) + rawotp[i + 1];
754                 } else {
755                         rc = -3;
756                         goto out;
757                 }
758         } else {
759                 bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
760
761                 /* There are two cases: 1) The whole otp is used as nvram
762                  * and 2) There is a hardware header followed by nvram.
763                  */
764                 if (rawotp[0] == OTP_MAGIC) {
765                         base = 0;
766                 } else
767                         base = bound;
768         }
769
770         /* Find and copy the data */
771
772         chunk = 0;
773         gchunks = 0;
774         i = base / 2;
775         offset = 0;
776         while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
777                 int dsz, rsz = rawotp[i + 1];
778
779                 if (((i * 2) + rsz) >= (int)lim) {
780                         /* Bad length, try to find another chunk anyway */
781                         rsz = 6;
782                 }
783                 if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) ==
784                         CRC16_GOOD_VALUE) {
785                         /* Good crc, copy the vars */
786                         gchunks++;
787                         dsz = rsz - 6;
788                         tsz += dsz;
789                         if (offset + dsz >= *len) {
790                                 goto out;
791                         }
792                         memcpy(&data[offset], &rawotp[i + 2], dsz);
793                         offset += dsz;
794                         /* Remove extra null characters at the end */
795                         while (offset > 1 &&
796                                data[offset - 1] == 0 && data[offset - 2] == 0)
797                                 offset--;
798                         i += rsz / 2;
799                 } else {
800                         /* bad length or crc didn't check, try to find the next set */
801                         if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
802                                 /* Assume length is good */
803                                 i += rsz / 2;
804                         } else {
805                                 while (++i < (int)(lim / 2))
806                                         if (rawotp[i] == OTP_MAGIC)
807                                                 break;
808                         }
809                 }
810                 chunk++;
811         }
812
813         *len = offset;
814
815  out:
816         kfree(rawotp);
817         ai_setcoreidx(oi->sih, idx);
818
819         return rc;
820 }
821
822 static otp_fn_t hndotp_fn = {
823         (otp_size_t) hndotp_size,
824         (otp_read_bit_t) hndotp_read_bit,
825
826         (otp_init_t) hndotp_init,
827         (otp_read_region_t) hndotp_read_region,
828         (otp_nvread_t) hndotp_nvread,
829
830         (otp_status_t) hndotp_status
831 };
832
833 #endif                          /* BCMHNDOTP */
834
835 /*
836  * Common Code: Compiled for IPX / HND / AUTO
837  *      otp_status()
838  *      otp_size()
839  *      otp_read_bit()
840  *      otp_init()
841  *      otp_read_region()
842  *      otp_nvread()
843  */
844
845 int otp_status(void *oh)
846 {
847         otpinfo_t *oi = (otpinfo_t *) oh;
848
849         return oi->fn->status(oh);
850 }
851
852 int otp_size(void *oh)
853 {
854         otpinfo_t *oi = (otpinfo_t *) oh;
855
856         return oi->fn->size(oh);
857 }
858
859 u16 otp_read_bit(void *oh, uint offset)
860 {
861         otpinfo_t *oi = (otpinfo_t *) oh;
862         uint idx = ai_coreidx(oi->sih);
863         chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
864         u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
865         ai_setcoreidx(oi->sih, idx);
866         return readBit;
867 }
868
869 void *otp_init(si_t *sih)
870 {
871         otpinfo_t *oi;
872         void *ret = NULL;
873
874         oi = &otpinfo;
875         memset(oi, 0, sizeof(otpinfo_t));
876
877         oi->ccrev = sih->ccrev;
878
879 #ifdef BCMIPXOTP
880         if (OTPTYPE_IPX(oi->ccrev))
881                 oi->fn = &ipxotp_fn;
882 #endif
883
884 #ifdef BCMHNDOTP
885         if (OTPTYPE_HND(oi->ccrev))
886                 oi->fn = &hndotp_fn;
887 #endif
888
889         if (oi->fn == NULL) {
890                 return NULL;
891         }
892
893         oi->sih = sih;
894
895         ret = (oi->fn->init) (sih);
896
897         return ret;
898 }
899
900 int
901 otp_read_region(si_t *sih, int region, u16 *data,
902                                  uint *wlen) {
903         bool wasup = false;
904         void *oh;
905         int err = 0;
906
907         wasup = ai_is_otp_powered(sih);
908         if (!wasup)
909                 ai_otp_power(sih, true);
910
911         if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) {
912                 err = -EPERM;
913                 goto out;
914         }
915
916         oh = otp_init(sih);
917         if (oh == NULL) {
918                 err = -EBADE;
919                 goto out;
920         }
921
922         err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
923
924  out:
925         if (!wasup)
926                 ai_otp_power(sih, false);
927
928         return err;
929 }
930
931 int otp_nvread(void *oh, char *data, uint *len)
932 {
933         otpinfo_t *oi = (otpinfo_t *) oh;
934
935         return oi->fn->nvread(oh, data, len);
936 }