// SPDX-License-Identifier: GPL-2.0
/*
 * rtl8712_efuse.c
 *
 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
 * Linux device driver for RTL8192SU
 *
 * Modifications for inclusion into the Linux staging tree are
 * Copyright(c) 2010 Larry Finger. All rights reserved.
 *
 * Contact information:
 * WLAN FAE <wlanfae@realtek.com>.
 * Larry Finger <Larry.Finger@lwfinger.net>
 *
 ******************************************************************************/

#define _RTL8712_EFUSE_C_

#include "osdep_service.h"
#include "drv_types.h"
#include "rtl8712_efuse.h"

/* reserve 3 bytes for HW stop read */
static int efuse_available_max_size = EFUSE_MAX_SIZE - 3 /*0x1FD*/;

static void efuse_reg_ctrl(struct _adapter *padapter, u8 bPowerOn)
{
	u8 tmpu8 = 0;

	if (bPowerOn) {
		/* -----------------e-fuse pwr & clk reg ctrl ---------------
		 * Enable LDOE25 Macro Block
		 */
		tmpu8 = r8712_read8(padapter, EFUSE_TEST + 3);
		tmpu8 |= 0x80;
		r8712_write8(padapter, EFUSE_TEST + 3, tmpu8);
		msleep(20); /* for some platform , need some delay time */
		/* Change Efuse Clock for write action to 40MHZ */
		r8712_write8(padapter, EFUSE_CLK_CTRL, 0x03);
		msleep(20); /* for some platform , need some delay time */
	} else {
		/* -----------------e-fuse pwr & clk reg ctrl -----------------
		 * Disable LDOE25 Macro Block
		 */
		tmpu8 = r8712_read8(padapter, EFUSE_TEST + 3);
		tmpu8 &= 0x7F;
		r8712_write8(padapter, EFUSE_TEST + 3, tmpu8);
		/* Change Efuse Clock for write action to 500K */
		r8712_write8(padapter, EFUSE_CLK_CTRL, 0x02);
	}
}

/*
 * Before write E-Fuse, this function must be called.
 */
u8 r8712_efuse_reg_init(struct _adapter *padapter)
{
	return true;
}

void r8712_efuse_reg_uninit(struct _adapter *padapter)
{
	efuse_reg_ctrl(padapter, false);
}

static u8 efuse_one_byte_read(struct _adapter *padapter, u16 addr, u8 *data)
{
	u8 tmpidx = 0, bResult;

	/* -----------------e-fuse reg ctrl --------------------------------- */
	r8712_write8(padapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */
	r8712_write8(padapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
	       (r8712_read8(padapter, EFUSE_CTRL + 2) & 0xFC));
	r8712_write8(padapter, EFUSE_CTRL + 3, 0x72); /* read cmd */
	/* wait for complete */
	while (!(0x80 & r8712_read8(padapter, EFUSE_CTRL + 3)) &&
	       (tmpidx < 100))
		tmpidx++;
	if (tmpidx < 100) {
		*data = r8712_read8(padapter, EFUSE_CTRL);
		bResult = true;
	} else {
		*data = 0xff;
		bResult = false;
	}
	return bResult;
}

static u8 efuse_one_byte_write(struct _adapter *padapter, u16 addr, u8 data)
{
	u8 tmpidx = 0, bResult;

	/* -----------------e-fuse reg ctrl -------------------------------- */
	r8712_write8(padapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */
	r8712_write8(padapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
	       (r8712_read8(padapter, EFUSE_CTRL + 2) & 0xFC));
	r8712_write8(padapter, EFUSE_CTRL, data); /* data */
	r8712_write8(padapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */
	/* wait for complete */
	while ((0x80 &  r8712_read8(padapter, EFUSE_CTRL + 3)) &&
	       (tmpidx < 100))
		tmpidx++;
	if (tmpidx < 100)
		bResult = true;
	else
		bResult = false;
	return bResult;
}

static u8 efuse_one_byte_rw(struct _adapter *padapter, u8 bRead, u16 addr,
			    u8 *data)
{
	u8 tmpidx = 0, tmpv8 = 0, bResult;

	/* -----------------e-fuse reg ctrl --------------------------------- */
	r8712_write8(padapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */
	tmpv8 = ((u8)((addr >> 8) & 0x03)) |
		 (r8712_read8(padapter, EFUSE_CTRL + 2) & 0xFC);
	r8712_write8(padapter, EFUSE_CTRL + 2, tmpv8);
	if (bRead) {
		r8712_write8(padapter, EFUSE_CTRL + 3,  0x72); /* read cmd */
		while (!(0x80 & r8712_read8(padapter, EFUSE_CTRL + 3)) &&
		       (tmpidx < 100))
			tmpidx++;
		if (tmpidx < 100) {
			*data = r8712_read8(padapter, EFUSE_CTRL);
			bResult = true;
		} else {
			*data = 0;
			bResult = false;
		}
	} else {
		r8712_write8(padapter, EFUSE_CTRL, *data); /* data */
		r8712_write8(padapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */
		while ((0x80 & r8712_read8(padapter, EFUSE_CTRL + 3)) &&
		       (tmpidx < 100))
			tmpidx++;
		if (tmpidx < 100)
			bResult = true;
		else
			bResult = false;
	}
	return bResult;
}

static u8 efuse_is_empty(struct _adapter *padapter, u8 *empty)
{
	u8 value, ret = true;

	/* read one byte to check if E-Fuse is empty */
	if (efuse_one_byte_rw(padapter, true, 0, &value)) {
		if (value == 0xFF)
			*empty = true;
		else
			*empty = false;
	} else {
		ret = false;
	}
	return ret;
}

void r8712_efuse_change_max_size(struct _adapter *padapter)
{
	u16 pre_pg_data_saddr = 0x1FB;
	u16 i;
	u16 pre_pg_data_size = 5;
	u8 pre_pg_data[5];

	for (i = 0; i < pre_pg_data_size; i++)
		efuse_one_byte_read(padapter, pre_pg_data_saddr + i,
				    &pre_pg_data[i]);
	if ((pre_pg_data[0] == 0x03) && (pre_pg_data[1] == 0x00) &&
	    (pre_pg_data[2] == 0x00) && (pre_pg_data[3] == 0x00) &&
	    (pre_pg_data[4] == 0x0C))
		efuse_available_max_size -= pre_pg_data_size;
}

int r8712_efuse_get_max_size(struct _adapter *padapter)
{
	return	efuse_available_max_size;
}

static u8 calculate_word_cnts(const u8 word_en)
{
	u8 word_cnts = 0;
	u8 word_idx;

	for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++)
		if (!(word_en & BIT(word_idx)))
			word_cnts++; /* 0 : write enable */
	return word_cnts;
}

static void pgpacket_copy_data(const u8 word_en, const u8 *sourdata,
			       u8 *targetdata)
{
	u8 tmpindex = 0;
	u8 word_idx, byte_idx;

	for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++) {
		if (!(word_en & BIT(word_idx))) {
			byte_idx = word_idx * 2;
			targetdata[byte_idx] = sourdata[tmpindex++];
			targetdata[byte_idx + 1] = sourdata[tmpindex++];
		}
	}
}

u16 r8712_efuse_get_current_size(struct _adapter *padapter)
{
	int bContinual = true;
	u16 efuse_addr = 0;
	u8 hworden = 0;
	u8 efuse_data, word_cnts = 0;

	while (bContinual && efuse_one_byte_read(padapter, efuse_addr,
	       &efuse_data) && (efuse_addr < efuse_available_max_size)) {
		if (efuse_data != 0xFF) {
			hworden =  efuse_data & 0x0F;
			word_cnts = calculate_word_cnts(hworden);
			/* read next header */
			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
		} else {
			bContinual = false;
		}
	}
	return efuse_addr;
}

u8 r8712_efuse_pg_packet_read(struct _adapter *padapter, u8 offset, u8 *data)
{
	u8 hoffset = 0, hworden = 0, word_cnts = 0;
	u16 efuse_addr = 0;
	u8 efuse_data;
	u8 tmpidx = 0;
	u8 tmpdata[PGPKT_DATA_SIZE];
	u8 ret = true;

	if (!data)
		return false;
	if (offset > 0x0f)
		return false;
	memset(data, 0xFF, sizeof(u8) * PGPKT_DATA_SIZE);
	while (efuse_addr < efuse_available_max_size) {
		if (efuse_one_byte_read(padapter, efuse_addr, &efuse_data)) {
			if (efuse_data == 0xFF)
				break;
			hoffset = (efuse_data >> 4) & 0x0F;
			hworden =  efuse_data & 0x0F;
			word_cnts = calculate_word_cnts(hworden);
			if (hoffset == offset) {
				memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
				for (tmpidx = 0; tmpidx < word_cnts * 2;
				     tmpidx++) {
					if (efuse_one_byte_read(padapter,
					    efuse_addr + 1 + tmpidx,
					    &efuse_data)) {
						tmpdata[tmpidx] = efuse_data;
					} else {
						ret = false;
					}
				}
				pgpacket_copy_data(hworden, tmpdata, data);
			}
			efuse_addr += 1 + (word_cnts * 2);
		} else {
			ret = false;
			break;
		}
	}
	return ret;
}

static u8 fix_header(struct _adapter *padapter, u8 header, u16 header_addr)
{
	struct PGPKT_STRUCT pkt;
	u8 offset, word_en, value;
	u16 addr;
	int i;
	u8 ret = true;

	pkt.offset = GET_EFUSE_OFFSET(header);
	pkt.word_en = GET_EFUSE_WORD_EN(header);
	addr = header_addr + 1 + calculate_word_cnts(pkt.word_en) * 2;
	if (addr > efuse_available_max_size)
		return false;
	/* retrieve original data */
	addr = 0;
	while (addr < header_addr) {
		if (!efuse_one_byte_read(padapter, addr++, &value)) {
			ret = false;
			break;
		}
		offset = GET_EFUSE_OFFSET(value);
		word_en = GET_EFUSE_WORD_EN(value);
		if (pkt.offset != offset) {
			addr += calculate_word_cnts(word_en) * 2;
			continue;
		}
		for (i = 0; i < PGPKG_MAX_WORDS; i++) {
			if (BIT(i) & word_en) {
				if (BIT(i) & pkt.word_en) {
					if (efuse_one_byte_read(
							padapter, addr,
							&value))
						pkt.data[i * 2] = value;
					else
						return false;
					if (efuse_one_byte_read(
							padapter,
							addr + 1,
							&value))
						pkt.data[i * 2 + 1] =
							value;
					else
						return false;
				}
				addr += 2;
			}
		}
	}
	if (addr != header_addr)
		return false;
	addr++;
	/* fill original data */
	for (i = 0; i < PGPKG_MAX_WORDS; i++) {
		if (BIT(i) & pkt.word_en) {
			efuse_one_byte_write(padapter, addr, pkt.data[i * 2]);
			efuse_one_byte_write(padapter, addr + 1,
					     pkt.data[i * 2 + 1]);
			/* additional check */
			if (!efuse_one_byte_read(padapter, addr, &value)) {
				ret = false;
			} else if (pkt.data[i * 2] != value) {
				ret = false;
				if (value == 0xFF) /* write again */
					efuse_one_byte_write(padapter, addr,
							     pkt.data[i * 2]);
			}
			if (!efuse_one_byte_read(padapter, addr + 1, &value)) {
				ret = false;
			} else if (pkt.data[i * 2 + 1] != value) {
				ret = false;
				if (value == 0xFF) /* write again */
					efuse_one_byte_write(padapter, addr + 1,
							     pkt.data[i * 2 +
								      1]);
			}
		}
		addr += 2;
	}
	return ret;
}

u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset,
			 const u8 word_en, const u8 *data)
{
	u8 pg_header = 0;
	u16 efuse_addr = 0, curr_size = 0;
	u8 efuse_data, target_word_cnts = 0;
	int repeat_times;
	int sub_repeat;
	u8 bResult = true;

	/* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */
	efuse_data = r8712_read8(padapter, EFUSE_CLK_CTRL);
	if (efuse_data != 0x03)
		return false;
	pg_header = MAKE_EFUSE_HEADER(offset, word_en);
	target_word_cnts = calculate_word_cnts(word_en);
	repeat_times = 0;
	efuse_addr = 0;
	while (efuse_addr < efuse_available_max_size) {
		curr_size = r8712_efuse_get_current_size(padapter);
		if ((curr_size + 1 + target_word_cnts * 2) >
		     efuse_available_max_size)
			return false; /*target_word_cnts + pg header(1 byte)*/
		efuse_addr = curr_size; /* current size is also the last addr*/
		efuse_one_byte_write(padapter, efuse_addr, pg_header); /*hdr*/
		sub_repeat = 0;
		/* check if what we read is what we write */
		while (!efuse_one_byte_read(padapter, efuse_addr,
					    &efuse_data)) {
			if (++sub_repeat > _REPEAT_THRESHOLD_) {
				bResult = false; /* continue to blind write */
				break; /* continue to blind write */
			}
		}
		if ((sub_repeat > _REPEAT_THRESHOLD_) ||
		    (pg_header == efuse_data)) {
			/* write header ok OR can't check header(creep) */
			u8 i;

			/* go to next address */
			efuse_addr++;
			for (i = 0; i < target_word_cnts * 2; i++) {
				efuse_one_byte_write(padapter,
						     efuse_addr + i,
						     *(data + i));
				if (!efuse_one_byte_read(padapter,
							 efuse_addr + i,
							 &efuse_data))
					bResult = false;
				else if (*(data + i) != efuse_data) /* fail */
					bResult = false;
			}
			break;
		}
		/* write header fail */
		bResult = false;
		if (efuse_data == 0xFF)
			return bResult; /* nothing damaged. */
		/* call rescue procedure */
		if (!fix_header(padapter, efuse_data, efuse_addr))
			return false; /* rescue fail */

		if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */
			break;
		/* otherwise, take another risk... */
	}
	return bResult;
}

u8 r8712_efuse_access(struct _adapter *padapter, u8 bRead, u16 start_addr,
		      u16 cnts, u8 *data)
{
	int i;
	u8 res = true;

	if (start_addr > EFUSE_MAX_SIZE)
		return false;
	if (!bRead && ((start_addr + cnts) >
	   efuse_available_max_size))
		return false;
	if (!bRead && !r8712_efuse_reg_init(padapter))
		return false;
	/* -----------------e-fuse one byte read / write ---------------------*/
	for (i = 0; i < cnts; i++) {
		if ((start_addr + i) > EFUSE_MAX_SIZE) {
			res = false;
			break;
		}
		res = efuse_one_byte_rw(padapter, bRead, start_addr + i,
		      data + i);
		if (!bRead && !res)
			break;
	}
	if (!bRead)
		r8712_efuse_reg_uninit(padapter);
	return res;
}

u8 r8712_efuse_map_read(struct _adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
	u8 offset, ret = true;
	u8 pktdata[PGPKT_DATA_SIZE];
	int i, idx;

	if ((addr + cnts) > EFUSE_MAP_MAX_SIZE)
		return false;
	if (efuse_is_empty(padapter, &offset) && offset) {
		for (i = 0; i < cnts; i++)
			data[i] = 0xFF;
		return ret;
	}
	offset = (addr >> 3) & 0xF;
	ret = r8712_efuse_pg_packet_read(padapter, offset, pktdata);
	i = addr & 0x7;	/* pktdata index */
	idx = 0;	/* data index */

	do {
		for (; i < PGPKT_DATA_SIZE; i++) {
			data[idx++] = pktdata[i];
			if (idx == cnts)
				return ret;
		}
		offset++;
		if (!r8712_efuse_pg_packet_read(padapter, offset, pktdata))
			ret = false;
		i = 0;
	} while (1);
	return ret;
}

u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr, u16 cnts,
			 u8 *data)
{
	u8 offset, word_en, empty;
	u8 pktdata[PGPKT_DATA_SIZE], newdata[PGPKT_DATA_SIZE];
	int i, j, idx;

	if ((addr + cnts) > EFUSE_MAP_MAX_SIZE)
		return false;
	/* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */
	empty = r8712_read8(padapter, EFUSE_CLK_CTRL);
	if (empty != 0x03)
		return false;
	if (efuse_is_empty(padapter, &empty)) {
		if (empty)
			memset(pktdata, 0xFF, PGPKT_DATA_SIZE);
	} else {
		return false;
	}
	offset = (addr >> 3) & 0xF;
	if (!empty)
		if (!r8712_efuse_pg_packet_read(padapter, offset, pktdata))
			return false;
	word_en = 0xF;
	memset(newdata, 0xFF, PGPKT_DATA_SIZE);
	i = addr & 0x7;	/* pktdata index */
	j = 0;		/* newdata index */
	idx = 0;	/* data index */

	if (i & 0x1) {
		/*  odd start */
		if (data[idx] != pktdata[i]) {
			word_en &= ~BIT(i >> 1);
			newdata[j++] = pktdata[i - 1];
			newdata[j++] = data[idx];
		}
		i++;
		idx++;
	}
	do {
		for (; i < PGPKT_DATA_SIZE; i += 2) {
			if ((cnts - idx) == 1) {
				if (data[idx] != pktdata[i]) {
					word_en &= ~BIT(i >> 1);
					newdata[j++] = data[idx];
					newdata[j++] = pktdata[1 + 1];
				}
				idx++;
				break;
			}

			if ((data[idx] != pktdata[i]) || (data[idx + 1] !=
			     pktdata[i + 1])) {
				word_en &= ~BIT(i >> 1);
				newdata[j++] = data[idx];
				newdata[j++] = data[idx + 1];
			}
			idx += 2;

			if (idx == cnts)
				break;
		}

		if (word_en != 0xF)
			if (!r8712_efuse_pg_packet_write(padapter, offset,
							 word_en, newdata))
				return false;
		if (idx == cnts)
			break;
		offset++;
		if (!empty)
			if (!r8712_efuse_pg_packet_read(padapter, offset,
			    pktdata))
				return false;
		i = 0;
		j = 0;
		word_en = 0xF;
		memset(newdata, 0xFF, PGPKT_DATA_SIZE);
	} while (1);

	return true;
}
