📄 intprismhostap.c
字号:
WLAN_LOG(DEBUG_ERROR, ("intPrismHostApInt: Offset error on " "BAP 0\n",0,0,0,0,0,0)); goto doneRx; } /* Read the first part of the header, to get the frame control fields, determine if it's worth reading the rest of the packet */ for (i=0; i< (sizeof(WLAN_FRAME) - 2)/2; i++) { *(( (UINT16*)rxFrame)+i) = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA0); } /* Copy the ethertype in unreversed */ *(( (UINT16*)rxFrame)+i) = WLAN_IN_16_ENDIAN(WLAN_BASE_ADDR + WLAN_DATA0); datalen = rxFrame->dataLen; /* Drop beacon, probe reply frames from other APs, since they just clog tNetTask without serving any useful purpose */ if ( ((rxFrame->frameCtl & 0xfc) == (WLAN_FTYPE_MGMT | WLAN_STYPE_MGMT_BEACON)) || ((rxFrame->frameCtl & 0xfc) == (WLAN_FTYPE_MGMT | WLAN_STYPE_MGMT_PROBE_REQ)) || ((rxFrame->frameCtl & 0xfc) == (WLAN_FTYPE_MGMT | WLAN_STYPE_MGMT_PROBE_RESP)) ) { goto doneRx; /* Drop the packet silently */ } /* Drop frames not to our BSS */ if ( ((frame.frame_ctl & WLAN_FTYPE_MASK) == WLAN_FTYPE_DATA) && ( (*(UINT16*)&frame.addr1[0] != (WLAN_TO_LE(*(UINT16*)&pWlanHostAp->bssid[0]))) || (*(UINT16*)&frame.addr1[2] != (WLAN_TO_LE(*(UINT16*)&pWlanHostAp->bssid[2]))) || (*(UINT16*)&frame.addr1[4] != (WLAN_TO_LE( *(UINT16*)&pWlanHostAp->bssid[4])))) ) { goto doneRx; } /* Drop data frames not sent to the DS */ if ( ((frame.frame_ctl & WLAN_FTYPE_MASK) == WLAN_FTYPE_DATA) && ((frame.frame_ctl & WLAN_FCTL_TO_DS) == 0) ) { goto doneRx; } if (pWlanDev->oneXMode == ONEX_MODE_ENABLED) { if ( ((frame.frame_ctl & INTPR_FCTL_WEP) == 0) && ((frame.frame_ctl & WLAN_FTYPE_MASK) == WLAN_FTYPE_DATA)) { if (frame.type != htons(ONEX_PROTOCOL)) { WLAN_LOG(DEBUG_INFO, ("intPrismHostApInt: 802.1x : " "dropping non-encrypted packet" " of type %04x\n", frame.type, 0,0,0,0,0)); goto doneRx; } else { WLAN_LOG(DEBUG_INFO, ("intPrismHostApInt: 802.1x packet" " accepted\n",0,0,0,0,0,0)); } } } /* If there was an error decoding the frame, don't worry about it, just scrap the frame */ if ((rxFrame->status & WLAN_STAT_ERRSTAT) != 0) { WLAN_LOG(DEBUG_INFO, ("intPrismHostApInt: Bad RX Frame!\n", 0,0,0,0,0,0)); END_ERR_ADD(&pWlanDev->endObj, MIB2_IN_ERRS, +1); goto doneRx; } if ((pRxPacket = (RX_PACKET *) netClusterGet (&pWlanDev->netPool, pWlanDev->pClPool)) == NULL) { WLAN_LOG(DEBUG_INFO, ("intPrismHostApInt: Error getting" " cluster\n", 0, 0, 0, 0, 0, 0)); goto doneRx; } pRxPacket->pData = ((char *)pRxPacket) + sizeof(RX_PACKET); /* Set up BAP 0 to read the data from. Note : It is assumed that other interrupts using this BAP will not pre-empt this one, thus there is no protection for the BAP */ 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" " BAP0 RX2\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) { WLAN_LOG(DEBUG_ERROR, ("intPrismHostApInt: Offset error " "on BAP 0\n",0,0,0,0,0,0)); goto doneRx; } /* If the packet is a data packet (and not using host decrypt) then read the packet in, skipping the SNAP header */ if ((rxFrame->frameCtl & WLAN_FTYPE_MASK) == WLAN_FTYPE_DATA) { /* Read the 802.11 header, swapped */ for (i=0; i< (sizeof(WLAN_RX_FRAME)-WLAN_EH_SIZE)/2; i++) { *(( (UINT16*)(pRxPacket->pData))+i) = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA0); } /* Read the dst and src mac addr. (not swapped) */ for (i=0; i<(2 * WLAN_ENET_ADDR_LEN) / 2; i++) { *(( (UINT16*)(pRxPacket->pData + sizeof(WLAN_RX_FRAME) - WLAN_EH_SIZE))+i) = WLAN_IN_16_ENDIAN(WLAN_BASE_ADDR + WLAN_DATA0); } if (rxFrame->dataLen != 0) /* Not not a NULL-data pkt */ { if (pWlanHostAp->hostDecrypt == 1) { for (i=0; i< (datalen + 2 + 1)/2; i++) { *(( (UINT16*)(pRxPacket->pData + sizeof(WLAN_RX_FRAME) - 2))+i) = WLAN_IN_16_ENDIAN(WLAN_BASE_ADDR + WLAN_DATA0); } } else /* Host decrypt != 1 */ { /* Skip the SNAP header */ for (i=0; i< (WLAN_SNAP_HDR_LEN)/2; i++) { reg = WLAN_IN_16_ENDIAN(WLAN_BASE_ADDR+WLAN_DATA0); } /* Read the rest of the data, including the ethertype, all not swapped */ for (i=0; i< (datalen-WLAN_SNAP_HDR_LEN+2+1)/2; i++) { *(( (UINT16*)(pRxPacket->pData + sizeof(WLAN_RX_FRAME) - 2))+i) = WLAN_IN_16_ENDIAN(WLAN_BASE_ADDR + WLAN_DATA0); } } } else /* dataLen == 0 */ { /* For zero-len packets, adjust the size so the SNAP headers (not present in a zero len) cancel out */ datalen += WLAN_SNAP_HDR_LEN; } pRxPacket->length = datalen + sizeof(WLAN_RX_FRAME) - WLAN_SNAP_HDR_LEN; /* Check for WDS packets - these will be passed to a separate driver, if installed */ if ( ((frame.frame_ctl & WLAN_FCTL_TO_DS) != 0) && ((frame.frame_ctl & WLAN_FCTL_FROM_DS) != 0) && (pWlanDev->pWds != NULL) ) { /* Send it to the receive handler. No RX buffer chaining here, but the WDS handler will at least understand the structure. */ netJobAdd(pWlanDev->pWds->receiveRtn, (int)pWlanDev->pWds, (int)pRxPacket, pRxPacket->length,0,0); } else /* Normal non-WDS packets */ { /* Add a netjob to process the RX packet if and only this is the only packet in the queue */ pRxPacket->pNext = NULL; if (pWlanDev->pRxTail != NULL) pWlanDev->pRxTail->pNext = pRxPacket; pWlanDev->pRxTail = pRxPacket; if (pWlanDev->pRxHead == NULL) { /* Set the head pointer so the RX rtn has somewhere to go */ pWlanDev->pRxHead = pRxPacket; netJobAdd(intPrismHostApReceive, (int)pWlanDev, (int)pRxPacket, 0,0,0); /* Send it to the receive handler */ } else { /* Do nothing - a packet is already enqueued */ } } } else /* Non-data packets */ { pRxPacket->length = datalen + sizeof(WLAN_RX_FRAME); /* Read the entire frame (assumed to be a control or management frame) swapped */ for (i=0; i< (sizeof(WLAN_RX_FRAME) + datalen + 1)/2; i++) { *(( (UINT16*)(pRxPacket->pData))+i) = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA0); } /* Add a netjob to process the RX packet if and only this is the only packet in the queue */ pRxPacket->pNext = NULL; if (pWlanDev->pRxTail != NULL) pWlanDev->pRxTail->pNext = pRxPacket; pWlanDev->pRxTail = pRxPacket; if (pWlanDev->pRxHead == NULL) { /* Set the head pointer so the RX rtn has somewhere to go */ pWlanDev->pRxHead = pRxPacket; netJobAdd(intPrismHostApReceive, (int)pWlanDev, (int)pRxPacket, 0, 0, 0); } else { /* Do nothing since a queue is already be processed by tNetJob */ } } doneRx: } /* Check if there's an INFO event. */ if ((status & (WLAN_EV_INFO)) != 0) { infofid = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_INFO_FID); /* Set up BAP 0 to read the data from. Note : It is assumed that other interrupts using this BAP will not pre-empt this one, thus there is no protection for the BAP */ WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_SEL0, infofid); WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_OFF0, 0); i = 0; do { if (i++ > WLAN_DEVICE_TIMEOUT) { WLAN_LOG(DEBUG_ERROR, ("intPrismHostApInt: Timeout on" " BAP0 Info Event\n",0,0,0,0,0,0)); goto doneInfo; } reg = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_OFF0); } while ((reg & WLAN_OFF_BUSY) != 0); if ((reg & WLAN_OFF_ERR) != 0) { WLAN_LOG(DEBUG_ERROR, ("intPrismHostApInt: Offset error " "on BAP 0\n",0,0,0,0,0,0)); goto doneInfo; } ltvInfoEvent.length = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA0); if (ltvInfoEvent.length == 0) { goto doneInfo; } ltvInfoEvent.type = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA0); for (i = 0; i< (UINT16)(ltvInfoEvent.length - 1); i++) ltvInfoEvent.data[i] = WLAN_IN_16(WLAN_BASE_ADDR + WLAN_DATA0); /* give the semaphore so the info event can be processed by the task tInfoFidRead */ semGive(semInfoFidRead); doneInfo: } /* Just ack any events that we don't normally handle */ if (status != 0x0000) { WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_EVENT_ACK, status); } } while ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & (WLAN_EV_RX | WLAN_EV_ALLOC | WLAN_EV_INFO | WLAN_EV_CMD) ) != 0); return; }/***************************************************************************** intPrismHostApReceive - Receive handler for Host-AP** This receive routine (unlike that present in the STA driver) handles raw* intersil packets. These packets are passed to this routine in exactly the* form that they are downloaded with the exception that they must be offset by* two, to quad-byte align the IP header (etherheader is 14 bytes...)** Management frames relevant to the host-ap are handled, and Data frames are* passed up the stackj or copied back to the wireless network as required.** 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: OK or ERROR*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -