// SPDX-License-Identifier: GPL-2.0
/******************************************************************************
 *
 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
 *
 ******************************************************************************/
#define _RTW_EFUSE_C_

#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_efuse.h>
#include <usb_ops_linux.h>
#include <rtl8188e_hal.h>
#include <rtw_iol.h>

#define REG_EFUSE_CTRL		0x0030
#define EFUSE_CTRL			REG_EFUSE_CTRL		/*  E-Fuse Control. */

enum{
		VOLTAGE_V25						= 0x03,
		LDOE25_SHIFT						= 28,
	};

/*
 * When we want to enable write operation, we should change to pwr on state.
 * When we stop write, we should switch to 500k mode and disable LDO 2.5V.
 */
static void efuse_power_switch(struct adapter *pAdapter, u8 write, u8 pwrstate)
{
	u8 tempval;
	u16 tmpv16;

	if (pwrstate) {
		usb_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);

		/*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), default valid */
		tmpv16 = usb_read16(pAdapter, REG_SYS_ISO_CTRL);
		if (!(tmpv16 & PWC_EV12V)) {
			tmpv16 |= PWC_EV12V;
			usb_write16(pAdapter, REG_SYS_ISO_CTRL, tmpv16);
		}
		/*  Reset: 0x0000h[28], default valid */
		tmpv16 =  usb_read16(pAdapter, REG_SYS_FUNC_EN);
		if (!(tmpv16 & FEN_ELDR)) {
			tmpv16 |= FEN_ELDR;
			usb_write16(pAdapter, REG_SYS_FUNC_EN, tmpv16);
		}

		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
		tmpv16 = usb_read16(pAdapter, REG_SYS_CLKR);
		if ((!(tmpv16 & LOADER_CLK_EN))  || (!(tmpv16 & ANA8M))) {
			tmpv16 |= (LOADER_CLK_EN | ANA8M);
			usb_write16(pAdapter, REG_SYS_CLKR, tmpv16);
		}

		if (write) {
			/*  Enable LDO 2.5V before read/write action */
			tempval = usb_read8(pAdapter, EFUSE_TEST + 3);
			tempval &= 0x0F;
			tempval |= (VOLTAGE_V25 << 4);
			usb_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
		}
	} else {
		usb_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);

		if (write) {
			/*  Disable LDO 2.5V after read/write action */
			tempval = usb_read8(pAdapter, EFUSE_TEST + 3);
			usb_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
		}
	}
}

static void
efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8  *pbuf)
{
	u8 *efuseTbl = NULL;
	u8 rtemp8;
	u16	eFuse_Addr = 0;
	u8 offset, wren;
	u16	i, j;
	u16	**eFuseWord = NULL;
	u16	efuse_utilized = 0;
	u8 u1temp = 0;
	void **tmp = NULL;

	efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
	if (!efuseTbl)
		return;

	tmp = kcalloc(EFUSE_MAX_SECTION_88E,
		      sizeof(void *) + EFUSE_MAX_WORD_UNIT * sizeof(u16),
		      GFP_KERNEL);
	if (!tmp) {
		DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
		goto eFuseWord_failed;
	}
	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
		tmp[i] = ((char *)(tmp + EFUSE_MAX_SECTION_88E)) + i * EFUSE_MAX_WORD_UNIT * sizeof(u16);
	eFuseWord = (u16 **)tmp;

	/*  0. Refresh efuse init map as all oxFF. */
	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
			eFuseWord[i][j] = 0xFFFF;

	/*  */
	/*  1. Read the first byte to check if efuse is empty!!! */
	/*  */
	/*  */
	rtemp8 = *(phymap + eFuse_Addr);
	if (rtemp8 != 0xFF) {
		efuse_utilized++;
		eFuse_Addr++;
	} else {
		DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8);
		goto exit;
	}

	/*  */
	/*  2. Read real efuse content. Filter PG header and every section data. */
	/*  */
	while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
		/*  Check PG header for section num. */
		if ((rtemp8 & 0x1F) == 0x0F) {		/* extended header */
			u1temp = (rtemp8 & 0xE0) >> 5;
			rtemp8 = *(phymap + eFuse_Addr);
			if ((rtemp8 & 0x0F) == 0x0F) {
				eFuse_Addr++;
				rtemp8 = *(phymap + eFuse_Addr);

				if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
					eFuse_Addr++;
				continue;
			} else {
				offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
				wren = rtemp8 & 0x0F;
				eFuse_Addr++;
			}
		} else {
			offset = (rtemp8 >> 4) & 0x0f;
			wren = rtemp8 & 0x0f;
		}

		if (offset < EFUSE_MAX_SECTION_88E) {
			/*  Get word enable value from PG header */
			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
				/*  Check word enable condition in the section */
				if (!(wren & 0x01)) {
					rtemp8 = *(phymap + eFuse_Addr);
					eFuse_Addr++;
					efuse_utilized++;
					eFuseWord[offset][i] = (rtemp8 & 0xff);
					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
						break;
					rtemp8 = *(phymap + eFuse_Addr);
					eFuse_Addr++;
					efuse_utilized++;
					eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);

					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
						break;
				}
				wren >>= 1;
			}
		}
		/*  Read next PG header */
		rtemp8 = *(phymap + eFuse_Addr);

		if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
			efuse_utilized++;
			eFuse_Addr++;
		}
	}

	/*  */
	/*  3. Collect 16 sections and 4 word unit into Efuse map. */
	/*  */
	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
			efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
			efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
		}
	}

	/*  */
	/*  4. Copy from Efuse map to output pointer memory!!! */
	/*  */
	for (i = 0; i < _size_byte; i++)
		pbuf[i] = efuseTbl[_offset + i];

	/*  */
	/*  5. Calculate Efuse utilization. */
	/*  */

exit:
	kfree(eFuseWord);

eFuseWord_failed:
	kfree(efuseTbl);
}

static void efuse_read_phymap_from_txpktbuf(
	struct adapter  *adapter,
	int bcnhead,	/* beacon head, where FW store len(2-byte) and efuse physical map. */
	u8 *content,	/* buffer to store efuse physical map */
	u16 *size	/* for efuse content: the max byte to read. will update to byte read */
	)
{
	u16 dbg_addr = 0;
	unsigned long start = 0;
	u8 reg_0x143 = 0;
	u32 lo32 = 0, hi32 = 0;
	u16 len = 0, count = 0;
	int i = 0;
	u16 limit = *size;

	u8 *pos = content;

	if (bcnhead < 0) /* if not valid */
		bcnhead = usb_read8(adapter, REG_TDECTRL + 1);

	DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);

	usb_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);

	dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */

	while (1) {
		usb_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i);

		usb_write8(adapter, REG_TXPKTBUF_DBG, 0);
		start = jiffies;
		while (!(reg_0x143 = usb_read8(adapter, REG_TXPKTBUF_DBG)) &&
		       jiffies_to_msecs(jiffies - start) < 1000) {
			DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, usb_read8(adapter, 0x106));
			usleep_range(1000, 2000);
		}

		lo32 = usb_read32(adapter, REG_PKTBUF_DBG_DATA_L);
		hi32 = usb_read32(adapter, REG_PKTBUF_DBG_DATA_H);

		if (i == 0) {
			u8 lenc[2];
			u16 lenbak, aaabak;
			u16 aaa;

			lenc[0] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L);
			lenc[1] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L + 1);

			aaabak = le16_to_cpup((__le16 *)lenc);
			lenbak = le16_to_cpu(*((__le16 *)lenc));
			aaa = le16_to_cpup((__le16 *)&lo32);
			len = le16_to_cpu(*((__le16 *)&lo32));

			limit = min_t(u16, len - 2, limit);

			DBG_88E("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __func__, len, lenbak, aaa, aaabak);

			memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
			count += (limit >= count + 2) ? 2 : limit - count;
			pos = content + count;

		} else {
			memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
			count += (limit >= count + 4) ? 4 : limit - count;
			pos = content + count;
		}

		if (limit > count && len - 2 > count) {
			memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
			count += (limit >= count + 4) ? 4 : limit - count;
			pos = content + count;
		}

		if (limit <= count || len - 2 <= count)
			break;
		i++;
	}
	usb_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
	DBG_88E("%s read count:%u\n", __func__, count);
	*size = count;
}

static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
{
	s32 status = _FAIL;
	u8 physical_map[512];
	u16 size = 512;

	usb_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
	memset(physical_map, 0xFF, 512);
	usb_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
	status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
	if (status == _SUCCESS)
		efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
	efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
	return status;
}

void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf)
{
	if (rtw_iol_applied(Adapter)) {
		rtw_hal_power_on(Adapter);
		iol_mode_enable(Adapter, 1);
		iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
		iol_mode_enable(Adapter, 0);
	}
}

u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data)
{
	u16	tmpaddr = 0;
	u16	start_addr = efuse_addr;
	u8 badworden = 0x0F;
	u8 tmpdata[8];

	memset(tmpdata, 0xff, PGPKT_DATA_SIZE);

	if (!(word_en & BIT(0))) {
		tmpaddr = start_addr;
		efuse_OneByteWrite(pAdapter, start_addr++, data[0]);
		efuse_OneByteWrite(pAdapter, start_addr++, data[1]);

		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0]);
		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1]);
		if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
			badworden &= (~BIT(0));
	}
	if (!(word_en & BIT(1))) {
		tmpaddr = start_addr;
		efuse_OneByteWrite(pAdapter, start_addr++, data[2]);
		efuse_OneByteWrite(pAdapter, start_addr++, data[3]);

		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[2]);
		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3]);
		if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
			badworden &= (~BIT(1));
	}
	if (!(word_en & BIT(2))) {
		tmpaddr = start_addr;
		efuse_OneByteWrite(pAdapter, start_addr++, data[4]);
		efuse_OneByteWrite(pAdapter, start_addr++, data[5]);

		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4]);
		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5]);
		if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
			badworden &= (~BIT(2));
	}
	if (!(word_en & BIT(3))) {
		tmpaddr = start_addr;
		efuse_OneByteWrite(pAdapter, start_addr++, data[6]);
		efuse_OneByteWrite(pAdapter, start_addr++, data[7]);

		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6]);
		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7]);
		if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
			badworden &= (~BIT(3));
	}
	return badworden;
}

static u16 Efuse_GetCurrentSize(struct adapter *pAdapter)
{
	u16	efuse_addr = 0;
	u8 hoffset = 0, hworden = 0;
	u8 efuse_data, word_cnts = 0;

	rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);

	while (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) &&
	       AVAILABLE_EFUSE_ADDR(efuse_addr)) {
		if (efuse_data == 0xFF)
			break;
		if ((efuse_data & 0x1F) == 0x0F) { /* extended header */
			hoffset = efuse_data;
			efuse_addr++;
			efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data);
			if ((efuse_data & 0x0F) == 0x0F) {
				efuse_addr++;
				continue;
			} else {
				hoffset = ((hoffset & 0xE0) >> 5) |
					  ((efuse_data & 0xF0) >> 1);
				hworden = efuse_data & 0x0F;
			}
		} else {
			hoffset = (efuse_data >> 4) & 0x0F;
			hworden =  efuse_data & 0x0F;
		}
		word_cnts = Efuse_CalculateWordCnts(hworden);
		/* read next header */
		efuse_addr = efuse_addr + (word_cnts * 2) + 1;
	}

	rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);

	return efuse_addr;
}

int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
{
	u8 ReadState = PG_STATE_HEADER;
	int	bDataEmpty = true;
	u8 efuse_data, word_cnts = 0;
	u16	efuse_addr = 0;
	u8 hoffset = 0, hworden = 0;
	u8 tmpidx = 0;
	u8 tmpdata[8];
	u8 tmp_header = 0;

	if (!data)
		return false;
	if (offset > EFUSE_MAX_SECTION_88E)
		return false;

	memset(data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
	memset(tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);

	/*  <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
	/*  Skip dummy parts to prevent unexpected data read from Efuse. */
	/*  By pass right now. 2009.02.19. */
	while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
		/*   Header Read ------------- */
		if (ReadState & PG_STATE_HEADER) {
			if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) {
				if (EXT_HEADER(efuse_data)) {
					tmp_header = efuse_data;
					efuse_addr++;
					efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data);
					if (!ALL_WORDS_DISABLED(efuse_data)) {
						hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
						hworden = efuse_data & 0x0F;
					} else {
						DBG_88E("Error, All words disabled\n");
						efuse_addr++;
						continue;
					}
				} else {
					hoffset = (efuse_data >> 4) & 0x0F;
					hworden =  efuse_data & 0x0F;
				}
				word_cnts = Efuse_CalculateWordCnts(hworden);
				bDataEmpty = true;

				if (hoffset == offset) {
					for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
						if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx, &efuse_data)) {
							tmpdata[tmpidx] = efuse_data;
							if (efuse_data != 0xff)
								bDataEmpty = false;
						}
					}
					if (!bDataEmpty) {
						ReadState = PG_STATE_DATA;
					} else {/* read next header */
						efuse_addr = efuse_addr + (word_cnts * 2) + 1;
						ReadState = PG_STATE_HEADER;
					}
				} else {/* read next header */
					efuse_addr = efuse_addr + (word_cnts * 2) + 1;
					ReadState = PG_STATE_HEADER;
				}
			} else {
				break;
			}
		} else if (ReadState & PG_STATE_DATA) {
			/*   Data section Read ------------- */
			efuse_WordEnableDataRead(hworden, tmpdata, data);
			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
			ReadState = PG_STATE_HEADER;
		}
	}

	if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff)  && (data[3] == 0xff) &&
	    (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff)  && (data[7] == 0xff))
		return false;
	else
		return true;
}

static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr)
{
	u8 originaldata[8], badworden = 0;
	u16	efuse_addr = *pAddr;
	u32	PgWriteSuccess = 0;

	memset(originaldata, 0xff, 8);

	if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata)) {
		/* check if data exist */
		badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata);

		if (badworden != 0xf) {	/*  write fail */
			PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata);

			if (!PgWriteSuccess)
				return false;

			efuse_addr = Efuse_GetCurrentSize(pAdapter);
		} else {
			efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
		}
	} else {
		efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
	}
	*pAddr = efuse_addr;
	return true;
}

static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
{
	bool ret = false;
	u16 efuse_addr = *pAddr;
	u16 efuse_max_available_len =
		EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E;
	u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
	u8 repeatcnt = 0;

	while (efuse_addr < efuse_max_available_len) {
		pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
		efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
		efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);

		while (tmp_header == 0xFF) {
			if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
				return false;

			efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
			efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
		}

		/* to write ext_header */
		if (tmp_header == pg_header) {
			efuse_addr++;
			pg_header_temp = pg_header;
			pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;

			efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
			efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);

			while (tmp_header == 0xFF) {
				if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
					return false;

				efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
				efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
			}

			if ((tmp_header & 0x0F) == 0x0F) {	/* word_en PG fail */
				if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
					return false;

				efuse_addr++;
				continue;
			} else if (pg_header != tmp_header) {	/* offset PG fail */
				struct pgpkt	fixPkt;

				fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
				fixPkt.word_en = tmp_header & 0x0F;
				fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
				if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr))
					return false;
			} else {
				ret = true;
				break;
			}
		} else if ((tmp_header & 0x1F) == 0x0F) {		/* wrong extended header */
			efuse_addr += 2;
			continue;
		}
	}

	*pAddr = efuse_addr;
	return ret;
}

static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
{
	bool ret = false;
	u8 pg_header = 0, tmp_header = 0;
	u16	efuse_addr = *pAddr;
	u8 repeatcnt = 0;

	pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;

	efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
	efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);

	while (tmp_header == 0xFF) {
		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
			return false;
		efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
		efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
	}

	if (pg_header == tmp_header) {
		ret = true;
	} else {
		struct pgpkt	fixPkt;

		fixPkt.offset = (tmp_header >> 4) & 0x0F;
		fixPkt.word_en = tmp_header & 0x0F;
		fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
		if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr))
			return false;
	}

	*pAddr = efuse_addr;
	return ret;
}

static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
{
	u16	efuse_addr = *pAddr;
	u8 badworden;
	u32	PgWriteSuccess = 0;

	badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data);
	if (badworden == 0x0F) {
		/*  write ok */
		return true;
	}
	/* reorganize other pg packet */
	PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data);
	if (!PgWriteSuccess)
		return false;
	else
		return true;
}

static bool
hal_EfusePgPacketWriteHeader(
				struct adapter *pAdapter,
				u8 efuseType,
				u16				*pAddr,
				struct pgpkt *pTargetPkt)
{
	bool ret = false;

	if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
		ret = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
	else
		ret = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);

	return ret;
}

static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
			  u8 *pWden)
{
	u8 match_word_en = 0x0F;	/*  default all words are disabled */

	/*  check if the same words are enabled both target and current PG packet */
	if (((pTargetPkt->word_en & BIT(0)) == 0) &&
	    ((pCurPkt->word_en & BIT(0)) == 0))
		match_word_en &= ~BIT(0);				/*  enable word 0 */
	if (((pTargetPkt->word_en & BIT(1)) == 0) &&
	    ((pCurPkt->word_en & BIT(1)) == 0))
		match_word_en &= ~BIT(1);				/*  enable word 1 */
	if (((pTargetPkt->word_en & BIT(2)) == 0) &&
	    ((pCurPkt->word_en & BIT(2)) == 0))
		match_word_en &= ~BIT(2);				/*  enable word 2 */
	if (((pTargetPkt->word_en & BIT(3)) == 0) &&
	    ((pCurPkt->word_en & BIT(3)) == 0))
		match_word_en &= ~BIT(3);				/*  enable word 3 */

	*pWden = match_word_en;

	if (match_word_en != 0xf)
		return true;
	else
		return false;
}

static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr)
{
	bool ret = false;
	u8 i, efuse_data;

	for (i = 0; i < (word_cnts * 2); i++) {
		if (efuse_OneByteRead(pAdapter, (startAddr + i), &efuse_data) && (efuse_data != 0xFF))
			ret = true;
	}
	return ret;
}

static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
{
	bool ret = false;
	u8 i, efuse_data = 0, cur_header = 0;
	u8 matched_wden = 0, badworden = 0;
	u16 startAddr = 0;
	u16 efuse_max_available_len =
		EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E;
	struct pgpkt curPkt;

	rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
	startAddr %= EFUSE_REAL_CONTENT_LEN;

	while (1) {
		if (startAddr >= efuse_max_available_len) {
			ret = false;
			break;
		}

		if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data) && (efuse_data != 0xFF)) {
			if (EXT_HEADER(efuse_data)) {
				cur_header = efuse_data;
				startAddr++;
				efuse_OneByteRead(pAdapter, startAddr, &efuse_data);
				if (ALL_WORDS_DISABLED(efuse_data)) {
					ret = false;
					break;
				}
				curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
				curPkt.word_en = efuse_data & 0x0F;
			} else {
				cur_header  =  efuse_data;
				curPkt.offset = (cur_header >> 4) & 0x0F;
				curPkt.word_en = cur_header & 0x0F;
			}

			curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
			/*  if same header is found but no data followed */
			/*  write some part of data followed by the header. */
			if ((curPkt.offset == pTargetPkt->offset) &&
			    (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1)) &&
			    wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
				/*  Here to write partial data */
				badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data);
				if (badworden != 0x0F) {
					u32	PgWriteSuccess = 0;
					/*  if write fail on some words, write these bad words again */

					PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data);

					if (!PgWriteSuccess) {
						ret = false;	/*  write fail, return */
						break;
					}
				}
				/*  partial write ok, update the target packet for later use */
				for (i = 0; i < 4; i++) {
					if ((matched_wden & (0x1 << i)) == 0)	/*  this word has been written */
						pTargetPkt->word_en |= (0x1 << i);	/*  disable the word */
				}
				pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
			}
			/*  read from next header */
			startAddr = startAddr + (curPkt.word_cnts * 2) + 1;
		} else {
			/*  not used header, 0xff */
			*pAddr = startAddr;
			ret = true;
			break;
		}
	}
	return ret;
}

static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt)
{
	memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8);
	pTargetPkt->offset = offset;
	pTargetPkt->word_en = word_en;
	efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
	pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
}

bool Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData)
{
	struct pgpkt	targetPkt;
	u16			startAddr = 0;
	u8 efuseType = EFUSE_WIFI;

	if (Efuse_GetCurrentSize(pAdapter) >= EFUSE_MAP_LEN_88E)
		return false;

	hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);

	if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt))
		return false;

	if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt))
		return false;

	if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt))
		return false;

	return true;
}

u8 Efuse_CalculateWordCnts(u8 word_en)
{
	u8 word_cnts = 0;

	if (!(word_en & BIT(0)))
		word_cnts++; /*  0 : write enable */
	if (!(word_en & BIT(1)))
		word_cnts++;
	if (!(word_en & BIT(2)))
		word_cnts++;
	if (!(word_en & BIT(3)))
		word_cnts++;
	return word_cnts;
}

u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data)
{
	u8 tmpidx = 0;
	u8 result;

	usb_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
	usb_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
		   (usb_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));

	usb_write8(pAdapter, EFUSE_CTRL + 3,  0x72);/* read cmd */

	while (!(0x80 & usb_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
		tmpidx++;
	if (tmpidx < 100) {
		*data = usb_read8(pAdapter, EFUSE_CTRL);
		result = true;
	} else {
		*data = 0xff;
		result = false;
	}
	return result;
}

u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data)
{
	u8 tmpidx = 0;
	u8 result;

	usb_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
	usb_write8(pAdapter, EFUSE_CTRL + 2,
		   (usb_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
		   (u8)((addr >> 8) & 0x03));
	usb_write8(pAdapter, EFUSE_CTRL, data);/* data */

	usb_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */

	while ((0x80 &  usb_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
		tmpidx++;

	if (tmpidx < 100)
		result = true;
	else
		result = false;

	return result;
}

/* Read allowed word in current efuse section data. */
void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
{
	if (!(word_en & BIT(0))) {
		targetdata[0] = sourdata[0];
		targetdata[1] = sourdata[1];
	}
	if (!(word_en & BIT(1))) {
		targetdata[2] = sourdata[2];
		targetdata[3] = sourdata[3];
	}
	if (!(word_en & BIT(2))) {
		targetdata[4] = sourdata[4];
		targetdata[5] = sourdata[5];
	}
	if (!(word_en & BIT(3))) {
		targetdata[6] = sourdata[6];
		targetdata[7] = sourdata[7];
	}
}

/* Read All Efuse content */
static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse)
{
	efuse_power_switch(pAdapter, false, true);

	efuse_ReadEFuse(pAdapter, efuseType, 0, EFUSE_MAP_LEN_88E, Efuse);

	efuse_power_switch(pAdapter, false, false);
}

/* Transfer current EFUSE content to shadow init and modify map. */
void EFUSE_ShadowMapUpdate(struct adapter *pAdapter, u8 efuseType)
{
	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);

	if (pEEPROM->bautoload_fail_flag)
		memset(pEEPROM->efuse_eeprom_data, 0xFF, EFUSE_MAP_LEN_88E);
	else
		Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data);
}
