/*
 * \file        optimus_buffer_manager.c
 * \brief       buffer manager for download data: A thin layer between receiving partition data and writing flash
 *
 * \version     1.0.0
 * \date        2013/5/2
 * \author      Sam.Wu <yihui.wu@Amlogic.com>
 *
 * Copyright (c) 2013 Amlogic Inc.. All Rights Reserved.
 *
 */
#include "../v2_burning_i.h"

#define OPTIMUS_SLOT_STA_FREE               (0)//buffer slot not used yet
#define OPTIMUS_SLOT_STA_USED               (0xee)//buffer slot current used for download
#define OPTIMUS_SLOT_STA_LEFT               (0xdd)//buffer slot not disposed over

#define PKT_TRANSFER_STA_EMPTY              0
#define PKT_TRANSFER_STA_WORKING            1
#define PKT_TRANSFER_STA_END                2

typedef struct bufManager{
    const u8*       transferBuf;//transfer buffer address
    const u32       transferBufSz;//transfer buffer size to

    const u32       transferUnitSz;//64k
    u32             writeBackUnitSz;//for NAND is transferSz, for sparse is transferUnitSz

    u64             tplcmdTotalSz;//total size of a file-system packet

    u32             totalSlotNum;//total slot number that already tranfferred
    u32             mediaAlignSz;//nand write align size, 16K/32k

    u32             nextWriteBackSlot;//when reach n* (writeBackUnitSz/transferUnitSz), then write back the recevied data to media
    u32             leftDataSz;//left data size, Assert that 'leftDataInBackBuf + leftDataSz == transferBuf'

    s16             isUpload;
    s16             pktTransferSta;
    u32             destMediaType;

    u32             partBaseOffset;//TODO: change it to memory address when dest media type is memory
    u32             itemOffsetNotAlignClusterSz_f;//For sdcard burning, item offset of aml_upgrade_package.img is not aligned to bytespercluster of FAT fs(_f means not changed inited)

}BufManager;

//TODO: if want to speed-up such as soft PING-PONG buffer, use multiple BufManager
static BufManager _bufManager =
{
//constant members
    .transferBuf        = (const u8*)OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR,
    .transferBufSz      = OPTIMUS_DOWNLOAD_TRANSFER_BUF_TOTALSZ,
    .transferUnitSz     = OPTIMUS_DOWNLOAD_SLOT_SZ,

//different for each command, note a command corresponding to a download file
//must create/destroy for a command
    .writeBackUnitSz    = OPTIMUS_DOWNLOAD_SLOT_SZ,

    .totalSlotNum      = 0,//not slot data recevied yet!

    .leftDataSz         = 0,
    .tplcmdTotalSz      = 0,
    .nextWriteBackSlot  = 0,//always 0 when upload??

    .isUpload           = 0,
    .pktTransferSta     = PKT_TRANSFER_STA_EMPTY,

    .itemOffsetNotAlignClusterSz_f  = 0,
};

int optimus_buf_manager_init(const unsigned mediaAlignSz)
{
    if (OPTIMUS_DOWNLOAD_TRANSFER_BUF_ADDR != (uint64_t)_bufManager.transferBuf) {
        DWN_ERR("Fatal fail in init-express, init here instead!\n");
        return OPT_DOWN_FAIL;
    }
    _bufManager.mediaAlignSz = mediaAlignSz;

    DWN_DBG("transfer=0x%p, transferBufSz=0x%x, transferUnitSz=0x%x, writeBackUnitSz=0x%x, totalSlotNum=%d\n", _bufManager.transferBuf,
            _bufManager.transferBufSz,  _bufManager.transferUnitSz,     _bufManager.writeBackUnitSz,        _bufManager.totalSlotNum);

    return OPT_DOWN_OK;
}

int optimus_buf_manager_exit(void)
{
    return 0;
}

int optimus_buf_manager_tplcmd_init(const char* mediaType,  const char* partName,   const u64 partBaseOffset,
                            const char* imgType, const u64 pktTotalSz, const int isUpload,
                            const unsigned itemSizeNotAligned /* if item offset 3 and bytepercluste 4k, then it's 4k -3 */)
{
    u32 writeBackUnitSz = OPTIMUS_VFAT_IMG_WRITE_BACK_SZ;
    const u64 pktSz4BufManager = pktTotalSz - itemSizeNotAligned;

    int cacheAll2Mem = 0;
#if OPTIMUS_BURN_TARGET_SUPPORT_UBIFS
    if ( !strcmp(imgType, "ubifs") ) cacheAll2Mem = 1;
#endif // #if OPTIMUS_BURN_TARGET_SUPPORT_UBIFS

    if (!strcmp("sparse", imgType)
            || itemSizeNotAligned/* use max memory if item 'itemOffset % bytespercluster != 0'*/)
    {
        writeBackUnitSz = OPTIMUS_SIMG_WRITE_BACK_SZ;
    }

    if (!strcmp("bootloader", partName) || !strcmp("_aml_dtb", partName)
#if defined(CONFIG_AML_MTD) && defined(CONFIG_TPL_PART_NAME)
        || ( !strcmp(CONFIG_TPL_PART_NAME, partName) )
#endif//#if defined(CONFIG_AML_MTD)
       )
    {
        if (pktSz4BufManager > _bufManager.transferBufSz) {
            DWN_ERR("packet size 0x%x too large, max is 0x%x\n", (u32)pktSz4BufManager, _bufManager.transferBufSz);
            return OPT_DOWN_FAIL;
        }
        /*writeBackUnitSz = OPTIMUS_BOOTLOADER_MAX_SZ;*/
        writeBackUnitSz             = pktSz4BufManager + _bufManager.transferUnitSz - 1;
        writeBackUnitSz             >>= OPTIMUS_DOWNLOAD_SLOT_SZ_SHIFT_BITS;
        writeBackUnitSz             <<= OPTIMUS_DOWNLOAD_SLOT_SZ_SHIFT_BITS;
    }

    _bufManager.destMediaType   = !strcmp("mem", mediaType) ? OPTIMUS_MEDIA_TYPE_MEM : OPTIMUS_MEDIA_TYPE_STORE ;
    if ( !cacheAll2Mem ) cacheAll2Mem = !strcmp("mem", mediaType) ;
    if (cacheAll2Mem)
    {
            writeBackUnitSz             = pktSz4BufManager + _bufManager.transferUnitSz - 1;
            writeBackUnitSz             >>= OPTIMUS_DOWNLOAD_SLOT_SZ_SHIFT_BITS;
            writeBackUnitSz             <<= OPTIMUS_DOWNLOAD_SLOT_SZ_SHIFT_BITS;

        if (partBaseOffset>>32) {
            DWN_ERR("partBaseOffset 0x%llx more than 4G!!\n", partBaseOffset);
            return OPT_DOWN_FAIL;
        }
        _bufManager.partBaseOffset = (u32)partBaseOffset;
    }

    if (_bufManager.transferBufSz < writeBackUnitSz && !cacheAll2Mem) {
        DWN_ERR("write back size 0x%x > max size 0x%x\n", writeBackUnitSz, _bufManager.transferBufSz);
        return OPT_DOWN_FAIL;
    }
    if (_bufManager.transferUnitSz > writeBackUnitSz) {
        DWN_ERR("write back size %d < align size %d\n", writeBackUnitSz, _bufManager.mediaAlignSz);
        return OPT_DOWN_FAIL;
    }
    DWN_DBG("writeBackUnitSz = 0x%x, pktSz4BufManager = %lld\n", writeBackUnitSz, pktSz4BufManager);

    _bufManager.writeBackUnitSz     = writeBackUnitSz;
    _bufManager.totalSlotNum        = 0;
    _bufManager.isUpload            = isUpload;
    _bufManager.pktTransferSta      = PKT_TRANSFER_STA_EMPTY;

    if (_bufManager.isUpload)
    {
        _bufManager.nextWriteBackSlot = 0;//always 0 if upload
    }
    else//has write back if download
    {
        if (pktSz4BufManager < writeBackUnitSz)
        {
            _bufManager.nextWriteBackSlot  = ((u32)pktSz4BufManager + _bufManager.transferUnitSz - 1)/_bufManager.transferUnitSz;//first slot index to write back to media
        }
        else
        {
            _bufManager.nextWriteBackSlot  = writeBackUnitSz/_bufManager.transferUnitSz;//first slot index to write back to media
        }

    }

    _bufManager.itemOffsetNotAlignClusterSz_f = itemSizeNotAligned;
    _bufManager.leftDataSz                  = itemSizeNotAligned;//data size in the buffer that not write back to media yet in previous transfer
    _bufManager.tplcmdTotalSz               = pktSz4BufManager;

    optimus_progress_init((u32)(_bufManager.tplcmdTotalSz>>32), (u32)_bufManager.tplcmdTotalSz, 0, 100);
    DWN_MSG("totalSlotNum = %d, nextWriteBackSlot %d\n", _bufManager.totalSlotNum, _bufManager.nextWriteBackSlot);

    return OPT_DOWN_OK;
}

int optimus_buf_manager_get_buf_for_bulk_transfer(char** pBuf, const unsigned wantSz, const unsigned sequenceNo, char* errInfo)
{
    const unsigned totalSlotNum      = _bufManager.totalSlotNum;
    const u64 totalTransferSz        = ((u64)totalSlotNum) * _bufManager.transferUnitSz;//data size already transferred
    const u64 leftPktSz              = (totalTransferSz > _bufManager.tplcmdTotalSz) ? 0 :(_bufManager.tplcmdTotalSz - totalTransferSz);
    const int isLastTransfer         = (leftPktSz == wantSz);//totalTransferSz + wantSz >= _bufManager.tplcmdTotalSz;
    const u32 bufSzNotDisposed       = ((u32)totalTransferSz)% _bufManager.writeBackUnitSz;//buffer data not disposed, bufSz is always writeBackUnitSz
    const u8* BufBase = (OPTIMUS_MEDIA_TYPE_MEM != _bufManager.destMediaType)  ? _bufManager.transferBuf :
                        (u8*)(u64)_bufManager.partBaseOffset ;

    if (wantSz < _bufManager.transferUnitSz && !isLastTransfer) {
        DWN_ERR("only last transfer can less 64K, this index %d at size 0x%u illegle\n", totalSlotNum + 1, wantSz);
        return OPT_DOWN_FAIL;
    }

    //TODO: totalSlotNum + 1 == sequenceNo
    if (totalSlotNum + 1 != sequenceNo) {//ASSERT it ??

    }

    *pBuf  = (char*)(bufSzNotDisposed + BufBase);
    DWN_DBG("bufSzNotDisposed 0x%x, _bufManager.transferBuf 0x%p, _bufManager.partBaseOffset 0x%x, *pBuf 0x%p\n",
            bufSzNotDisposed, _bufManager.transferBuf, _bufManager.partBaseOffset, *pBuf);

    _bufManager.pktTransferSta      = PKT_TRANSFER_STA_WORKING;

    //prepare data for upload
    if (!bufSzNotDisposed && _bufManager.isUpload)
    {
        u32 wantSz = (leftPktSz > _bufManager.writeBackUnitSz) ? _bufManager.writeBackUnitSz : ((u32)leftPktSz);
        DWN_DBG("want size 0x%x\n", wantSz);

        u32 readSz = optimus_dump_storage_data((u8*)BufBase, wantSz, errInfo);
        if (readSz != wantSz) {
            DWN_ERR("Want read %u, but %u\n", wantSz, readSz);
            return OPT_DOWN_FAIL;
        }
    }

    return OPT_DOWN_OK;
}

int optimus_buf_manager_report_transfer_complete(const u32 transferSz, char* errInfo)
{
    const unsigned totalSlotNum      = _bufManager.totalSlotNum;
    const u64 totalTransferSz        = ((u64)totalSlotNum) * _bufManager.transferUnitSz + transferSz;
    const u64 leftPktSz              = (totalTransferSz > _bufManager.tplcmdTotalSz) ? 0 :(_bufManager.tplcmdTotalSz - totalTransferSz);
    const u32 thisWriteBackSz        = (_bufManager.transferUnitSz == transferSz) ? _bufManager.writeBackUnitSz : ((u32)totalTransferSz % _bufManager.writeBackUnitSz);
    const u8* BufBase = (OPTIMUS_MEDIA_TYPE_MEM != _bufManager.destMediaType)  ? _bufManager.transferBuf :
                        (u8*)(u64)_bufManager.partBaseOffset ;

    DWN_DBG("transferSz=0x%x\n", transferSz);
    //state fileds to update
    _bufManager.totalSlotNum += 1;
    if (_bufManager.totalSlotNum == _bufManager.nextWriteBackSlot)
    {
        u32   burnSz   = 0;
        u32   leftSz   = _bufManager.leftDataSz;//data size not write to media in previous write back, > 0 only when not normal packet
        const u32 size = leftSz + thisWriteBackSz;
        const u8* data = (u8*)BufBase -leftSz;
        const unsigned reserveNotAlignSz = leftPktSz ? _bufManager.itemOffsetNotAlignClusterSz_f : 0;//reserve

        //call cb function to write to media
        DWN_DBG("size 0x%x, reserveNotAlignSz 0x%x\n", size, reserveNotAlignSz);
        burnSz = optimus_download_img_data(data, size - reserveNotAlignSz, errInfo);
        if (burnSz <= leftSz || !burnSz) {
            DWN_ERR("this burn size %d <= last left size %d, data 0x%p\n", burnSz, leftSz, data);
            return OPT_DOWN_FAIL;
        }
        if (size - reserveNotAlignSz < burnSz) {
            DWN_ERR("Exception:siz 0x%x < burnSz 0x%x\n", size - reserveNotAlignSz, burnSz);
            return OPT_DOWN_FAIL;
        }

        leftSz = size - burnSz;
        if (leftSz)
        {
            const u8* src = data + burnSz;
            u8* dest = (u8*)BufBase - leftSz;

            if (totalTransferSz >= _bufManager.tplcmdTotalSz) {
                DWN_ERR("Exception:packet end but data left 0x%x, totalTransferSz 0x%llx, cmd sz 0x%llx!\n",
                        leftSz, totalTransferSz, _bufManager.tplcmdTotalSz);
                return OPT_DOWN_FAIL;
            }

            if (leftSz > OPTIMUS_SPARSE_IMG_LEFT_DATA_MAX_SZ) {
                DWN_ERR("Exception, left data sz 0x%x > back buf sz 0x%x!\n", leftSz, OPTIMUS_SPARSE_IMG_LEFT_DATA_MAX_SZ);
                return OPT_DOWN_FAIL;
            }
            if (leftSz & 0x03) {
                DWN_ERR("Exception, copy size not align to 4! May will copy fail!\n");
                return OPT_DOWN_FAIL;
            }

            DWN_DBG("MV:left size 0x%08x, src %p, dest %p\n", leftSz, src, dest);
            memcpy(dest, src, leftSz);
        }

        //update _bufManager.leftDataSz and _bufManager.nextWriteBackSlot
        _bufManager.leftDataSz = leftSz;
        if (leftPktSz >= _bufManager.writeBackUnitSz)
        {
            _bufManager.nextWriteBackSlot += _bufManager.writeBackUnitSz/_bufManager.transferUnitSz;
        }
        else
        {
            _bufManager.nextWriteBackSlot += ((u32)leftPktSz + _bufManager.transferUnitSz - 1)/_bufManager.transferUnitSz;
        }
    }

    optimus_update_progress(transferSz);//report burning steps
    return OPT_DOWN_OK;
}

int is_largest_data_transferring(void)
{
    const unsigned totalSlotNum      = _bufManager.totalSlotNum;
    const u64 totalTransferSz        = ((u64)totalSlotNum) * _bufManager.transferUnitSz;//data size already transferred

    return (PKT_TRANSFER_STA_WORKING == _bufManager.pktTransferSta)
        && (_bufManager.tplcmdTotalSz > totalTransferSz);//as last packet may less than 64k, var totalSlotNum may > _bufManager.tplcmdTotalSz
}

int set_largest_data_transfer_sta_end(void)
{
    _bufManager.pktTransferSta = PKT_TRANSFER_STA_END;
    return 0;
}

//command data format: [0-3]reserver, [4-7]dataLen, [8-11]sequence number, [12-15]check sum
int optimus_buf_manager_get_command_data_for_upload_transfer(u8* cmdDataBuf, const unsigned bufLen)
{
    const unsigned totalSlotNum      = _bufManager.totalSlotNum;
    const u64 totalTransferSz        = ((u64)totalSlotNum) * _bufManager.transferUnitSz;
    const u64 leftPktSz              = (totalTransferSz > _bufManager.tplcmdTotalSz) ? 0 :(_bufManager.tplcmdTotalSz - totalTransferSz);
    const unsigned thisTransDataLen = (leftPktSz > _bufManager.transferUnitSz) ? _bufManager.transferUnitSz : ((u32)leftPktSz);

    DWN_DBG("thisTransDataLen 0x%x, left 0x%x, total 0x%x\n", thisTransDataLen, (u32)leftPktSz, (u32)totalTransferSz);
    DWN_DBG("totalSlotNum %d, totalTransferSz 0x%x\n", totalSlotNum, (u32)totalTransferSz);
    memset(cmdDataBuf, bufLen, 0);
    *(unsigned*)(cmdDataBuf + 0) = 0xefe8;
    *(unsigned*)(cmdDataBuf + 4) = thisTransDataLen;//Fill transfer data length of this bulk transfer

    _bufManager.pktTransferSta      = PKT_TRANSFER_STA_WORKING;
    return 0;
}


