?? bmi.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], ¶m, 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 + -