📄 intprismhostap.c
字号:
( END_OBJ * pDrvCtrl ) { WLAN_DEV * pWlanDev = (WLAN_DEV *)pDrvCtrl; STATUS result; WLAN_DEBUG(DEBUG_INFO,("intPrismHostApStart: Start of routine\n")); /* Make sure all card interrupts are clear and all events acknowledged before we enable system interrupts */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_INT_EN, 0x0000); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, 0xffff); WLAN_INT_ENABLE(pWlanDev->iLevel, &result); if (result != OK) { WLAN_DEBUG(DEBUG_FATAL, ("intPrismHostApStart: Error enabling " "interrupts")); } /* OK. Now that all the interrupt infrastrucure is in place, setup our interrupts */ if (intPrismCommand(pWlanDev, WLAN_CMD_ENABLE | WLAN_PORT_0, 0,0,0)) { return ERROR; } pWlanDev->intMask = WLAN_EV_ALLOC | WLAN_EV_RX | WLAN_EV_INFO | WLAN_EV_CMD; WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_INT_EN, ((WLAN_DEV *) pWlanDev)->intMask); END_OBJ_READY(&(pWlanDev->endObj), IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_UP | IFF_RUNNING); pWlanDev->cardStatus = WLAN_STATUS_UP; return OK; }/***************************************************************************** intPrismHostApStop - Not implemented yet,** * RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS intPrismHostApStop ( END_OBJ * pDrvCtrl ) { WLAN_DEBUG(DEBUG_FATAL, ("intPrismHostApStop not implemented yet\n")); return ERROR; }/***************************************************************************** NOMANUAL* intPrismHostApStaHash - returns the hash key for the specified MAC** The hash key is generated by XORing the three least significant bytes of* the MAC address together. The upper three, the manufacturer's code, is not* used to hash, as there is a low number (relatively) of manufactureres of * wireless cards. Use a macro to inline this commonly performed task.** RETURNS: 8-bit hash value** ERRNO: N/A*/#define intPrismHostApStaHash(x) ((x)[3] ^ (x)[4] ^ (x)[5] )/***************************************************************************** intPrismHostApStaAdd - Adds a new station to the hash table** A new station is added to the hash table by this routine. There is no* ordering performed - it is merely added to the end of the branch in the* hash table.* * RETURNS: NULL or pointer to WLAN_STA entry** ERRNO: N/A*/ LOCAL WLAN_STA * intPrismHostApStaAdd ( UINT8* MACAddr ) { UINT8 hashVal; WLAN_STA *pBug; hashVal = intPrismHostApStaHash(MACAddr); WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApStaAdd: Adding "MAC_ADDR_STRING":" " with hash value %d\n", MAC_ADDR(MACAddr), hashVal)); /* If this branch of the hash table is empty, just create a new node */ if (pWlanHostAp->pWlanSta[hashVal] == NULL) { if ((pWlanHostAp->pWlanSta[hashVal] = (WLAN_STA *)calloc (1,sizeof(WLAN_STA))) == NULL) { WLAN_DEBUG(DEBUG_FATAL, ("intPrismHostApStaAdd: Can't allocate " "node: out of memory\n")); return NULL; } pBug = pWlanHostAp->pWlanSta[hashVal]; } else /* Otherwise, we need to go to the end of the branch before adding the station */ { pBug = pWlanHostAp->pWlanSta[hashVal]; while (pBug->pNext != NULL) { pBug = pBug->pNext; } /* Now we're at the end of the linked-list. Add a new node */ if ((pBug->pNext = calloc(1, sizeof(WLAN_STA))) == NULL) { WLAN_DEBUG(DEBUG_FATAL, ("intPrismHostApStaAdd: Can't allocate" " node: out of memory\n")); return NULL; } pBug = pBug->pNext; } WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApStaAdd: Created node at 0x%08x", (UINT32)pBug)); bcopy((char *) MACAddr, (char *) pBug->MACAddr, WLAN_ENET_ADDR_LEN); pBug->pNext = NULL; pBug->authStatus = FALSE; pBug->assocStatus = FALSE; pBug->assocId = 0; pBug->lastTxRate = 2 * INTERSIL_1_MBIT; pBug->pPMQueue = NULL; if ((pBug->timeoutWd = wdCreate()) == NULL) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismHostApStaAdd : Error creating" " timeout watchdog!\n")); return NULL; } if (pWlanHostAp->authTime != 0) { if (wdStart(pBug->timeoutWd, pWlanHostAp->authTime * sysClkRateGet(), (FUNCPTR)intPrismHostApRemoveSta, (int)pBug) == ERROR) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismHostApStaAdd : Error starting" " timeout watchdog!\n")); return NULL; } } return pBug; }/***************************************************************************** intPrismHostApStaLookup - Look up the given station in the known station * list** Examines the known station list to determine if the given MAC address is in* the list. If so, it returns a pointer to the WLAN_STA record. If not, it* returns NULL.** Note : This routine is not callable from inside an ISR due to debug * statements (WLAN_DEBUG is used, which uses printf)** RETURNS: Pointer to the WLAN_STA record for the station, or NULL if not * found** ERRNO: N/A*/LOCAL WLAN_STA * intPrismHostApStaLookup ( UINT8* MACAddr /* MAC of STA to look up */ ) { WLAN_STA * pBug; UINT16 hashVal; hashVal = intPrismHostApStaHash(MACAddr); pBug = pWlanHostAp->pWlanSta[hashVal]; while ((pBug != NULL) && (bcmp((char *) MACAddr, (char *) pBug->MACAddr, WLAN_ENET_ADDR_LEN) != 0)) { pBug = pBug->pNext; } WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApStaLookup: STA "MAC_ADDR_STRING " %sfound\n", MAC_ADDR(MACAddr), (pBug == NULL)?"NOT ":"")); return pBug; }/***************************************************************************** intPrismHostApInt - Interrupt service routine for host-ap** This is a replacement routine for intPrismInt() that adds functionality * necessary for the host-ap. This includes the passing of the complete * incoming packet (including 802.11 header) to the receive routine, the * ability to trap transmit errors if wanted, and the filtering out of * unnecessary incoming packets that would flood the software, such as beacons,* probe requests and probe responses (all of which are handled in the F/W * anyways.)** Received packets do not use WLAN_OFFSET any more, since the parsing of the * Intersil frame header already assures that the IP header is long-aligned* * RETURNS: void** ERRNO: N/A*/LOCAL void intPrismHostApInt ( WLAN_DEV * pWlanDev ) { UINT16 status; /* Stores status register on card */ UINT16 rxFID; /* Store FID of incoming frame on RX event */ LOCAL WLAN_FRAME frame;/* Temp buffer to store frame & SNAP header */ WLAN_RX_FRAME *rxFrame;/* Structure for frame header (NO SNAP) */ UINT16 reg; /* Temp variable for polling offset register*/ UINT32 datalen; /* Length of data field */ UINT32 i; /* Counter for */ int fid; /* Current Frame ID to read into */ int infofid; /* FID used for reading INFO events */ RX_PACKET * pRxPacket; /* Pointer to RX_PAKET structure, passed to RX fn */ rxFrame = (WLAN_RX_FRAME *)&frame; if (pWlanDev == NULL) { WLAN_LOG(DEBUG_FATAL, ("intPrismHostApInt: Fatal error - NULL " "pWlanDev\n", 0,0,0,0,0,0)); return; } if (WLAN_IN_16(WLAN_BASE_ADDR + WLAN_INT_EN) == 0) { WLAN_LOG(DEBUG_INFO, ("intPrismHostApInt: No intMask\n", 0,0,0,0,0,0)); return; } if (WLAN_IN_16(WLAN_BASE_ADDR + WLAN_SW0) != WLAN_SW_MAGIC) { WLAN_LOG(DEBUG_ERROR, ("intPrismHostApInt: card not found!\n", 0,0,0,0,0,0)); return; } do { /* Read the EVENT STATUS */ status = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT); if ((status & WLAN_EV_CMD) != 0) { semGive(pWlanDev->commandComplete); } /* Allocation Event - generated when a buffer is reclaimed after the transmit command is sent. We release the semaphore for the FID. */ if ((status & WLAN_EV_ALLOC) != 0) { fid = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_ALLOC_FID); /* Search fot this FID, and free the corresponding semaphore */ for (i = 0; i< WLAN_MAX_TX_BUF; i++) { if (pWlanDev->txPool[i].fid == fid) { if (semGive(pWlanDev->txPool[i].empty) != OK) { WLAN_LOG(DEBUG_ERROR, ("ALLOC: Error giving sem\n", 0,0,0,0,0,0)); } fid = -1; /* Mark FID as found */ if (pWlanDev->txBlocked) { pWlanDev->txBlocked = FALSE; netJobAdd((FUNCPTR)muxTxRestart, (int)pWlanDev, 0,0,0,0); } WLAN_LOG(DEBUG_FLOOD, ("ALLOC: Found\n",0,0,0,0,0,0)); break; } } /* Spit out an error message if the allocated FID is not in the pool of allocated TX FIDs */ if (fid != -1) { WLAN_LOG(DEBUG_ERROR, ("ALLOC: Reclaimed TX FID unknown!!!", 0,0,0,0,0,0)); } } /* RECEIVE EVENT */ if ((status & WLAN_EV_RX) != 0) { rxFID = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_RX_FID); /* Set up BAP 0 to read the data from. Note that this BAP is only used in the ISR, and thus has no protection mechanisms around it*/ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_SEL0, rxFID); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_OFF0, 0); i = 0; do { if (i++ > WLAN_DEVICE_TIMEOUT) { WLAN_LOG(DEBUG_ERROR, ("intPrismHostApInt: Timeout on BAP" "0 RX 1\n",0,0,0,0,0,0)); goto doneRx; } reg = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_OFF0); } while ((reg & WLAN_OFF_BUSY) != 0); if ((reg & WLAN_OFF_ERR) != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -