📄 intprismhw.c
字号:
WLAN_DEBUG(DEBUG_ERROR, ("intPrismNICIdentify: Unknown card " "type! To support this card, please " "add the following information\n")); WLAN_DEBUG(DEBUG_ERROR, ("intPrismNICIdentify: to the supportedCards[] " "table in intPrismHw.c:\n")); WLAN_DEBUG(DEBUG_ERROR, ("intPrismNICIdentify: Component ID = %x, " "Component variant = %x, " "firmware version = %x\n\n", ltv.data[0], ltv.data[1], intPrismFirmwareGet(pWlanDev))); return OK; }/****************************************************************************** NOMANUAL* intPrismBSSJoin - Joins the specified BSS. ** Sets the desired SSID on the card to the specified value, If the card is* in IBSS mode an IBSS is joined, otherwise an ESS is joined. If the card* is in AP mode, the AP SSID, contained in WLAN_RID_OWN_SSID is also set.* A disassociation message is sent to the old AP before the new SSID is joined* to eliminate loops.** RETURNS: OK or ERROR ** ERRNO: N/A**/STATUS intPrismBSSJoin ( WLAN_DEV * pWlanDev, /* Pointer to device handle */ char * bssName /* SSID of the BSS you wish to join/create */ ) { STATUS status = OK; LTV_RECORD ltv; /* Store the bssid*/ UINT8 * bssid; /* Dereferences the BSSID inside the LTV record*/ /* Whether we're joining an ESS or IBSS is determined by the setting of EIOCSIBSSMODE for all card excepot the wavelan, which will create an IBSS if an ESS of the specified name does not exist */ switch (pWlanDev->cardType) { case WLAN_CARDTYPE_WAVELAN: case WLAN_CARDTYPE_3COM: case WLAN_CARDTYPE_INTERSIL_2: case WLAN_CARDTYPE_INTERSIL_2_5: case WLAN_CARDTYPE_INTERSIL_3: if (pWlanDev->cardMode == WLAN_CARDMODE_STA) { if (pWlanDev->cardStatus == WLAN_STATUS_UP) { /* If the card is up, read the BSSID of the current AP from the card, make sure it's a valid BSSID, and then send a de-authentication packet to it */ ltv.type = WLAN_RID_CURRENT_BSSID; status = intPrismLTVRead(pWlanDev, <v); if ((ltv.length != 4) || (status != OK)) { WLAN_DEBUG(DEBUG_ERROR, ("IntPrismBSSJoin: Error " "getting BSSID\n")); } else { bssid = (UINT8 *)<v.data[0]; /* Check if the BSSID is either all zeros or all 0xff's - in either case it's not valid, otherwise send the disassoc message. */ if (((bssid[0] | bssid[1] | bssid[2] | bssid[3] | bssid[4] | bssid[5]) != 0) && ((bssid[0] & bssid[1] & bssid[2] & bssid[3] & bssid[4] & bssid[5]) != 0xff)) { status |= intPrismDisassocSend(pWlanDev, bssid); } } } /* Change to the new BSS */ status |= intPrismRIDStringWrite(pWlanDev, WLAN_RID_DESIRED_SSID, bssName); } /* Need to do OWN_SSID for both STA and AP mode, since the STA could be in IBSS mode */ status |= intPrismRIDStringWrite(pWlanDev, WLAN_RID_OWN_SSID, bssName); break; default: WLAN_DEBUG(DEBUG_ERROR, ("intPrismBSSJoin: Unknown card type\n")); status = ERROR; break; } /* Fix for SPR 71834: The 3Com cards seem not to require a reset after setting network name, and will sometimes fail to connect if you do, unless there's a large (~1s) taskDelay in between. Accordingly, the reset is not performed for 3Com cards */ if (pWlanDev->cardType != WLAN_CARDTYPE_3COM) status |= intPrismReset(pWlanDev); return status; }/****************************************************************************** NOMANUAL* intPrismBSSScan - Performs a BSS scan and prints the results to STDOUT* * A BSS scan searches all channels for ESSs or IBSSs that match the currently* set network name. If the network name is set to NULL, then all ESSs and * IBSSs that are publically available are shown. Note that some access points* support a feature to deny BSS scans as a security measure. If this is * enabled on the access point, then that particular ESS will not show up in * this listing.** RETURNS: Number of BSSs found or ERROR** ERRNO: N/A*/INT32 intPrismBSSScan ( WLAN_DEV * pWlanDev /* Pointer to device control strucutre */ ) { LTV_RECORD ltv; int i; int numBSS; SCAN_RESULT *pScan; char bssName[WLAN_BSS_NAME_MAX]; if (pWlanDev == NULL) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismBSSScan: NULL pWlanDev\n")); return ERROR; } if ( (pWlanDev->cardType != WLAN_CARDTYPE_INTERSIL_2) && (pWlanDev->cardType != WLAN_CARDTYPE_INTERSIL_2_5) && (pWlanDev->cardType != WLAN_CARDTYPE_INTERSIL_3)) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismBSSScan: Only supported for Intersil" " cards\n")); return ERROR; } /* Issue the scan request */ ltv.type = INTERSIL_RID_SCAN_REQUEST; ltv.length = 3; ltv.data[0] = 0x3fff; ltv.data[1] = WLAN_11_MBIT; intPrismLTVWrite(pWlanDev, <v); taskDelay(sysClkRateGet()/2); /* wait 500 msec */ ltv.type = INTERSIL_RID_SCAN_RESULTS; intPrismLTVRead(pWlanDev, <v); switch (ltv.data[1]) { case 0: WLAN_DEBUG(DEBUG_INFO, ("intPrismBSSScan: Scan in progress\n")); break; case 1: WLAN_DEBUG(DEBUG_INFO, ("intPrismBSSScan: Host initiated scan\n")); break; case 2: WLAN_DEBUG(DEBUG_INFO, ("intPrismBSSScan: Firmware initiated " "scan\n")); break; case 3: WLAN_DEBUG(DEBUG_INFO, ("intPrismBSSScan: Inquiry request SCN\n")); break; default: WLAN_DEBUG(DEBUG_ERROR, ("intPrismBSSScan: Unknown scan reason:" " %d\n", ltv.data[1])); } numBSS = (ltv.length - 3) / 31; intPrismIoctl((END_OBJ *)pWlanDev, EIOCGDESIREDSSID, (caddr_t)bssName); printf(" Number of BSS identified that match %s = %d\n", (bssName[0] == 0x00)?"ANY":bssName, numBSS); pScan = (SCAN_RESULT *)<v.data[2]; for (i = 0; i < numBSS; i++) { printf("\n BSS #%d\n", i); bcopyswap((UINT8 *)pScan->SSID, (UINT8 *) bssName, pScan->SSIDlen); bssName[pScan->SSIDlen] = 0x00; printf(" SSID = \"%s\"\n", bssName); if ((pScan->cap & WLAN_SCAN_CAP_ESS) != 0 ) { printf(" ESS\n"); } if ((pScan->cap & WLAN_SCAN_CAP_IBSS) != 0 ) { printf(" IBSS\n"); } if ((pScan->cap & WLAN_SCAN_CAP_WEP) != 0 ) { printf(" WEP Required\n"); } /* We'll use bssName to swap the BSSID */ bcopyswap((UINT8 *) pScan->BSSID, (UINT8 *) bssName, 6); printf(" BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n", (UINT8)bssName[0], (UINT8)bssName[1], (UINT8)bssName[2], (UINT8)bssName[3], (UINT8)bssName[4], (UINT8)bssName[5] ); printf(" Channel %d\n", pScan->channel); pScan ++; } return numBSS; }/****************************************************************************** NOMANUAL* intPrismCommandAsync - Issues a command to the card; blocks for CMD event.** Issues a command to the card, and waits for the busy bit to* be cleared. Then, a semaphore is blocked on that is released in the ISR* when a WLAN_EV_CMD event is detected. This is more efficient than the * polling method used by intPrismCommand(), but only works when interrupts are* enabled (ie. after intPrismStart has been called and not in polled mode)** RETURNS: OK or ERROR if the command did not successfully complete** ERRNO: N/A**/STATUS intPrismCommandAsync ( 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 */ ) { if (pWlanDev == NULL) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismCommandAsync: NULL pWlanDev\n")); return ERROR; } /* Take the command-exclusion semaphore. Try for 500ms (arbitrary) */ if (semTake(pWlanDev->commandProt, sysClkRateGet()/2) != OK) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismCommandAsync: Error getting command" " protection semaphore.")); return ERROR; } WLAN_DEBUG(DEBUG_INFO,("intPrismCommandAsync: issuing command 0x%2x (param" " 0x%04x) to 0x%08x\n", command, param0, 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, ("intPrismCommandAsync: Card not found!")); semGive(pWlanDev->commandProt); return ERROR; } /* Check is the busy bit ia 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_ERROR,("intPrismCommandAsync: BUSY bit not cleared" ".\n")); 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_FATAL, ("intPrismCommandAsync: 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 for now, although a wiser choice might be to spin on it and wait for the ISR */ while ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & WLAN_EV_CMD) != 0) { WLAN_DEBUG(DEBUG_INFO,("intPrismCommandAsync : unacknowleged CMD " "event\n")); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, WLAN_EV_CMD); } /* Check if the command completion semaphore has already been sent - if so, we need to filter out the old event that was not properly acked, so we can wait for this particular event */ if (semTake(pWlanDev->commandComplete, NO_WAIT) == OK) { WLAN_DEBUG(DEBUG_INFO, ("intPrismCommandAsync: Clearing old command" "Complete semaphore\n")); } /* 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); 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. */ if (semTake(pWlanDev->commandComplete, sysClkRateGet()/2) != OK) { if ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & WLAN_EV_CMD) != 0) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismCommandAsync: Warning ISR missed" " command event!\n")); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT, WLAN_EV_CMD); } else {#if (CPU==STRONGARM) || (CPU==XSCALE) || (CPU==ARMARCH4) WLAN_DEBUG(DEBUG_INFO, ("intPrismCommandAsync: Error: Command " "complete not received\n"));#else WLAN_DEBUG(DEBUG_ERROR, ("intPrismCommandAsync: Error: Command " "complete not received\n"));#endif if (intPrismKickstart(pWlanDev) != OK) { semGive(pWlanDev->commandProt); return ERROR; } } } semGive(pWlanDev->commandProt); return OK; }/****************************************************************************** intPrismFirmwareGet - Returns the secondary firmware version** Returns the secondary (station) functions firmware version. This is packed* into a 32 bit word as follows* Bit: |31 24|23 16|15 8|7 0|* =======================================* | 0 | major | minor | var |* Where <major> is the major version number, <minor> is the minor number,* and <var> is the variant version number. For example, firmware version* 0.8.3 would be returned as 0x00000803** RETURNS: Firmware version in packed byte form or ERROR** ERRNO: N/A**/UINT32 intPrismFirmwareGet ( WLAN_DEV *pWlanDev /* Pointer to device handle for this card
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -