📄 intprismhw.c
字号:
} else { WLAN_DEBUG(DEBUG_ERROR, ("intPrismDiagnose : Card diagnostics pattern " "match FAILED!\n")); WLAN_DEBUG(DEBUG_ERROR, ("intPrismDiagnose : RESP0 = 0x%04x " "RESP1 = 0x%04x\n", result0, result1)); return ERROR; } return OK; }/****************************************************************************** intPrismCommand - Issues a command to the WLAN card.** Issues a command to the card and polls for the command complete. The polling* takes place under an intLock() to ensure that the ISR (if it is running) does* not intercept the command completion event. If the card has been initialized* commands other than WLAN_CMD_INI and WLAN_CMD_DIAG are passed to * intPrismCommandAsync() to avoid this polling behaviour.** RETURNS: OK or ERROR if the command did not successfully complete** ERRNO: N/A**/STATUS intPrismCommand ( WLAN_DEV *pWlanDev, /* Pointer to device handle for this card */ UINT16 command, /* Value for the command register */ UINT16 param0, /* Value for the PARAM0 register */ UINT16 param1, /* Value for the PARAM1 register */ UINT16 param2 /* Value for the PARAM2 regsiter */ ) { UINT16 status; /* Used to check for successful command compelteion*/ int i; int intLevel; if (pWlanDev == NULL) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismCommand: ERROR - NULL pWlanDev\n")); return ERROR; } /* Use the more efficient intPrismCommandAsync if interrupts are enabled. Note that INIT and DIAG command can't be sent while the card is UP */ if ((pWlanDev->cardStatus == WLAN_STATUS_UP) && (command != WLAN_CMD_INI) && (command != WLAN_CMD_DIAG) ) { return intPrismCommandAsync(pWlanDev, command, param0, param1, param2); } if (semTake(pWlanDev->commandProt, sysClkRateGet()/2) != OK) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismCommand: Error getting command" " protection semaphore.")); return ERROR; } WLAN_DEBUG(DEBUG_INFO,("intPrismCommand : issuing command 0x%02x to " "0x%08x\n", command, WLAN_BASE_ADDR+WLAN_COMMAND)); if (command == WLAN_CMD_INI) { WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_SW0, WLAN_SW_MAGIC); } /* Check for card presence */ if (WLAN_IN_16(WLAN_BASE_ADDR + WLAN_SW0) != WLAN_SW_MAGIC) { WLAN_DEBUG(DEBUG_FATAL, ("intPrismCommand: Card not found!")); semGive(pWlanDev->commandProt); return ERROR; } /* Check is the busy bit is set. If it is, the card is stuck. Try resetting it. If that still doesn't help, return ERROR */ if ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_COMMAND) & WLAN_CMD_BUSY) != 0) { WLAN_DEBUG(DEBUG_INFO,("intPrismCommand : BUSY bit not cleared.\n")); taskDelay(sysClkRateGet()/60); /* wait 16 msec */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, WLAN_EV_CMD); /* OK. If the bit is still cleared, it is an unrecoverable error */ if ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_COMMAND) & WLAN_CMD_BUSY) != 0) { WLAN_DEBUG(DEBUG_INFO, ("intPrismCommand : BUSY bit cannot be" " cleared.\n")); semGive(pWlanDev->commandProt); return ERROR; } } /* Check if we have an unacknowledged COMMAND event. If so, we'll acknowledge it and see if it's been cleared. If this still doesn't clear it, then the card must not have been initialized correctly */ if ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & WLAN_EV_CMD) != 0) { WLAN_DEBUG(DEBUG_INFO,("intPrismCommand : unacknowleged CMD event\n")); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, WLAN_EV_CMD); /* Delay the smallest amount of time we can */ taskDelay(2); if ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & WLAN_EV_CMD) != 0) { /* It's still not cleared - chances are that the COR reset was not performed correctly */ WLAN_DEBUG(DEBUG_ERROR,("intPrismCommand : cannot acknowlege " "CMD event - perform COR rReset\n")); return ERROR; } } /* Setup the parameter registers, then issue the command */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_PARAM0, param0); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_PARAM1, param1); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_PARAM2, param2); /* Mask out interrupts in card */ intLevel = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_INT_EN); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_INT_EN, 0); /* Issue the command */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_COMMAND, command); /* The basic sequence here is wait for the command event to be posted then acknowledge it. */ i = 0; while ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & WLAN_EV_CMD) == 0) { if (i++ == (WLAN_DEVICE_TIMEOUT * 50) ) { WLAN_DEBUG(DEBUG_INFO, ("intPrismCommand: Timeout on command" " complete\n")); break; } } /* Now, check the status register to see if the command succeeded... */ if (((status = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_STATUS)) & WLAN_STAT_CMD_RESULT) != 0) { WLAN_DEBUG(DEBUG_ERROR,("intPrismCommand : Command 0x%04x failed! " "Status Reg is 0x%04x Error qualified is %4x\n" ,command, status, WLAN_IN_16(WLAN_BASE_ADDR + WLAN_RESP0))); semGive(pWlanDev->commandProt); /* ACK the command */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, WLAN_EV_CMD); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_INT_EN, intLevel); return ERROR; } /* ACK the command */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, WLAN_EV_CMD); /* Restore card interrupts */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_INT_EN, intLevel); STORMPAD_INT_FIX(pWlanDev); if (i > WLAN_DEVICE_TIMEOUT * 50) { semGive(pWlanDev->commandProt); return ERROR; } if (command == WLAN_CMD_INI) { WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_SW0, WLAN_SW_MAGIC); } semGive(pWlanDev->commandProt); return OK; }/****************************************************************************** intPrismCommandResp - Returns the value of the command response registers** This function gets the value of the 3 response registers and places* it in the given variables resp0 - resp2. If the value of a particular* response register is unwanted, pass NULL instead of a pointer to a variable,* and it will be ignored.* * RETURNS: OK** ERRNO: N/A** SEE ALSO: intPrismCommand()**/STATUS intPrismCommandResp ( WLAN_DEV * pWlanDev, /* Pointer to device handle for this card */ UINT16 * resp0, /* Variable to store value of RESP0 in */ UINT16 * resp1, /* Variable to store value of RESP1 in */ UINT16 * resp2 /* Variable to store value of RESP2 in */ ) { /* If we don't want all of the paramters, just pass NULL as the poitner, and a value won't be read into it. Good error checking too */ if (resp0 != NULL) { *resp0 = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_RESP0); } if (resp1 != NULL) { *resp1 = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_RESP1); } if (resp2 != NULL) { *resp2 = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_RESP2); } return OK; }/****************************************************************************** intPrismLTVRead - Reads an LTV record from the device** This function reads the specified LTV (Length-Type-Value) record from the * NIC and returns it in the structure provided. The record requested should* be entered into the <type> field of the record pointed to by <pRecord>.** RETURNS: OK or ERROR if the record could not be read** ERRNO: N/A**/STATUS intPrismLTVRead ( WLAN_DEV* pWlanDev, /* Pointer to device handle */ LTV_RECORD* pRecord /* Pointer to LTV structure with type field entered*/ ) { int RIDlength; int RIDtype; int i; int intLevel; if ((pRecord == NULL) || (pWlanDev == NULL)) { WLAN_DEBUG(DEBUG_ERROR,("intPrismLTVRead: Invalid LTV request\n")); return ERROR; } /* Send an ACCESS/READ command, with the desired record as PARAM0 */ if (intPrismCommand(pWlanDev, WLAN_CMD_ACCESS | WLAN_ACCESS_READ, pRecord->type, 0, 0) == ERROR) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismLTVRead: ACCESS command failed for" " RID 0x%04x\n", pRecord->type)); return ERROR; } /* Prevent the ISR from interrupting the read and crashing the card */ WLAN_INT_LOCK; if (intPrismBAP1Offset(pWlanDev, pRecord->type, 0) == ERROR) { WLAN_INT_UNLOCK; WLAN_DEBUG(DEBUG_ERROR, ("intPrismLTVRead : Error opening BAP\n")); return ERROR; } /* The LTV record should now be accessible through the BAP. */ RIDlength = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA1); pRecord->length = RIDlength; RIDtype = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA1); pRecord->type = RIDtype; for (i = 0; i < (RIDlength-1); i++) { pRecord->data[i] = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA1); } WLAN_INT_UNLOCK; STORMPAD_INT_FIX(pWlanDev); WLAN_DEBUG(DEBUG_INFO,("intPrismLTVRead : Type = %04x\n", RIDtype)); WLAN_DEBUG(DEBUG_FLOOD,("intPrismLTVRead : Length = %d\n", RIDlength)); return OK; }/****************************************************************************** intPrismRIDWordWrite - Writes the specified word to the specified RID** This function writes the specified RID - it is basically a wrapper for* intPrismLTVWrite()** RETURNS: OK or ERROR if the record could not be written** ERRNO: N/A** SEE ALSO: intPrismLTVWrite()**/STATUS intPrismRIDWordWrite ( WLAN_DEV *pWlanDev, /* Pointer to device handle */ UINT16 RID, /* Record ID to write */ UINT16 value /* Data to be written */ ) { LTV_RECORD ltv; ltv.length = 2; /* Length includes itself and the data */ ltv.data[0] = value; ltv.type = RID; return intPrismLTVWrite(pWlanDev, <v); }/****************************************************************************** intPrismRIDWordRead - Reads the specified word to the specified RID** Reads a single word from the specified RID.** RETURNS: Value read from the Record or 0xffff on ERROR** ERRNO: N/A** SEE ALSO: intPrismLTVWrite()**/UINT16 intPrismRIDWordRead ( WLAN_DEV *pWlanDev, /* Pointer to device handle */ UINT16 RID /* Record ID to read from */ ) { LTV_RECORD ltv; ltv.length = 2; /* Length includes itself and the data */ ltv.type = RID; if (intPrismLTVRead(pWlanDev, <v) == ERROR) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismRIDWordRead: ERROR\n")); } return ltv.data[0]; }/****************************************************************************** intPrismRIDStringWrite - Writes the specified string to the specified RID** This function writes the specified RID - it is basically a wrapper for* intPrismLTVWrite(). ** RETURNS: OK or ERROR if the record could not be written** ERRNO: N/A** SEE ALSO: intPrismLTVWrite()**/STATUS intPrismRIDStringWrite ( WLAN_DEV *pWlanDev, UINT16 RID, const char * pStr ) { LTV_RECORD ltv; /* Strings are stored with the length of the string in the first word of <data> and the string starts in the second word. Thus The record length is the length of the type field, plus the string length field, plus the length of the string (in 16-bit words) */ ltv.length = 2 + (strlen(pStr)+1)/2; ltv.data[0] = strlen(pStr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -