1/* 2 * OTP support. 3 * 4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: bcmotp.c,v 1.137.2.23 2011/02/01 06:16:34 Exp $ 19 */ 20 21#include <typedefs.h> 22#include <bcmdefs.h> 23#include <osl.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 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 OTP_ERR_VAL 0x0001 53#define OTP_MSG_VAL 0x0002 54#define OTP_DBG_VAL 0x0004 55uint32 otp_msg_level = OTP_ERR_VAL; 56 57#define OTP_ERR(args) 58 59#define OTP_MSG(args) 60#define OTP_DBG(args) 61 62#define OTPP_TRIES 10000000 /* # of tries for OTPP */ 63 64#ifdef BCMIPXOTP 65#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */ 66#endif 67 68/* OTP common function type */ 69typedef int (*otp_status_t)(void *oh); 70typedef int (*otp_size_t)(void *oh); 71typedef void* (*otp_init_t)(si_t *sih); 72typedef uint16 (*otp_read_bit_t)(void *oh, chipcregs_t *cc, uint off); 73typedef int (*otp_read_region_t)(si_t *sih, int region, uint16 *data, uint *wlen); 74typedef int (*otp_nvread_t)(void *oh, char *data, uint *len); 75typedef int (*otp_write_region_t)(void *oh, int region, uint16 *data, uint wlen); 76typedef int (*otp_cis_append_region_t)(si_t *sih, int region, char *vars, int count); 77typedef int (*otp_lock_t)(si_t *sih); 78typedef int (*otp_nvwrite_t)(void *oh, uint16 *data, uint wlen); 79typedef int (*otp_dump_t)(void *oh, int arg, char *buf, uint size); 80typedef int (*otp_write_word_t)(void *oh, uint wn, uint16 data); 81typedef int (*otp_read_word_t)(void *oh, uint wn, uint16 *data); 82 83/* OTP function struct */ 84typedef struct otp_fn_s { 85 otp_size_t size; 86 otp_read_bit_t read_bit; 87 88 otp_init_t init; 89 otp_read_region_t read_region; 90 otp_nvread_t nvread; 91#ifdef BCMNVRAMW 92 otp_write_region_t write_region; 93 otp_cis_append_region_t cis_append_region; 94 otp_lock_t lock; 95 otp_nvwrite_t nvwrite; 96#endif /* BCMNVRAMW */ 97 98#if defined(WLTEST) 99 otp_dump_t dump; 100#endif 101 102 otp_status_t status; 103#ifdef BCMNVRAMW 104 otp_write_word_t write_word; 105#endif /* BCMNVRAMW */ 106 otp_read_word_t read_word; 107} otp_fn_t; 108 109typedef struct { 110 uint ccrev; /* chipc revision */ 111 otp_fn_t *fn; /* OTP functions */ 112 si_t *sih; /* Saved sb handle */ 113 osl_t *osh; 114 115#ifdef BCMIPXOTP 116 /* IPX OTP section */ 117 uint16 wsize; /* Size of otp in words */ 118 uint16 rows; /* Geometry */ 119 uint16 cols; /* Geometry */ 120 uint32 status; /* Flag bits (lock/prog/rv). 121 * (Reflected only when OTP is power cycled) 122 */ 123 uint16 hwbase; /* hardware subregion offset */ 124 uint16 hwlim; /* hardware subregion boundary */ 125 uint16 swbase; /* software subregion offset */ 126 uint16 swlim; /* software subregion boundary */ 127 uint16 fbase; /* fuse subregion offset */ 128 uint16 flim; /* fuse subregion boundary */ 129 int otpgu_base; /* offset to General Use Region */ 130 uint16 fusebits; /* num of fusebits */ 131#ifdef BCMNVRAMW 132 struct { 133 uint8 width; /* entry width in bits */ 134 uint8 val_shift; /* value bit offset in the entry */ 135 uint8 offsets; /* # entries */ 136 uint8 stat_shift; /* valid bit in otpstatus */ 137 uint16 offset[MAXNUMRDES]; /* entry offset in OTP */ 138 } rde_cb; /* OTP redundancy control blocks */ 139#endif /* BCMNVRAMW */ 140#endif /* BCMIPXOTP */ 141 142#ifdef BCMHNDOTP 143 /* HND OTP section */ 144 uint size; /* Size of otp in bytes */ 145 uint hwprot; /* Hardware protection bits */ 146 uint signvalid; /* Signature valid bits */ 147 int boundary; /* hw/sw boundary */ 148#endif /* BCMHNDOTP */ 149} otpinfo_t; 150 151static otpinfo_t otpinfo; 152 153/* 154 * IPX OTP Code 155 * 156 * Exported functions: 157 * ipxotp_status() 158 * ipxotp_size() 159 * ipxotp_init() 160 * ipxotp_read_bit() 161 * ipxotp_read_region() 162 * ipxotp_read_word() 163 * ipxotp_nvread() 164 * ipxotp_write_region() 165 * ipxotp_write_word() 166 * ipxotp_cis_append_region() 167 * ipxotp_lock() 168 * ipxotp_nvwrite() 169 * ipxotp_dump() 170 * 171 * IPX internal functions: 172 * ipxotp_otpr() 173 * _ipxotp_init() 174 * ipxotp_write_bit() 175 * ipxotp_otpwb16() 176 * ipxotp_write_rde() 177 * ipxotp_fix_word16() 178 * ipxotp_check_word16() 179 * ipxotp_max_rgnsz() 180 * ipxotp_otprb16() 181 * 182 */ 183 184#ifdef BCMIPXOTP 185 186#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w") 187 188/* OTP layout */ 189/* CC revs 21, 24 and 27 OTP General Use Region word offset */ 190#define REVA4_OTPGU_BASE 12 191 192/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */ 193#define REVB8_OTPGU_BASE 20 194 195/* CC rev 36 OTP General Use Region word offset */ 196#define REV36_OTPGU_BASE 12 197 198/* Subregion word offsets in General Use region */ 199#define OTPGU_HSB_OFF 0 200#define OTPGU_SFB_OFF 1 201#define OTPGU_CI_OFF 2 202#define OTPGU_P_OFF 3 203#define OTPGU_SROM_OFF 4 204 205/* Flag bit offsets in General Use region */ 206#define OTPGU_HWP_OFF 60 207#define OTPGU_SWP_OFF 61 208#define OTPGU_CIP_OFF 62 209#define OTPGU_FUSEP_OFF 63 210#define OTPGU_CIP_MSK 0x4000 211#define OTPGU_P_MSK 0xf000 212#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16) 213 214/* LOCK but offset */ 215#define OTP_LOCK_ROW1_LOC_OFF 63 /* 1st ROW lock bit */ 216#define OTP_LOCK_ROW2_LOC_OFF 127 /* 2nd ROW lock bit */ 217#define OTP_LOCK_RD_LOC_OFF 128 /* Redundnancy Region lock bit */ 218#define OTP_LOCK_GU_LOC_OFF 129 /* General User Region lock bit */ 219 220 221/* OTP Size */ 222#define OTP_SZ_FU_324 ((ROUNDUP(324,8))/8) /* 324 bits */ 223#define OTP_SZ_FU_288 (288/8) /* 288 bits */ 224#define OTP_SZ_FU_216 (216/8) /* 216 bits */ 225#define OTP_SZ_FU_72 (72/8) /* 72 bits */ 226#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */ 227#define OTP4315_SWREG_SZ 178 /* 178 bytes */ 228#define OTP_SZ_FU_144 (144/8) /* 144 bits */ 229#define OTP_SZ_FU_180 ((ROUNDUP(180,8))/8) /* 180 bits */ 230 231static int 232ipxotp_status(void *oh) 233{ 234 otpinfo_t *oi = (otpinfo_t *)oh; 235 return (int)(oi->status); 236} 237 238/* Return size in bytes */ 239static int 240ipxotp_size(void *oh) 241{ 242 otpinfo_t *oi = (otpinfo_t *)oh; 243 return (int)oi->wsize * 2; 244} 245 246static uint16 247ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn) 248{ 249 otpinfo_t *oi; 250 251 oi = (otpinfo_t *)oh; 252 253 ASSERT(wn < oi->wsize); 254 ASSERT(cc != NULL); 255 256 return R_REG(oi->osh, &cc->sromotp[wn]); 257} 258 259static uint16 260ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) 261{ 262 otpinfo_t *oi = (otpinfo_t *)oh; 263 uint k, row, col; 264 uint32 otpp, st; 265 266 row = off / oi->cols; 267 col = off % oi->cols; 268 269 otpp = OTPP_START_BUSY | 270 ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) | 271 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | 272 ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK); 273 OTP_DBG(("%s: off = %d, row = %d, col = %d, otpp = 0x%x", 274 __FUNCTION__, off, row, col, otpp)); 275 W_REG(oi->osh, &cc->otpprog, otpp); 276 277 for (k = 0; 278 ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); 279 k ++) 280 ; 281 if (k >= OTPP_TRIES) { 282 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__, st, k)); 283 return 0xffff; 284 } 285 if (st & OTPP_READERR) { 286 OTP_ERR(("\n%s: Could not read OTP bit %d\n", __FUNCTION__, off)); 287 return 0xffff; 288 } 289 st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT; 290 291 OTP_DBG((" => %d\n", st)); 292 return (int)st; 293} 294 295 296/* Calculate max HW/SW region byte size by substracting fuse region and checksum size, 297 * osizew is oi->wsize (OTP size - GU size) in words 298 */ 299static int 300ipxotp_max_rgnsz(otpinfo_t *oi) 301{ 302 int osizew = oi->wsize; 303 int ret = 0; 304 uint16 checksum; 305 uint idx; 306 chipcregs_t *cc; 307 308 idx = si_coreidx(oi->sih); 309 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 310 ASSERT(cc != NULL); 311 312 checksum = OTP_SZ_CHECKSUM; 313 314 /* for new chips, fusebit is available from cc register */ 315 if (oi->sih->ccrev >= 35) { 316 oi->fusebits = R_REG(oi->osh, &cc->otplayoutextension) & OTPLAYOUTEXT_FUSE_MASK; 317 } 318 319 si_setcoreidx(oi->sih, idx); 320 321 switch (CHIPID(oi->sih->chip)) { 322 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 323 oi->fusebits = OTP_SZ_FU_288; 324 break; 325 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 326 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: 327 case BCM43226_CHIP_ID: case BCM43420_CHIP_ID: 328 oi->fusebits = OTP_SZ_FU_72; 329 break; 330 case BCM43236_CHIP_ID: case BCM43235_CHIP_ID: case BCM43238_CHIP_ID: 331 case BCM43234_CHIP_ID: case BCM43237_CHIP_ID: 332 oi->fusebits = OTP_SZ_FU_324; 333 break; 334 case BCM4325_CHIP_ID: 335 case BCM5356_CHIP_ID: 336 oi->fusebits = OTP_SZ_FU_216; 337 break; 338 case BCM4336_CHIP_ID: 339 case BCM43362_CHIP_ID: 340 oi->fusebits = OTP_SZ_FU_144; 341 break; 342 case BCM4313_CHIP_ID: 343 oi->fusebits = OTP_SZ_FU_72; 344 break; 345 case BCM4330_CHIP_ID: 346 oi->fusebits = OTP_SZ_FU_144; 347 break; 348 case BCM4319_CHIP_ID: 349 oi->fusebits = OTP_SZ_FU_180; 350 break; 351 case BCM4331_CHIP_ID: 352 case BCM43431_CHIP_ID: 353 oi->fusebits = OTP_SZ_FU_72; 354 break; 355 case BCM43228_CHIP_ID: 356 case BCM43428_CHIP_ID: 357 oi->fusebits = OTP_SZ_FU_72; 358 break; 359 case BCM43227_CHIP_ID: 360 oi->fusebits = OTP_SZ_FU_72; 361 break; 362 default: 363 ASSERT(0); /* Don't konw about this chip */ 364 } 365 366 ret = osizew*2 - oi->fusebits - checksum; 367 368 if (CHIPID(oi->sih->chip) == BCM4315_CHIP_ID) { 369 ret = OTP4315_SWREG_SZ; 370 } 371 372 OTP_MSG(("max region size %d bytes\n", ret)); 373 return ret; 374} 375 376static void 377BCMNMIATTACHFN(_ipxotp_init)(otpinfo_t *oi, chipcregs_t *cc) 378{ 379 uint k; 380 uint32 otpp, st; 381 382 /* record word offset of General Use Region for various chipcommon revs */ 383 if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24 || oi->sih->ccrev == 27) { 384 oi->otpgu_base = REVA4_OTPGU_BASE; 385 } else if (oi->sih->ccrev == 36) { 386 /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */ 387 if (oi->wsize >= 128) 388 oi->otpgu_base = REVB8_OTPGU_BASE; 389 else 390 oi->otpgu_base = REV36_OTPGU_BASE; 391 } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) { 392 oi->otpgu_base = REVB8_OTPGU_BASE; 393 } else { 394 OTP_ERR(("%s: chipc rev %d not supported\n", __FUNCTION__, oi->sih->ccrev)); 395 } 396 397 /* First issue an init command so the status is up to date */ 398 otpp = OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK); 399 400 OTP_DBG(("%s: otpp = 0x%x", __FUNCTION__, otpp)); 401 W_REG(oi->osh, &cc->otpprog, otpp); 402 for (k = 0; 403 ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); 404 k ++) 405 ; 406 if (k >= OTPP_TRIES) { 407 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__, st, k)); 408 return; 409 } 410 411 /* Read OTP lock bits and subregion programmed indication bits */ 412 oi->status = R_REG(oi->osh, &cc->otpstatus); 413 414 if ((CHIPID(oi->sih->chip) == BCM43222_CHIP_ID) || 415 (CHIPID(oi->sih->chip) == BCM43420_CHIP_ID) || 416 (CHIPID(oi->sih->chip) == BCM43111_CHIP_ID) || 417 (CHIPID(oi->sih->chip) == BCM43112_CHIP_ID) || 418 (CHIPID(oi->sih->chip) == BCM43224_CHIP_ID) || 419 (CHIPID(oi->sih->chip) == BCM43225_CHIP_ID) || 420 (CHIPID(oi->sih->chip) == BCM43421_CHIP_ID) || 421 (CHIPID(oi->sih->chip) == BCM43226_CHIP_ID) || 422 (CHIPID(oi->sih->chip) == BCM43236_CHIP_ID) || 423 (CHIPID(oi->sih->chip) == BCM43235_CHIP_ID) || 424 (CHIPID(oi->sih->chip) == BCM43234_CHIP_ID) || 425 (CHIPID(oi->sih->chip) == BCM43238_CHIP_ID) || 426 (CHIPID(oi->sih->chip) == BCM43237_CHIP_ID) || 427 (CHIPID(oi->sih->chip) == BCM4331_CHIP_ID) || 428 (CHIPID(oi->sih->chip) == BCM43431_CHIP_ID) || 429 0) { 430 uint32 p_bits; 431 p_bits = (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) & OTPGU_P_MSK) 432 >> OTPGU_P_SHIFT; 433 oi->status |= (p_bits << OTPS_GUP_SHIFT); 434 } 435 OTP_DBG(("%s: status 0x%x\n", __FUNCTION__, oi->status)); 436 437 /* 438 * h/w region base and fuse region limit are fixed to the top and 439 * the bottom of the general use region. Everything else can be flexible. 440 */ 441 oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF; 442 oi->hwlim = oi->wsize; 443 if (oi->status & OTPS_GUP_HW) { 444 OTP_DBG(("%s: hw region programmed\n", __FUNCTION__)); 445 oi->hwlim = ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16; 446 oi->swbase = oi->hwlim; 447 } else { 448 oi->hwlim = ipxotp_max_rgnsz(oi) / 2; 449 oi->swbase = oi->hwbase; 450 } 451 452 /* subtract fuse and checksum from beginning */ 453 oi->swlim = ipxotp_max_rgnsz(oi) / 2; 454 455 if (oi->status & OTPS_GUP_SW) { 456 OTP_DBG(("%s: sw region programmed\n", __FUNCTION__)); 457 oi->swlim = ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16; 458 oi->fbase = oi->swlim; 459 } 460 else 461 oi->fbase = oi->swbase; 462 463 oi->flim = oi->wsize; 464 465 OTP_DBG(("%s: OTP limits---\n" 466 "hwbase %d/%d hwlim %d/%d\n" 467 "swbase %d/%d swlim %d/%d\n" 468 "fbase %d/%d flim %d/%d\n", __FUNCTION__, 469 oi->hwbase, oi->hwbase * 16, oi->hwlim, oi->hwlim * 16, 470 oi->swbase, oi->swbase * 16, oi->swlim, oi->swlim * 16, 471 oi->fbase, oi->fbase * 16, oi->flim, oi->flim * 16)); 472} 473 474static void * 475BCMNMIATTACHFN(ipxotp_init)(si_t *sih) 476{ 477 uint idx; 478 chipcregs_t *cc; 479 otpinfo_t *oi; 480 481 OTP_MSG(("%s: Use IPX OTP controller\n", __FUNCTION__)); 482 483 /* Make sure we're running IPX OTP */ 484 ASSERT(OTPTYPE_IPX(sih->ccrev)); 485 if (!OTPTYPE_IPX(sih->ccrev)) 486 return NULL; 487 488 /* Make sure OTP is not disabled */ 489 if (si_is_otp_disabled(sih)) { 490 OTP_MSG(("%s: OTP is disabled\n", __FUNCTION__)); 491#if !defined(WLTEST) 492 return NULL; 493#endif 494 } 495 496 /* Make sure OTP is powered up */ 497 if (!si_is_otp_powered(sih)) { 498 OTP_ERR(("%s: OTP is powered down\n", __FUNCTION__)); 499 return NULL; 500 } 501 502 oi = &otpinfo; 503 504 /* Check for otp size */ 505 switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) { 506 case 0: 507 /* Nothing there */ 508 OTP_ERR(("%s: no OTP\n", __FUNCTION__)); 509 return NULL; 510 case 1: /* 32x64 */ 511 oi->rows = 32; 512 oi->cols = 64; 513 oi->wsize = 128; 514 break; 515 case 2: /* 64x64 */ 516 oi->rows = 64; 517 oi->cols = 64; 518 oi->wsize = 256; 519 break; 520 case 5: /* 96x64 */ 521 oi->rows = 96; 522 oi->cols = 64; 523 oi->wsize = 384; 524 break; 525 case 7: /* 16x64 */ /* 1024 bits */ 526 oi->rows = 16; 527 oi->cols = 64; 528 oi->wsize = 64; 529 break; 530 default: 531 /* Don't know the geometry */ 532 OTP_ERR(("%s: unknown OTP geometry\n", __FUNCTION__)); 533 return NULL; 534 } 535 536 OTP_MSG(("%s: rows %u cols %u wsize %u\n", __FUNCTION__, oi->rows, oi->cols, oi->wsize)); 537 538#ifdef BCMNVRAMW 539 /* Initialize OTP redundancy control blocks */ 540 if (sih->ccrev == 21 || sih->ccrev == 24) { 541 uint16 offset[] = {64, 79, 94, 109, 128, 143, 158, 173}; 542 bcopy(offset, &oi->rde_cb.offset, sizeof(offset)); 543 oi->rde_cb.offsets = ARRAYSIZE(offset); 544 oi->rde_cb.width = 15; 545 oi->rde_cb.val_shift = 11; 546 oi->rde_cb.stat_shift = 16; 547 } 548 else if (sih->ccrev == 27) { 549 uint16 offset[] = {128, 143, 158, 173}; 550 bcopy(offset, &oi->rde_cb.offset, sizeof(offset)); 551 oi->rde_cb.offsets = ARRAYSIZE(offset); 552 oi->rde_cb.width = 15; 553 oi->rde_cb.val_shift = 11; 554 oi->rde_cb.stat_shift = 20; 555 } 556 else { 557 uint16 offset[] = {141, 158, 175, 205, 222, 239, 269, 286, 303}; 558 bcopy(offset, &oi->rde_cb.offset, sizeof(offset)); 559 oi->rde_cb.offsets = ARRAYSIZE(offset); 560 oi->rde_cb.width = 17; 561 oi->rde_cb.val_shift = 13; 562 oi->rde_cb.stat_shift = 16; 563 } 564 ASSERT(oi->rde_cb.offsets <= MAXNUMRDES); 565#endif /* BCMNVRAMW */ 566 567 /* Retrieve OTP region info */ 568 idx = si_coreidx(sih); 569 cc = si_setcoreidx(sih, SI_CC_IDX); 570 ASSERT(cc != NULL); 571 572 _ipxotp_init(oi, cc); 573 574 si_setcoreidx(sih, idx); 575 576 return (void *)oi; 577} 578 579static int 580ipxotp_read_region(void *oh, int region, uint16 *data, uint *wlen) 581{ 582 otpinfo_t *oi = (otpinfo_t *)oh; 583 uint idx; 584 chipcregs_t *cc; 585 uint base, i, sz; 586 587 /* Validate region selection */ 588 switch (region) { 589 case OTP_HW_RGN: 590 sz = (uint)oi->hwlim - oi->hwbase; 591 if (!(oi->status & OTPS_GUP_HW)) { 592 OTP_ERR(("%s: h/w region not programmed\n", __FUNCTION__)); 593 *wlen = sz; 594 return BCME_NOTFOUND; 595 } 596 if (*wlen < sz) { 597 OTP_ERR(("%s: buffer too small, should be at least %u\n", 598 __FUNCTION__, oi->hwlim - oi->hwbase)); 599 *wlen = sz; 600 return BCME_BUFTOOSHORT; 601 } 602 base = oi->hwbase; 603 break; 604 case OTP_SW_RGN: 605 sz = ((uint)oi->swlim - oi->swbase); 606 if (!(oi->status & OTPS_GUP_SW)) { 607 OTP_ERR(("%s: s/w region not programmed\n", __FUNCTION__)); 608 *wlen = sz; 609 return BCME_NOTFOUND; 610 } 611 if (*wlen < sz) { 612 OTP_ERR(("%s: buffer too small should be at least %u\n", 613 __FUNCTION__, oi->swlim - oi->swbase)); 614 *wlen = sz; 615 return BCME_BUFTOOSHORT; 616 } 617 base = oi->swbase; 618 break; 619 case OTP_CI_RGN: 620 sz = OTPGU_CI_SZ; 621 if (!(oi->status & OTPS_GUP_CI)) { 622 OTP_ERR(("%s: chipid region not programmed\n", __FUNCTION__)); 623 *wlen = sz; 624 return BCME_NOTFOUND; 625 } 626 if (*wlen < sz) { 627 OTP_ERR(("%s: buffer too small, should be at least %u\n", 628 __FUNCTION__, OTPGU_CI_SZ)); 629 *wlen = sz; 630 return BCME_BUFTOOSHORT; 631 } 632 base = oi->otpgu_base + OTPGU_CI_OFF; 633 break; 634 case OTP_FUSE_RGN: 635 sz = (uint)oi->flim - oi->fbase; 636 if (!(oi->status & OTPS_GUP_FUSE)) { 637 OTP_ERR(("%s: fuse region not programmed\n", __FUNCTION__)); 638 *wlen = sz; 639 return BCME_NOTFOUND; 640 } 641 if (*wlen < sz) { 642 OTP_ERR(("%s: buffer too small, should be at least %u\n", 643 __FUNCTION__, oi->flim - oi->fbase)); 644 *wlen = sz; 645 return BCME_BUFTOOSHORT; 646 } 647 base = oi->fbase; 648 break; 649 case OTP_ALL_RGN: 650 sz = ((uint)oi->flim - oi->hwbase); 651 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) { 652 OTP_ERR(("%s: h/w & s/w region not programmed\n", __FUNCTION__)); 653 *wlen = sz; 654 return BCME_NOTFOUND; 655 } 656 if (*wlen < sz) { 657 OTP_ERR(("%s: buffer too small, should be at least %u\n", 658 __FUNCTION__, oi->hwlim - oi->hwbase)); 659 *wlen = sz; 660 return BCME_BUFTOOSHORT; 661 } 662 base = oi->hwbase; 663 break; 664 default: 665 OTP_ERR(("%s: reading region %d is not supported\n", __FUNCTION__, region)); 666 return BCME_BADARG; 667 } 668 669 idx = si_coreidx(oi->sih); 670 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 671 ASSERT(cc != NULL); 672 673 /* Read the data */ 674 for (i = 0; i < sz; i ++) 675 data[i] = ipxotp_otpr(oh, cc, base + i); 676 677 si_setcoreidx(oi->sih, idx); 678 *wlen = sz; 679 return 0; 680} 681 682static int 683ipxotp_read_word(void *oh, uint wn, uint16 *data) 684{ 685 otpinfo_t *oi = (otpinfo_t *)oh; 686 uint idx; 687 chipcregs_t *cc; 688 689 idx = si_coreidx(oi->sih); 690 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 691 ASSERT(cc != NULL); 692 693 /* Read the data */ 694 *data = ipxotp_otpr(oh, cc, wn); 695 696 si_setcoreidx(oi->sih, idx); 697 return 0; 698} 699 700static int 701ipxotp_nvread(void *oh, char *data, uint *len) 702{ 703 return BCME_UNSUPPORTED; 704} 705 706#ifdef BCMNVRAMW 707static int 708ipxotp_write_bit(otpinfo_t *oi, chipcregs_t *cc, uint off) 709{ 710 uint k, row, col; 711 uint32 otpp, st; 712 713 row = off / oi->cols; 714 col = off % oi->cols; 715 716 otpp = OTPP_START_BUSY | 717 ((1 << OTPP_VALUE_SHIFT) & OTPP_VALUE_MASK) | 718 ((OTPPOC_BIT_PROG << OTPP_OC_SHIFT) & OTPP_OC_MASK) | 719 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | 720 ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK); 721 OTP_DBG(("%s: off = %d, row = %d, col = %d, otpp = 0x%x\n", 722 __FUNCTION__, off, row, col, otpp)); 723 724 W_REG(oi->osh, &cc->otpprog, otpp); 725 726 for (k = 0; 727 ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); 728 k ++) 729 ; 730 if (k >= OTPP_TRIES) { 731 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__, st, k)); 732 return -1; 733 } 734 735 return 0; 736} 737 738 739static int 740ipxotp_write_lock_bit(otpinfo_t *oi, chipcregs_t *cc, uint off) 741{ 742 uint k, row, col; 743 uint32 otpp, st; 744 745 row = off / oi->cols; 746 col = off % oi->cols; 747 748 otpp = OTPP_START_BUSY | 749 ((OTPPOC_ROW_LOCK << OTPP_OC_SHIFT) & OTPP_OC_MASK) | 750 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | 751 ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK); 752 OTP_DBG(("%s: off = %d, row = %d, col = %d, otpp = 0x%x\n", 753 __FUNCTION__, off, row, col, otpp)); 754 755 W_REG(oi->osh, &cc->otpprog, otpp); 756 757 for (k = 0; 758 ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); 759 k ++) 760 ; 761 if (k >= OTPP_TRIES) { 762 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__, st, k)); 763 return -1; 764 } 765 766 return 0; 767} 768 769static int 770ipxotp_otpwb16(otpinfo_t *oi, chipcregs_t *cc, int wn, uint16 data) 771{ 772 uint base, i; 773 int rc = 0; 774 775 base = wn * 16; 776 for (i = 0; i < 16; i++) { 777 if (data & (1 << i)) { 778 if ((rc = ipxotp_write_bit(oi, cc, base + i))) 779 break; 780 } 781 } 782 783 return rc; 784} 785 786/* Write OTP redundancy entry: 787 * rde - redundancy entry index (-ve for "next") 788 * bit - bit offset 789 * val - bit value 790 */ 791int 792ipxotp_write_rde(void *oh, int rde, uint bit, uint val) 793{ 794 otpinfo_t *oi = (otpinfo_t *)oh; 795 uint idx; 796 chipcregs_t *cc; 797 uint i, temp; 798 799#ifdef BCMCBG 800 if ((rde >= oi->rde_cb.offsets) || (bit >= oi->rows * oi->cols) || (val > 1)) 801 return BCME_RANGE; 802#endif 803 804 if (rde < 0) { 805 for (rde = 0; rde < oi->rde_cb.offsets - 1; rde++) { 806 if ((oi->status & (1 << (oi->rde_cb.stat_shift + rde))) == 0) 807 break; 808 } 809 OTP_MSG(("%s: Auto rde index %d\n", __FUNCTION__, rde)); 810 } 811 812 if (oi->status & (1 << (oi->rde_cb.stat_shift + rde))) { 813 OTP_MSG(("%s: rde %d already in use, status 0x%08x\n", __FUNCTION__, 814 rde, oi->status)); 815 return BCME_ERROR; 816 } 817 818 idx = si_coreidx(oi->sih); 819 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 820 ASSERT(cc != NULL); 821 822 temp = ~(~0 << oi->rde_cb.width) & 823 ((~0 << (oi->rde_cb.val_shift + 1)) | (val << oi->rde_cb.val_shift) | bit); 824 825 OTP_MSG(("%s: rde %d bit %d val %d bmp 0x%08x\n", __FUNCTION__, rde, bit, val, temp)); 826 827 /* Enable Write */ 828 OR_REG(oi->osh, &cc->otpcontrol, OTPC_PROGEN); 829 830 for (i = 0; i < oi->rde_cb.width; i ++) { 831 if (!(temp & (1 << i))) 832 continue; 833 ipxotp_write_bit(oi, cc, oi->rde_cb.offset[rde] + i); 834 } 835 836 /* Disable Write */ 837 AND_REG(oi->osh, &cc->otpcontrol, ~OTPC_PROGEN); 838 839 si_otp_power(oi->sih, FALSE); 840 si_otp_power(oi->sih, TRUE); 841 _ipxotp_init(oi, cc); 842 843 si_setcoreidx(oi->sih, idx); 844 return BCME_OK; 845} 846 847/* Set up redundancy entries for the specified bits */ 848static int 849ipxotp_fix_word16(void *oh, uint wn, uint16 mask, uint16 val) 850{ 851 otpinfo_t *oi; 852 uint bit; 853 int rc = 0; 854 855 oi = (otpinfo_t *)oh; 856 857 ASSERT(oi != NULL); 858 ASSERT(wn < oi->wsize); 859 860 for (bit = wn * 16; mask; bit++, mask >>= 1, val >>= 1) { 861 if (mask & 1) { 862 if ((rc = ipxotp_write_rde(oi, -1, bit, val & 1))) 863 break; 864 } 865 } 866 867 return rc; 868} 869 870static int 871ipxotp_check_word16(void *oh, chipcregs_t *cc, uint wn, uint16 val) 872{ 873 otpinfo_t *oi = (otpinfo_t *)oh; 874 uint16 word = ipxotp_otpr(oi, cc, wn); 875 int rc = 0; 876 877 if ((word ^= val)) { 878 OTP_MSG(("%s: word %d is 0x%04x, wanted 0x%04x, fixing...\n", 879 __FUNCTION__, wn, (word ^ val), val)); 880 if ((rc = ipxotp_fix_word16(oi, wn, word, val))) { 881 OTP_ERR(("FAILED, ipxotp_fix_word16 returns %d\n", rc)); 882 /* Fatal error, unfixable. MFGC will have to fail. Board 883 * needs to be discarded!! 884 */ 885 return BCME_NORESOURCE; 886 } 887 } 888 889 return BCME_OK; 890} 891 892/* expects the caller to disable interrupts before calling this routine */ 893static int 894ipxotp_write_region(void *oh, int region, uint16 *data, uint wlen) 895{ 896 otpinfo_t *oi = (otpinfo_t *)oh; 897 uint idx; 898 chipcregs_t *cc; 899 uint base, i; 900 int otpgu_bit_base; 901 bool rewrite = FALSE; 902 int rc = 0; 903 uint16 *origdata = NULL; 904 905 otpgu_bit_base = oi->otpgu_base * 16; 906 907 /* Validate region selection */ 908 switch (region) { 909 case OTP_HW_RGN: 910 if (wlen > (uint)(oi->hwlim - oi->hwbase)) { 911 OTP_ERR(("%s: wlen %u exceeds OTP h/w region limit %u\n", 912 __FUNCTION__, wlen, oi->hwlim - oi->hwbase)); 913 return BCME_BUFTOOLONG; 914 } 915 rewrite = !!(oi->status & OTPS_GUP_HW); 916 base = oi->hwbase; 917 break; 918 case OTP_SW_RGN: 919 if (wlen > (uint)(oi->swlim - oi->swbase)) { 920 OTP_ERR(("%s: wlen %u exceeds OTP s/w region limit %u\n", 921 __FUNCTION__, wlen, oi->swlim - oi->swbase)); 922 return BCME_BUFTOOLONG; 923 } 924 rewrite = !!(oi->status & OTPS_GUP_SW); 925 base = oi->swbase; 926 break; 927 case OTP_CI_RGN: 928 if (oi->status & OTPS_GUP_CI) { 929 OTP_ERR(("%s: chipid region has been programmed\n", __FUNCTION__)); 930 return BCME_ERROR; 931 } 932 if (wlen > OTPGU_CI_SZ) { 933 OTP_ERR(("%s: wlen %u exceeds OTP ci region limit %u\n", 934 __FUNCTION__, wlen, OTPGU_CI_SZ)); 935 return BCME_BUFTOOLONG; 936 } 937 if ((wlen == OTPGU_CI_SZ) && (data[OTPGU_CI_SZ - 1] & OTPGU_P_MSK) != 0) { 938 OTP_ERR(("%s: subregion programmed bits not zero\n", __FUNCTION__)); 939 return BCME_BADARG; 940 } 941 base = oi->otpgu_base + OTPGU_CI_OFF; 942 break; 943 case OTP_FUSE_RGN: 944 if (oi->status & OTPS_GUP_FUSE) { 945 OTP_ERR(("%s: fuse region has been programmed\n", __FUNCTION__)); 946 return BCME_ERROR; 947 } 948 if (wlen > (uint)(oi->flim - oi->fbase)) { 949 OTP_ERR(("%s: wlen %u exceeds OTP ci region limit %u\n", 950 __FUNCTION__, wlen, oi->flim - oi->fbase)); 951 return BCME_BUFTOOLONG; 952 } 953 base = oi->flim - wlen; 954 break; 955 default: 956 OTP_ERR(("%s: writing region %d is not supported\n", __FUNCTION__, region)); 957 return BCME_ERROR; 958 } 959 960 idx = si_coreidx(oi->sih); 961 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 962 ASSERT(cc != NULL); 963 964 /* Check for conflict; Since some bits might be programmed at ATE time, we need to 965 * avoid redundancy by clearing already written bits, but copy original for verification. 966 */ 967 if ((origdata = (uint16*)MALLOC(oi->osh, wlen * 2)) == NULL) { 968 rc = BCME_NOMEM; 969 goto exit; 970 } 971 for (i = 0; i < wlen; i++) { 972 origdata[i] = data[i]; 973 data[i] = ipxotp_otpr(oi, cc, base + i); 974 if (data[i] & ~origdata[i]) { 975 OTP_ERR(("%s: %s region: word %d incompatible (0x%04x->0x%04x)\n", 976 __FUNCTION__, HWSW_RGN(region), i, data[i], origdata[i])); 977 rc = BCME_BADARG; 978 goto exit; 979 } 980 data[i] ^= origdata[i]; 981 } 982 OTP_MSG(("%s: writing new bits in %s region\n", __FUNCTION__, HWSW_RGN(region))); 983 984 /* Enable Write */ 985 OR_REG(oi->osh, &cc->otpcontrol, OTPC_PROGEN); 986 987 /* Write the data */ 988 for (i = 0; i < wlen; i++) { 989 ipxotp_otpwb16(oi, cc, base + i, data[i]); 990 } 991 992 /* One time set region flag: Update boundary/flag in memory and in OTP */ 993 if (!rewrite) { 994 switch (region) { 995 case OTP_HW_RGN: 996 ipxotp_otpwb16(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF, (base + i) * 16); 997 ipxotp_write_bit(oi, cc, otpgu_bit_base + OTPGU_HWP_OFF); 998 break; 999 case OTP_SW_RGN: 1000 /* Write HW region limit as well */ 1001 ipxotp_otpwb16(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF, base * 16); 1002 /* write max swlim(covert to bits) to the sw/fuse boundary */ 1003 ipxotp_otpwb16(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF, oi->swlim * 16); 1004 ipxotp_write_bit(oi, cc, otpgu_bit_base + OTPGU_SWP_OFF); 1005 break; 1006 case OTP_CI_RGN: 1007 ipxotp_write_bit(oi, cc, otpgu_bit_base + OTPGU_CIP_OFF); 1008 /* Also set the OTPGU_CIP_MSK bit in the input so verification 1009 * doesn't fail 1010 */ 1011 if (wlen >= OTPGU_CI_SZ) 1012 data[OTPGU_CI_SZ - 1] |= OTPGU_CIP_MSK; 1013 break; 1014 case OTP_FUSE_RGN: 1015 ipxotp_otpwb16(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF, base * 16); 1016 ipxotp_write_bit(oi, cc, otpgu_bit_base + OTPGU_FUSEP_OFF); 1017 break; 1018 } 1019 } 1020 1021 /* Disable Write */ 1022 AND_REG(oi->osh, &cc->otpcontrol, ~OTPC_PROGEN); 1023 1024 /* Sync region info by retrieving them again (use PMU bit to power cycle OTP) */ 1025 si_otp_power(oi->sih, FALSE); 1026 si_otp_power(oi->sih, TRUE); 1027 1028 /* Check and fix for region size and region programmed bits */ 1029 if (!rewrite) { 1030 uint16 boundary_off = 0, boundary_val = 0; 1031 uint16 programmed_off = 0; 1032 uint16 bit = 0; 1033 1034 switch (region) { 1035 case OTP_HW_RGN: 1036 boundary_off = OTPGU_HSB_OFF; 1037 boundary_val = (base + i) * 16; 1038 programmed_off = OTPGU_HWP_OFF; 1039 break; 1040 case OTP_SW_RGN: 1041 /* Also write 0 to HW region boundary */ 1042 if ((rc = ipxotp_check_word16(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF, 1043 base * 16))) 1044 goto exit; 1045 boundary_off = OTPGU_SFB_OFF; 1046 boundary_val = oi->swlim * 16; 1047 programmed_off = OTPGU_SWP_OFF; 1048 break; 1049 case OTP_CI_RGN: 1050 /* No CI region boundary */ 1051 programmed_off = OTPGU_CIP_OFF; 1052 break; 1053 case OTP_FUSE_RGN: 1054 boundary_off = OTPGU_SFB_OFF; 1055 boundary_val = base * 16; 1056 programmed_off = OTPGU_FUSEP_OFF; 1057 break; 1058 } 1059 1060 /* Do the actual checking and return BCME_NORESOURCE if we cannot fix */ 1061 if ((region != OTP_CI_RGN) && 1062 (rc = ipxotp_check_word16(oi, cc, oi->otpgu_base + boundary_off, 1063 boundary_val))) { 1064 goto exit; 1065 } 1066 1067 if ((bit = ipxotp_read_bit(oh, cc, otpgu_bit_base + programmed_off)) == 0xffff) { 1068 OTP_ERR(("\n%s: FAILED bit %d reads %d\n", __FUNCTION__, otpgu_bit_base + 1069 programmed_off, bit)); 1070 goto exit; 1071 } else if (bit == 0) { /* error detected, fix it */ 1072 OTP_ERR(("\n%s: FAILED bit %d reads %d, fixing\n", __FUNCTION__, 1073 otpgu_bit_base + programmed_off, bit)); 1074 if ((rc = ipxotp_write_rde(oi, -1, otpgu_bit_base + programmed_off, 1))) { 1075 OTP_ERR(("\n%s: cannot fix, ipxotp_write_rde returns %d\n", 1076 __FUNCTION__, rc)); 1077 goto exit; 1078 } 1079 } 1080 } 1081 1082 /* Update status, apply WAR */ 1083 _ipxotp_init(oi, cc); 1084 1085 /* Recover original data... */ 1086 if (origdata) 1087 bcopy(origdata, data, wlen * 2); 1088 1089 /* ...so we can verify and fix where possible */ 1090 for (i = 0; i < wlen; i++) { 1091 if ((rc = ipxotp_check_word16(oi, cc, base + i, data[i]))) 1092 goto exit; 1093 } 1094 1095exit: 1096 if (origdata) 1097 MFREE(oi->osh, origdata, wlen * 2); 1098 1099 si_setcoreidx(oi->sih, idx); 1100 return rc; 1101} 1102 1103static int 1104ipxotp_write_word(void *oh, uint wn, uint16 data) 1105{ 1106 otpinfo_t *oi = (otpinfo_t *)oh; 1107 int rc = 0; 1108 uint16 origdata; 1109 uint idx; 1110 chipcregs_t *cc; 1111 1112 idx = si_coreidx(oi->sih); 1113 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 1114 ASSERT(cc != NULL); 1115 1116 /* Check for conflict */ 1117 origdata = data; 1118 data = ipxotp_otpr(oi, cc, wn); 1119 if (data & ~origdata) { 1120 OTP_ERR(("%s: word %d incompatible (0x%04x->0x%04x)\n", 1121 __FUNCTION__, wn, data, origdata)); 1122 rc = BCME_BADARG; 1123 goto exit; 1124 } 1125 data ^= origdata; 1126 1127 /* Enable Write */ 1128 OR_REG(oi->osh, &cc->otpcontrol, OTPC_PROGEN); 1129 1130 rc = ipxotp_otpwb16(oi, cc, wn, data); 1131 1132 /* Disable Write */ 1133 AND_REG(oi->osh, &cc->otpcontrol, ~OTPC_PROGEN); 1134 1135 data = origdata; 1136 if ((rc = ipxotp_check_word16(oi, cc, wn, data))) 1137 goto exit; 1138exit: 1139 si_setcoreidx(oi->sih, idx); 1140 return rc; 1141} 1142 1143static int 1144ipxotp_cis_append_region(si_t *sih, int region, char *vars, int count) 1145{ 1146 uint8 *cis; 1147 osl_t *osh; 1148 uint sz = OTP_SZ_MAX/2; /* size in words */ 1149 int rc = 0; 1150 bool newchip = FALSE; 1151 1152 ASSERT(region == OTP_HW_RGN || region == OTP_SW_RGN); 1153 1154 osh = si_osh(sih); 1155 if ((cis = MALLOC(osh, OTP_SZ_MAX)) == NULL) { 1156 return BCME_ERROR; 1157 } 1158 1159 bzero(cis, OTP_SZ_MAX); 1160 1161 rc = otp_read_region(sih, region, (uint16 *)cis, &sz); 1162 newchip = (rc == BCME_NOTFOUND) ? TRUE : FALSE; 1163 if ((rc != 0) && (rc != BCME_NOTFOUND)) { 1164 return BCME_ERROR; 1165 } 1166 rc = 0; 1167 1168 /* zero count for read, non-zero count for write */ 1169 if (count) { 1170 int i = 0, newlen = 0; 1171 1172 if (newchip) { 1173 int termw_len = 0; /* length of termination word */ 1174 1175 /* convert halfwords to bytes offset */ 1176 newlen = sz * 2; 1177 1178 if ((CHIPID(sih->chip) == BCM4322_CHIP_ID) || 1179 (CHIPID(sih->chip) == BCM43231_CHIP_ID) || 1180 (CHIPID(sih->chip) == BCM4315_CHIP_ID) || 1181 (CHIPID(sih->chip) == BCM4319_CHIP_ID)) { 1182 /* bootloader WAR, refer to above twiki link */ 1183 cis[newlen-1] = 0x00; 1184 cis[newlen-2] = 0xff; 1185 cis[newlen-3] = 0x00; 1186 cis[newlen-4] = 0xff; 1187 cis[newlen-5] = 0xff; 1188 cis[newlen-6] = 0x1; 1189 cis[newlen-7] = 0x2; 1190 termw_len = 7; 1191 } else { 1192 cis[newlen-1] = 0xff; 1193 cis[newlen-2] = 0xff; 1194 termw_len = 2; 1195 } 1196 1197 if (count >= newlen - termw_len) { 1198 OTP_MSG(("OTP left %x bytes; buffer %x bytes\n", newlen, count)); 1199 rc = BCME_BUFTOOLONG; 1200 } 1201 } else { 1202 int end = 0; 1203 1204 /* Walk through the leading zeros (could be 0 or 8 bytes for now) */ 1205 for (i = 0; i < (int)sz*2; i++) 1206 if (cis[i] != 0) 1207 break; 1208 1209 /* Find the place to append */ 1210 for (; i < (int)sz*2; i++) { 1211 if (cis[i] == 0) 1212 break; 1213 i += ((int)cis[i+1] + 1); 1214 } 1215 1216 for (end = i; end < (int)sz*2; end++) { 1217 if (cis[end] != 0) 1218 break; 1219 } 1220 1221 newlen = i + count; 1222 if (newlen & 1) /* make it even-sized buffer */ 1223 newlen++; 1224 1225 if (newlen >= (end - 1)) { 1226 OTP_MSG(("OTP left %x bytes; buffer %x bytes\n", end-i, count)); 1227 rc = BCME_BUFTOOLONG; 1228 } 1229 } 1230 1231 /* copy the buffer */ 1232 memcpy(&cis[i], vars, count); 1233#ifdef BCMNVRAMW 1234 /* Write the buffer back */ 1235 if (!rc) 1236 rc = otp_write_region(sih, region, (uint16*)cis, newlen/2); 1237 1238 /* Print the buffer */ 1239 OTP_MSG(("Buffer of size %d bytes to write:\n", newlen)); 1240 for (i = 0; i < newlen; i++) { 1241 OTP_DBG(("%02x ", cis[i] & 0xff)); 1242 if ((i % 16) == 15) { 1243 OTP_DBG(("\n")); 1244 } 1245 } 1246 OTP_MSG(("\n")); 1247#endif /* BCMNVRAMW */ 1248 } 1249 1250 if (cis) 1251 MFREE(osh, cis, OTP_SZ_MAX); 1252 1253 return (rc); 1254} 1255 1256/* No need to lock for IPXOTP */ 1257static int 1258ipxotp_lock(void *oh) 1259{ 1260 uint idx; 1261 chipcregs_t *cc; 1262 otpinfo_t *oi = (otpinfo_t *)oh; 1263 int err = 0, rc = 0; 1264 1265 idx = si_coreidx(oi->sih); 1266 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 1267 ASSERT(cc != NULL); 1268 1269 /* Enable Write */ 1270 OR_REG(oi->osh, &cc->otpcontrol, OTPC_PROGEN); 1271 1272 err = ipxotp_write_lock_bit(oi, cc, OTP_LOCK_ROW1_LOC_OFF); 1273 if (err) { 1274 OTP_ERR(("fail to lock ROW1\n")); 1275 rc = -1; 1276 } 1277 err = ipxotp_write_lock_bit(oi, cc, OTP_LOCK_ROW2_LOC_OFF); 1278 if (err) { 1279 OTP_ERR(("fail to lock ROW2\n")); 1280 rc = -2; 1281 } 1282 err = ipxotp_write_lock_bit(oi, cc, OTP_LOCK_RD_LOC_OFF); 1283 if (err) { 1284 OTP_ERR(("fail to lock RD\n")); 1285 rc = -3; 1286 } 1287 err = ipxotp_write_lock_bit(oi, cc, OTP_LOCK_GU_LOC_OFF); 1288 if (err) { 1289 OTP_ERR(("fail to lock GU\n")); 1290 rc = -4; 1291 } 1292 1293 /* Disable Write */ 1294 AND_REG(oi->osh, &cc->otpcontrol, ~OTPC_PROGEN); 1295 1296 /* Sync region info by retrieving them again (use PMU bit to power cycle OTP) */ 1297 si_otp_power(oi->sih, FALSE); 1298 si_otp_power(oi->sih, TRUE); 1299 1300 /* Update status, apply WAR */ 1301 _ipxotp_init(oi, cc); 1302 return rc; 1303} 1304 1305static int 1306ipxotp_nvwrite(void *oh, uint16 *data, uint wlen) 1307{ 1308 return -1; 1309} 1310#endif /* BCMNVRAMW */ 1311 1312#if defined(WLTEST) 1313static uint16 1314ipxotp_otprb16(void *oh, chipcregs_t *cc, uint wn) 1315{ 1316 uint base, i; 1317 uint16 val; 1318 uint16 bit; 1319 1320 base = wn * 16; 1321 1322 val = 0; 1323 for (i = 0; i < 16; i++) { 1324 if ((bit = ipxotp_read_bit(oh, cc, base + i)) == 0xffff) 1325 break; 1326 val = val | (bit << i); 1327 } 1328 if (i < 16) 1329 val = 0xffff; 1330 1331 return val; 1332} 1333 1334static int 1335ipxotp_dump(void *oh, int arg, char *buf, uint size) 1336{ 1337 otpinfo_t *oi = (otpinfo_t *)oh; 1338 chipcregs_t *cc; 1339 uint idx, i, count; 1340 uint16 val; 1341 struct bcmstrbuf b; 1342 1343 idx = si_coreidx(oi->sih); 1344 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 1345 ASSERT(cc != NULL); 1346 1347 count = ipxotp_size(oh); 1348 1349 bcm_binit(&b, buf, size); 1350 for (i = 0; i < count / 2; i++) { 1351 if (!(i % 4)) 1352 bcm_bprintf(&b, "\n0x%04x:", 2 * i); 1353 if (arg == 0) 1354 val = ipxotp_otpr(oh, cc, i); 1355 else 1356 val = ipxotp_otprb16(oi, cc, i); 1357 bcm_bprintf(&b, " 0x%04x", val); 1358 } 1359 bcm_bprintf(&b, "\n"); 1360 1361 si_setcoreidx(oi->sih, idx); 1362 1363 return ((int)(b.buf - b.origbuf)); 1364} 1365#endif 1366 1367static otp_fn_t ipxotp_fn = { 1368 (otp_size_t)ipxotp_size, 1369 (otp_read_bit_t)ipxotp_read_bit, 1370 1371 (otp_init_t)ipxotp_init, 1372 (otp_read_region_t)ipxotp_read_region, 1373 (otp_nvread_t)ipxotp_nvread, 1374#ifdef BCMNVRAMW 1375 (otp_write_region_t)ipxotp_write_region, 1376 (otp_cis_append_region_t)ipxotp_cis_append_region, 1377 (otp_lock_t)ipxotp_lock, 1378 (otp_nvwrite_t)ipxotp_nvwrite, 1379#endif /* BCMNVRAMW */ 1380 1381#if defined(WLTEST) 1382 (otp_dump_t)ipxotp_dump, 1383#endif 1384 1385 (otp_status_t)ipxotp_status, 1386#ifdef BCMNVRAMW 1387 (otp_write_word_t)ipxotp_write_word, 1388#endif /* BCMNVRAMW */ 1389 (otp_read_word_t)ipxotp_read_word, 1390}; 1391 1392#endif /* BCMIPXOTP */ 1393 1394 1395/* 1396 * HND OTP Code 1397 * 1398 * Exported functions: 1399 * hndotp_status() 1400 * hndotp_size() 1401 * hndotp_init() 1402 * hndotp_read_bit() 1403 * hndotp_read_region() 1404 * hndotp_read_word() 1405 * hndotp_nvread() 1406 * hndotp_write_region() 1407 * hndotp_cis_append_region() 1408 * hndotp_lock() 1409 * hndotp_nvwrite() 1410 * hndotp_dump() 1411 * 1412 * HND internal functions: 1413 * hndotp_otpr() 1414 * hndotp_otproff() 1415 * hndotp_write_bit() 1416 * hndotp_write_word() 1417 * hndotp_valid_rce() 1418 * hndotp_write_rce() 1419 * hndotp_write_row() 1420 * hndotp_otprb16() 1421 * 1422 */ 1423 1424#ifdef BCMHNDOTP 1425 1426/* Fields in otpstatus */ 1427#define OTPS_PROGFAIL 0x80000000 1428#define OTPS_PROTECT 0x00000007 1429#define OTPS_HW_PROTECT 0x00000001 1430#define OTPS_SW_PROTECT 0x00000002 1431#define OTPS_CID_PROTECT 0x00000004 1432#define OTPS_RCEV_MSK 0x00003f00 1433#define OTPS_RCEV_SHIFT 8 1434 1435/* Fields in the otpcontrol register */ 1436#define OTPC_RECWAIT 0xff000000 1437#define OTPC_PROGWAIT 0x00ffff00 1438#define OTPC_PRW_SHIFT 8 1439#define OTPC_MAXFAIL 0x00000038 1440#define OTPC_VSEL 0x00000006 1441#define OTPC_SELVL 0x00000001 1442 1443/* OTP regions (Word offsets from otp size) */ 1444#define OTP_SWLIM_OFF (-4) 1445#define OTP_CIDBASE_OFF 0 1446#define OTP_CIDLIM_OFF 4 1447 1448/* Predefined OTP words (Word offset from otp size) */ 1449#define OTP_BOUNDARY_OFF (-4) 1450#define OTP_HWSIGN_OFF (-3) 1451#define OTP_SWSIGN_OFF (-2) 1452#define OTP_CIDSIGN_OFF (-1) 1453#define OTP_CID_OFF 0 1454#define OTP_PKG_OFF 1 1455#define OTP_FID_OFF 2 1456#define OTP_RSV_OFF 3 1457#define OTP_LIM_OFF 4 1458#define OTP_RD_OFF 4 /* Redundancy row starts here */ 1459#define OTP_RC0_OFF 28 /* Redundancy control word 1 */ 1460#define OTP_RC1_OFF 32 /* Redundancy control word 2 */ 1461#define OTP_RC_LIM_OFF 36 /* Redundancy control word end */ 1462 1463#define OTP_HW_REGION OTPS_HW_PROTECT 1464#define OTP_SW_REGION OTPS_SW_PROTECT 1465#define OTP_CID_REGION OTPS_CID_PROTECT 1466 1467#if OTP_HW_REGION != OTP_HW_RGN 1468#error "incompatible OTP_HW_RGN" 1469#endif 1470#if OTP_SW_REGION != OTP_SW_RGN 1471#error "incompatible OTP_SW_RGN" 1472#endif 1473#if OTP_CID_REGION != OTP_CI_RGN 1474#error "incompatible OTP_CI_RGN" 1475#endif 1476 1477/* Redundancy entry definitions */ 1478#define OTP_RCE_ROW_SZ 6 1479#define OTP_RCE_SIGN_MASK 0x7fff 1480#define OTP_RCE_ROW_MASK 0x3f 1481#define OTP_RCE_BITS 21 1482#define OTP_RCE_SIGN_SZ 15 1483#define OTP_RCE_BIT0 1 1484 1485#define OTP_WPR 4 1486#define OTP_SIGNATURE 0x578a 1487#define OTP_MAGIC 0x4e56 1488 1489static int 1490hndotp_status(void *oh) 1491{ 1492 otpinfo_t *oi = (otpinfo_t *)oh; 1493 return ((int)(oi->hwprot | oi->signvalid)); 1494} 1495 1496static int 1497hndotp_size(void *oh) 1498{ 1499 otpinfo_t *oi = (otpinfo_t *)oh; 1500 return ((int)(oi->size)); 1501} 1502 1503static uint16 1504hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) 1505{ 1506 otpinfo_t *oi = (otpinfo_t *)oh; 1507 osl_t *osh; 1508 volatile uint16 *ptr; 1509 1510 ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF)); 1511 ASSERT(cc != NULL); 1512 1513 osh = si_osh(oi->sih); 1514 1515 ptr = (volatile uint16 *)((volatile char *)cc + CC_SROM_OTP); 1516 return (R_REG(osh, &ptr[wn])); 1517} 1518 1519static uint16 1520hndotp_otproff(void *oh, chipcregs_t *cc, int woff) 1521{ 1522 otpinfo_t *oi = (otpinfo_t *)oh; 1523 osl_t *osh; 1524 volatile uint16 *ptr; 1525 1526 ASSERT(woff >= (-((int)oi->size / 2))); 1527 ASSERT(woff < OTP_LIM_OFF); 1528 ASSERT(cc != NULL); 1529 1530 osh = si_osh(oi->sih); 1531 1532 ptr = (volatile uint16 *)((volatile char *)cc + CC_SROM_OTP); 1533 1534 return (R_REG(osh, &ptr[(oi->size / 2) + woff])); 1535} 1536 1537static uint16 1538hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) 1539{ 1540 otpinfo_t *oi = (otpinfo_t *)oh; 1541 uint k, row, col; 1542 uint32 otpp, st; 1543 osl_t *osh; 1544 1545 osh = si_osh(oi->sih); 1546 row = idx / 65; 1547 col = idx % 65; 1548 1549 otpp = OTPP_START_BUSY | OTPP_READ | 1550 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | 1551 (col & OTPP_COL_MASK); 1552 1553 OTP_DBG(("%s: idx = %d, row = %d, col = %d, otpp = 0x%x", __FUNCTION__, 1554 idx, row, col, otpp)); 1555 1556 W_REG(osh, &cc->otpprog, otpp); 1557 st = R_REG(osh, &cc->otpprog); 1558 for (k = 0; ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES); k++) 1559 st = R_REG(osh, &cc->otpprog); 1560 1561 if (k >= OTPP_TRIES) { 1562 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__, st, k)); 1563 return 0xffff; 1564 } 1565 if (st & OTPP_READERR) { 1566 OTP_ERR(("\n%s: Could not read OTP bit %d\n", __FUNCTION__, idx)); 1567 return 0xffff; 1568 } 1569 st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT; 1570 OTP_DBG((" => %d\n", st)); 1571 return (uint16)st; 1572} 1573 1574static void * 1575BCMNMIATTACHFN(hndotp_init)(si_t *sih) 1576{ 1577 uint idx; 1578 chipcregs_t *cc; 1579 otpinfo_t *oi; 1580 uint32 cap = 0, clkdiv, otpdiv = 0; 1581 void *ret = NULL; 1582 osl_t *osh; 1583 1584 OTP_MSG(("%s: Use HND OTP controller\n", __FUNCTION__)); 1585 oi = &otpinfo; 1586 1587 idx = si_coreidx(sih); 1588 osh = si_osh(oi->sih); 1589 1590 /* Check for otp */ 1591 if ((cc = si_setcoreidx(sih, SI_CC_IDX)) != NULL) { 1592 cap = R_REG(osh, &cc->capabilities); 1593 if ((cap & CC_CAP_OTPSIZE) == 0) { 1594 /* Nothing there */ 1595 goto out; 1596 } 1597 1598 /* As of right now, support only 4320a2, 4311a1 and 4312 */ 1599 ASSERT((oi->ccrev == 12) || (oi->ccrev == 17) || (oi->ccrev == 22)); 1600 if (!((oi->ccrev == 12) || (oi->ccrev == 17) || (oi->ccrev == 22))) 1601 return NULL; 1602 1603 /* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is 1604 * 8 row (64 bytes) smaller 1605 */ 1606 oi->size = 1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) 1607 + CC_CAP_OTPSIZE_BASE); 1608 if (oi->ccrev >= 18) { 1609 oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2); 1610 } else { 1611 OTP_ERR(("Negative otp size, shouldn't happen for programmed chip.")); 1612 oi->size = 0; 1613 } 1614 1615 oi->hwprot = (int)(R_REG(osh, &cc->otpstatus) & OTPS_PROTECT); 1616 oi->boundary = -1; 1617 1618 /* Check the region signature */ 1619 if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) { 1620 oi->signvalid |= OTP_HW_REGION; 1621 oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF); 1622 } 1623 1624 if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE) 1625 oi->signvalid |= OTP_SW_REGION; 1626 1627 if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE) 1628 oi->signvalid |= OTP_CID_REGION; 1629 1630 /* Set OTP clkdiv for stability */ 1631 if (oi->ccrev == 22) 1632 otpdiv = 12; 1633 1634 if (otpdiv) { 1635 clkdiv = R_REG(osh, &cc->clkdiv); 1636 clkdiv = (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT); 1637 W_REG(osh, &cc->clkdiv, clkdiv); 1638 OTP_MSG(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv)); 1639 } 1640 OSL_DELAY(10); 1641 1642 ret = (void *)oi; 1643 } 1644 1645 OTP_MSG(("%s: ccrev %d\tsize %d bytes\thwprot %x\tsignvalid %x\tboundary %x\n", 1646 __FUNCTION__, oi->ccrev, oi->size, oi->hwprot, oi->signvalid, 1647 oi->boundary)); 1648 1649out: /* All done */ 1650 si_setcoreidx(sih, idx); 1651 1652 return ret; 1653} 1654 1655static int 1656hndotp_read_region(void *oh, int region, uint16 *data, uint *wlen) 1657{ 1658 otpinfo_t *oi = (otpinfo_t *)oh; 1659 uint32 idx, st; 1660 chipcregs_t *cc; 1661 int i; 1662 1663 /* Only support HW region (no active chips use HND OTP SW region) */ 1664 ASSERT(region == OTP_HW_REGION); 1665 1666 OTP_MSG(("%s: region %x wlen %d\n", __FUNCTION__, region, *wlen)); 1667 1668 /* Region empty? */ 1669 st = oi->hwprot | oi-> signvalid; 1670 if ((st & region) == 0) 1671 return BCME_NOTFOUND; 1672 1673 *wlen = ((int)*wlen < oi->boundary/2) ? *wlen : (uint)oi->boundary/2; 1674 1675 idx = si_coreidx(oi->sih); 1676 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 1677 ASSERT(cc != NULL); 1678 1679 for (i = 0; i < (int)*wlen; i++) 1680 data[i] = hndotp_otpr(oh, cc, i); 1681 1682 si_setcoreidx(oi->sih, idx); 1683 1684 return 0; 1685} 1686 1687static int 1688hndotp_read_word(void *oh, uint wn, uint16 *data) 1689{ 1690 otpinfo_t *oi = (otpinfo_t *)oh; 1691 uint32 idx; 1692 chipcregs_t *cc; 1693 1694 idx = si_coreidx(oi->sih); 1695 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 1696 ASSERT(cc != NULL); 1697 1698 *data = hndotp_otpr(oh, cc, wn); 1699 1700 si_setcoreidx(oi->sih, idx); 1701 return 0; 1702} 1703 1704static int 1705hndotp_nvread(void *oh, char *data, uint *len) 1706{ 1707 int rc = 0; 1708 otpinfo_t *oi = (otpinfo_t *)oh; 1709 uint32 base, bound, lim = 0, st; 1710 int i, chunk, gchunks, tsz = 0; 1711 uint32 idx; 1712 chipcregs_t *cc; 1713 uint offset; 1714 uint16 *rawotp = NULL; 1715 1716 /* save the orig core */ 1717 idx = si_coreidx(oi->sih); 1718 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 1719 ASSERT(cc != NULL); 1720 1721 st = hndotp_status(oh); 1722 if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) { 1723 OTP_ERR(("OTP not programmed\n")); 1724 rc = -1; 1725 goto out; 1726 } 1727 1728 /* Read the whole otp so we can easily manipulate it */ 1729 lim = hndotp_size(oh); 1730 if (lim == 0) { 1731 OTP_ERR(("OTP size is 0\n")); 1732 rc = -1; 1733 goto out; 1734 } 1735 if ((rawotp = MALLOC(si_osh(oi->sih), lim)) == NULL) { 1736 OTP_ERR(("Out of memory for rawotp\n")); 1737 rc = -2; 1738 goto out; 1739 } 1740 for (i = 0; i < (int)(lim / 2); i++) 1741 rawotp[i] = hndotp_otpr(oh, cc, i); 1742 1743 if ((st & OTP_HW_REGION) == 0) { 1744 OTP_ERR(("otp: hw region not written (0x%x)\n", st)); 1745 1746 /* This could be a programming failure in the first 1747 * chunk followed by one or more good chunks 1748 */ 1749 for (i = 0; i < (int)(lim / 2); i++) 1750 if (rawotp[i] == OTP_MAGIC) 1751 break; 1752 1753 if (i < (int)(lim / 2)) { 1754 base = i; 1755 bound = (i * 2) + rawotp[i + 1]; 1756 OTP_MSG(("otp: trying chunk at 0x%x-0x%x\n", i * 2, bound)); 1757 } else { 1758 OTP_MSG(("otp: unprogrammed\n")); 1759 rc = -3; 1760 goto out; 1761 } 1762 } else { 1763 bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF]; 1764 1765 /* There are two cases: 1) The whole otp is used as nvram 1766 * and 2) There is a hardware header followed by nvram. 1767 */ 1768 if (rawotp[0] == OTP_MAGIC) { 1769 base = 0; 1770 if (bound != rawotp[1]) 1771 OTP_MSG(("otp: Bound 0x%x != chunk0 len 0x%x\n", bound, 1772 rawotp[1])); 1773 } else 1774 base = bound; 1775 } 1776 1777 /* Find and copy the data */ 1778 1779 chunk = 0; 1780 gchunks = 0; 1781 i = base / 2; 1782 offset = 0; 1783 while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) { 1784 int dsz, rsz = rawotp[i + 1]; 1785 1786 if (((i * 2) + rsz) >= (int)lim) { 1787 OTP_MSG((" bad chunk size, chunk %d, base 0x%x, size 0x%x\n", 1788 chunk, i * 2, rsz)); 1789 /* Bad length, try to find another chunk anyway */ 1790 rsz = 6; 1791 } 1792 if (hndcrc16((uint8 *)&rawotp[i], rsz, 1793 CRC16_INIT_VALUE) == CRC16_GOOD_VALUE) { 1794 /* Good crc, copy the vars */ 1795 OTP_MSG((" good chunk %d, base 0x%x, size 0x%x\n", 1796 chunk, i * 2, rsz)); 1797 gchunks++; 1798 dsz = rsz - 6; 1799 tsz += dsz; 1800 if (offset + dsz >= *len) { 1801 OTP_MSG(("Out of memory for otp\n")); 1802 goto out; 1803 } 1804 bcopy((char *)&rawotp[i + 2], &data[offset], dsz); 1805 offset += dsz; 1806 /* Remove extra null characters at the end */ 1807 while (offset > 1 && 1808 data[offset - 1] == 0 && data[offset - 2] == 0) 1809 offset --; 1810 i += rsz / 2; 1811 } else { 1812 /* bad length or crc didn't check, try to find the next set */ 1813 OTP_MSG((" chunk %d @ 0x%x size 0x%x: bad crc, ", 1814 chunk, i * 2, rsz)); 1815 if (rawotp[i + (rsz / 2)] == OTP_MAGIC) { 1816 /* Assume length is good */ 1817 i += rsz / 2; 1818 } else { 1819 while (++i < (int)(lim / 2)) 1820 if (rawotp[i] == OTP_MAGIC) 1821 break; 1822 } 1823 if (i < (int)(lim / 2)) 1824 OTP_MSG(("trying next base 0x%x\n", i * 2)); 1825 else 1826 OTP_MSG(("no more chunks\n")); 1827 } 1828 chunk++; 1829 } 1830 1831 OTP_MSG((" otp size = %d, boundary = 0x%x, nv base = 0x%x\n", lim, bound, base)); 1832 if (tsz != 0) { 1833 OTP_MSG((" Found %d bytes in %d good chunks out of %d\n", tsz, gchunks, chunk)); 1834 } else { 1835 OTP_MSG((" No good chunks found out of %d\n", chunk)); 1836 } 1837 1838 *len = offset; 1839 1840out: 1841 if (rawotp) 1842 MFREE(si_osh(oi->sih), rawotp, lim); 1843 si_setcoreidx(oi->sih, idx); 1844 1845 return rc; 1846} 1847 1848#ifdef BCMNVRAMW 1849#if defined(WLTEST) 1850static uint st_n, st_s, st_hwm, pp_hwm; 1851#ifdef OTP_FORCEFAIL 1852static uint forcefail_bitcount = 0; 1853#endif /* OTP_FORCEFAIL */ 1854#endif 1855 1856static int 1857hndotp_write_bit(void *oh, chipcregs_t *cc, int bn, bool bit, int no_retry) 1858{ 1859 otpinfo_t *oi = (otpinfo_t *)oh; 1860 uint row, col, j, k; 1861 uint32 pwait, init_pwait, otpc, otpp, pst, st; 1862 osl_t *osh; 1863 1864 osh = si_osh(oi->sih); 1865 ASSERT((bit >> 1) == 0); 1866 1867#ifdef OTP_FORCEFAIL 1868 OTP_MSG(("%s: [0x%x] = 0x%x\n", __FUNCTION__, wn * 2, data)); 1869#endif 1870 1871 /* This is bit-at-a-time writing, future cores may do word-at-a-time */ 1872 if (oi->ccrev == 12) { 1873 otpc = 0x20000001; 1874 init_pwait = 0x00000200; 1875 } else if (oi->ccrev == 22) { 1876 otpc = 0x20000001; 1877 init_pwait = 0x00000400; 1878 } else { 1879 otpc = 0x20000001; 1880 init_pwait = 0x00004000; 1881 } 1882 1883 pwait = init_pwait; 1884 row = bn / 65; 1885 col = bn % 65; 1886 otpp = OTPP_START_BUSY | 1887 ((bit << OTPP_VALUE_SHIFT) & OTPP_VALUE_MASK) | 1888 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | 1889 (col & OTPP_COL_MASK); 1890 j = 0; 1891 while (1) { 1892 j++; 1893 if (j > 1) { 1894 OTP_DBG(("row %d, col %d, val %d, otpc 0x%x, otpp 0x%x\n", 1895 row, col, bit, (otpc | pwait), otpp)); 1896 } 1897 W_REG(osh, &cc->otpcontrol, otpc | pwait); 1898 W_REG(osh, &cc->otpprog, otpp); 1899 pst = R_REG(osh, &cc->otpprog); 1900 for (k = 0; ((pst & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES); k++) 1901 pst = R_REG(osh, &cc->otpprog); 1902#if defined(WLTEST) 1903 if (k > pp_hwm) 1904 pp_hwm = k; 1905#endif 1906 if (k >= OTPP_TRIES) { 1907 OTP_ERR(("BUSY stuck: pst=0x%x, count=%d\n", pst, k)); 1908 st = OTPS_PROGFAIL; 1909 break; 1910 } 1911 st = R_REG(osh, &cc->otpstatus); 1912 if (((st & OTPS_PROGFAIL) == 0) || (pwait == OTPC_PROGWAIT) || (no_retry)) { 1913 break; 1914 } else { 1915 if ((oi->ccrev == 12) || (oi->ccrev == 22)) 1916 pwait = (pwait << 3) & OTPC_PROGWAIT; 1917 else 1918 pwait = (pwait << 1) & OTPC_PROGWAIT; 1919 if (pwait == 0) 1920 pwait = OTPC_PROGWAIT; 1921 } 1922 } 1923#if defined(WLTEST) 1924 st_n++; 1925 st_s += j; 1926 if (j > st_hwm) 1927 st_hwm = j; 1928#ifdef OTP_FORCEFAIL 1929 if (forcefail_bitcount++ == OTP_FORCEFAIL * 16) { 1930 OTP_DBG(("Forcing PROGFAIL on bit %d (FORCEFAIL = %d/0x%x)\n", 1931 forcefail_bitcount, OTP_FORCEFAIL, OTP_FORCEFAIL)); 1932 st = OTPS_PROGFAIL; 1933 } 1934#endif 1935#endif 1936 if (st & OTPS_PROGFAIL) { 1937 OTP_ERR(("After %d tries: otpc = 0x%x, otpp = 0x%x/0x%x, otps = 0x%x\n", 1938 j, otpc | pwait, otpp, pst, st)); 1939 OTP_ERR(("otp prog failed. bit=%d, ppret=%d, ret=%d\n", bit, k, j)); 1940 return 1; 1941 } 1942 1943 return 0; 1944} 1945 1946static int 1947hndotp_write_word(void *oh, chipcregs_t *cc, int wn, uint16 data) 1948{ 1949 uint base, i; 1950 int err = 0; 1951 1952 OTP_MSG(("%s: wn %d data %x\n", __FUNCTION__, wn, data)); 1953 1954 /* There is one test bit for each row */ 1955 base = (wn * 16) + (wn / 4); 1956 1957 for (i = 0; i < 16; i++) { 1958 err += hndotp_write_bit(oh, cc, base + i, data & 1, 0); 1959 data >>= 1; 1960 /* abort write after first error to avoid stress the charge-pump */ 1961 if (err) { 1962 OTP_DBG(("%s: wn %d fail on bit %d\n", __FUNCTION__, wn, i)); 1963 break; 1964 } 1965 } 1966 1967 return err; 1968} 1969 1970static int 1971hndotp_valid_rce(void *oh, chipcregs_t *cc, int i) 1972{ 1973 otpinfo_t *oi = (otpinfo_t *)oh; 1974 osl_t *osh; 1975 uint32 hwv, fw, rce, e, sign, row, st; 1976 1977 ASSERT(oi->ccrev >= 18); 1978 1979 /* HW valid bit */ 1980 osh = si_osh(oi->sih); 1981 st = R_REG(osh, &cc->otpstatus); 1982 hwv = (st & OTPS_RCEV_MSK) & (1 << (OTPS_RCEV_SHIFT + i)); 1983 1984 if (i < 3) { 1985 e = i; 1986 fw = hndotp_size(oh)/2 + OTP_RC0_OFF + e; 1987 } else { 1988 e = i - 3; 1989 fw = hndotp_size(oh)/2 + OTP_RC1_OFF + e; 1990 } 1991 1992 rce = hndotp_otpr(oh, cc, fw+1) << 16 | hndotp_otpr(oh, cc, fw); 1993 rce >>= ((e * OTP_RCE_BITS) + OTP_RCE_BIT0 - (e * 16)); 1994 row = rce & OTP_RCE_ROW_MASK; 1995 sign = (rce >> OTP_RCE_ROW_SZ) & OTP_RCE_SIGN_MASK; 1996 1997 OTP_MSG(("rce %d sign %x row %d hwv %x\n", i, sign, row, hwv)); 1998 1999 return (sign == OTP_SIGNATURE) ? row : -1; 2000} 2001 2002static int 2003hndotp_write_rce(void *oh, chipcregs_t *cc, int r, uint16* data) 2004{ 2005 int i, rce = -1; 2006 uint32 sign; 2007 2008 ASSERT(((otpinfo_t *)oh)->ccrev >= 18); 2009 ASSERT(r >= 0 && r < hndotp_size(oh)/(2*OTP_WPR)); 2010 ASSERT(data); 2011 2012 for (rce = OTP_RCE_ROW_SZ -1; rce >= 0; rce--) { 2013 int e, rt, rcr, bit, err = 0; 2014 2015 int rr = hndotp_valid_rce(oh, cc, rce); 2016 /* redundancy row in use already */ 2017 if (rr != -1) { 2018 if (rr == r) { 2019 OTP_MSG(("%s: row %d already replaced by RCE %d", 2020 __FUNCTION__, r, rce)); 2021 return 0; 2022 } 2023 2024 continue; /* If row used, go for the next row */ 2025 } 2026 2027 /* 2028 * previously used bad rce entry maybe treaed as valid rce and used again, abort on 2029 * first bit error to avoid stress the charge pump 2030 */ 2031 2032 /* Write the data to the redundant row */ 2033 for (i = 0; i < OTP_WPR; i++) { 2034 err += hndotp_write_word(oh, cc, hndotp_size(oh)/2+OTP_RD_OFF+rce*4+i, 2035 data[i]); 2036 if (err) { 2037 OTP_MSG(("fail to write redundant row %d\n", rce)); 2038 break; 2039 } 2040 } 2041 2042 /* Now write the redundant row index */ 2043 if (rce < 3) { 2044 e = rce; 2045 rcr = hndotp_size(oh)/2 + OTP_RC0_OFF; 2046 } else { 2047 e = rce - 3; 2048 rcr = hndotp_size(oh)/2 + OTP_RC1_OFF; 2049 } 2050 2051 /* Write row numer bit-by-bit */ 2052 bit = (rcr * 16 + rcr / 4) + e * OTP_RCE_BITS + OTP_RCE_BIT0; 2053 rt = r; 2054 for (i = 0; i < OTP_RCE_ROW_SZ; i++) { 2055 /* If any timeout happened, invalidate the subsequent bits with 0 */ 2056 if (hndotp_write_bit(oh, cc, bit, (rt & (err ? 0 : 1)), err)) { 2057 OTP_MSG(("%s: timeout fixing row %d with RCE %d - at row" 2058 " number bit %x\n", __FUNCTION__, r, rce, i)); 2059 err++; 2060 } 2061 rt >>= 1; 2062 bit ++; 2063 } 2064 2065 /* Write the RCE signature bit-by-bit */ 2066 sign = OTP_SIGNATURE; 2067 for (i = 0; i < OTP_RCE_SIGN_SZ; i++) { 2068 /* If any timeout happened, invalidate the subsequent bits with 0 */ 2069 if (hndotp_write_bit(oh, cc, bit, (sign & (err ? 0 : 1)), err)) { 2070 OTP_MSG(("%s: timeout fixing row %d with RCE %d - at row" 2071 " number bit %x\n", __FUNCTION__, r, rce, i)); 2072 err++; 2073 } 2074 sign >>= 1; 2075 bit ++; 2076 } 2077 2078 if (err) { 2079 OTP_ERR(("%s: row %d not fixed by RCE %d due to %d timeouts. try next" 2080 " RCE\n", __FUNCTION__, r, rce, err)); 2081 continue; 2082 } else { 2083 OTP_MSG(("%s: Fixed row %d by RCE %d\n", __FUNCTION__, r, rce)); 2084 return BCME_OK; 2085 } 2086 } 2087 2088 OTP_ERR(("All RCE's are in use. Failed fixing OTP.\n")); 2089 /* Fatal error, unfixable. MFGC will have to fail. Board needs to be discarded!! */ 2090 return BCME_NORESOURCE; 2091} 2092 2093/* Write a row and fix it with RCE if any error detected */ 2094static int 2095hndotp_write_row(void *oh, chipcregs_t *cc, int wn, uint16* data, bool rewrite) 2096{ 2097 otpinfo_t *oi = (otpinfo_t *)oh; 2098 int err = 0, i; 2099 2100 ASSERT(wn % OTP_WPR == 0); 2101 2102 /* Write the data */ 2103 for (i = 0; i < OTP_WPR; i++) { 2104 if (rewrite && (data[i] == hndotp_otpr(oh, cc, wn+i))) 2105 continue; 2106 2107 err += hndotp_write_word(oh, cc, wn + i, data[i]); 2108 } 2109 2110 /* Fix this row if any error */ 2111 if (err && (oi->ccrev >= 18)) { 2112 OTP_DBG(("%s: %d write errors in row %d. Fixing...\n", __FUNCTION__, err, wn/4)); 2113 if ((err = hndotp_write_rce(oh, cc, wn / OTP_WPR, data))) 2114 OTP_MSG(("%s: failed to fix row %d\n", __FUNCTION__, wn/4)); 2115 } 2116 2117 return err; 2118} 2119 2120/* expects the caller to disable interrupts before calling this routine */ 2121static int 2122hndotp_write_region(void *oh, int region, uint16 *data, uint wlen) 2123{ 2124 otpinfo_t *oi = (otpinfo_t *)oh; 2125 uint32 st; 2126 uint wn, base = 0, lim; 2127 int ret = BCME_OK; 2128 uint idx; 2129 chipcregs_t *cc; 2130 bool rewrite = FALSE; 2131 uint32 save_clk; 2132 2133 ASSERT(wlen % OTP_WPR == 0); 2134 2135 idx = si_coreidx(oi->sih); 2136 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 2137 ASSERT(cc != NULL); 2138 2139 /* Check valid region */ 2140 if ((region != OTP_HW_REGION) && 2141 (region != OTP_SW_REGION) && 2142 (region != OTP_CID_REGION)) { 2143 ret = BCME_BADARG; 2144 goto out; 2145 } 2146 2147 /* Region already written? */ 2148 st = oi->hwprot | oi-> signvalid; 2149 if ((st & region) != 0) 2150 rewrite = TRUE; 2151 2152 /* HW and CID have to be written before SW */ 2153 if ((((st & (OTP_HW_REGION | OTP_CID_REGION)) == 0) && 2154 (st & OTP_SW_REGION) != 0)) { 2155 OTP_ERR(("%s: HW/CID region should be programmed first\n", __FUNCTION__)); 2156 ret = BCME_BADARG; 2157 goto out; 2158 } 2159 2160 /* Bounds for the region */ 2161 lim = (oi->size / 2) + OTP_SWLIM_OFF; 2162 if (region == OTP_HW_REGION) { 2163 base = 0; 2164 } else if (region == OTP_SW_REGION) { 2165 base = oi->boundary / 2; 2166 } else if (region == OTP_CID_REGION) { 2167 base = (oi->size / 2) + OTP_CID_OFF; 2168 lim = (oi->size / 2) + OTP_LIM_OFF; 2169 } 2170 2171 if (wlen > (lim - base)) { 2172 ret = BCME_BUFTOOLONG; 2173 goto out; 2174 } 2175 lim = base + wlen; 2176 2177#if defined(WLTEST) 2178 st_n = st_s = st_hwm = pp_hwm = 0; 2179#endif 2180 2181 /* force ALP for progrramming stability */ 2182 save_clk = R_REG(oi->osh, &cc->clk_ctl_st); 2183 OR_REG(oi->osh, &cc->clk_ctl_st, CCS_FORCEALP); 2184 OSL_DELAY(10); 2185 2186 /* Write the data row by row */ 2187 for (wn = base; wn < lim; wn += OTP_WPR, data += OTP_WPR) { 2188 if ((ret = hndotp_write_row(oh, cc, wn, data, rewrite)) != 0) { 2189 if (ret == BCME_NORESOURCE) { 2190 OTP_ERR(("%s: Abort at word %x\n", __FUNCTION__, wn)); 2191 break; 2192 } 2193 } 2194 } 2195 2196 /* Don't need to update signature & boundary if rewrite */ 2197 if (rewrite) 2198 goto out_rclk; 2199 2200 /* Done with the data, write the signature & boundary if needed */ 2201 if (region == OTP_HW_REGION) { 2202 if (hndotp_write_word(oh, cc, (oi->size / 2) + OTP_BOUNDARY_OFF, lim * 2) != 0) { 2203 ret = BCME_NORESOURCE; 2204 goto out_rclk; 2205 } 2206 if (hndotp_write_word(oh, cc, (oi->size / 2) + OTP_HWSIGN_OFF, 2207 OTP_SIGNATURE) != 0) { 2208 ret = BCME_NORESOURCE; 2209 goto out_rclk; 2210 } 2211 oi->boundary = lim * 2; 2212 oi->signvalid |= OTP_HW_REGION; 2213 } else if (region == OTP_SW_REGION) { 2214 if (hndotp_write_word(oh, cc, (oi->size / 2) + OTP_SWSIGN_OFF, 2215 OTP_SIGNATURE) != 0) { 2216 ret = BCME_NORESOURCE; 2217 goto out_rclk; 2218 } 2219 oi->signvalid |= OTP_SW_REGION; 2220 } else if (region == OTP_CID_REGION) { 2221 if (hndotp_write_word(oh, cc, (oi->size / 2) + OTP_CIDSIGN_OFF, 2222 OTP_SIGNATURE) != 0) { 2223 ret = BCME_NORESOURCE; 2224 goto out_rclk; 2225 } 2226 oi->signvalid |= OTP_CID_REGION; 2227 } 2228 2229out_rclk: 2230 /* Restore clock */ 2231 W_REG(oi->osh, &cc->clk_ctl_st, save_clk); 2232 2233out: 2234#if defined(WLTEST) 2235 OTP_MSG(("bits written: %d, average (%d/%d): %d, max retry: %d, pp max: %d\n", 2236 st_n, st_s, st_n, st_n?(st_s / st_n):0, st_hwm, pp_hwm)); 2237#endif 2238 2239 si_setcoreidx(oi->sih, idx); 2240 2241 return ret; 2242} 2243 2244/* For HND OTP, there's no space for appending after filling in SROM image */ 2245static int 2246hndotp_cis_append_region(si_t *sih, int region, char *vars, int count) 2247{ 2248 return otp_write_region(sih, region, (uint16*)vars, count/2); 2249} 2250 2251/* 2252 * Fill all unwritten RCE signature with 0 and return the number of them. 2253 * HNDOTP needs lock due to the randomness of unprogrammed content. 2254 */ 2255static int 2256hndotp_lock(void *oh) 2257{ 2258 otpinfo_t *oi = (otpinfo_t *)oh; 2259 int i, j, e, rcr, bit, ret = 0; 2260 uint32 st, idx; 2261 chipcregs_t *cc; 2262 2263 ASSERT(oi->ccrev >= 18); 2264 2265 idx = si_coreidx(oi->sih); 2266 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 2267 ASSERT(cc != NULL); 2268 2269 /* Region already written? */ 2270 st = oi->hwprot | oi-> signvalid; 2271 if ((st & (OTP_HW_REGION | OTP_SW_REGION)) == 0) { 2272 si_setcoreidx(oi->sih, idx); 2273 return BCME_NOTREADY; /* Don't lock unprogrammed OTP */ 2274 } 2275 2276 /* Find the highest valid RCE */ 2277 for (i = 0; i < OTP_RCE_ROW_SZ -1; i++) { 2278 if ((hndotp_valid_rce(oh, cc, i) != -1)) 2279 break; 2280 } 2281 i--; /* Start invalidating from the next RCE */ 2282 2283 for (; i >= 0; i--) { 2284 if ((hndotp_valid_rce(oh, cc, i) == -1)) { 2285 2286 ret++; /* This is a unprogrammed row */ 2287 2288 /* Invalidate the row with 0 */ 2289 if (i < 3) { 2290 e = i; 2291 rcr = hndotp_size(oh)/2 + OTP_RC0_OFF; 2292 } else { 2293 e = i - 3; 2294 rcr = hndotp_size(oh)/2 + OTP_RC1_OFF; 2295 } 2296 2297 /* Fill row numer and signature with 0 bit-by-bit */ 2298 bit = (rcr * 16 + rcr / 4) + e * OTP_RCE_BITS + OTP_RCE_BIT0; 2299 for (j = 0; j < (OTP_RCE_ROW_SZ + OTP_RCE_SIGN_SZ); j++) { 2300 hndotp_write_bit(oh, cc, bit, 0, 1); 2301 bit ++; 2302 } 2303 2304 OTP_MSG(("locking rce %d\n", i)); 2305 } 2306 } 2307 2308 si_setcoreidx(oi->sih, idx); 2309 2310 return ret; 2311} 2312 2313/* expects the caller to disable interrupts before calling this routine */ 2314static int 2315hndotp_nvwrite(void *oh, uint16 *data, uint wlen) 2316{ 2317 otpinfo_t *oi = (otpinfo_t *)oh; 2318 uint32 st; 2319 uint16 crc, clen, *p, hdr[2]; 2320 uint wn, base = 0, lim; 2321 int err, gerr = 0; 2322 uint idx; 2323 chipcregs_t *cc; 2324 2325 /* otp already written? */ 2326 st = oi->hwprot | oi-> signvalid; 2327 if ((st & (OTP_HW_REGION | OTP_SW_REGION)) == (OTP_HW_REGION | OTP_SW_REGION)) 2328 return BCME_EPERM; 2329 2330 /* save the orig core */ 2331 idx = si_coreidx(oi->sih); 2332 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 2333 ASSERT(cc != NULL); 2334 2335 /* Bounds for the region */ 2336 lim = (oi->size / 2) + OTP_SWLIM_OFF; 2337 base = 0; 2338 2339 /* Look for possible chunks from the end down */ 2340 wn = lim; 2341 while (wn > 0) { 2342 wn--; 2343 if (hndotp_otpr(oh, cc, wn) == OTP_MAGIC) { 2344 base = wn + (hndotp_otpr(oh, cc, wn + 1) / 2); 2345 break; 2346 } 2347 } 2348 if (base == 0) { 2349 OTP_MSG(("Unprogrammed otp\n")); 2350 } else { 2351 OTP_MSG(("Found some chunks, skipping to 0x%x\n", base * 2)); 2352 } 2353 if ((wlen + 3) > (lim - base)) { 2354 err = BCME_NORESOURCE; 2355 goto out; 2356 } 2357 2358#if defined(WLTEST) 2359 st_n = st_s = st_hwm = pp_hwm = 0; 2360#endif 2361 2362 /* Prepare the header and crc */ 2363 hdr[0] = OTP_MAGIC; 2364 hdr[1] = (wlen + 3) * 2; 2365 crc = hndcrc16((uint8 *)hdr, sizeof(hdr), CRC16_INIT_VALUE); 2366 crc = hndcrc16((uint8 *)data, wlen * 2, crc); 2367 crc = ~crc; 2368 2369 do { 2370 p = data; 2371 wn = base + 2; 2372 lim = base + wlen + 2; 2373 2374 OTP_MSG(("writing chunk, 0x%x bytes @ 0x%x-0x%x\n", wlen * 2, 2375 base * 2, (lim + 1) * 2)); 2376 2377 /* Write the header */ 2378 err = hndotp_write_word(oh, cc, base, hdr[0]); 2379 2380 /* Write the data */ 2381 while (wn < lim) { 2382 err += hndotp_write_word(oh, cc, wn++, *p++); 2383 2384 /* If there has been an error, close this chunk */ 2385 if (err != 0) { 2386 OTP_MSG(("closing early @ 0x%x\n", wn * 2)); 2387 break; 2388 } 2389 } 2390 2391 /* If we wrote the whole chunk, write the crc */ 2392 if (wn == lim) { 2393 OTP_MSG((" whole chunk written, crc = 0x%x\n", crc)); 2394 err += hndotp_write_word(oh, cc, wn++, crc); 2395 clen = hdr[1]; 2396 } else { 2397 /* If there was an error adjust the count to point to 2398 * the word after the error so we can start the next 2399 * chunk there. 2400 */ 2401 clen = (wn - base) * 2; 2402 OTP_MSG((" partial chunk written, chunk len = 0x%x\n", clen)); 2403 } 2404 /* And now write the chunk length */ 2405 err += hndotp_write_word(oh, cc, base + 1, clen); 2406 2407 if (base == 0) { 2408 /* Write the signature and boundary if this is the HW region, 2409 * but don't report failure if either of these 2 writes fail. 2410 */ 2411 if (hndotp_write_word(oh, cc, (oi->size / 2) + OTP_BOUNDARY_OFF, 2412 wn * 2) == 0) 2413 gerr += hndotp_write_word(oh, cc, (oi->size / 2) + OTP_HWSIGN_OFF, 2414 OTP_SIGNATURE); 2415 else 2416 gerr++; 2417 oi->boundary = wn * 2; 2418 oi->signvalid |= OTP_HW_REGION; 2419 } 2420 2421 if (err != 0) { 2422 gerr += err; 2423 /* Errors, do it all over again if there is space left */ 2424 if ((wlen + 3) <= ((oi->size / 2) + OTP_SWLIM_OFF - wn)) { 2425 base = wn; 2426 lim = base + wlen + 2; 2427 OTP_ERR(("Programming errors, retry @ 0x%x\n", wn * 2)); 2428 } else { 2429 OTP_ERR(("Programming errors, no space left ( 0x%x)\n", wn * 2)); 2430 break; 2431 } 2432 } 2433 } while (err != 0); 2434 2435 OTP_MSG(("bits written: %d, average (%d/%d): %d, max retry: %d, pp max: %d\n", 2436 st_n, st_s, st_n, st_s / st_n, st_hwm, pp_hwm)); 2437 2438 if (gerr != 0) 2439 OTP_MSG(("programming %s after %d errors\n", (err == 0) ? "succedded" : "failed", 2440 gerr)); 2441out: 2442 /* done */ 2443 si_setcoreidx(oi->sih, idx); 2444 2445 if (err) 2446 return BCME_ERROR; 2447 else 2448 return 0; 2449} 2450#endif /* BCMNVRAMW */ 2451 2452#if defined(WLTEST) 2453static uint16 2454hndotp_otprb16(void *oh, chipcregs_t *cc, uint wn) 2455{ 2456 uint base, i; 2457 uint16 val, bit; 2458 2459 base = (wn * 16) + (wn / 4); 2460 val = 0; 2461 for (i = 0; i < 16; i++) { 2462 if ((bit = hndotp_read_bit(oh, cc, base + i)) == 0xffff) 2463 break; 2464 val = val | (bit << i); 2465 } 2466 if (i < 16) 2467 val = 0xaaaa; 2468 return val; 2469} 2470 2471static int 2472hndotp_dump(void *oh, int arg, char *buf, uint size) 2473{ 2474 otpinfo_t *oi = (otpinfo_t *)oh; 2475 chipcregs_t *cc; 2476 uint idx, i, count, lil; 2477 uint16 val; 2478 struct bcmstrbuf b; 2479 2480 idx = si_coreidx(oi->sih); 2481 cc = si_setcoreidx(oi->sih, SI_CC_IDX); 2482 ASSERT(cc != NULL); 2483 2484 if (arg >= 16) 2485 arg -= 16; 2486 2487 if (arg == 2) { 2488 count = 66 * 4; 2489 lil = 3; 2490 } else { 2491 count = (oi->size / 2) + OTP_RC_LIM_OFF; 2492 lil = 7; 2493 } 2494 2495 OTP_MSG(("%s: arg %d, size %d, words %d\n", __FUNCTION__, arg, size, count)); 2496 bcm_binit(&b, buf, size); 2497 for (i = 0; i < count; i++) { 2498 if ((i & lil) == 0) 2499 bcm_bprintf(&b, "0x%04x:", 2 * i); 2500 2501 if (arg == 0) 2502 val = hndotp_otpr(oh, cc, i); 2503 else 2504 val = hndotp_otprb16(oi, cc, i); 2505 bcm_bprintf(&b, " 0x%04x", val); 2506 if ((i & lil) == lil) { 2507 if (arg == 2) { 2508 bcm_bprintf(&b, " %d\n", 2509 hndotp_read_bit(oh, cc, ((i / 4) * 65) + 64) & 1); 2510 } else { 2511 bcm_bprintf(&b, "\n"); 2512 } 2513 } 2514 } 2515 if ((i & lil) != lil) 2516 bcm_bprintf(&b, "\n"); 2517 2518 OTP_MSG(("%s: returning %d, left %d, wn %d\n", 2519 __FUNCTION__, (int)(b.buf - b.origbuf), b.size, i)); 2520 2521 si_setcoreidx(oi->sih, idx); 2522 2523 return ((int)(b.buf - b.origbuf)); 2524} 2525#endif 2526 2527static otp_fn_t hndotp_fn = { 2528 (otp_size_t)hndotp_size, 2529 (otp_read_bit_t)hndotp_read_bit, 2530 2531 (otp_init_t)hndotp_init, 2532 (otp_read_region_t)hndotp_read_region, 2533 (otp_nvread_t)hndotp_nvread, 2534#ifdef BCMNVRAMW 2535 (otp_write_region_t)hndotp_write_region, 2536 (otp_cis_append_region_t)hndotp_cis_append_region, 2537 (otp_lock_t)hndotp_lock, 2538 (otp_nvwrite_t)hndotp_nvwrite, 2539#endif /* BCMNVRAMW */ 2540 2541#if defined(WLTEST) 2542 (otp_dump_t)hndotp_dump, 2543#endif 2544 2545 (otp_status_t)hndotp_status, 2546#ifdef BCMNVRAMW 2547 (otp_write_word_t)NULL, 2548#endif /* BCMNVRAMW */ 2549 (otp_read_word_t)hndotp_read_word, 2550}; 2551 2552#endif /* BCMHNDOTP */ 2553 2554/* 2555 * Common Code: Compiled for IPX / HND / AUTO 2556 * otp_status() 2557 * otp_size() 2558 * otp_read_bit() 2559 * otp_init() 2560 * otp_read_region() 2561 * otp_read_word() 2562 * otp_nvread() 2563 * otp_write_region() 2564 * otp_write_word() 2565 * otp_cis_append_region() 2566 * otp_lock() 2567 * otp_nvwrite() 2568 * otp_dump() 2569 */ 2570 2571int 2572otp_status(void *oh) 2573{ 2574 otpinfo_t *oi = (otpinfo_t *)oh; 2575 2576 return oi->fn->status(oh); 2577} 2578 2579int 2580otp_size(void *oh) 2581{ 2582 otpinfo_t *oi = (otpinfo_t *)oh; 2583 2584 return oi->fn->size(oh); 2585} 2586 2587uint16 2588otp_read_bit(void *oh, uint offset) 2589{ 2590 otpinfo_t *oi = (otpinfo_t *)oh; 2591 uint idx = si_coreidx(oi->sih); 2592 chipcregs_t *cc = si_setcoreidx(oi->sih, SI_CC_IDX); 2593 uint16 readBit = (uint16)oi->fn->read_bit(oh, cc, offset); 2594 si_setcoreidx(oi->sih, idx); 2595 return readBit; 2596} 2597 2598void * 2599BCMNMIATTACHFN(otp_init)(si_t *sih) 2600{ 2601 otpinfo_t *oi; 2602 void *ret = NULL; 2603 2604 oi = &otpinfo; 2605 bzero(oi, sizeof(otpinfo_t)); 2606 2607 oi->ccrev = sih->ccrev; 2608 2609#ifdef BCMIPXOTP 2610 if (OTPTYPE_IPX(oi->ccrev)) 2611 oi->fn = &ipxotp_fn; 2612#endif 2613 2614#ifdef BCMHNDOTP 2615 if (OTPTYPE_HND(oi->ccrev)) 2616 oi->fn = &hndotp_fn; 2617#endif 2618 2619 if (oi->fn == NULL) { 2620 OTP_ERR(("otp_init: unsupported OTP type\n")); 2621 return NULL; 2622 } 2623 2624 oi->sih = sih; 2625 oi->osh = si_osh(oi->sih); 2626 2627 ret = (oi->fn->init)(sih); 2628 2629 return ret; 2630} 2631 2632int 2633BCMNMIATTACHFN(otp_read_region)(si_t *sih, int region, uint16 *data, uint *wlen) 2634{ 2635 bool wasup = FALSE; 2636 void *oh; 2637 int err = 0; 2638 2639 if (!(wasup = si_is_otp_powered(sih))) 2640 si_otp_power(sih, TRUE); 2641 2642 if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) { 2643 err = BCME_NOTREADY; 2644 goto out; 2645 } 2646 2647 oh = otp_init(sih); 2648 if (oh == NULL) { 2649 OTP_ERR(("otp_init failed.\n")); 2650 err = BCME_ERROR; 2651 goto out; 2652 } 2653 2654 err = (((otpinfo_t*)oh)->fn->read_region)(oh, region, data, wlen); 2655 2656out: 2657 if (!wasup) 2658 si_otp_power(sih, FALSE); 2659 2660 return err; 2661} 2662 2663int 2664otp_read_word(si_t *sih, uint wn, uint16 *data) 2665{ 2666 bool wasup = FALSE; 2667 void *oh; 2668 int err = 0; 2669 2670 if (!(wasup = si_is_otp_powered(sih))) 2671 si_otp_power(sih, TRUE); 2672 2673 if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) { 2674 err = BCME_NOTREADY; 2675 goto out; 2676 } 2677 2678 oh = otp_init(sih); 2679 if (oh == NULL) { 2680 OTP_ERR(("otp_init failed.\n")); 2681 err = BCME_ERROR; 2682 goto out; 2683 } 2684 2685 if (((otpinfo_t*)oh)->fn->read_word == NULL) { 2686 err = BCME_UNSUPPORTED; 2687 goto out; 2688 } 2689 err = (((otpinfo_t*)oh)->fn->read_word)(oh, wn, data); 2690 2691out: 2692 if (!wasup) 2693 si_otp_power(sih, FALSE); 2694 2695 return err; 2696} 2697 2698int 2699otp_nvread(void *oh, char *data, uint *len) 2700{ 2701 otpinfo_t *oi = (otpinfo_t *)oh; 2702 2703 return oi->fn->nvread(oh, data, len); 2704} 2705 2706#ifdef BCMNVRAMW 2707int 2708BCMNMIATTACHFN(otp_write_region)(si_t *sih, int region, uint16 *data, uint wlen) 2709{ 2710 bool wasup = FALSE; 2711 void *oh; 2712 int err = 0; 2713 2714 if (!(wasup = si_is_otp_powered(sih))) 2715 si_otp_power(sih, TRUE); 2716 2717 if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) { 2718 err = BCME_NOTREADY; 2719 goto out; 2720 } 2721 2722 oh = otp_init(sih); 2723 if (oh == NULL) { 2724 OTP_ERR(("otp_init failed.\n")); 2725 err = BCME_ERROR; 2726 goto out; 2727 } 2728 2729 err = (((otpinfo_t*)oh)->fn->write_region)(oh, region, data, wlen); 2730 2731out: 2732 if (!wasup) 2733 si_otp_power(sih, FALSE); 2734 2735 return err; 2736} 2737 2738int 2739otp_write_word(si_t *sih, uint wn, uint16 data) 2740{ 2741 bool wasup = FALSE; 2742 void *oh; 2743 int err = 0; 2744 2745 if (!(wasup = si_is_otp_powered(sih))) 2746 si_otp_power(sih, TRUE); 2747 2748 if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) { 2749 err = BCME_NOTREADY; 2750 goto out; 2751 } 2752 2753 oh = otp_init(sih); 2754 if (oh == NULL) { 2755 OTP_ERR(("otp_init failed.\n")); 2756 err = BCME_ERROR; 2757 goto out; 2758 } 2759 2760 if (((otpinfo_t*)oh)->fn->write_word == NULL) { 2761 err = BCME_UNSUPPORTED; 2762 goto out; 2763 } 2764 err = (((otpinfo_t*)oh)->fn->write_word)(oh, wn, data); 2765 2766out: 2767 if (!wasup) 2768 si_otp_power(sih, FALSE); 2769 2770 return err; 2771} 2772 2773int 2774otp_cis_append_region(si_t *sih, int region, char *vars, int count) 2775{ 2776 void *oh = otp_init(sih); 2777 2778 if (oh == NULL) { 2779 OTP_ERR(("otp_init failed.\n")); 2780 return -1; 2781 } 2782 return (((otpinfo_t*)oh)->fn->cis_append_region)(sih, region, vars, count); 2783} 2784 2785int 2786otp_lock(si_t *sih) 2787{ 2788 bool wasup = FALSE; 2789 void *oh; 2790 int ret = 0; 2791 2792 if (!(wasup = si_is_otp_powered(sih))) 2793 si_otp_power(sih, TRUE); 2794 2795 if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) { 2796 ret = BCME_NOTREADY; 2797 goto out; 2798 } 2799 2800 oh = otp_init(sih); 2801 if (oh == NULL) { 2802 OTP_ERR(("otp_init failed.\n")); 2803 ret = BCME_ERROR; 2804 goto out; 2805 } 2806 2807 ret = (((otpinfo_t*)oh)->fn->lock)(oh); 2808 2809out: 2810 if (!wasup) 2811 si_otp_power(sih, FALSE); 2812 2813 return ret; 2814} 2815 2816int 2817otp_nvwrite(void *oh, uint16 *data, uint wlen) 2818{ 2819 otpinfo_t *oi = (otpinfo_t *)oh; 2820 2821 return oi->fn->nvwrite(oh, data, wlen); 2822} 2823#endif /* BCMNVRAMW */ 2824 2825#if defined(WLTEST) 2826int 2827otp_dump(void *oh, int arg, char *buf, uint size) 2828{ 2829 otpinfo_t *oi = (otpinfo_t *)oh; 2830 2831 return oi->fn->dump(oh, arg, buf, size); 2832} 2833 2834int 2835otp_dumpstats(void *oh, int arg, char *buf, uint size) 2836{ 2837 otpinfo_t *oi = (otpinfo_t *)oh; 2838 struct bcmstrbuf b; 2839 2840 bcm_binit(&b, buf, size); 2841 2842 bcm_bprintf(&b, "\nOTP, ccrev 0x%04x\n", oi->ccrev); 2843#if defined(BCMIPXOTP) 2844 bcm_bprintf(&b, "wsize %d rows %d cols %d\n", oi->wsize, oi->rows, oi->cols); 2845 bcm_bprintf(&b, "hwbase %d hwlim %d swbase %d swlim %d fusebits %d\n", 2846 oi->hwbase, oi->hwlim, oi->swbase, oi->swlim, oi->fbase, oi->flim, oi->fusebits); 2847 bcm_bprintf(&b, "otpgu_base %d status %d\n", oi->otpgu_base, oi->status); 2848#endif 2849#if defined(BCMHNDOTP) 2850 bcm_bprintf(&b, "OLD OTP, size %d hwprot 0x%x signvalid 0x%x boundary %d\n", 2851 oi->size, oi->hwprot, oi->signvalid, oi->boundary); 2852#endif 2853 bcm_bprintf(&b, "\n"); 2854 2855 return 200; /* real buf length, pick one to cover above print */ 2856} 2857 2858#endif 2859