⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmi.c

📁 linux下的SDIO 驱动
💻 C
字号:
/* * Copyright (c) 2004-2006 Atheros Communications Inc. *  Wireless Network driver for Atheros AR6001 * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation; * *  Software distributed under the License is distributed on an "AS *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or *  implied. See the License for the specific language governing *  rights and limitations under the License. * * * This file contains the routines that implement the Boot loader messaging * interface */#include "../include/hif.h"#include "../include/bmi.h"#include "../include/htc.h"#include "bmi_internal.h"/*Although we had envisioned BMI to run on top of HTC, this is not what thefinal implementation boiled down to on dragon. Its a part of BSP and doesnot use the HTC protocol either. On the host side, however, we were stillliving with the original idea. I think the time has come to accept the truthand separate it from HTC which has been carrying BMI's burden all this while.It shall make HTC state machine relatively simpler*//* ------ Static Variables ------ *//* ------ Global Variable Declarations ------- */A_BOOL bmiDone;extern A_UINT32 debugbmi;#ifdef DEBUG#define AR_DEBUG_PRINTF(...)        if (debugbmi) A_PRINTF(__VA_ARGS__);#else#define AR_DEBUG_PRINTF(...)#endif/* APIs visible to the driver */voidBMIInit(void){    bmiDone = FALSE;}A_STATUSBMIDone(HIF_DEVICE *device){    A_STATUS status;    A_UINT32 cid;    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF("BMI Done: Enter (device: 0x%p)\n", device);    bmiDone = TRUE;    cid = BMI_DONE;    status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to write to the device\n");        return A_ERROR;    }    AR_DEBUG_PRINTF("BMI Done: Exit\n");    return A_OK;}A_STATUSBMIGetTargetId(HIF_DEVICE *device, A_UINT32 *id){    A_STATUS status;    A_UINT32 cid;    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF("BMI Get Target ID: Enter (device: 0x%p)\n", device);    cid = BMI_GET_TARGET_ID;    status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to write to the device\n");        return A_ERROR;    }    status = bmiBufferReceive(device, (A_UCHAR *)id, sizeof(*id));    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to read from the device\n");        return A_ERROR;    }    AR_DEBUG_PRINTF("BMI Get Target ID: Exit (ID: 0x%x)\n", *id);    return A_OK;}A_STATUSBMIReadMemory(HIF_DEVICE *device,              A_UINT32 address,              A_UCHAR *buffer,              A_UINT32 length){    A_UINT32 cid;    A_STATUS status;    A_UINT32 offset;    A_UINT32 remaining, rxlen;    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);    A_UCHAR data[BMI_DATASZ_MAX + header];    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF(       "BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",        device, address, length);    cid = BMI_READ_MEMORY;    remaining = length;    while (remaining)    {        rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;        offset = 0;        A_MEMCPY(&data[offset], &cid, sizeof(cid));        offset += sizeof(cid);        A_MEMCPY(&data[offset], &address, sizeof(address));        offset += sizeof(address);        A_MEMCPY(&data[offset], &rxlen, sizeof(rxlen));        offset += sizeof(length);        status = bmiBufferSend(device, data, offset);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to write to the device\n");            return A_ERROR;        }        status = bmiBufferReceive(device, data, rxlen);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to read from the device\n");            return A_ERROR;        }        A_MEMCPY(&buffer[length - remaining], data, rxlen);        remaining -= rxlen; address += rxlen;    }    AR_DEBUG_PRINTF("BMI Read Memory: Exit\n");    return A_OK;}A_STATUSBMIWriteMemory(HIF_DEVICE *device,               A_UINT32 address,               A_UCHAR *buffer,               A_UINT32 length){    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 data[BMI_DATASZ_MAX + header];    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF(         "BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",          device, address, length);    cid = BMI_WRITE_MEMORY;    remaining = length;    while (remaining)    {        txlen = (remaining < (BMI_DATASZ_MAX - header)) ?                                       remaining : (BMI_DATASZ_MAX - header);        offset = 0;        A_MEMCPY(&data[offset], &cid, sizeof(cid));        offset += sizeof(cid);        A_MEMCPY(&data[offset], &address, sizeof(address));        offset += sizeof(address);        A_MEMCPY(&data[offset], &txlen, sizeof(txlen));        offset += sizeof(txlen);        A_MEMCPY(&data[offset], &buffer[length - remaining], txlen);        offset += txlen;        status = bmiBufferSend(device, data, offset);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to write to the device\n");            return A_ERROR;        }        remaining -= txlen; address += txlen;    }    AR_DEBUG_PRINTF("BMI Write Memory: Exit\n");    return A_OK;}A_STATUSBMIExecute(HIF_DEVICE *device,           A_UINT32 address,           A_UINT32 *param){    A_UINT32 cid;    A_STATUS status;    A_UINT32 offset;    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(*param);    A_UCHAR data[header];    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF(       "BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",        device, address, *param);    cid = BMI_EXECUTE;    offset = 0;    A_MEMCPY(&data[offset], &cid, sizeof(cid));    offset += sizeof(cid);    A_MEMCPY(&data[offset], &address, sizeof(address));    offset += sizeof(address);    A_MEMCPY(&data[offset], param, sizeof(*param));    offset += sizeof(*param);    status = bmiBufferSend(device, data, offset);    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to write to the device\n");        return A_ERROR;    }    status = bmiBufferReceive(device, data, sizeof(*param));    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to read from the device\n");        return A_ERROR;    }    A_MEMCPY(param, data, sizeof(*param));    AR_DEBUG_PRINTF("BMI Execute: Exit (param: %d)\n", *param);    return A_OK;}A_STATUSBMISetAppStart(HIF_DEVICE *device,               A_UINT32 address){    A_UINT32 cid;    A_STATUS status;    A_UINT32 offset;    const A_UINT32 header = sizeof(cid) + sizeof(address);    A_UCHAR data[header];    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF(       "BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",        device, address);    cid = BMI_SET_APP_START;    offset = 0;    A_MEMCPY(&data[offset], &cid, sizeof(cid));    offset += sizeof(cid);    A_MEMCPY(&data[offset], &address, sizeof(address));    offset += sizeof(address);    status = bmiBufferSend(device, data, offset);    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to write to the device\n");        return A_ERROR;    }    AR_DEBUG_PRINTF("BMI Set App Start: Exit\n");    return A_OK;}A_STATUSBMIReadSOCRegister(HIF_DEVICE *device,                   A_UINT32 address,                   A_UINT32 *param){    A_UINT32 cid;    A_STATUS status;    A_UINT32 offset;    const A_UINT32 header = sizeof(cid) + sizeof(address);    A_UCHAR data[header];    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF(       "BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",        device, address);    cid = BMI_READ_SOC_REGISTER;    offset = 0;    A_MEMCPY(&data[offset], &cid, sizeof(cid));    offset += sizeof(cid);    A_MEMCPY(&data[offset], &address, sizeof(address));    offset += sizeof(address);    status = bmiBufferSend(device, data, offset);    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to write to the device\n");        return A_ERROR;    }    status = bmiBufferReceive(device, data, sizeof(*param));    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to read from the device\n");        return A_ERROR;    }    A_MEMCPY(param, data, sizeof(*param));    AR_DEBUG_PRINTF("BMI Read SOC Register: Exit (value: %d)\n", *param);    return A_OK;}A_STATUSBMIWriteSOCRegister(HIF_DEVICE *device,                    A_UINT32 address,                    A_UINT32 param){    A_UINT32 cid;    A_STATUS status;    A_UINT32 offset;    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(param);    A_UCHAR data[header];    if (bmiDone) {        AR_DEBUG_PRINTF("Command disallowed\n");        return A_ERROR;    }    AR_DEBUG_PRINTF(     "BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",      device, address, param);    cid = BMI_WRITE_SOC_REGISTER;    offset = 0;    A_MEMCPY(&data[offset], &cid, sizeof(cid));    offset += sizeof(cid);    A_MEMCPY(&data[offset], &address, sizeof(address));    offset += sizeof(address);    A_MEMCPY(&data[offset], &param, sizeof(param));    offset += sizeof(param);    status = bmiBufferSend(device, data, offset);    if (status != A_OK) {        AR_DEBUG_PRINTF("Unable to write to the device\n");        return A_ERROR;    }    AR_DEBUG_PRINTF("BMI Read SOC Register: Exit\n");    return A_OK;}/* BMI Access routines */A_STATUSbmiBufferSend(HIF_DEVICE *device,              A_UCHAR *buffer,              A_UINT32 length){    A_STATUS status;    A_UINT32 timeout;    A_UINT32 address;    A_UCHAR cmdCredits;    HIF_REQUEST request;    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,                       &mboxAddress, sizeof(mboxAddress));    cmdCredits = 0;    timeout = BMI_COMMUNICATION_TIMEOUT;    while(timeout-- && !cmdCredits) {        /* Read the counter register to get the command credits */        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,                          HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;        status = HIFReadWrite(device, address, &cmdCredits, 1,                              &request, NULL);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to decrement the command credit count register\n");            return A_ERROR;        }    }    if (cmdCredits) {        HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,                              HIF_SYNCHRONOUS, HIF_BYTE_BASIS,                              HIF_INCREMENTAL_ADDRESS);        address = mboxAddress[ENDPOINT1];        status = HIFReadWrite(device, address, buffer, length, &request, NULL);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to send the BMI data to the device\n");            return A_ERROR;        }    } else {        AR_DEBUG_PRINTF("BMI Communication timeout\n");        return A_ERROR;    }    return status;}A_STATUSbmiBufferReceive(HIF_DEVICE *device,                 A_UCHAR *buffer,                 A_UINT32 length){    A_STATUS status;    A_UINT32 address;    A_UINT32 timeout;    A_UCHAR cmdCredits;    HIF_REQUEST request;    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,                       &mboxAddress, sizeof(mboxAddress));    cmdCredits = 0;    timeout = BMI_COMMUNICATION_TIMEOUT;    while(timeout-- && !cmdCredits) {        /* Read the counter register to get the command credits */        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,                          HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);        address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;        status = HIFReadWrite(device, address, &cmdCredits, sizeof(cmdCredits),                              &request, NULL);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to decrement the command credit count register\n");            return A_ERROR;        }        status = A_ERROR;    }    if (cmdCredits) {        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,                          HIF_SYNCHRONOUS, HIF_BYTE_BASIS,                          HIF_INCREMENTAL_ADDRESS);        address = mboxAddress[ENDPOINT1];        status = HIFReadWrite(device, address, buffer, length, &request, NULL);        if (status != A_OK) {            AR_DEBUG_PRINTF("Unable to read the BMI data from the device\n");            return A_ERROR;        }    } else {        AR_DEBUG_PRINTF("BMI Communication timeout\n");        return A_ERROR;    }    return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -