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