/*
 * Copyright (c) 2012, 2014, 2016-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

#include "hif.h"
#include "bmi.h"
#include "bmi_internal.h"
#include "ol_fw.h"

#ifdef HIF_MESSAGE_BASED

#ifdef HIF_USB
#include "a_usb_defs.h"
#endif

#if defined(HIF_BMI_MAX_TRANSFER_SIZE)

#if BMI_DATASZ_MAX > HIF_BMI_MAX_TRANSFER_SIZE
    /* override */
#undef BMI_DATASZ_MAX
#define BMI_DATASZ_MAX  HIF_BMI_MAX_TRANSFER_SIZE
#endif
#endif

#endif

#ifdef WLAN_DEBUG
static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = {
    { ATH_DEBUG_BMI , "BMI Tracing"},
};

ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
                                 "bmi",
                                 "Boot Manager Interface",
                                 ATH_DEBUG_MASK_DEFAULTS,
                                 ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
                                 bmi_debug_desc);

#endif

/*
Although we had envisioned BMI to run on top of HTC, this is not how the
final implementation ended up. On the Target side, BMI is a part of the BSP
and does not use the HTC protocol nor even DMA -- it is intentionally kept
very simple.
*/

#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
                       sizeof(A_UINT32) /* cmd */ + \
                       sizeof(A_UINT32) /* addr */ + \
                       sizeof(A_UINT32))/* length */
#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
#define BMI_EXCHANGE_TIMEOUT_MS  1000

/* APIs visible to the driver */
void
BMIInit(struct ol_softc *scn)
{
    if (!scn) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn context\n"));
        ASSERT(0);
        return;
    }
    scn->bmiDone = FALSE;

    /*
     * On some platforms, it's not possible to DMA to a static variable
     * in a device driver (e.g. Linux loadable driver module).
     * So we need to A_MALLOC space for "command credits" and for commands.
     *
     * Note: implicitly relies on A_MALLOC to provide a buffer that is
     * suitable for DMA (or PIO).  This buffer will be passed down the
     * bus stack.
     */

    if (!scn->pBMICmdBuf) {
#ifndef HIF_PCI
        scn->pBMICmdBuf =
                (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ);
#else
        scn->pBMICmdBuf =
                (A_UCHAR *)pci_alloc_consistent(scn->sc_osdev->bdev,
                                    MAX_BMI_CMDBUF_SZ,
                                    &scn->BMICmd_pa);
#endif
        ASSERT(scn->pBMICmdBuf);
    }

    if (!scn->pBMIRspBuf) {
#ifndef HIF_PCI
        scn->pBMIRspBuf =
                (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ);
#else
        scn->pBMIRspBuf =
                (A_UCHAR *)pci_alloc_consistent(scn->sc_osdev->bdev,
                                MAX_BMI_CMDBUF_SZ,
                                &scn->BMIRsp_pa);
#endif
        ASSERT(scn->pBMIRspBuf);
    }

    A_REGISTER_MODULE_DEBUG_INFO(bmi);
}

void
BMICleanup(struct ol_softc *scn)
{
    if (scn->pBMICmdBuf) {
#ifndef HIF_PCI
        A_FREE(scn->pBMICmdBuf );
#else
        pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ,
                        scn->pBMICmdBuf, scn->BMICmd_pa);
#endif
        scn->pBMICmdBuf = NULL;
        scn->BMICmd_pa = 0;
    }

    if (scn->pBMIRspBuf) {
#ifndef HIF_PCI
        A_FREE(scn->pBMIRspBuf);
#else
        pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ,
                        scn->pBMIRspBuf, scn->BMIRsp_pa);
#endif
        scn->pBMIRspBuf = NULL;
        scn->BMIRsp_pa = 0;
    }
}

static A_STATUS
BMIDone(HIF_DEVICE *device, struct ol_softc *scn)
{
    A_STATUS status;
    A_UINT32 cid;

    if (!scn) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn context\n"));
        ASSERT(0);
        return A_ERROR;
    }

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
        return A_OK;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%pK)\n", device));

#if defined(A_SIMOS_DEVHOST)
    /* Let HIF layer know that BMI phase is done.
     * Note that this call enqueues a bunch of receive buffers,
     * so it is important that this complete before we tell the
     * target about BMI_DONE.
     */
    (void)HIFConfigureDevice(device, HIF_BMI_DONE, NULL, 0);
#endif

    scn->bmiDone = TRUE;
    cid = BMI_DONE;

    if (!scn->pBMICmdBuf) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn BMICmdBuff\n"));
        ASSERT(0);
        return A_ERROR;
    }

    A_MEMCPY(scn->pBMICmdBuf,&cid,sizeof(cid));

    status = HIFExchangeBMIMsg(device, scn->pBMICmdBuf, sizeof(cid), NULL, NULL, 0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
        return A_ERROR;
    }

    if (scn->pBMICmdBuf) {
#ifndef HIF_PCI
        A_FREE(scn->pBMICmdBuf);
#else
        pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ,
                        scn->pBMICmdBuf, scn->BMICmd_pa);
#endif
        scn->pBMICmdBuf = NULL;
        scn->BMICmd_pa = 0;
    }

    if (scn->pBMIRspBuf) {
#ifndef HIF_PCI
        A_FREE(scn->pBMIRspBuf);
#else
        pci_free_consistent(scn->sc_osdev->bdev, MAX_BMI_CMDBUF_SZ,
                        scn->pBMIRspBuf, scn->BMIRsp_pa);
#endif
        scn->pBMIRspBuf = NULL;
        scn->BMIRsp_pa = 0;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));

    return A_OK;
}

A_STATUS bmi_done(struct ol_softc *scn)
{
    HIFClaimDevice(scn->hif_hdl, scn);

    if (BMIDone(scn->hif_hdl, scn) != A_OK)
	    return -1;

    return 0;
}

void bmi_target_ready(struct ol_softc *scn, void *cfg_ctx)
{
    ol_target_ready(scn, cfg_ctx);
}

#ifndef HIF_MESSAGE_BASED
extern A_STATUS HIFRegBasedGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info);
#endif

static A_STATUS
BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info, struct ol_softc *scn)
{
#ifndef HIF_MESSAGE_BASED
#else
    A_STATUS status;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;
    A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf;
#endif

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Get Target Info Command disallowed\n"));
        return A_ERROR;
    }

#ifndef HIF_MESSAGE_BASED
        /* getting the target ID requires special handling because of the variable length
         * message */
    return HIFRegBasedGetTargetInfo(device,targ_info);
#else

    {
        A_UINT32 cid;
        A_UINT32 length;

        cid = BMI_GET_TARGET_INFO;

        A_MEMCPY(pBMICmdBuf,&cid,sizeof(cid));
        length = sizeof(struct bmi_target_info);

        status = HIFExchangeBMIMsg(device,
                                 pBMICmdBuf,
                                 sizeof(cid),
                                 (A_UINT8 *)pBMIRspBuf,
                                 &length,
                                 BMI_EXCHANGE_TIMEOUT_MS);

        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to get target information from the device\n"));
            return A_ERROR;
        }

        A_MEMCPY(targ_info, pBMIRspBuf, length);
        return status;
    }
#endif
}

A_STATUS bmi_download_firmware(struct ol_softc *scn)
{
	struct bmi_target_info targ_info;
	OS_MEMZERO(&targ_info, sizeof(targ_info));

	if (!scn){
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid scn context\n"));
		ASSERT(0);
		return A_EINVAL;
	}

	/* Initialize BMI */
	BMIInit(scn);

	if (scn->pBMICmdBuf == NULL || scn->pBMIRspBuf == NULL) {
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIInit failed!\n"));
		return -1;
	}

	/* Get target information */
	if (BMIGetTargetInfo(scn->hif_hdl, &targ_info, scn) != A_OK)
		return -1;

	scn->target_type = targ_info.target_type;
	scn->target_version = targ_info.target_ver;

	/* Configure target */
	if (ol_configure_target(scn) != A_OK)
		return -1;

	if (ol_download_firmware(scn) != EOK)
		return -EIO;

	return 0;
}

A_STATUS
BMIReadMemory(HIF_DEVICE *device,
              A_UINT32 address,
              A_UCHAR *buffer,
              A_UINT32 length,
              struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UINT32 remaining, rxlen;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;
    A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf;
    A_UINT32 align;

    ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)));
    memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
    memset (pBMIRspBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
                ("BMI Read Memory: Enter (device: 0x%pK, address: 0x%x, length: %d)\n",
                    device, address, length));

    cid = BMI_READ_MEMORY;
#if defined(SDIO_3_0)
    /* 4bytes align operation */
    align = 4 - (length & 3);
    remaining = length + align;
#else
    align = 0;
    remaining = length;
#endif
    while (remaining)
    {
        rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
        offset = 0;
        A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
        offset += sizeof(cid);
        A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
        offset += sizeof(address);
        A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
        offset += sizeof(length);

        status = HIFExchangeBMIMsg(device,
                                   pBMICmdBuf,
                                   offset,
                                   pBMIRspBuf, /* note we reuse the same buffer to receive on */
                                   &rxlen,
                                   BMI_EXCHANGE_TIMEOUT_MS);

        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
            return A_ERROR;
        }
	if (remaining == rxlen) {
            A_MEMCPY(&buffer[length - remaining + align], pBMIRspBuf, rxlen - align); /* last align bytes are invalid */
	} else {
            A_MEMCPY(&buffer[length - remaining + align], pBMIRspBuf, rxlen);
	}
        remaining -= rxlen; address += rxlen;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
    return A_OK;
}

A_STATUS
BMIWriteMemory(HIF_DEVICE *device,
               A_UINT32 address,
               A_UCHAR *buffer,
               A_UINT32 length,
               struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UINT32 remaining, txlen;
    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
    A_UCHAR alignedBuffer[BMI_DATASZ_MAX];
    A_UCHAR *src;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;

    ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
    memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
         ("BMI Write Memory: Enter (device: 0x%pK, address: 0x%x, length: %d)\n",
         device, address, length));

    cid = BMI_WRITE_MEMORY;

    remaining = length;
    while (remaining)
    {
        src = &buffer[length - remaining];
        if (remaining < (BMI_DATASZ_MAX - header)) {
            if (remaining & 3) {
                /* align it with 4 bytes */
                remaining = remaining + (4 - (remaining & 3));
                memcpy(alignedBuffer, src, remaining);
                src = alignedBuffer;
            }
            txlen = remaining;
        } else {
            txlen = (BMI_DATASZ_MAX - header);
        }
        offset = 0;
        A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
        offset += sizeof(cid);
        A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
        offset += sizeof(address);
        A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
        offset += sizeof(txlen);
        A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen);
        offset += txlen;
        status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, BMI_EXCHANGE_TIMEOUT_MS);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
            return A_ERROR;
        }
        remaining -= txlen; address += txlen;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));

    return A_OK;
}

A_STATUS
BMIExecute(HIF_DEVICE *device,
           A_UINT32 address,
           A_UINT32 *param,
           struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UINT32 paramLen;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;
    A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf;

    ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
    memset (pBMIRspBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
       ("BMI Execute: Enter (device: 0x%pK, address: 0x%x, param: %d)\n",
        device, address, *param));

    cid = BMI_EXECUTE;

    offset = 0;
    A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
    offset += sizeof(cid);
    A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
    offset += sizeof(address);
    A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param));
    offset += sizeof(*param);
    paramLen = sizeof(*param);
    status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMIRspBuf, &paramLen, 0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
        return A_ERROR;
    }

    A_MEMCPY(param, pBMIRspBuf, sizeof(*param));

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
    return A_OK;
}

A_STATUS
BMISetAppStart(HIF_DEVICE *device,
               A_UINT32 address,
               struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;

    ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
       ("BMI Set App Start: Enter (device: 0x%pK, address: 0x%x)\n",
        device, address));

    cid = BMI_SET_APP_START;

    offset = 0;
    A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
    offset += sizeof(cid);
    A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
    offset += sizeof(address);

    status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
    return A_OK;
}

A_STATUS
BMIReadSOCRegister(HIF_DEVICE *device,
                   A_UINT32 address,
                   A_UINT32 *param,
                   struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset,paramLen;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;
    A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf;

    ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
    memset (pBMIRspBuf, 0, sizeof(cid) + sizeof(address));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
       ("BMI Read SOC Register: Enter (device: 0x%pK, address: 0x%x)\n",
       device, address));

    cid = BMI_READ_SOC_REGISTER;

    offset = 0;
    A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
    offset += sizeof(cid);
    A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
    offset += sizeof(address);
    paramLen = sizeof(*param);
    status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMIRspBuf, &paramLen, BMI_EXCHANGE_TIMEOUT_MS);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
        return A_ERROR;
    }
    A_MEMCPY(param, pBMIRspBuf, sizeof(*param));

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
    return A_OK;
}

A_STATUS
BMIWriteSOCRegister(HIF_DEVICE *device,
                    A_UINT32 address,
                    A_UINT32 param,
                    struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;

    ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
     ("BMI Write SOC Register: Enter (device: 0x%pK, address: 0x%x, param: %d)\n",
     device, address, param));

    cid = BMI_WRITE_SOC_REGISTER;

    offset = 0;
    A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
    offset += sizeof(cid);
    A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
    offset += sizeof(address);
    A_MEMCPY(&(pBMICmdBuf[offset]), &param, sizeof(param));
    offset += sizeof(param);
    status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
    return A_OK;
}

A_STATUS
BMILZData(HIF_DEVICE *device,
          A_UCHAR *buffer,
          A_UINT32 length,
          struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UINT32 remaining, txlen;
    const A_UINT32 header = sizeof(cid) + sizeof(length);
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;

    ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
    memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
         ("BMI Send LZ Data: Enter (device: 0x%pK, length: %d)\n",
         device, length));

    cid = BMI_LZ_DATA;

    remaining = length;
    while (remaining)
    {
        txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
                                       remaining : (BMI_DATASZ_MAX - header);
        offset = 0;
        A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
        offset += sizeof(cid);
        A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
        offset += sizeof(txlen);
        A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
        offset += txlen;
        status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
            return A_ERROR;
        }
        remaining -= txlen;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));

    return A_OK;
}

A_STATUS
BMISignStreamStart(HIF_DEVICE *device,
                   A_UINT32 address,
                   A_UCHAR *buffer,
                   A_UINT32 length,
                   struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
    A_UCHAR alignedBuffer[BMI_DATASZ_MAX + 4];
    A_UCHAR *src;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;
    A_UINT32 remaining, txlen;

    ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
    memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + header);

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
         ("BMI SIGN Stream Start: Enter (device: 0x%pK, address: 0x%x, length: %d)\n",
         device, address, length));

    cid = BMI_SIGN_STREAM_START;
    remaining = length;
    while (remaining)
    {
        src = &buffer[length - remaining];
        if (remaining < (BMI_DATASZ_MAX - header)) {
            /*  Actually it shall be aligned binary from header definition.
             *  Not necessary for align process. Kept for possible changes
             */
            if (remaining & 0x3) {
                remaining = remaining + (4 - (remaining & 0x3));
                memcpy(alignedBuffer, src, remaining);
                src = alignedBuffer;
            }
            txlen = remaining;
        } else {
            txlen = (BMI_DATASZ_MAX - header);
        }

        offset = 0;
        A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
        offset += sizeof(cid);
        A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
        offset += sizeof(offset);
        A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
        offset += sizeof(txlen);
        A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen);
        offset += txlen;
        status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, BMI_EXCHANGE_TIMEOUT_MS);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
            return A_ERROR;
        }
        remaining -= txlen;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI SIGN Stream Start: Exit\n"));

    return A_OK;
}

A_STATUS
BMILZStreamStart(HIF_DEVICE *device,
                 A_UINT32 address,
                 struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;

    ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
         ("BMI LZ Stream Start: Enter (device: 0x%pK, address: 0x%x)\n",
         device, address));

    cid = BMI_LZ_STREAM_START;
    offset = 0;
    A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
    offset += sizeof(cid);
    A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
    offset += sizeof(address);
    status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));

    return A_OK;
}

A_STATUS
BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, struct ol_softc *scn)
{
    A_STATUS status = A_ERROR;
    A_UINT32  lastWord = 0;
    A_UINT32  lastWordOffset = length & ~0x3;
    A_UINT32  unalignedBytes = length & 0x3;

    status = BMILZStreamStart (device, address, scn);
    if (A_FAILED(status)) {
            return A_ERROR;
    }

    if (unalignedBytes) {
            /* copy the last word into a zero padded buffer */
        A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes);
    }

    status = BMILZData(device, buffer, lastWordOffset, scn);

    if (A_FAILED(status)) {
        return A_ERROR;
    }

    if (unalignedBytes) {
        status = BMILZData(device, (A_UINT8 *)&lastWord, 4, scn);
    }

    if (A_SUCCESS(status)) {
        //
        // Close compressed stream and open a new (fake) one.  This serves mainly to flush Target caches.
        //
        status = BMILZStreamStart (device, 0x00, scn);
        if (A_FAILED(status)) {
           return A_ERROR;
        }
    }
    return status;
}

A_STATUS
BMInvramProcess(HIF_DEVICE *device, A_UCHAR *seg_name, A_UINT32 *retval,
                 struct ol_softc *scn)
{
    A_UINT32 cid;
    A_STATUS status;
    A_UINT32 offset;
    A_UINT32 retvalLen;
    A_UCHAR *pBMICmdBuf = scn->pBMICmdBuf;
    A_UCHAR *pBMIRspBuf = scn->pBMIRspBuf;

    ASSERT(BMI_COMMAND_FITS(sizeof(cid) + BMI_NVRAM_SEG_NAME_SZ));

    if (scn->bmiDone) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
        return A_ERROR;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
         ("BMI NVRAM Process: Enter (device: 0x%pK, name: %s)\n",
           device, seg_name));

    cid = BMI_NVRAM_PROCESS;
    offset = 0;
    A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
    offset += sizeof(cid);
    A_MEMCPY(&(pBMICmdBuf[offset]), seg_name, BMI_NVRAM_SEG_NAME_SZ);
    offset += BMI_NVRAM_SEG_NAME_SZ;
    retvalLen = sizeof(*retval);
    status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMIRspBuf, &retvalLen, 0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to access the device\n"));
        return A_ERROR;
    }

    A_MEMCPY(retval, pBMIRspBuf, sizeof(*retval));

    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI NVRAM Process: Exit\n"));

    return A_OK;
}

#ifdef HIF_MESSAGE_BASED

/* TODO.. stubs.. for message-based HIFs, the RAW access APIs need to be changed
 */

A_STATUS
BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length)
{
        /* TODO */
    return A_ERROR;
}

A_STATUS
BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout)
{
        /* TODO */
    return A_ERROR;
}

#endif
