/******************************************************************************
|
*
|
* Copyright(c) 2019 Realtek Corporation. All rights reserved.
|
*
|
* This program is free software; you can redistribute it and/or modify it
|
* under the terms of version 2 of the GNU General Public License as
|
* published by the Free Software Foundation.
|
*
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* more details.
|
*
|
******************************************************************************/
|
|
#include "flash.h"
|
#include "../mac_ax/fwcmd.h"
|
|
#if MAC_AX_FW_REG_OFLD
|
u32 mac_flash_erase(struct mac_ax_adapter *adapter,
|
u32 addr,
|
u32 length,
|
u32 timeout)
|
{
|
u32 ret = 0, pkt_len, local_timeout = 10000, no_timeout = 0;
|
u32 data[2];
|
|
struct h2c_info h2c_info = {0};
|
|
if (timeout == 0)
|
no_timeout = 1;
|
else
|
local_timeout = timeout;
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erase_done = 0;
|
adapter->flash_info.erasing = 1;
|
adapter->flash_info.erase_addr = addr;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
pkt_len = LEN_FLASH_H2C_HDR;
|
|
h2c_info.agg_en = 0;
|
h2c_info.content_len = (u16)pkt_len;
|
h2c_info.h2c_cat = FWCMD_H2C_CAT_MAC;
|
h2c_info.h2c_class = FWCMD_H2C_CL_FLASH;
|
h2c_info.h2c_func = FWCMD_H2C_FUNC_PLAT_FLASH_ERASE;
|
h2c_info.rec_ack = 0;
|
h2c_info.done_ack = 0;
|
|
data[0] = cpu_to_le32(addr);
|
data[1] = cpu_to_le32(length);
|
|
ret = mac_h2c_common(adapter, &h2c_info, (u32 *)&data[0]);
|
|
if (ret) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
|
while (1) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (adapter->flash_info.erase_done == 1) {
|
adapter->flash_info.erase_done = 0;
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
break;
|
}
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
//Sleep(50);
|
PLTFM_DELAY_MS(1);
|
if (no_timeout == 0) {
|
local_timeout--;
|
if (local_timeout == 0) {
|
ret = MACFLASHFAIL;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
}
|
}
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
return MACSUCCESS;
|
}
|
|
u32 mac_flash_read(struct mac_ax_adapter *adapter,
|
u32 addr,
|
u32 length,
|
u8 *buffer,
|
u32 timeout)
|
{
|
u32 ret = 0, pkt_len, local_timeout = 10000, no_timeout = 0;
|
u32 data[2];
|
|
struct h2c_info h2c_info = {0};
|
|
if (length > FLASH_H2C_SIZE)
|
return MACFLASHFAIL;
|
|
if (timeout == 0)
|
no_timeout = 1;
|
else
|
local_timeout = timeout;
|
|
if ((addr % 4) || (length % 4)) {
|
PLTFM_MSG_ERR("Address/length not 4 byte aligned, addr : 0x%x, length : 0x%x\n"
|
, addr, length);
|
return MACFLASHFAIL;
|
}
|
|
// mutex
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.read_done = 0;
|
adapter->flash_info.reading = 1;
|
adapter->flash_info.buf_addr = buffer;
|
adapter->flash_info.read_addr = addr;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
pkt_len = LEN_FLASH_H2C_HDR;
|
|
h2c_info.agg_en = 0;
|
h2c_info.content_len = (u16)pkt_len;
|
h2c_info.h2c_cat = FWCMD_H2C_CAT_MAC;
|
h2c_info.h2c_class = FWCMD_H2C_CL_FLASH;
|
h2c_info.h2c_func = FWCMD_H2C_FUNC_PLAT_FLASH_READ;
|
h2c_info.rec_ack = 0;
|
h2c_info.done_ack = 0;
|
|
data[0] = cpu_to_le32(addr);
|
data[1] = cpu_to_le32(length);
|
|
ret = mac_h2c_common(adapter, &h2c_info, (u32 *)&data[0]);
|
|
if (ret) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
adapter->flash_info.read_done = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
|
while (1) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
//PLTFM_MSG_TRACE("polling enter critical\n");
|
if (adapter->flash_info.read_done == 1) {
|
//PLTFM_MSG_TRACE("read DONE\n");
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
adapter->flash_info.read_done = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
break;
|
}
|
//PLTFM_MSG_TRACE("polling exit critical\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
//Sleep(1);
|
PLTFM_DELAY_MS(1);
|
if (no_timeout == 0) {
|
local_timeout--;
|
if (local_timeout == 0) {
|
ret = MACFLASHFAIL;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
adapter->flash_info.read_done = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
}
|
}
|
|
// end mutex
|
//adapter->flash_info.read_done == 0;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
return MACSUCCESS;
|
}
|
|
u32 mac_flash_write(struct mac_ax_adapter *adapter,
|
u32 addr,
|
u32 length,
|
u8 *buffer,
|
u32 timeout)
|
{
|
u8 *buf;
|
u32 ret = 0, residue_len, pkt_len, local_timeout = 5000, no_timeout = 0, i;
|
u32 data[2];
|
u32 waddr, wlength;
|
u32 *pbuf;
|
u32 *psource_data;
|
|
struct h2c_info h2c_info = {0};
|
|
if (timeout == 0)
|
no_timeout = 1;
|
else
|
local_timeout = timeout;
|
|
residue_len = length;
|
waddr = addr;
|
wlength = length;
|
|
if ((addr % 4) || (length % 4)) {
|
PLTFM_MSG_ERR("Address/length not 4 byte aligned, addr : 0x%x, length : 0x%x\n"
|
, addr, length);
|
return MACFLASHFAIL;
|
}
|
|
while (residue_len) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.write_done = 0;
|
adapter->flash_info.writing = 1;
|
adapter->flash_info.write_addr = waddr;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
if (residue_len >= FLASH_H2C_SIZE)
|
pkt_len = FLASH_H2C_SIZE;
|
else
|
pkt_len = residue_len;
|
|
h2c_info.agg_en = 0;
|
h2c_info.content_len = (u16)(pkt_len + LEN_FLASH_H2C_HDR);
|
h2c_info.h2c_cat = FWCMD_H2C_CAT_MAC;
|
h2c_info.h2c_class = FWCMD_H2C_CL_FLASH;
|
h2c_info.h2c_func = FWCMD_H2C_FUNC_PLAT_FLASH_WRITE;
|
h2c_info.rec_ack = 0;
|
h2c_info.done_ack = 0;
|
|
buf = (u8 *)PLTFM_MALLOC(h2c_info.content_len);
|
if (!buf) {
|
adapter->fw_info.h2c_seq--;
|
return MACBUFALLOC;
|
}
|
|
data[0] = cpu_to_le32(waddr);
|
data[1] = cpu_to_le32(pkt_len);
|
PLTFM_MEMCPY(buf, (u8 *)data, LEN_FLASH_H2C_HDR);
|
|
//copy data
|
pbuf = (u32 *)(buf + LEN_FLASH_H2C_HDR);
|
psource_data = (u32 *)buffer;
|
for (i = 0; i < (pkt_len / sizeof(u32)); i++) {
|
*pbuf = cpu_to_le32(*psource_data);
|
pbuf++;
|
psource_data++;
|
}
|
|
ret = mac_h2c_common(adapter, &h2c_info, (u32 *)buf);
|
|
if (ret) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
PLTFM_FREE(buf, h2c_info.content_len);
|
return ret;
|
}
|
|
PLTFM_MSG_ERR("Write H2C, addr = 0x%x, length = %d\n", waddr, pkt_len);
|
|
// delay for flash write
|
//Sleep(1000);
|
while (1) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (adapter->flash_info.write_done == 1) {
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
adapter->flash_info.write_done = 0;
|
PLTFM_MSG_TRACE("write DONE\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
break;
|
}
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
//Sleep(1);
|
PLTFM_DELAY_MS(1);
|
if (no_timeout == 0) {
|
local_timeout--;
|
if (local_timeout == 0) {
|
ret = MACFLASHFAIL;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
PLTFM_MSG_TRACE("write timeout\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
PLTFM_FREE(buf, h2c_info.content_len);
|
return ret;
|
}
|
}
|
}
|
|
PLTFM_FREE(buf, h2c_info.content_len);
|
residue_len -= pkt_len;
|
buffer += pkt_len;
|
waddr += pkt_len;
|
}
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
return MACSUCCESS;
|
}
|
|
#else
|
u32 mac_flash_erase(struct mac_ax_adapter *adapter,
|
u32 addr,
|
u32 length,
|
u32 timeout)
|
{
|
u32 ret = 0, pkt_len, local_timeout = 10000, no_timeout = 0;
|
u32 data[2];
|
|
struct h2c_info h2c_info = {0};
|
|
if (timeout == 0)
|
no_timeout = 1;
|
else
|
local_timeout = timeout;
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erase_done = 0;
|
adapter->flash_info.erasing = 1;
|
adapter->flash_info.erase_addr = addr;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
pkt_len = LEN_FLASH_H2C_HDR;
|
|
h2c_info.agg_en = 0;
|
h2c_info.content_len = (u16)pkt_len;
|
h2c_info.h2c_cat = FWCMD_H2C_CAT_MAC;
|
h2c_info.h2c_class = FWCMD_H2C_CL_FLASH;
|
h2c_info.h2c_func = FWCMD_H2C_FUNC_PLAT_FLASH_ERASE;
|
h2c_info.rec_ack = 0;
|
h2c_info.done_ack = 0;
|
|
data[0] = cpu_to_le32(addr);
|
data[1] = cpu_to_le32(length);
|
|
ret = mac_h2c_common(adapter, &h2c_info, (u32 *)&data[0]);
|
|
if (ret) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
|
while (1) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (adapter->flash_info.erase_done == 1) {
|
adapter->flash_info.erase_done = 0;
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
break;
|
}
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
//Sleep(50);
|
PLTFM_DELAY_MS(1);
|
if (no_timeout == 0) {
|
local_timeout--;
|
if (local_timeout == 0) {
|
ret = MACFLASHFAIL;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
}
|
}
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
return MACSUCCESS;
|
}
|
|
u32 mac_flash_read(struct mac_ax_adapter *adapter,
|
u32 addr,
|
u32 length,
|
u8 *buffer,
|
u32 timeout)
|
{
|
u32 ret = 0, pkt_len, local_timeout = 10000, no_timeout = 0;
|
u32 data[2];
|
|
struct h2c_info h2c_info = {0};
|
|
if (length > FLASH_H2C_SIZE)
|
return MACFLASHFAIL;
|
|
if (timeout == 0)
|
no_timeout = 1;
|
else
|
local_timeout = timeout;
|
|
if ((addr % 4) || (length % 4)) {
|
PLTFM_MSG_ERR("Address/length not 4 byte aligned, addr : 0x%x, length : 0x%x\n"
|
, addr, length);
|
return MACFLASHFAIL;
|
}
|
|
// mutex
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.read_done = 0;
|
adapter->flash_info.reading = 1;
|
adapter->flash_info.buf_addr = buffer;
|
adapter->flash_info.read_addr = addr;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
pkt_len = LEN_FLASH_H2C_HDR;
|
|
h2c_info.agg_en = 0;
|
h2c_info.content_len = (u16)pkt_len;
|
h2c_info.h2c_cat = FWCMD_H2C_CAT_MAC;
|
h2c_info.h2c_class = FWCMD_H2C_CL_FLASH;
|
h2c_info.h2c_func = FWCMD_H2C_FUNC_PLAT_FLASH_READ;
|
h2c_info.rec_ack = 0;
|
h2c_info.done_ack = 0;
|
|
data[0] = cpu_to_le32(addr);
|
data[1] = cpu_to_le32(length);
|
|
ret = mac_h2c_common(adapter, &h2c_info, (u32 *)&data[0]);
|
|
if (ret) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
adapter->flash_info.read_done = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
|
while (1) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
//PLTFM_MSG_TRACE("polling enter critical\n");
|
if (adapter->flash_info.read_done == 1) {
|
//PLTFM_MSG_TRACE("read DONE\n");
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
adapter->flash_info.read_done = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
break;
|
}
|
//PLTFM_MSG_TRACE("polling exit critical\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
//Sleep(1);
|
PLTFM_DELAY_MS(1);
|
if (no_timeout == 0) {
|
local_timeout--;
|
if (local_timeout == 0) {
|
ret = MACFLASHFAIL;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
adapter->flash_info.read_done = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
return ret;
|
}
|
}
|
}
|
|
// end mutex
|
//adapter->flash_info.read_done == 0;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.buf_addr = NULL;
|
adapter->flash_info.read_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
return MACSUCCESS;
|
}
|
|
u32 mac_flash_write(struct mac_ax_adapter *adapter,
|
u32 addr,
|
u32 length,
|
u8 *buffer,
|
u32 timeout)
|
{
|
u8 *buf;
|
u32 ret = 0, residue_len, pkt_len, local_timeout = 5000, no_timeout = 0, i;
|
u32 data[2];
|
u32 waddr, wlength;
|
u32 *pbuf;
|
u32 *psource_data;
|
|
struct h2c_info h2c_info = {0};
|
|
if (timeout == 0)
|
no_timeout = 1;
|
else
|
local_timeout = timeout;
|
|
residue_len = length;
|
waddr = addr;
|
wlength = length;
|
|
if ((addr % 4) || (length % 4)) {
|
PLTFM_MSG_ERR("Address/length not 4 byte aligned, addr : 0x%x, length : 0x%x\n"
|
, addr, length);
|
return MACFLASHFAIL;
|
}
|
|
while (residue_len) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.write_done = 0;
|
adapter->flash_info.writing = 1;
|
adapter->flash_info.write_addr = waddr;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
|
if (residue_len >= FLASH_H2C_SIZE)
|
pkt_len = FLASH_H2C_SIZE;
|
else
|
pkt_len = residue_len;
|
|
h2c_info.agg_en = 0;
|
h2c_info.content_len = (u16)(pkt_len + LEN_FLASH_H2C_HDR);
|
h2c_info.h2c_cat = FWCMD_H2C_CAT_MAC;
|
h2c_info.h2c_class = FWCMD_H2C_CL_FLASH;
|
h2c_info.h2c_func = FWCMD_H2C_FUNC_PLAT_FLASH_WRITE;
|
h2c_info.rec_ack = 0;
|
h2c_info.done_ack = 0;
|
|
buf = (u8 *)PLTFM_MALLOC(h2c_info.content_len);
|
if (!buf) {
|
adapter->fw_info.h2c_seq--;
|
return MACBUFALLOC;
|
}
|
|
data[0] = cpu_to_le32(waddr);
|
data[1] = cpu_to_le32(pkt_len);
|
PLTFM_MEMCPY(buf, (u8 *)data, LEN_FLASH_H2C_HDR);
|
|
//copy data
|
pbuf = (u32 *)(buf + LEN_FLASH_H2C_HDR);
|
psource_data = (u32 *)buffer;
|
for (i = 0; i < (pkt_len / sizeof(u32)); i++) {
|
*pbuf = cpu_to_le32(*psource_data);
|
pbuf++;
|
psource_data++;
|
}
|
|
ret = mac_h2c_common(adapter, &h2c_info, (u32 *)buf);
|
|
if (ret) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
PLTFM_FREE(buf, h2c_info.content_len);
|
return ret;
|
}
|
|
PLTFM_MSG_ERR("Write H2C, addr = 0x%x, length = %d\n", waddr, pkt_len);
|
|
// delay for flash write
|
//Sleep(1000);
|
while (1) {
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (adapter->flash_info.write_done == 1) {
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
adapter->flash_info.write_done = 0;
|
PLTFM_MSG_TRACE("write DONE\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
break;
|
}
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
//Sleep(1);
|
PLTFM_DELAY_MS(1);
|
if (no_timeout == 0) {
|
local_timeout--;
|
if (local_timeout == 0) {
|
ret = MACFLASHFAIL;
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
PLTFM_MSG_TRACE("write timeout\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
adapter->fw_info.h2c_seq--;
|
PLTFM_FREE(buf, h2c_info.content_len);
|
return ret;
|
}
|
}
|
}
|
|
PLTFM_FREE(buf, h2c_info.content_len);
|
residue_len -= pkt_len;
|
buffer += pkt_len;
|
waddr += pkt_len;
|
}
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_addr = 0;
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
return MACSUCCESS;
|
}
|
|
#endif
|
|
u32 c2h_sys_flash_pkt(struct mac_ax_adapter *adapter, u8 *buf, u32 len,
|
struct rtw_c2h_info *info)
|
{
|
u32 hdr0, i;
|
u32 func, length, addr;
|
u32 *pbuf;
|
u32 *psource_data;
|
|
PLTFM_MSG_TRACE("%s\n", __func__);
|
hdr0 = ((struct fwcmd_hdr *)buf)->hdr0;
|
hdr0 = le32_to_cpu(hdr0);
|
|
//set info
|
info->c2h_cat = GET_FIELD(hdr0, C2H_HDR_CAT);
|
info->c2h_class = GET_FIELD(hdr0, C2H_HDR_CLASS);
|
info->c2h_func = GET_FIELD(hdr0, C2H_HDR_FUNC);
|
//info->done_ack = 0;
|
//info->rec_ack = 0;
|
info->content = buf + FWCMD_HDR_LEN;
|
//info->h2c_return = info->c2h_data[1];
|
|
func = GET_FIELD(hdr0, C2H_HDR_FUNC);
|
|
if (func == FWCMD_H2C_FUNC_PLAT_FLASH_READ) {
|
addr = *((u32 *)info->content);
|
addr = le32_to_cpu(addr);
|
length = *((u32 *)(info->content + LEN_FLASH_C2H_HDR_ADDR));
|
length = le32_to_cpu(length);
|
PLTFM_MSG_TRACE("addr = 0x%x, length = 0x%x\n", addr, length);
|
PLTFM_MSG_TRACE("adapter->flash_info.read_addr = 0x%x\n",
|
adapter->flash_info.read_addr);
|
//PLTFM_MSG_TRACE("adapter->flash_info.buf_addr = 0x%llx\n",
|
//(u64)adapter->flash_info.buf_addr);
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (addr == adapter->flash_info.read_addr && adapter->flash_info.reading == 1) {
|
// lost data if timeout happened
|
//PLTFM_MSG_TRACE("ready to read\n");
|
if (adapter->flash_info.buf_addr && length <= MAX_READ_SIZE) {
|
PLTFM_MSG_TRACE("memcpy to buf\n");
|
//PLTFM_MEMCPY(adapter->flash_info.buf_addr,
|
// info->content + LEN_FLASH_C2H_HDR, length);
|
pbuf = (u32 *)adapter->flash_info.buf_addr;
|
psource_data = (u32 *)(info->content + LEN_FLASH_C2H_HDR);
|
for (i = 0; i < length / sizeof(u32); i++) {
|
*pbuf = le32_to_cpu(*psource_data);
|
pbuf++;
|
psource_data++;
|
}
|
//PLTFM_MSG_TRACE("memcpy to buf end\n");
|
}
|
}
|
//PLTFM_MSG_TRACE("set reading = 0\n");
|
adapter->flash_info.reading = 0;
|
adapter->flash_info.read_done = 1;
|
//PLTFM_MSG_TRACE("set reading = 0 end\n");
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
//PLTFM_MSG_TRACE("exit critical\n");
|
} else if (func == FWCMD_H2C_FUNC_PLAT_FLASH_WRITE) {
|
addr = *((u32 *)info->content);
|
addr = le32_to_cpu(addr);
|
length = *((u32 *)(info->content + LEN_FLASH_C2H_HDR_ADDR));
|
length = le32_to_cpu(length);
|
PLTFM_MSG_TRACE("write addr = 0x%x\n", *((u32 *)info->content));
|
PLTFM_MSG_TRACE("adapter->flash_info.write_addr = 0x%x\n",
|
adapter->flash_info.write_addr);
|
PLTFM_MSG_TRACE("write length = 0x%x\n", length);
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (addr == adapter->flash_info.write_addr && adapter->flash_info.writing == 1) {
|
adapter->flash_info.writing = 0;
|
adapter->flash_info.write_done = 1;
|
}
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
} else if (func == FWCMD_H2C_FUNC_PLAT_FLASH_ERASE) {
|
addr = *((u32 *)info->content);
|
addr = le32_to_cpu(addr);
|
length = *((u32 *)(info->content + LEN_FLASH_C2H_HDR_ADDR));
|
length = le32_to_cpu(length);
|
PLTFM_MSG_TRACE("erase addr = 0x%x\n", *((u32 *)info->content));
|
PLTFM_MSG_TRACE("adapter->flash_info.erase_addr = 0x%x\n",
|
adapter->flash_info.erase_addr);
|
PLTFM_MSG_TRACE("erase length = 0x%x\n", length);
|
|
PLTFM_MUTEX_LOCK(&adapter->flash_info.lock);
|
if (addr == adapter->flash_info.erase_addr && adapter->flash_info.erasing == 1) {
|
adapter->flash_info.erasing = 0;
|
adapter->flash_info.erase_done = 1;
|
}
|
PLTFM_MUTEX_UNLOCK(&adapter->flash_info.lock);
|
}
|
|
return MACSUCCESS;
|
}
|