/*
 * Copyright (c) 2010 Broadcom Corporation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <bcmdefs.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <bcmdevs.h>
#include <bcmutils.h>
#include <siutils.h>
#include <hndsoc.h>
#include <sbchipc.h>
#include <bcmotp.h>
#include "siutils_priv.h"

/*
 * There are two different OTP controllers so far:
 * 	1. new IPX OTP controller:	chipc 21, >=23
 * 	2. older HND OTP controller:	chipc 12, 17, 22
 *
 * Define BCMHNDOTP to include support for the HND OTP controller.
 * Define BCMIPXOTP to include support for the IPX OTP controller.
 *
 * NOTE 1: More than one may be defined
 * NOTE 2: If none are defined, the default is to include them all.
 */

#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
#define BCMHNDOTP	1
#define BCMIPXOTP	1
#endif

#define OTPTYPE_HND(ccrev)	((ccrev) < 21 || (ccrev) == 22)
#define OTPTYPE_IPX(ccrev)	((ccrev) == 21 || (ccrev) >= 23)

#define OTPP_TRIES	10000000	/* # of tries for OTPP */

#ifdef BCMIPXOTP
#define MAXNUMRDES		9	/* Maximum OTP redundancy entries */
#endif

/* OTP common function type */
typedef int (*otp_status_t) (void *oh);
typedef int (*otp_size_t) (void *oh);
typedef void *(*otp_init_t) (si_t *sih);
typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
				  uint *wlen);
typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);

/* OTP function struct */
typedef struct otp_fn_s {
	otp_size_t size;
	otp_read_bit_t read_bit;
	otp_init_t init;
	otp_read_region_t read_region;
	otp_nvread_t nvread;
	otp_status_t status;
} otp_fn_t;

typedef struct {
	uint ccrev;		/* chipc revision */
	otp_fn_t *fn;		/* OTP functions */
	si_t *sih;		/* Saved sb handle */

#ifdef BCMIPXOTP
	/* IPX OTP section */
	u16 wsize;		/* Size of otp in words */
	u16 rows;		/* Geometry */
	u16 cols;		/* Geometry */
	u32 status;		/* Flag bits (lock/prog/rv).
				 * (Reflected only when OTP is power cycled)
				 */
	u16 hwbase;		/* hardware subregion offset */
	u16 hwlim;		/* hardware subregion boundary */
	u16 swbase;		/* software subregion offset */
	u16 swlim;		/* software subregion boundary */
	u16 fbase;		/* fuse subregion offset */
	u16 flim;		/* fuse subregion boundary */
	int otpgu_base;		/* offset to General Use Region */
#endif				/* BCMIPXOTP */

#ifdef BCMHNDOTP
	/* HND OTP section */
	uint size;		/* Size of otp in bytes */
	uint hwprot;		/* Hardware protection bits */
	uint signvalid;		/* Signature valid bits */
	int boundary;		/* hw/sw boundary */
#endif				/* BCMHNDOTP */
} otpinfo_t;

static otpinfo_t otpinfo;

/*
 * IPX OTP Code
 *
 *   Exported functions:
 *	ipxotp_status()
 *	ipxotp_size()
 *	ipxotp_init()
 *	ipxotp_read_bit()
 *	ipxotp_read_region()
 *	ipxotp_nvread()
 *
 */

#ifdef BCMIPXOTP

#define HWSW_RGN(rgn)		(((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")

/* OTP layout */
/* CC revs 21, 24 and 27 OTP General Use Region word offset */
#define REVA4_OTPGU_BASE	12

/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
#define REVB8_OTPGU_BASE	20

/* CC rev 36 OTP General Use Region word offset */
#define REV36_OTPGU_BASE	12

/* Subregion word offsets in General Use region */
#define OTPGU_HSB_OFF		0
#define OTPGU_SFB_OFF		1
#define OTPGU_CI_OFF		2
#define OTPGU_P_OFF		3
#define OTPGU_SROM_OFF		4

/* Flag bit offsets in General Use region  */
#define OTPGU_HWP_OFF		60
#define OTPGU_SWP_OFF		61
#define OTPGU_CIP_OFF		62
#define OTPGU_FUSEP_OFF		63
#define OTPGU_CIP_MSK		0x4000
#define OTPGU_P_MSK		0xf000
#define OTPGU_P_SHIFT		(OTPGU_HWP_OFF % 16)

/* OTP Size */
#define OTP_SZ_FU_324		((roundup(324, 8))/8)	/* 324 bits */
#define OTP_SZ_FU_288		(288/8)	/* 288 bits */
#define OTP_SZ_FU_216		(216/8)	/* 216 bits */
#define OTP_SZ_FU_72		(72/8)	/* 72 bits */
#define OTP_SZ_CHECKSUM		(16/8)	/* 16 bits */
#define OTP4315_SWREG_SZ	178	/* 178 bytes */
#define OTP_SZ_FU_144		(144/8)	/* 144 bits */

static int ipxotp_status(void *oh)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	return (int)(oi->status);
}

/* Return size in bytes */
static int ipxotp_size(void *oh)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	return (int)oi->wsize * 2;
}

static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
{
	otpinfo_t *oi;

	oi = (otpinfo_t *) oh;

	ASSERT(wn < oi->wsize);
	ASSERT(cc != NULL);

	return R_REG(&cc->sromotp[wn]);
}

static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	uint k, row, col;
	u32 otpp, st;

	row = off / oi->cols;
	col = off % oi->cols;

	otpp = OTPP_START_BUSY |
	    ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
	    ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
	W_REG(&cc->otpprog, otpp);

	for (k = 0;
	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
	     && (k < OTPP_TRIES); k++)
		;
	if (k >= OTPP_TRIES) {
		return 0xffff;
	}
	if (st & OTPP_READERR) {
		return 0xffff;
	}
	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;

	return (int)st;
}

/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
 * osizew is oi->wsize (OTP size - GU size) in words
 */
static int ipxotp_max_rgnsz(si_t *sih, int osizew)
{
	int ret = 0;

	switch (sih->chip) {
	case BCM43224_CHIP_ID:
	case BCM43225_CHIP_ID:
		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
		break;
	case BCM4313_CHIP_ID:
		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
		break;
	default:
		ASSERT(0);	/* Don't know about this chip */
	}

	return ret;
}

static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc)
{
	uint k;
	u32 otpp, st;

	/* record word offset of General Use Region for various chipcommon revs */
	if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
	    || oi->sih->ccrev == 27) {
		oi->otpgu_base = REVA4_OTPGU_BASE;
	} else if (oi->sih->ccrev == 36) {
		/* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
		if (oi->wsize >= 128)
			oi->otpgu_base = REVB8_OTPGU_BASE;
		else
			oi->otpgu_base = REV36_OTPGU_BASE;
	} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
		oi->otpgu_base = REVB8_OTPGU_BASE;
	}

	/* First issue an init command so the status is up to date */
	otpp =
	    OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);

	W_REG(&cc->otpprog, otpp);
	for (k = 0;
	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
	     && (k < OTPP_TRIES); k++)
		;
	if (k >= OTPP_TRIES) {
		return;
	}

	/* Read OTP lock bits and subregion programmed indication bits */
	oi->status = R_REG(&cc->otpstatus);

	if ((oi->sih->chip == BCM43224_CHIP_ID)
	    || (oi->sih->chip == BCM43225_CHIP_ID)) {
		u32 p_bits;
		p_bits =
		    (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
		     OTPGU_P_MSK)
		    >> OTPGU_P_SHIFT;
		oi->status |= (p_bits << OTPS_GUP_SHIFT);
	}

	/*
	 * h/w region base and fuse region limit are fixed to the top and
	 * the bottom of the general use region. Everything else can be flexible.
	 */
	oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
	oi->hwlim = oi->wsize;
	if (oi->status & OTPS_GUP_HW) {
		oi->hwlim =
		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
		oi->swbase = oi->hwlim;
	} else
		oi->swbase = oi->hwbase;

	/* subtract fuse and checksum from beginning */
	oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;

	if (oi->status & OTPS_GUP_SW) {
		oi->swlim =
		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
		oi->fbase = oi->swlim;
	} else
		oi->fbase = oi->swbase;

	oi->flim = oi->wsize;
}

static void *ipxotp_init(si_t *sih)
{
	uint idx;
	chipcregs_t *cc;
	otpinfo_t *oi;

	/* Make sure we're running IPX OTP */
	ASSERT(OTPTYPE_IPX(sih->ccrev));
	if (!OTPTYPE_IPX(sih->ccrev))
		return NULL;

	/* Make sure OTP is not disabled */
	if (si_is_otp_disabled(sih)) {
		return NULL;
	}

	/* Make sure OTP is powered up */
	if (!si_is_otp_powered(sih)) {
		return NULL;
	}

	oi = &otpinfo;

	/* Check for otp size */
	switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
	case 0:
		/* Nothing there */
		return NULL;
	case 1:		/* 32x64 */
		oi->rows = 32;
		oi->cols = 64;
		oi->wsize = 128;
		break;
	case 2:		/* 64x64 */
		oi->rows = 64;
		oi->cols = 64;
		oi->wsize = 256;
		break;
	case 5:		/* 96x64 */
		oi->rows = 96;
		oi->cols = 64;
		oi->wsize = 384;
		break;
	case 7:		/* 16x64 *//* 1024 bits */
		oi->rows = 16;
		oi->cols = 64;
		oi->wsize = 64;
		break;
	default:
		/* Don't know the geometry */
		return NULL;
	}

	/* Retrieve OTP region info */
	idx = si_coreidx(sih);
	cc = si_setcoreidx(sih, SI_CC_IDX);
	ASSERT(cc != NULL);

	_ipxotp_init(oi, cc);

	si_setcoreidx(sih, idx);

	return (void *)oi;
}

static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	uint idx;
	chipcregs_t *cc;
	uint base, i, sz;

	/* Validate region selection */
	switch (region) {
	case OTP_HW_RGN:
		sz = (uint) oi->hwlim - oi->hwbase;
		if (!(oi->status & OTPS_GUP_HW)) {
			*wlen = sz;
			return BCME_NOTFOUND;
		}
		if (*wlen < sz) {
			*wlen = sz;
			return BCME_BUFTOOSHORT;
		}
		base = oi->hwbase;
		break;
	case OTP_SW_RGN:
		sz = ((uint) oi->swlim - oi->swbase);
		if (!(oi->status & OTPS_GUP_SW)) {
			*wlen = sz;
			return BCME_NOTFOUND;
		}
		if (*wlen < sz) {
			*wlen = sz;
			return BCME_BUFTOOSHORT;
		}
		base = oi->swbase;
		break;
	case OTP_CI_RGN:
		sz = OTPGU_CI_SZ;
		if (!(oi->status & OTPS_GUP_CI)) {
			*wlen = sz;
			return BCME_NOTFOUND;
		}
		if (*wlen < sz) {
			*wlen = sz;
			return BCME_BUFTOOSHORT;
		}
		base = oi->otpgu_base + OTPGU_CI_OFF;
		break;
	case OTP_FUSE_RGN:
		sz = (uint) oi->flim - oi->fbase;
		if (!(oi->status & OTPS_GUP_FUSE)) {
			*wlen = sz;
			return BCME_NOTFOUND;
		}
		if (*wlen < sz) {
			*wlen = sz;
			return BCME_BUFTOOSHORT;
		}
		base = oi->fbase;
		break;
	case OTP_ALL_RGN:
		sz = ((uint) oi->flim - oi->hwbase);
		if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
			*wlen = sz;
			return BCME_NOTFOUND;
		}
		if (*wlen < sz) {
			*wlen = sz;
			return BCME_BUFTOOSHORT;
		}
		base = oi->hwbase;
		break;
	default:
		return BCME_BADARG;
	}

	idx = si_coreidx(oi->sih);
	cc = si_setcoreidx(oi->sih, SI_CC_IDX);
	ASSERT(cc != NULL);

	/* Read the data */
	for (i = 0; i < sz; i++)
		data[i] = ipxotp_otpr(oh, cc, base + i);

	si_setcoreidx(oi->sih, idx);
	*wlen = sz;
	return 0;
}

static int ipxotp_nvread(void *oh, char *data, uint *len)
{
	return BCME_UNSUPPORTED;
}

static otp_fn_t ipxotp_fn = {
	(otp_size_t) ipxotp_size,
	(otp_read_bit_t) ipxotp_read_bit,

	(otp_init_t) ipxotp_init,
	(otp_read_region_t) ipxotp_read_region,
	(otp_nvread_t) ipxotp_nvread,

	(otp_status_t) ipxotp_status
};

#endif				/* BCMIPXOTP */

/*
 * HND OTP Code
 *
 *   Exported functions:
 *	hndotp_status()
 *	hndotp_size()
 *	hndotp_init()
 *	hndotp_read_bit()
 *	hndotp_read_region()
 *	hndotp_nvread()
 *
 */

#ifdef BCMHNDOTP

/* Fields in otpstatus */
#define	OTPS_PROGFAIL		0x80000000
#define	OTPS_PROTECT		0x00000007
#define	OTPS_HW_PROTECT		0x00000001
#define	OTPS_SW_PROTECT		0x00000002
#define	OTPS_CID_PROTECT	0x00000004
#define	OTPS_RCEV_MSK		0x00003f00
#define	OTPS_RCEV_SHIFT		8

/* Fields in the otpcontrol register */
#define	OTPC_RECWAIT		0xff000000
#define	OTPC_PROGWAIT		0x00ffff00
#define	OTPC_PRW_SHIFT		8
#define	OTPC_MAXFAIL		0x00000038
#define	OTPC_VSEL		0x00000006
#define	OTPC_SELVL		0x00000001

/* OTP regions (Word offsets from otp size) */
#define	OTP_SWLIM_OFF	(-4)
#define	OTP_CIDBASE_OFF	0
#define	OTP_CIDLIM_OFF	4

/* Predefined OTP words (Word offset from otp size) */
#define	OTP_BOUNDARY_OFF (-4)
#define	OTP_HWSIGN_OFF	(-3)
#define	OTP_SWSIGN_OFF	(-2)
#define	OTP_CIDSIGN_OFF	(-1)
#define	OTP_CID_OFF	0
#define	OTP_PKG_OFF	1
#define	OTP_FID_OFF	2
#define	OTP_RSV_OFF	3
#define	OTP_LIM_OFF	4
#define	OTP_RD_OFF	4	/* Redundancy row starts here */
#define	OTP_RC0_OFF	28	/* Redundancy control word 1 */
#define	OTP_RC1_OFF	32	/* Redundancy control word 2 */
#define	OTP_RC_LIM_OFF	36	/* Redundancy control word end */

#define	OTP_HW_REGION	OTPS_HW_PROTECT
#define	OTP_SW_REGION	OTPS_SW_PROTECT
#define	OTP_CID_REGION	OTPS_CID_PROTECT

#if OTP_HW_REGION != OTP_HW_RGN
#error "incompatible OTP_HW_RGN"
#endif
#if OTP_SW_REGION != OTP_SW_RGN
#error "incompatible OTP_SW_RGN"
#endif
#if OTP_CID_REGION != OTP_CI_RGN
#error "incompatible OTP_CI_RGN"
#endif

/* Redundancy entry definitions */
#define	OTP_RCE_ROW_SZ		6
#define	OTP_RCE_SIGN_MASK	0x7fff
#define	OTP_RCE_ROW_MASK	0x3f
#define	OTP_RCE_BITS		21
#define	OTP_RCE_SIGN_SZ		15
#define	OTP_RCE_BIT0		1

#define	OTP_WPR		4
#define	OTP_SIGNATURE	0x578a
#define	OTP_MAGIC	0x4e56

static int hndotp_status(void *oh)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	return (int)(oi->hwprot | oi->signvalid);
}

static int hndotp_size(void *oh)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	return (int)(oi->size);
}

static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
{
#ifdef BCMDBG
	otpinfo_t *oi = (otpinfo_t *) oh;
#endif
	volatile u16 *ptr;

	ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF));
	ASSERT(cc != NULL);

	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
	return R_REG(&ptr[wn]);
}

static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	volatile u16 *ptr;

	ASSERT(woff >= (-((int)oi->size / 2)));
	ASSERT(woff < OTP_LIM_OFF);
	ASSERT(cc != NULL);

	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);

	return R_REG(&ptr[(oi->size / 2) + woff]);
}

static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
{
	uint k, row, col;
	u32 otpp, st;

	row = idx / 65;
	col = idx % 65;

	otpp = OTPP_START_BUSY | OTPP_READ |
	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);

	W_REG(&cc->otpprog, otpp);
	st = R_REG(&cc->otpprog);
	for (k = 0;
	     ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
	     k++)
		st = R_REG(&cc->otpprog);

	if (k >= OTPP_TRIES) {
		return 0xffff;
	}
	if (st & OTPP_READERR) {
		return 0xffff;
	}
	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
	return (u16) st;
}

static void *hndotp_init(si_t *sih)
{
	uint idx;
	chipcregs_t *cc;
	otpinfo_t *oi;
	u32 cap = 0, clkdiv, otpdiv = 0;
	void *ret = NULL;

	oi = &otpinfo;

	idx = si_coreidx(sih);

	/* Check for otp */
	cc = si_setcoreidx(sih, SI_CC_IDX);
	if (cc != NULL) {
		cap = R_REG(&cc->capabilities);
		if ((cap & CC_CAP_OTPSIZE) == 0) {
			/* Nothing there */
			goto out;
		}

		/* As of right now, support only 4320a2, 4311a1 and 4312 */
		ASSERT((oi->ccrev == 12) || (oi->ccrev == 17)
		       || (oi->ccrev == 22));
		if (!
		    ((oi->ccrev == 12) || (oi->ccrev == 17)
		     || (oi->ccrev == 22)))
			return NULL;

		/* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
		 * 8 row (64 bytes) smaller
		 */
		oi->size =
		    1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
			  + CC_CAP_OTPSIZE_BASE);
		if (oi->ccrev >= 18)
			oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);

		oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
		oi->boundary = -1;

		/* Check the region signature */
		if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
			oi->signvalid |= OTP_HW_REGION;
			oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
		}

		if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
			oi->signvalid |= OTP_SW_REGION;

		if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
			oi->signvalid |= OTP_CID_REGION;

		/* Set OTP clkdiv for stability */
		if (oi->ccrev == 22)
			otpdiv = 12;

		if (otpdiv) {
			clkdiv = R_REG(&cc->clkdiv);
			clkdiv =
			    (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
			W_REG(&cc->clkdiv, clkdiv);
		}
		udelay(10);

		ret = (void *)oi;
	}

 out:				/* All done */
	si_setcoreidx(sih, idx);

	return ret;
}

static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	u32 idx, st;
	chipcregs_t *cc;
	int i;

	/* Only support HW region (no active chips use HND OTP SW region) */
	ASSERT(region == OTP_HW_REGION);

	/* Region empty? */
	st = oi->hwprot | oi->signvalid;
	if ((st & region) == 0)
		return BCME_NOTFOUND;

	*wlen =
	    ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;

	idx = si_coreidx(oi->sih);
	cc = si_setcoreidx(oi->sih, SI_CC_IDX);
	ASSERT(cc != NULL);

	for (i = 0; i < (int)*wlen; i++)
		data[i] = hndotp_otpr(oh, cc, i);

	si_setcoreidx(oi->sih, idx);

	return 0;
}

static int hndotp_nvread(void *oh, char *data, uint *len)
{
	int rc = 0;
	otpinfo_t *oi = (otpinfo_t *) oh;
	u32 base, bound, lim = 0, st;
	int i, chunk, gchunks, tsz = 0;
	u32 idx;
	chipcregs_t *cc;
	uint offset;
	u16 *rawotp = NULL;

	/* save the orig core */
	idx = si_coreidx(oi->sih);
	cc = si_setcoreidx(oi->sih, SI_CC_IDX);
	ASSERT(cc != NULL);

	st = hndotp_status(oh);
	if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
		rc = -1;
		goto out;
	}

	/* Read the whole otp so we can easily manipulate it */
	lim = hndotp_size(oh);
	rawotp = kmalloc(lim, GFP_ATOMIC);
	if (rawotp == NULL) {
		rc = -2;
		goto out;
	}
	for (i = 0; i < (int)(lim / 2); i++)
		rawotp[i] = hndotp_otpr(oh, cc, i);

	if ((st & OTP_HW_REGION) == 0) {
		/* This could be a programming failure in the first
		 * chunk followed by one or more good chunks
		 */
		for (i = 0; i < (int)(lim / 2); i++)
			if (rawotp[i] == OTP_MAGIC)
				break;

		if (i < (int)(lim / 2)) {
			base = i;
			bound = (i * 2) + rawotp[i + 1];
		} else {
			rc = -3;
			goto out;
		}
	} else {
		bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];

		/* There are two cases: 1) The whole otp is used as nvram
		 * and 2) There is a hardware header followed by nvram.
		 */
		if (rawotp[0] == OTP_MAGIC) {
			base = 0;
		} else
			base = bound;
	}

	/* Find and copy the data */

	chunk = 0;
	gchunks = 0;
	i = base / 2;
	offset = 0;
	while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
		int dsz, rsz = rawotp[i + 1];

		if (((i * 2) + rsz) >= (int)lim) {
			/* Bad length, try to find another chunk anyway */
			rsz = 6;
		}
		if (hndcrc16((u8 *) &rawotp[i], rsz,
			     CRC16_INIT_VALUE) == CRC16_GOOD_VALUE) {
			/* Good crc, copy the vars */
			gchunks++;
			dsz = rsz - 6;
			tsz += dsz;
			if (offset + dsz >= *len) {
				goto out;
			}
			memcpy(&data[offset], &rawotp[i + 2], dsz);
			offset += dsz;
			/* Remove extra null characters at the end */
			while (offset > 1 &&
			       data[offset - 1] == 0 && data[offset - 2] == 0)
				offset--;
			i += rsz / 2;
		} else {
			/* bad length or crc didn't check, try to find the next set */
			if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
				/* Assume length is good */
				i += rsz / 2;
			} else {
				while (++i < (int)(lim / 2))
					if (rawotp[i] == OTP_MAGIC)
						break;
			}
		}
		chunk++;
	}

	*len = offset;

 out:
	kfree(rawotp);
	si_setcoreidx(oi->sih, idx);

	return rc;
}

static otp_fn_t hndotp_fn = {
	(otp_size_t) hndotp_size,
	(otp_read_bit_t) hndotp_read_bit,

	(otp_init_t) hndotp_init,
	(otp_read_region_t) hndotp_read_region,
	(otp_nvread_t) hndotp_nvread,

	(otp_status_t) hndotp_status
};

#endif				/* BCMHNDOTP */

/*
 * Common Code: Compiled for IPX / HND / AUTO
 *	otp_status()
 *	otp_size()
 *	otp_read_bit()
 *	otp_init()
 * 	otp_read_region()
 * 	otp_nvread()
 */

int otp_status(void *oh)
{
	otpinfo_t *oi = (otpinfo_t *) oh;

	return oi->fn->status(oh);
}

int otp_size(void *oh)
{
	otpinfo_t *oi = (otpinfo_t *) oh;

	return oi->fn->size(oh);
}

u16 otp_read_bit(void *oh, uint offset)
{
	otpinfo_t *oi = (otpinfo_t *) oh;
	uint idx = si_coreidx(oi->sih);
	chipcregs_t *cc = si_setcoreidx(oi->sih, SI_CC_IDX);
	u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
	si_setcoreidx(oi->sih, idx);
	return readBit;
}

void *otp_init(si_t *sih)
{
	otpinfo_t *oi;
	void *ret = NULL;

	oi = &otpinfo;
	memset(oi, 0, sizeof(otpinfo_t));

	oi->ccrev = sih->ccrev;

#ifdef BCMIPXOTP
	if (OTPTYPE_IPX(oi->ccrev))
		oi->fn = &ipxotp_fn;
#endif

#ifdef BCMHNDOTP
	if (OTPTYPE_HND(oi->ccrev))
		oi->fn = &hndotp_fn;
#endif

	if (oi->fn == NULL) {
		return NULL;
	}

	oi->sih = sih;

	ret = (oi->fn->init) (sih);

	return ret;
}

int
otp_read_region(si_t *sih, int region, u16 *data,
				 uint *wlen) {
	bool wasup = false;
	void *oh;
	int err = 0;

	wasup = si_is_otp_powered(sih);
	if (!wasup)
		si_otp_power(sih, true);

	if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) {
		err = BCME_NOTREADY;
		goto out;
	}

	oh = otp_init(sih);
	if (oh == NULL) {
		err = BCME_ERROR;
		goto out;
	}

	err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);

 out:
	if (!wasup)
		si_otp_power(sih, false);

	return err;
}

int otp_nvread(void *oh, char *data, uint *len)
{
	otpinfo_t *oi = (otpinfo_t *) oh;

	return oi->fn->nvread(oh, data, len);
}
