Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.h ('k') | chromeos/drivers/ath6kl/miscdrv/common_drv.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
diff --git a/chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
new file mode 100644
index 0000000000000000000000000000000000000000..8392777512ec46de8621f7298f5327fae1330232
--- /dev/null
+++ b/chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
@@ -0,0 +1,972 @@
+/*
+ * Copyright (c) 2004-2008 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * This file implements the Atheros PS and patch parser.
+ * It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
+ *
+ *
+ *
+ * ar3kpsparser.c
+ *
+ *
+ *
+ * The software source and binaries included in this development package are
+ * licensed, not sold. You, or your company, received the package under one
+ * or more license agreements. The rights granted to you are specifically
+ * listed in these license agreement(s). All other rights remain with Atheros
+ * Communications, Inc., its subsidiaries, or the respective owner including
+ * those listed on the included copyright notices.. Distribution of any
+ * portion of this package must be in strict compliance with the license
+ * agreement(s) terms.
+ *
+ *
+ *
+ */
+
+
+#include "ar3kpsparser.h"
+
+#define BD_ADDR_SIZE 6
+#define WRITE_PATCH 8
+#define ENABLE_PATCH 11
+#define PS_RESET 2
+#define PS_WRITE 1
+#define PS_VERIFY_CRC 9
+#define CHANGE_BDADDR 15
+
+#define HCI_COMMAND_HEADER 7
+
+#define HCI_EVENT_SIZE 7
+
+#define WRITE_PATCH_COMMAND_STATUS_OFFSET 5
+
+#define RAM_PS_REGION (1<<0)
+#define RAM_PATCH_REGION (1<<1)
+#define RAMPS_MAX_PS_DATA_PER_TAG 20000
+#define MAX_RADIO_CFG_TABLE_SIZE 244
+#define RAMPS_MAX_PS_TAGS_PER_FILE 50
+
+#define PS_MAX_LEN 500
+#define LINE_SIZE_MAX (PS_MAX_LEN *2)
+
+/* Constant values used by parser */
+#define BYTES_OF_PS_DATA_PER_LINE 16
+#define RAMPS_MAX_PS_DATA_PER_TAG 20000
+
+
+/* Number pf PS/Patch entries in an HCI packet */
+#define MAX_BYTE_LENGTH 244
+
+#define SKIP_BLANKS(str) while (*str == ' ') str++
+#define MIN(x, y) (((x) <= (y))? (x):(y))
+#define MAX(x, y) (((x) >= (y))? (x):(y))
+
+#define UNUSED(x) (x=x)
+
+#define IS_BETWEEN(x, lower, upper) (((lower) <= (x)) && ((x) <= (upper)))
+#define IS_DIGIT(c) (IS_BETWEEN((c), '0', '9'))
+#define IS_HEX(c) (IS_BETWEEN((c), '0', '9') || IS_BETWEEN((c), 'a', 'f') || IS_BETWEEN((c), 'A', 'F'))
+#define TO_LOWER(c) (IS_BETWEEN((c), 'A', 'Z') ? ((c) - 'A' + 'a') : (c))
+#define IS_BLANK(c) ((c) == ' ')
+#define CONV_DEC_DIGIT_TO_VALUE(c) ((c) - '0')
+#define CONV_HEX_DIGIT_TO_VALUE(c) (IS_DIGIT(c) ? ((c) - '0') : (IS_BETWEEN((c), 'A', 'Z') ? ((c) - 'A' + 10) : ((c) - 'a' + 10)))
+#define CONV_VALUE_TO_HEX(v) ((A_UINT8)( ((v & 0x0F) <= 9) ? ((v & 0x0F) + '0') : ((v & 0x0F) - 10 + 'A') ) )
+
+
+enum MinBootFileFormatE
+{
+ MB_FILEFORMAT_RADIOTBL,
+ MB_FILEFORMAT_PATCH,
+ MB_FILEFORMAT_COEXCONFIG
+};
+
+enum RamPsSection
+{
+ RAM_PS_SECTION,
+ RAM_PATCH_SECTION,
+ RAM_DYN_MEM_SECTION
+};
+
+enum eType {
+ eHex,
+ edecimal
+};
+
+
+typedef struct tPsTagEntry
+{
+ A_UINT32 TagId;
+ A_UINT32 TagLen;
+ A_UINT8 *TagData;
+} tPsTagEntry, *tpPsTagEntry;
+
+typedef struct tRamPatch
+{
+ A_UINT16 Len;
+ A_UINT8 * Data;
+} tRamPatch, *ptRamPatch;
+
+
+
+typedef struct ST_PS_DATA_FORMAT {
+ enum eType eDataType;
+ A_BOOL bIsArray;
+}ST_PS_DATA_FORMAT;
+
+typedef struct ST_READ_STATUS {
+ unsigned uTagID;
+ unsigned uSection;
+ unsigned uLineCount;
+ unsigned uCharCount;
+ unsigned uByteCount;
+}ST_READ_STATUS;
+
+
+/* Stores the number of PS Tags */
+static A_UINT32 Tag_Count = 0;
+
+/* Stores the number of patch commands */
+static A_UINT32 Patch_Count = 0;
+static A_UINT32 Total_tag_lenght = 0;
+static A_BOOL BDADDR = FALSE;
+A_UINT32 StartTagId;
+
+tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE];
+tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY];
+
+
+A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat);
+char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos);
+char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos);
+static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index);
+
+/* Function to reads the next character from the input buffer */
+char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos)
+{
+ char Ch;
+ if(buffer == NULL || *pos >=len )
+ {
+ return '\0';
+ } else {
+ Ch = buffer[*pos];
+ (*pos)++;
+ return Ch;
+ }
+}
+/* PS parser helper function */
+unsigned int uGetInputDataFormat(char* pCharLine, ST_PS_DATA_FORMAT *pstFormat)
+{
+ if(pCharLine[0] != '[') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ return 0;
+ }
+ switch(pCharLine[1]) {
+ case 'H':
+ case 'h':
+ if(pCharLine[2]==':') {
+ if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
+ return 1;
+ }
+ }
+ if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = false;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
+ return 1;
+ }
+ }
+ else if(pCharLine[3] == ']') { //[H:]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 4;
+ return 0;
+ }
+ else { //[H:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
+ return 1;
+ }
+ }
+ else if(pCharLine[2]==']') { //[H]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 3;
+ return 0;
+ }
+ else { //[H
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
+ return 1;
+ }
+ break;
+
+ case 'A':
+ case 'a':
+ if(pCharLine[2]==':') {
+ if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 1\n")); //[A:H
+ return 1;
+ }
+ }
+ else if(pCharLine[3]== ']') { //[A:]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 4;
+ return 0;
+ }
+ else { //[A:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 2\n"));
+ return 1;
+ }
+ }
+ else if(pCharLine[2]==']') { //[H]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 3;
+ return 0;
+ }
+ else { //[H
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 3\n"));
+ return 1;
+ }
+ break;
+
+ case 'S':
+ case 's':
+ if(pCharLine[2]==':') {
+ if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 5\n")); //[A:H
+ return 1;
+ }
+ }
+ else if(pCharLine[3]== ']') { //[A:]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 4;
+ return 0;
+ }
+ else { //[A:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 6\n"));
+ return 1;
+ }
+ }
+ else if(pCharLine[2]==']') { //[H]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 3;
+ return 0;
+ }
+ else { //[H
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 7\n"));
+ return 1;
+ }
+ break;
+
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 8\n"));
+ return 1;
+ }
+}
+
+unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataFormat)
+{
+ char *pTokenPtr = pCharLine;
+
+ if(pTokenPtr[0] == '[') {
+ while(pTokenPtr[0] != ']' && pTokenPtr[0] != '\0') {
+ pTokenPtr++;
+ }
+ if(pTokenPtr[0] == '\0') {
+ return (0x0FFF);
+ }
+ pTokenPtr++;
+
+
+ }
+ if(stPS_DataFormat.eDataType == eHex) {
+ if(stPS_DataFormat.bIsArray == true) {
+ //Not implemented
+ return (0x0FFF);
+ }
+ else {
+ return (A_STRTOL(pTokenPtr, NULL, 16));
+ }
+ }
+ else {
+ //Not implemented
+ return (0x0FFF);
+ }
+}
+A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat)
+{
+ char *Buffer;
+ char *pCharLine;
+ A_UINT8 TagCount;
+ A_UINT16 ByteCount;
+ A_UINT8 ParseSection=RAM_PS_SECTION;
+ A_UINT32 pos;
+
+
+
+ int uReadCount;
+ ST_PS_DATA_FORMAT stPS_DataFormat;
+ ST_READ_STATUS stReadStatus = {0, 0, 0,0};
+ pos = 0;
+ Buffer = NULL;
+
+ if (srcbuffer == NULL || srclen == 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not open .\n"));
+ return A_ERROR;
+ }
+ TagCount = 0;
+ ByteCount = 0;
+ Buffer = A_MALLOC(LINE_SIZE_MAX + 1);
+ if(NULL == Buffer) {
+ return A_ERROR;
+ }
+ if (FileFormat == MB_FILEFORMAT_PATCH)
+ {
+ int LineRead = 0;
+ while((pCharLine = AthGetLine(Buffer, LINE_SIZE_MAX, srcbuffer,srclen,&pos)) != NULL)
+ {
+
+ SKIP_BLANKS(pCharLine);
+
+ // Comment line or empty line
+ if ((pCharLine[0] == '/') && (pCharLine[1] == '/'))
+ {
+ continue;
+ }
+
+ if ((pCharLine[0] == '#')) {
+ if (stReadStatus.uSection != 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ else {
+ stReadStatus.uSection = 1;
+ continue;
+ }
+ }
+ if ((pCharLine[0] == '/') && (pCharLine[1] == '*'))
+ {
+ pCharLine+=2;
+ SKIP_BLANKS(pCharLine);
+
+ if(!strncmp(pCharLine,"PA",2)||!strncmp(pCharLine,"Pa",2)||!strncmp(pCharLine,"pa",2))
+ ParseSection=RAM_PATCH_SECTION;
+
+ if(!strncmp(pCharLine,"DY",2)||!strncmp(pCharLine,"Dy",2)||!strncmp(pCharLine,"dy",2))
+ ParseSection=RAM_DYN_MEM_SECTION;
+
+ if(!strncmp(pCharLine,"PS",2)||!strncmp(pCharLine,"Ps",2)||!strncmp(pCharLine,"ps",2))
+ ParseSection=RAM_PS_SECTION;
+
+ LineRead = 0;
+ stReadStatus.uSection = 0;
+
+ continue;
+ }
+
+ switch(ParseSection)
+ {
+ case RAM_PS_SECTION:
+ {
+ if (stReadStatus.uSection == 1) //TagID
+ {
+ SKIP_BLANKS(pCharLine);
+ if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ //pCharLine +=5;
+ PsTagEntry[TagCount].TagId = uReadDataInSection(pCharLine, stPS_DataFormat);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG ID %d \n",PsTagEntry[TagCount].TagId));
+
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag # %x\n", PsTagEntry[TagCount].TagId);
+ if (TagCount == 0)
+ {
+ StartTagId = PsTagEntry[TagCount].TagId;
+ }
+ stReadStatus.uSection = 2;
+ }
+ else if (stReadStatus.uSection == 2) //TagLength
+ {
+
+ if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ //pCharLine +=5;
+ ByteCount = uReadDataInSection(pCharLine, stPS_DataFormat);
+
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag length %x\n", ByteCount));
+ if (ByteCount > LINE_SIZE_MAX/2)
+ {
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ PsTagEntry[TagCount].TagLen = ByteCount;
+ PsTagEntry[TagCount].TagData = (A_UINT8*)A_MALLOC(ByteCount);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount));
+ stReadStatus.uSection = 3;
+ stReadStatus.uLineCount = 0;
+ }
+ else if( stReadStatus.uSection == 3) { //Data
+
+ if(stReadStatus.uLineCount == 0) {
+ if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ //pCharLine +=5;
+ }
+ SKIP_BLANKS(pCharLine);
+ stReadStatus.uCharCount = 0;
+ if(pCharLine[stReadStatus.uCharCount] == '[') {
+ while(pCharLine[stReadStatus.uCharCount] != ']' && pCharLine[stReadStatus.uCharCount] != '\0' ) {
+ stReadStatus.uCharCount++;
+ }
+ if(pCharLine[stReadStatus.uCharCount] == ']' ) {
+ stReadStatus.uCharCount++;
+ } else {
+ stReadStatus.uCharCount = 0;
+ }
+ }
+ uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount;
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" "));
+ if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) {
+ while(uReadCount > 0) {
+ PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] =
+ (A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount]) << 4)
+ | (A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount + 1]));
+
+ PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] =
+ (A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount + 3]) << 4)
+ | (A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount + 4]));
+
+ stReadStatus.uCharCount += 6; // read two bytes, plus a space;
+ stReadStatus.uByteCount += 2;
+ uReadCount -= 2;
+ }
+ if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) {
+ ByteCount -= BYTES_OF_PS_DATA_PER_LINE;
+ }
+ else {
+ ByteCount = 0;
+ }
+ }
+ else {
+ //to be implemented
+ }
+
+ stReadStatus.uLineCount++;
+
+ if(ByteCount == 0) {
+ stReadStatus.uSection = 0;
+ stReadStatus.uCharCount = 0;
+ stReadStatus.uLineCount = 0;
+ stReadStatus.uByteCount = 0;
+ }
+ else {
+ stReadStatus.uCharCount = 0;
+ }
+
+ if((stReadStatus.uSection == 0)&&(++TagCount == RAMPS_MAX_PS_TAGS_PER_FILE))
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ //Sleep (3000);
+ //exit(1);
+ }
+
+ }
+ }
+
+ break;
+ default:
+ {
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ break;
+ }
+ LineRead++;
+ }
+ Tag_Count = TagCount;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Number of Tags %d\n", Tag_Count));
+ }
+
+
+ if (TagCount > RAMPS_MAX_PS_TAGS_PER_FILE)
+ {
+
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_OK;
+
+}
+
+
+
+/********************/
+
+
+A_STATUS GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer)
+{
+ unsigned char ch;
+
+ ch = AthReadChar(srcbuffer,len,pos);
+ if(ch != '\0' && IS_HEX(ch)) {
+ buffer[0] = ch;
+ } else
+ {
+ return A_ERROR;
+ }
+ ch = AthReadChar(srcbuffer,len,pos);
+ if(ch != '\0' && IS_HEX(ch)) {
+ buffer[1] = ch;
+ } else
+ {
+ return A_ERROR;
+ }
+ return A_OK;
+}
+
+A_STATUS AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen)
+{
+
+ char Byte[3];
+ char Line[MAX_BYTE_LENGTH + 1];
+ int ByteCount,ByteCount_Org;
+ int count;
+ int i,j,k;
+ int data;
+ A_UINT32 filepos;
+ Byte[2] = '\0';
+ j = 0;
+ filepos = 0;
+
+ while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) {
+ if(strlen(Line) <= 1 || !IS_HEX(Line[0])) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ ByteCount = A_STRTOL(Line, NULL, 16);
+ ByteCount_Org = ByteCount;
+
+ while(ByteCount > MAX_BYTE_LENGTH){
+
+ /* Handle case when the number of patch buffer is more than the 20K */
+ if(MAX_NUM_PATCH_ENTRY == Patch_Count) {
+ for(i = 0; i < Patch_Count; i++) {
+ A_FREE(RamPatch[i].Data);
+ }
+ return A_ERROR;
+ }
+ RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH;
+ RamPatch[Patch_Count].Data = (A_UINT8*)A_MALLOC(MAX_BYTE_LENGTH);
+ Patch_Count ++;
+
+
+ ByteCount= ByteCount - MAX_BYTE_LENGTH;
+ }
+
+ RamPatch[Patch_Count].Len= (ByteCount & 0xFF);
+ if(ByteCount != 0) {
+ RamPatch[Patch_Count].Data = (A_UINT8*)A_MALLOC(ByteCount);
+ Patch_Count ++;
+ }
+ count = 0;
+ while(ByteCount_Org > MAX_BYTE_LENGTH){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
+ for (i = 0,k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++,count +=2) {
+ if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
+ return A_ERROR;
+ }
+ data = A_STRTOUL(&Byte[0], NULL, 16);
+ RamPatch[j].Data[k] = (data & 0xFF);
+
+
+ }
+ j++;
+ ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH;
+ }
+ if(j == 0){
+ j++;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
+ for (k=0; k < ByteCount_Org; i += 2,k++,count+=2) {
+ if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
+ return A_ERROR;
+ }
+ data = A_STRTOUL(Byte, NULL, 16);
+ RamPatch[j].Data[k] = (data & 0xFF);
+
+
+ }
+ return A_OK;
+}
+
+
+/********************/
+A_STATUS AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen)
+{
+ A_STATUS status;
+ int i;
+ A_BOOL BDADDR_Present = A_ERROR;
+
+
+
+ status = A_ERROR;
+
+ if(NULL != srcbuffer && srclen != 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("File Open Operation Successful\n"));
+
+ status = AthParseFilesUnified(srcbuffer,srclen,MB_FILEFORMAT_PATCH);
+ }
+
+
+
+ if(Tag_Count == 0){
+ Total_tag_lenght = 10;
+
+ }
+ else{
+ for(i=0; i<Tag_Count; i++){
+ if(PsTagEntry[i].TagId == 1){
+ BDADDR_Present = A_OK;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is present in Patch File \r\n"));
+
+ }
+ if(PsTagEntry[i].TagLen % 2 == 1){
+ Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1;
+ }
+ else{
+ Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen;
+ }
+
+ }
+ }
+
+ if(Tag_Count > 0 && !BDADDR_Present){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is not present adding 10 extra bytes \r\n"));
+ Total_tag_lenght=Total_tag_lenght + 10;
+ }
+ Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Total Length %d\n",Total_tag_lenght));
+
+
+ return status;
+}
+char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos)
+{
+
+ int count;
+ static short flag;
+ char CharRead;
+ count = 0;
+ flag = A_ERROR;
+
+ do
+ {
+ CharRead = AthReadChar(srcbuffer,len,pos);
+ if( CharRead == '\0' ) {
+ buffer[count+1] = '\0';
+ if(count == 0) {
+ return NULL;
+ }
+ else {
+ return buffer;
+ }
+ }
+
+ if(CharRead == 13) {
+ } else if(CharRead == 10) {
+ buffer[count] ='\0';
+ flag = A_ERROR;
+ return buffer;
+ }else {
+ buffer[count++] = CharRead;
+ }
+
+ }
+ while(count < maxlen-1 && CharRead != '\0');
+ buffer[count] = '\0';
+
+ return buffer;
+}
+
+static void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR opcode,int length,int index){
+
+ HCI_PS_Command[0]= 0x0B;
+ HCI_PS_Command[1]= 0xFC;
+ HCI_PS_Command[2]= length + 4;
+ HCI_PS_Command[3]= opcode;
+ HCI_PS_Command[4]= (index & 0xFF);
+ HCI_PS_Command[5]= ((index>>8) & 0xFF);
+ HCI_PS_Command[6]= length;
+}
+
+/////////////////////////
+//
+int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets)
+{
+
+ A_UINT8 count;
+ A_UINT32 NumcmdEntry = 0;
+
+ A_UINT32 Crc = 0;
+ *numPackets = 0;
+
+
+ if(Patch_Count > 0)
+ Crc |= RAM_PATCH_REGION;
+ if(Tag_Count > 0)
+ Crc |= RAM_PS_REGION;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Thread Started CRC %x Patch Count %d Tag Count %d \n",Crc,Patch_Count,Tag_Count));
+
+ if(Patch_Count || Tag_Count ){
+ NumcmdEntry+=(2 + Patch_Count + Tag_Count); /* CRC Packet + PS Reset Packet + Patch List + PS List*/
+ if(Patch_Count > 0) {
+ NumcmdEntry++; /* Patch Enable Command */
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,sizeof(PSCmdPacket) * NumcmdEntry));
+ (*HciPacketList) = A_MALLOC(sizeof(PSCmdPacket) * NumcmdEntry);
+ if(NULL == *HciPacketList) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n"));
+ }
+ AthPSCreateHCICommand(PS_VERIFY_CRC,Crc,*HciPacketList,numPackets);
+ if(Patch_Count > 0){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Write Patch**** \r\n"));
+ AthPSCreateHCICommand(WRITE_PATCH,Patch_Count,*HciPacketList,numPackets);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Enable Patch**** \r\n"));
+ AthPSCreateHCICommand(ENABLE_PATCH,0,*HciPacketList,numPackets);
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Reset**** \r\n"));
+ AthPSCreateHCICommand(PS_RESET,Total_tag_lenght,*HciPacketList,numPackets);
+ if(Tag_Count > 0){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Write**** \r\n"));
+ AthPSCreateHCICommand(PS_WRITE,Tag_Count,*HciPacketList,numPackets);
+ }
+ }
+ if(!BDADDR){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR not present \r\n"));
+
+ }
+ for(count = 0; count < Patch_Count; count++) {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count));
+ A_FREE(RamPatch[Patch_Count].Data);
+ }
+
+ for(count = 0; count < Tag_Count; count++) {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count));
+ A_FREE(PsTagEntry[count].TagData);
+ }
+
+/*
+ * SDIO Transport uses synchronous mode of data transfer
+ * So, AthPSOperations() call returns only after receiving the
+ * command complete event.
+ */
+ return *numPackets;
+}
+
+
+////////////////////////
+
+/////////////
+static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index)
+{
+ A_UCHAR *HCI_PS_Command;
+ A_UINT32 Length;
+ int i,j;
+
+ switch(Opcode)
+ {
+ case WRITE_PATCH:
+
+
+ for(i=0;i< Param1;i++){
+
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER));
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+ memset (HCI_PS_Command, 0, RamPatch[i].Len+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,RamPatch[i].Len,i);
+ for(j=0;j<RamPatch[i].Len;j++){
+ HCI_PS_Command[HCI_COMMAND_HEADER+j]=RamPatch[i].Data[j];
+ }
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = RamPatch[i].Len+HCI_COMMAND_HEADER;
+ (*index)++;
+
+
+ }
+
+ break;
+
+ case ENABLE_PATCH:
+
+
+ Length = 0;
+ i= 0;
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+
+ memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,Length,i);
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ break;
+
+ case PS_RESET:
+ Length = 0x06;
+ i=0;
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+ memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,Length,i);
+ HCI_PS_Command[7]= 0x00;
+ HCI_PS_Command[Length+HCI_COMMAND_HEADER -2]= (Param1 & 0xFF);
+ HCI_PS_Command[Length+HCI_COMMAND_HEADER -1]= ((Param1 >> 8) & 0xFF);
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ break;
+
+ case PS_WRITE:
+ for(i=0;i< Param1;i++){
+ if(PsTagEntry[i].TagId ==1)
+ BDADDR = TRUE;
+
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+
+ memset (HCI_PS_Command, 0, PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId);
+
+ for(j=0;j<PsTagEntry[i].TagLen;j++){
+ HCI_PS_Command[HCI_COMMAND_HEADER+j]=PsTagEntry[i].TagData[j];
+ }
+
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = PsTagEntry[i].TagLen+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ }
+
+ break;
+
+
+ case PS_VERIFY_CRC:
+ Length = 0x0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index));
+
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+ memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,Length,Param1);
+
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ break;
+
+ case CHANGE_BDADDR:
+ break;
+ }
+ return A_OK;
+}
+A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets)
+{
+ int i;
+ if(*HciPacketList == NULL) {
+ return A_ERROR;
+ }
+ for(i = 0; i < numPackets;i++) {
+ A_FREE((*HciPacketList)[i].Hcipacket);
+ }
+ A_FREE(*HciPacketList);
+ return A_OK;
+}
« no previous file with comments | « chromeos/drivers/ath6kl/miscdrv/ar3kps/ar3kpsparser.h ('k') | chromeos/drivers/ath6kl/miscdrv/common_drv.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698