29 #define _RTL8712_EFUSE_C_
38 static void efuse_reg_ctrl(
struct _adapter *padapter,
u8 bPowerOn)
42 if (
true == bPowerOn) {
75 efuse_reg_ctrl(padapter,
false);
80 u8 tmpidx = 0, bResult;
100 static u8 efuse_one_byte_write(
struct _adapter *padapter,
u16 addr,
u8 data)
102 u8 tmpidx = 0, bResult;
120 static u8 efuse_one_byte_rw(
struct _adapter *padapter,
u8 bRead,
u16 addr,
123 u8 tmpidx = 0, tmpv8 = 0, bResult;
127 tmpv8 = ((
u8)((addr >> 8) & 0x03)) |
161 if (efuse_one_byte_rw(padapter,
true, 0, &value) ==
true) {
173 u16 pre_pg_data_saddr = 0x1FB;
175 u16 pre_pg_data_size = 5;
178 for (i = 0; i < pre_pg_data_size; i++)
179 efuse_one_byte_read(padapter, pre_pg_data_saddr + i,
181 if ((pre_pg_data[0] == 0x03) && (pre_pg_data[1] == 0x00) &&
182 (pre_pg_data[2] == 0x00) && (pre_pg_data[3] == 0x00) &&
183 (pre_pg_data[4] == 0x0C))
184 efuse_available_max_size -= pre_pg_data_size;
189 return efuse_available_max_size;
192 static u8 calculate_word_cnts(
const u8 word_en)
198 if (!(word_en &
BIT(word_idx)))
203 static void pgpacket_copy_data(
const u8 word_en,
const u8 *sourdata,
207 u8 word_idx, byte_idx;
210 if (!(word_en&
BIT(word_idx))) {
211 byte_idx = word_idx * 2;
212 targetdata[byte_idx] = sourdata[tmpindex++];
213 targetdata[byte_idx + 1] = sourdata[tmpindex++];
220 int bContinual =
true;
222 u8 hoffset = 0, hworden = 0;
223 u8 efuse_data, word_cnts = 0;
225 while (bContinual && efuse_one_byte_read(padapter, efuse_addr,
226 &efuse_data) && (efuse_addr < efuse_available_max_size)) {
227 if (efuse_data != 0xFF) {
228 hoffset = (efuse_data >> 4) & 0x0F;
229 hworden = efuse_data & 0x0F;
230 word_cnts = calculate_word_cnts(hworden);
232 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
241 u8 hoffset = 0, hworden = 0, word_cnts = 0;
253 while (efuse_addr < efuse_available_max_size) {
254 if (efuse_one_byte_read(padapter, efuse_addr, &efuse_data) ==
256 if (efuse_data == 0xFF)
258 hoffset = (efuse_data >> 4) & 0x0F;
259 hworden = efuse_data & 0x0F;
260 word_cnts = calculate_word_cnts(hworden);
261 if (hoffset == offset) {
262 memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
263 for (tmpidx = 0; tmpidx < word_cnts * 2;
265 if (efuse_one_byte_read(padapter,
266 efuse_addr+1+tmpidx, &efuse_data) ==
268 tmpdata[tmpidx] = efuse_data;
272 pgpacket_copy_data(hworden, tmpdata, data);
274 efuse_addr += 1 + (word_cnts*2);
293 addr = header_addr + 1 + calculate_word_cnts(pkt.word_en) * 2;
294 if (addr > efuse_available_max_size)
298 while (addr < header_addr) {
299 if (efuse_one_byte_read(padapter, addr++, &value) ==
false) {
305 if (pkt.offset != offset) {
306 addr += calculate_word_cnts(word_en)*2;
310 if (
BIT(i) & word_en) {
311 if (
BIT(i) & pkt.word_en) {
312 if (efuse_one_byte_read(
315 pkt.data[i*2] =
value;
318 if (efuse_one_byte_read(
331 if (addr != header_addr)
336 if (
BIT(i) & pkt.word_en) {
337 efuse_one_byte_write(padapter, addr, pkt.data[i*2]);
338 efuse_one_byte_write(padapter, addr+1,
341 if (efuse_one_byte_read(padapter, addr, &value)
344 else if (pkt.data[i*2] != value) {
347 efuse_one_byte_write(padapter, addr,
350 if (efuse_one_byte_read(padapter, addr+1, &value) ==
353 else if (pkt.data[i*2 + 1] != value) {
356 efuse_one_byte_write(padapter, addr+1,
366 const u8 word_en,
const u8 *data)
369 u16 efuse_addr = 0, curr_size = 0;
370 u8 efuse_data, target_word_cnts = 0;
371 static int repeat_times;
377 if (efuse_data != 0x03)
380 target_word_cnts = calculate_word_cnts(word_en);
383 while (efuse_addr < efuse_available_max_size) {
385 if ((curr_size + 1 + target_word_cnts * 2) >
386 efuse_available_max_size)
388 efuse_addr = curr_size;
389 efuse_one_byte_write(padapter, efuse_addr, pg_header);
392 while (efuse_one_byte_read(padapter, efuse_addr,
393 &efuse_data) ==
false) {
400 (pg_header == efuse_data)) {
406 for (i = 0; i < target_word_cnts*2; i++) {
407 efuse_one_byte_write(padapter,
410 if (efuse_one_byte_read(padapter,
411 efuse_addr + i, &efuse_data) ==
false)
413 else if (*(data+i) != efuse_data)
419 if (0xFF == efuse_data)
422 if (fix_header(padapter, efuse_data, efuse_addr) ==
442 if ((bRead ==
false) && ((start_addr + cnts) >
443 efuse_available_max_size))
448 for (i = 0; i < cnts; i++) {
453 res = efuse_one_byte_rw(padapter, bRead, start_addr + i,
455 if ((
false == bRead) && (
false == res))
471 if ((efuse_is_empty(padapter, &offset) ==
true) && (offset ==
473 for (i = 0; i < cnts; i++)
477 offset = (addr >> 3) & 0xF;
484 data[idx++] = pktdata[
i];
509 if (efuse_is_empty(padapter, &empty) ==
true) {
514 offset = (addr >> 3) & 0xF;
526 if (data[idx] != pktdata[i]) {
527 word_en &= ~
BIT(i >> 1);
528 newdata[j++] = pktdata[i - 1];
529 newdata[j++] = data[
idx];
536 if ((cnts - idx) == 1) {
537 if (data[idx] != pktdata[i]) {
538 word_en &= ~
BIT(i >> 1);
539 newdata[j++] = data[
idx];
540 newdata[j++] = pktdata[1 + 1];
545 if ((data[idx] != pktdata[i]) || (data[idx+1] !=
547 word_en &= ~
BIT(i >> 1);
548 newdata[j++] = data[
idx];
549 newdata[j++] = data[idx + 1];
559 word_en, newdata) ==
false)
571 memset(newdata, 0xFF, PGPKT_DATA_SIZE);