Files
luban-lite/bsp/peripheral/wireless/atbm603x/hal/usb/atbm_usb_fwio.c
刘可亮 8bca5e8332 v1.0.4
2024-04-03 16:40:57 +08:00

254 lines
6.4 KiB
C

/**************************************************************************************************************
* altobeam RTOS
*
* Copyright (c) 2018, altobeam.inc All rights reserved.
*
* The source code contains proprietary information of AltoBeam, and shall not be distributed,
* copied, reproduced, or disclosed in whole or in part without prior written permission of AltoBeam.
*****************************************************************************************************************/
#include "atbm_hal.h"
#if (PROJ_TYPE == ATHENA_LITE)
#include "firmware_lite.h"
#elif (PROJ_TYPE == ATHENA_B)
#if ATBM_TX_SKB_NO_TXCONFIRM
#include "firmware_athenaB_usb_notxconfirm.h"
#else //ATBM_TX_SKB_NO_TXCONFIRM
#include "firmware_athenaB_usb.h"
#endif //ATBM_TX_SKB_NO_TXCONFIRM
#elif ((PROJ_TYPE == ARES_A) || (PROJ_TYPE == ARES_B) )
#if ATBM_TX_SKB_NO_TXCONFIRM
#if USE_COMPRESSED_FIRMWARE
#include "compress.h"
#include "firmware_ares_usb_notxconfirm_compress.h"
#else
#include "firmware_ares_usb_notxconfirm.h"
#endif
#else
#include "firmware_ares_usb.h"
#endif
#elif (PROJ_TYPE == ASMLITE)
#if CONFIG_WIFI_BT_COMB
#include "firmware_asmlite_usb_combo_notxconfirm.h"
#else
#include "firmware_asmlite_usb_notxconfirm.h"
#endif
#elif (PROJ_TYPE == MERCURIUS)
#include "firmware_mercurius_usb_notxconfirm.h"
#else
#error error, project type is invalid.
#endif //ATHENA_LITE
static struct firmware_altobeam fw_altobeam;
extern int atbm_direct_read_reg_32(struct atbmwifi_common *hw_priv, atbm_uint32 addr, atbm_uint32 *val);
atbm_void atbm_release_firmware(atbm_void)
{
wifi_printk(WIFI_ALWAYS,"atbm_release_firmware\n");
}
int atbm_init_firmware(atbm_void)
{
wifi_printk(WIFI_ALWAYS,"atbm_init_firmware\n");
atbm_memset(&fw_altobeam,0,sizeof(struct firmware_altobeam));
return 0;
}
static int atbm_load_firmware_generic(struct atbmwifi_common *priv, atbm_uint8 *data,atbm_uint32 size,atbm_uint32 addr)
{
int ret=0;
atbm_uint32 put = 0;
atbm_uint8 *buf = ATBM_NULL;
buf = atbm_kmalloc(DOWNLOAD_BLOCK_SIZE*2,GFP_KERNEL);
if (!buf) {
wifi_printk(WIFI_DBG_ERROR,
"%s: can't allocate bootloader buffer.\n", __FUNCTION__);
ret = -ATBM_ENOMEM;
goto error;
}
//if(priv->sbus_ops->bootloader_debug_config)
// priv->sbus_ops->bootloader_debug_config(priv->sbus_priv,0);
/* downloading loop */
wifi_printk(WIFI_ALWAYS,"%s: addr %x: len %x\n",__FUNCTION__,addr,size);
for (put = 0; put < size ;put += DOWNLOAD_BLOCK_SIZE) {
atbm_uint32 tx_size;
/* calculate the block size */
tx_size = atbm_min((size - put),(atbm_uint32)DOWNLOAD_BLOCK_SIZE);
atbm_memcpy(buf, &data[put], tx_size);
/* send the block to sram */
ret = atbm_fw_write(priv,put+addr,buf, tx_size);
if (ret < 0) {
wifi_printk(WIFI_DBG_ERROR,
"%s: can't write block at line %d.\n",
__FUNCTION__, __LINE__);
goto error;
}
} /* End of bootloader download loop */
error:
atbm_kfree(buf);
return ret;
}
char * atbm_HwGetChipFw(struct atbmwifi_common *priv)
{
atbm_uint32 chipver = 0;
char * strHwChipFw;
atbm_direct_read_reg_32(priv,0x0acc017c,&chipver);
chipver&=0x3f;
switch(chipver)
{
case 0x0:
strHwChipFw = ("ApolloC0.bin");
break;
case 0x1:
strHwChipFw = ("ApolloC0_TC.bin");
break;
case 0x3:
strHwChipFw = ("ApolloC1_TC.bin");
break;
case 0xc:
strHwChipFw = ("ApolloD.bin");
break;
case 0xd:
strHwChipFw = ("ApolloD_TC.bin");
break;
case 0x10:
strHwChipFw = ("ApolloE.bin");
break;
case 0x20:
strHwChipFw = ("AthenaA.bin");
break;
case 0x14:
strHwChipFw = ("ApolloF.bin");
break;
case 0x15:
strHwChipFw = ("ApolloF_TC.bin");
break;
case 0x24:
strHwChipFw = ("AthenaB.bin");
break;
case 0x25:
strHwChipFw = ("AthenaBX.bin");
break;
case 0x18:
strHwChipFw = ("Apollo_FM.bin");
break;
default:
strHwChipFw = FIRMWARE_DEFAULT_PATH;
break;
}
wifi_printk(WIFI_ALWAYS,"%s, chipver=0x%x, use fw [%s]\n",__FUNCTION__, chipver,strHwChipFw );
return strHwChipFw;
}
#if USE_COMPRESSED_FIRMWARE
static int decopress_callback(CBP *cbp, atbm_uint8 *addr, int offset, int size){
return atbm_load_firmware_generic(cbp->priv,addr,size,cbp->addr+offset);
}
static int atbm_start_load_firmware(struct atbmwifi_common *priv)
{
CBP cbp;
cbp.addr = DOWNLOAD_ITCM_ADDR;
cbp.priv = priv;
cbp.cb = decopress_callback;
fcs_decompress(&fw_code, &cbp);
cbp.addr = DOWNLOAD_DTCM_ADDR;
fcs_decompress(&fw_data, &cbp);
}
#else
//#define USED_FW_FILE
static int atbm_start_load_firmware(struct atbmwifi_common *priv)
{
int ret;
struct firmware_headr* hdr = (struct firmware_headr*)firmware_headr;
wifi_printk(WIFI_DBG_ERROR,"%s: used firmware.h=\n", __FUNCTION__);
fw_altobeam.hdr.iccm_len = sizeof(fw_code);
fw_altobeam.hdr.dccm_len = sizeof(fw_data);
fw_altobeam.fw_iccm = &fw_code[0];
fw_altobeam.fw_dccm = &fw_data[0];
#if CONFIG_WIFI_BT_COMB
fw_altobeam.hdr.sram_len = sizeof(fw_sram);
if (hdr->flags == ALTOBEAM_WIFI_HDR_FLAG_V2)
fw_altobeam.hdr.sram_addr = hdr->sram_addr;
else
fw_altobeam.hdr.sram_addr = DOWNLOAD_BLE_SRAM_ADDR;
fw_altobeam.fw_sram = &fw_sram[0];
#endif
wifi_printk(WIFI_DBG_ERROR,"%s: START DOWNLOAD ICCM=========\n", __FUNCTION__);
ret = atbm_load_firmware_generic(priv,fw_altobeam.fw_iccm,fw_altobeam.hdr.iccm_len,DOWNLOAD_ITCM_ADDR);
if(ret<0)
goto error;
if(fw_altobeam.hdr.dccm_len > 0x9000)
fw_altobeam.hdr.dccm_len = 0x9000;
wifi_printk(WIFI_DBG_ERROR,"%s: START DOWNLOAD DCCM=========\n", __FUNCTION__);
ret = atbm_load_firmware_generic(priv,fw_altobeam.fw_dccm,fw_altobeam.hdr.dccm_len,DOWNLOAD_DTCM_ADDR);
if(ret<0)
goto error;
#if CONFIG_WIFI_BT_COMB
if(fw_altobeam.hdr.sram_len){
wifi_printk(WIFI_DBG_ERROR,"START DOWNLOAD BLE SRAM=========\n");
ret = atbm_load_firmware_generic(priv, fw_altobeam.fw_sram, fw_altobeam.hdr.sram_len, fw_altobeam.hdr.sram_addr);
if(ret<0)
goto error;
}
#endif
wifi_printk(WIFI_DBG_ERROR, "%s: FIRMWARE DOWNLOAD SUCCESS\n",__FUNCTION__);
error:
return ret;
}
#endif
int atbm_load_firmware(struct atbmwifi_common *hw_priv)
{
int ret;
wifi_printk(WIFI_ALWAYS,"atbm_before_load_firmware++\n");
ret = atbm_before_load_firmware(hw_priv);
if(ret <0)
goto out;
wifi_printk(WIFI_ALWAYS,"atbm_start_load_firmware++\n");
ret = atbm_start_load_firmware(hw_priv);
if(ret <0)
goto out;
wifi_printk(WIFI_ALWAYS,"atbm_after_load_firmware++\n");
ret = atbm_after_load_firmware(hw_priv);
if(ret <0){
goto out;
}
ret =0;
out:
return ret;
}