PNDIS_PACKET DuplicatePacket( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID) { struct sk_buff *skb; PNDIS_PACKET pRetPacket = NULL; USHORT DataSize; UCHAR *pData; DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); if (skb) { skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pRetPacket = OSPKT_TO_RTPKT(skb); } #if 0 if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL) { skb_reserve(skb, 2+32); NdisMoveMemory(skb->tail, pData, DataSize); skb_put(skb, DataSize); skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pRetPacket = OSPKT_TO_RTPKT(skb); } #endif return pRetPacket; }
NDIS_STATUS IgmpPktInfoQuery( IN PRTMP_ADAPTER pAd, IN PUCHAR pSrcBufVA, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID, OUT INT *pInIgmpGroup, OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry) { if(IS_MULTICAST_MAC_ADDR(pSrcBufVA)) { INT32 ExcludedGroupType = -1; UINT16 EtherType = ntohs(*((UINT16 *)(pSrcBufVA + 12))); if (EtherType == ETH_P_IPV6) { ExcludedGroupType = IPv6MulticastFilterExcluded(pSrcBufVA); } else if(EtherType == ETH_P_IP) { ExcludedGroupType = IPv4MulticastFilterExcluded(pSrcBufVA); } if (ExcludedGroupType) { *ppGroupEntry = NULL; if (ExcludedGroupType == 1) *pInIgmpGroup = IGMP_PKT; } else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA, get_netdev_from_bssid(pAd, FromWhichBSSID))) == NULL) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else *pInIgmpGroup = IGMP_IN_GROUP; } else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA)) { PUCHAR pDstIpAddr = pSrcBufVA + 30; /* point to Destination of Ip address of IP header. */ UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr, get_netdev_from_bssid(pAd, FromWhichBSSID))) != NULL) { *pInIgmpGroup = IGMP_IN_GROUP; } } return NDIS_STATUS_SUCCESS; }
VOID REPORT_AMSDU_FRAMES_TO_LLC( IN PRTMP_ADAPTER pAd, IN PUCHAR pData, IN ULONG DataSize) { PNDIS_PACKET pPacket; UINT nMSDU; struct sk_buff *pSkb; nMSDU = 0; /* allocate a rx packet */ pSkb = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_AGGRESIZE); pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb); if (pSkb) { /* convert 802.11 to 802.3 packet */ GET_OS_PKT_NETDEV(pSkb) = get_netdev_from_bssid(pAd, BSS0); RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize); } else { DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n")); } }
void wlan_802_11_to_802_3_packet( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk, IN PUCHAR pHeader802_3, IN UCHAR FromWhichBSSID) { struct sk_buff *pOSPkt; ASSERT(pRxBlk->pRxPacket); ASSERT(pHeader802_3); pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pOSPkt->data = pRxBlk->pData; pOSPkt->len = pRxBlk->DataSize; pOSPkt->tail = pOSPkt->data + pOSPkt->len; // // copy 802.3 header // // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3); #endif // CONFIG_STA_SUPPORT // }
void wlan_802_11_to_802_3_packet( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk, IN PUCHAR pHeader802_3, IN UCHAR FromWhichBSSID) { struct sk_buff *pOSPkt; ASSERT(pRxBlk->pRxPacket); ASSERT(pHeader802_3); pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pOSPkt->data = pRxBlk->pData; pOSPkt->head = pOSPkt->data; pOSPkt->len = pRxBlk->DataSize; skb_set_tail_pointer(pOSPkt, pOSPkt->len); // // copy 802.3 header // // NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3); }
void convert_reordering_packet_to_preAMSDU_or_802_3_packet(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) { void *pRxPkt; u8 Header802_3[LENGTH_802_3]; /* 1. get 802.3 Header */ /* 2. remove LLC */ /* a. pointer pRxBlk->pData to payload */ /* b. modify pRxBlk->DataSize */ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); ASSERT(pRxBlk->pRxPacket); pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID)); SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData); SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize); SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize); /* */ /* copy 802.3 header, if necessary */ /* */ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) { { #ifdef LINUX NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3); #endif } } }
PNDIS_PACKET duplicate_pkt( IN PRTMP_ADAPTER pAd, IN PUCHAR pHeader802_3, IN UINT HdrLen, IN PUCHAR pData, IN ULONG DataSize, IN UCHAR FromWhichBSSID) { struct sk_buff *skb; PNDIS_PACKET pPacket = NULL; if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) { skb_reserve(skb, 2); NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen); skb_put(skb, HdrLen); NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize); skb_put(skb, DataSize); skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pPacket = OSPKT_TO_RTPKT(skb); } return pPacket; }
// // change OS packet DataPtr and DataLen // void update_os_packet_info( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk, IN UCHAR FromWhichBSSID) { struct sk_buff *pOSPkt; ASSERT(pRxBlk->pRxPacket); pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pOSPkt->data = pRxBlk->pData; pOSPkt->len = pRxBlk->DataSize; pOSPkt->tail = pOSPkt->data + pOSPkt->len; }
/* ======================================================================== Routine Description: Ikanos WLAN --> LAN transmit fast path function. Arguments: pFrame - the received packet (Ikanos packet format) Return Value: None Note: Ikanos platform supports only 8 VAPs ======================================================================== */ static void IKANOS_WlanPktFromAp( IN apPreHeader_t *pFrame) { PRTMP_ADAPTER pAd; struct net_device *dev = NULL; struct sk_buff *skb; INT32 index; apPreHeader_t *apBuf = K0_TO_K1(pFrame); pAd = pIkanosAd; /*index = apBuf->specInfoElement; */ /*dev = pAd->ApCfg.MBSSID[index].MSSIDDev; */ index = GetSpecInfoIdxFromBssid(pAd, apBuf->specInfoElement); dev = get_netdev_from_bssid(pAd, apBuf->specInfoElement); if (dev == NULL) { printk("ikanos> %s: ERROR null device ***************\n", __FUNCTION__); return; } /* End of if */ skb = (struct sk_buff *)translateApbuf2Mbuf(apBuf); if (NULL == skb) { printk("ikanos> %s: skb is null *********************\n", __FUNCTION__); return; } /* End of if */ pAd->IkanosRxInfo[index].netdev = dev; pAd->IkanosRxInfo[index].fp = &IKANOS_WlanDataFramesTx; skb->dev = dev; skb->apFlowData.rxApId = IKANOS_PERAP_ID; /*skb->apFlowData.txHandle = &(txinforx[index]); */ skb->apFlowData.rxHandle = &(pAd->IkanosRxInfo[index]); skb->protocol = eth_type_trans(skb, skb->dev); #ifdef IKANOS_DEBUG printk("ikanos> rx no fp!\n"); /* debug use */ #endif /* IKANOS_DEBUG */ netif_rx(skb); return; } /* End of IKANOS_WlanPktFromAp */
/* ======================================================================== Routine Description: Send Leyer 2 Update Frame to update forwarding table in Layer 2 devices. Arguments: *mac_p - the STATION MAC address pointer Return Value: TRUE - send successfully FAIL - send fail Note: ======================================================================== */ static BOOLEAN IAPP_L2_Update_Frame_Send( IN PRTMP_ADAPTER pAd, IN UINT8 *mac_p, IN int bssid) { NDIS_PACKET *pNetBuf; pNetBuf = RtmpOsPktIappMakeUp(get_netdev_from_bssid(pAd, bssid), mac_p); if (pNetBuf == NULL) return FALSE; /* UCOS: update the built-in bridge, too (don't use gmac.xmit()) */ announce_802_3_packet(pAd, pNetBuf, OPMODE_AP); IAPP_L2_UpdatePostCtrl(pAd, mac_p, bssid); return TRUE; } /* End of IAPP_L2_Update_Frame_Send */
void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd, u8 *pData, unsigned long DataSize) { void *pPacket; u32 nMSDU; struct sk_buff *pSkb; nMSDU = 0; /* allocate a rx packet */ pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE); pPacket = (void *)OSPKT_TO_RTPKT(pSkb); if (pSkb) { /* convert 802.11 to 802.3 packet */ pSkb->dev = get_netdev_from_bssid(pAd, BSS0); RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize); } else { DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n")); } }
PNDIS_PACKET DuplicatePacket( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID) { struct sk_buff *skb; PNDIS_PACKET pRetPacket = NULL; USHORT DataSize; UCHAR *pData; DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); if (skb) { skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pRetPacket = OSPKT_TO_RTPKT(skb); } return pRetPacket; }
NDIS_STATUS IgmpPktClone( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN int IgmpPktInGroup, IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry, IN UCHAR QueIdx, IN UINT8 UserPriority, IN PNET_DEV pNetDev) { PNDIS_PACKET pSkbClone = NULL; PMEMBER_ENTRY pMemberEntry = NULL; MAC_TABLE_ENTRY *pMacEntry = NULL; USHORT Aid; SST Sst = SST_ASSOC; UCHAR PsMode = PWR_ACTIVE; UCHAR Rate; unsigned long IrqFlags; int MacEntryIdx; BOOLEAN bContinue; PUCHAR pMemberAddr = NULL; bContinue = FALSE; if ((IgmpPktInGroup == IGMP_IN_GROUP) && (pGroupEntry == NULL)) return NDIS_STATUS_FAILURE; if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } } else { return NDIS_STATUS_FAILURE; } /* check all members of the IGMP group. */ while(bContinue == TRUE) { if (pMacEntry && (Sst == SST_ASSOC)) { OS_PKT_CLONE(pAd, pPacket, pSkbClone, MEM_ALLOC_FLAG); if ((pSkbClone) ) { RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)pMacEntry->Aid); /* Pkt type must set to PKTSRC_NDIS. */ /* It cause of the deason that APHardTransmit() */ /* doesn't handle PKTSRC_DRIVER pkt type in version 1.3.0.0. */ RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS); } else { if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } else bContinue = FALSE; continue; } if (PsMode == PWR_SAVE) { APInsertPsQueue(pAd, pSkbClone, pMacEntry, QueIdx); } else { /* insert the pkt to TxSwQueue. */ if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) { #ifdef BLOCK_NET_IF StopNetIfQueue(pAd, QueIdx, pSkbClone); #endif /* BLOCK_NET_IF */ RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } #ifdef DOT11_N_SUPPORT RTMP_BASetup(pAd, pMacEntry, UserPriority); #endif /* DOT11_N_SUPPORT */ } if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } else bContinue = FALSE; } return NDIS_STATUS_SUCCESS; }
/* ======================================================================== Routine Description: Get a received packet. Arguments: pAd device control block pSaveRxD receive descriptor information *pbReschedule need reschedule flag *pRxPending pending received packet flag Return Value: the received packet Note: ======================================================================== */ void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd, OUT PRT28XX_RXD_STRUC pSaveRxD, OUT BOOLEAN * pbReschedule, IN u32 * pRxPending) { struct rt_rx_context *pRxContext; void *pSkb; u8 *pData; unsigned long ThisFrameLen; unsigned long RxBufferLength; struct rt_rxwi * pRxWI; pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) return NULL; RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) + sizeof(struct rt_rxinfo))) { goto label_null; } pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */ /* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */ ThisFrameLen = *pData + (*(pData + 1) << 8); if (ThisFrameLen == 0) { DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); goto label_null; } if ((ThisFrameLen & 0x3) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); goto label_null; } if ((ThisFrameLen + 8) > RxBufferLength) /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */ { DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition)); /* error frame. finish this loop */ goto label_null; } /* skip USB frame length field */ pData += RT2870_RXDMALEN_FIELD_SIZE; pRxWI = (struct rt_rxwi *) pData; if (pRxWI->MPDUtotalByteCount > ThisFrameLen) { DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen)); goto label_null; } /* allocate a rx packet */ pSkb = dev_alloc_skb(ThisFrameLen); if (pSkb == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__)); goto label_null; } /* copy the rx packet */ memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen); RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0); RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS); /* copy RxD */ *pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen); /* update next packet read position. */ pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */ return pSkb; label_null: return NULL; }
/* ======================================================================== Routine Description: Get a received packet. Arguments: pAd device control block pSaveRxD receive descriptor information *pbReschedule need reschedule flag *pRxPending pending received packet flag Return Value: the recieved packet Note: ======================================================================== */ PNDIS_PACKET GetPacketFromRxRing( IN RTMP_ADAPTER *pAd, OUT RX_BLK *pRxBlk, OUT BOOLEAN *pbReschedule, INOUT UINT32 *pRxPending, OUT BOOLEAN *bCmdRspPacket) { RX_CONTEXT *pRxContext; PNDIS_PACKET pNetPkt; UCHAR *pData, *RXDMA; ULONG ThisFrameLen, RxBufferLength, valid_len; RXWI_STRUC *pRxWI; UINT8 RXWISize = pAd->chipCap.RXWISize; RXINFO_STRUC *pRxInfo; #ifdef RLT_MAC RXFCE_INFO *pRxFceInfo; #endif /* RLT_MAC */ *bCmdRspPacket = FALSE; pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) return NULL; RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; valid_len = RXDMA_FIELD_SIZE * 2; if (RxBufferLength < valid_len) { goto label_null; } pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; RXDMA = pData; /* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */ ThisFrameLen = *pData + (*(pData+1)<<8); if (ThisFrameLen == 0) { DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); goto label_null; } if ((ThisFrameLen & 0x3) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); goto label_null; } if ((ThisFrameLen + 8) > RxBufferLength) /* 8 for (RXDMA_FIELD_SIZE + sizeof(RXINFO_STRUC))*/ { DBGPRINT(RT_DEBUG_ERROR,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition)); /* error frame. finish this loop*/ goto label_null; } /* skip USB frame length field*/ pData += RXDMA_FIELD_SIZE; #ifdef RLT_MAC pRxFceInfo = (RXFCE_INFO *)(pData + ThisFrameLen); /* Check if command response or data packet */ if ((pRxFceInfo->info_type == CMD_PACKET) && (pAd->chipCap.CmdRspRxRing == RX_RING0)) { //CmdRspEventCallbackHandle(pAd, RXDMA); /* Update next packet read position.*/ pAd->ReadPosition += (sizeof(*pRxFceInfo) * 2 + pRxFceInfo->pkt_len); *bCmdRspPacket = TRUE; goto label_null; } pRxInfo = (RXINFO_STRUC *)pData; pData += RXINFO_SIZE; #endif /* RLT_MAC */ #ifdef RTMP_MAC pRxInfo = *(RXINFO_STRUC *)(pData + ThisFrameLen); #endif /* RTMP_MAC */ pRxWI = (RXWI_STRUC *)pData; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, pData, TYPE_RXWI); #endif /* RT_BIG_ENDIAN */ if (pRxWI->RxWIMPDUByteCnt > ThisFrameLen) { DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", __FUNCTION__, pRxWI->RxWIMPDUByteCnt, ThisFrameLen)); goto label_null; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, pData, TYPE_RXWI); #endif /* RT_BIG_ENDIAN */ /* allocate a rx packet*/ pNetPkt = RTMP_AllocateFragPacketBuffer(pAd, ThisFrameLen); if (pNetPkt == NULL) { DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__)); goto label_null; } /* copy the rx packet*/ RTMP_USB_PKT_COPY(get_netdev_from_bssid(pAd, BSS0), pNetPkt, ThisFrameLen, pData); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pRxInfo, TYPE_RXINFO); #endif /* RT_BIG_ENDIAN */ #ifdef RLT_MAC NdisMoveMemory((VOID *)&pRxBlk->hw_rx_info[0], (VOID *)pRxFceInfo, sizeof(RXFCE_INFO)); pRxBlk->pRxFceInfo = (RXFCE_INFO *)&pRxBlk->hw_rx_info[0]; #endif /* RLT_MAC */ NdisMoveMemory(&pRxBlk->hw_rx_info[RXINFO_OFFSET], pRxInfo, RXINFO_SIZE); pRxBlk->pRxInfo = (RXINFO_STRUC *)&pRxBlk->hw_rx_info[RXINFO_OFFSET]; /* update next packet read position.*/ pAd->ReadPosition += (ThisFrameLen + RXDMA_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RXDMA_FIELD_SIZE + sizeof(RXINFO_STRUC))*/ return pNetPkt; label_null: return NULL; }
NDIS_STATUS IgmpPktInfoQuery( IN PRTMP_ADAPTER pAd, IN PUCHAR pSrcBufVA, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID, OUT INT *pInIgmpGroup, OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry) { if(IS_MULTICAST_MAC_ADDR(pSrcBufVA)) { BOOLEAN IgmpMldPkt = FALSE; PUCHAR pIpHeader = pSrcBufVA + 12; if(ntohs(*((UINT16 *)(pIpHeader))) == ETH_P_IPV6) IgmpMldPkt = IPv6MulticastFilterExcluded(pSrcBufVA, pIpHeader); else IgmpMldPkt = isIgmpPkt(pSrcBufVA, pIpHeader); /*-----------------*/ if(IS_IPV6_RA_MAC_ADDR(pSrcBufVA)) return NDIS_STATUS_SUCCESS; if(IS_IPV6_RS_MAC_ADDR(pSrcBufVA)) return NDIS_STATUS_SUCCESS; if(IS_IPV6_NS_MAC_ADDR(pSrcBufVA)) return NDIS_STATUS_SUCCESS; /*-----------------*/ if (IgmpMldPkt) { *ppGroupEntry = NULL; // *pInIgmpGroup = IGMP_PKT; *pInIgmpGroup = IGMP_NONE; } /*-----------------*/ else if(isIgmpMDNSPkt(pSrcBufVA,pSrcBufVA+14)) { return NDIS_STATUS_SUCCESS; } /*-----------------*/ else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA, get_netdev_from_bssid(pAd, FromWhichBSSID))) == NULL) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else *pInIgmpGroup = IGMP_IN_GROUP; } else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA)) { PUCHAR pDstIpAddr = pSrcBufVA + 30; /* point to Destination of Ip address of IP header. */ UCHAR GroupMacAddr[6]; PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr; ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP); if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr, get_netdev_from_bssid(pAd, FromWhichBSSID))) != NULL) { *pInIgmpGroup = IGMP_IN_GROUP; } } return NDIS_STATUS_SUCCESS; }
void STA_MonPktSend( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk) { PNET_DEV pNetDev; PNDIS_PACKET pRxPacket; PHEADER_802_11 pHeader; USHORT DataSize; UINT32 MaxRssi; UCHAR L2PAD, PHYMODE, BW, ShortGI, MCS, AMPDU, STBC, RSSI1; UCHAR BssMonitorFlag11n, Channel, CentralChannel; UCHAR *pData, *pDevName; /* sanity check */ ASSERT(pRxBlk->pRxPacket); if (pRxBlk->DataSize < 10) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize)); goto err_free_sk_buff; } if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); goto err_free_sk_buff; } /* init */ MaxRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2)); pNetDev = get_netdev_from_bssid(pAd, BSS0); pRxPacket = pRxBlk->pRxPacket; pHeader = pRxBlk->pHeader; pData = pRxBlk->pData; DataSize = pRxBlk->DataSize; L2PAD = pRxBlk->RxD.L2PAD; PHYMODE = pRxBlk->pRxWI->PHYMODE; BW = pRxBlk->pRxWI->BW; ShortGI = pRxBlk->pRxWI->ShortGI; MCS = pRxBlk->pRxWI->MCS; AMPDU = pRxBlk->RxD.AMPDU; STBC = pRxBlk->pRxWI->STBC; RSSI1 = pRxBlk->pRxWI->RSSI1; BssMonitorFlag11n = 0; #ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT BssMonitorFlag11n = (pAd->StaCfg.BssMonitorFlag & MONITOR_FLAG_11N_SNIFFER); #endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ pDevName = (UCHAR *)RtmpOsGetNetDevName(pAd->net_dev); Channel = pAd->CommonCfg.Channel; CentralChannel = pAd->CommonCfg.CentralChannel; /* pass the packet */ send_monitor_packets(pNetDev, pRxPacket, pHeader, pData, DataSize, L2PAD, PHYMODE, BW, ShortGI, MCS, AMPDU, STBC, RSSI1, BssMonitorFlag11n, pDevName, Channel, CentralChannel, MaxRssi); return; err_free_sk_buff: RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); return; }
/* ======================================================================== Routine Description: Get a received packet. Arguments: pAd device control block pSaveRxD receive descriptor information *pbReschedule need reschedule flag *pRxPending pending received packet flag Return Value: the recieved packet Note: ======================================================================== */ PNDIS_PACKET GetPacketFromRxRing( IN PRTMP_ADAPTER pAd, OUT PRT28XX_RXD_STRUC pSaveRxD, OUT BOOLEAN *pbReschedule, IN OUT UINT32 *pRxPending) { PRX_CONTEXT pRxContext; PNDIS_PACKET pNetPkt; PUCHAR pData; ULONG ThisFrameLen; ULONG RxBufferLength; PRXWI_STRUC pRxWI; pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) return NULL; RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC))) { goto label_null; } pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */ // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) ThisFrameLen = *pData + (*(pData+1)<<8); if (ThisFrameLen == 0) { DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); goto label_null; } if ((ThisFrameLen&0x3) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); goto label_null; } if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC)) { DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition)); // error frame. finish this loop goto label_null; } // skip USB frame length field pData += RT2870_RXDMALEN_FIELD_SIZE; pRxWI = (PRXWI_STRUC)pData; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pData, TYPE_RXWI); #endif // RT_BIG_ENDIAN // if (pRxWI->MPDUtotalByteCount > ThisFrameLen) { DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen)); goto label_null; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pData, TYPE_RXWI); #endif // RT_BIG_ENDIAN // // allocate a rx packet pNetPkt = RTMP_AllocateFragPacketBuffer(pAd, ThisFrameLen); if (pNetPkt == NULL) { DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__)); goto label_null; } // copy the rx packet memcpy(skb_put(pNetPkt, ThisFrameLen), pData, ThisFrameLen); GET_OS_PKT_NETDEV(pNetPkt) = get_netdev_from_bssid(pAd, BSS0);; RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pNetPkt), PKTSRC_NDIS); // copy RxD *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO); #endif // RT_BIG_ENDIAN // // update next packet read position. pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC)) return pNetPkt; label_null: return NULL; }
NDIS_STATUS IgmpPktClone( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN INT IgmpPktInGroup, IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry, IN UCHAR QueIdx, IN UINT8 UserPriority) { PNDIS_PACKET pSkbClone = NULL; PMEMBER_ENTRY pMemberEntry = NULL; MAC_TABLE_ENTRY *pMacEntry = NULL; USHORT Aid; SST Sst = SST_ASSOC; UCHAR PsMode = PWR_ACTIVE; UCHAR Rate; unsigned long IrqFlags; INT MacEntryIdx; BOOLEAN bContinue; PUCHAR pMemberAddr = NULL; PUCHAR pSrcMAC = NULL; PNET_DEV pNetDev = NULL; bContinue = FALSE; if (IgmpPktInGroup == IGMP_IN_GROUP) { if (!pGroupEntry) return NDIS_STATUS_FAILURE; pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead; if (pMemberEntry) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } } else if (IgmpPktInGroup == IGMP_PKT) { pNetDev = GET_OS_PKT_NETDEV(pPacket); pSrcMAC = GET_OS_PKT_DATAPTR(pPacket) + 6; for(MacEntryIdx=1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if ((pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) && (get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) && (!MAC_ADDR_EQUAL(pMacEntry->Addr, pSrcMAC))) /* DAD IPv6 issue */ { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } } else { return NDIS_STATUS_FAILURE; } /* check all members of the IGMP group. */ while(bContinue == TRUE) { if (pMacEntry && (Sst == SST_ASSOC) && (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED)) { OS_PKT_CLONE(pAd, pPacket, pSkbClone, MEM_ALLOC_FLAG); if (!pSkbClone) return NDIS_STATUS_FAILURE; RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)pMacEntry->Aid); if (PsMode == PWR_SAVE) { APInsertPsQueue(pAd, pSkbClone, pMacEntry, QueIdx); } else { /* insert the pkt to TxSwQueue. */ if (pAd->TxSwQueue[QueIdx].Number >= pAd->TxSwQMaxLen) { #ifdef BLOCK_NET_IF StopNetIfQueue(pAd, QueIdx, pSkbClone); #endif /* BLOCK_NET_IF */ RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } #ifdef DOT11_N_SUPPORT RTMP_BASetup(pAd, pMacEntry, UserPriority); #endif /* DOT11_N_SUPPORT */ } if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if ((pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) && (get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) && (!MAC_ADDR_EQUAL(pMacEntry->Addr, pSrcMAC))) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } } return NDIS_STATUS_SUCCESS; }
void send_monitor_packets( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk) { struct sk_buff *pOSPkt; wlan_ng_prism2_header *ph; int rate_index = 0; USHORT header_len = 0; UCHAR temp_header[40] = {0}; u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96, 108, 109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80}; ASSERT(pRxBlk->pRxPacket); if (pRxBlk->DataSize < 10) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize)); goto err_free_sk_buff; } if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); goto err_free_sk_buff; } pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0); if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) { pRxBlk->DataSize -= LENGTH_802_11; if ((pRxBlk->pHeader->FC.ToDs == 1) && (pRxBlk->pHeader->FC.FrDs == 1)) header_len = LENGTH_802_11_WITH_ADDR4; else header_len = LENGTH_802_11; // QOS if (pRxBlk->pHeader->FC.SubType & 0x08) { header_len += 2; // Data skip QOS contorl field pRxBlk->DataSize -=2; } // Order bit: A-Ralink or HTC+ if (pRxBlk->pHeader->FC.Order) { header_len += 4; // Data skip HTC contorl field pRxBlk->DataSize -= 4; } // Copy Header if (header_len <= 40) NdisMoveMemory(temp_header, pRxBlk->pData, header_len); // skip HW padding if (pRxBlk->RxD.L2PAD) pRxBlk->pData += (header_len + 2); else pRxBlk->pData += header_len; } //end if if (pRxBlk->DataSize < pOSPkt->len) { skb_trim(pOSPkt,pRxBlk->DataSize); } else { skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len)); } //end if if ((pRxBlk->pData - pOSPkt->data) > 0) { skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data)); skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data)); } //end if if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) { if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__)); goto err_free_sk_buff; } //end if } //end if if (header_len > 0) NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len); ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header)); NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header)); ph->msgcode = DIDmsg_lnxind_wlansniffrm; ph->msglen = sizeof(wlan_ng_prism2_header); strcpy(ph->devname, pAd->net_dev->name); ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; ph->hosttime.status = 0; ph->hosttime.len = 4; ph->hosttime.data = jiffies; ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; ph->mactime.status = 0; ph->mactime.len = 0; ph->mactime.data = 0; ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx; ph->istx.status = 0; ph->istx.len = 0; ph->istx.data = 0; ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel; ph->channel.status = 0; ph->channel.len = 4; ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel; ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; ph->rssi.status = 0; ph->rssi.len = 4; ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));; ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; ph->signal.status = 0; ph->signal.len = 4; ph->signal.data = 0; //rssi + noise; ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; ph->noise.status = 0; ph->noise.len = 4; ph->noise.data = 0; if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) { rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS); } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM) rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4; else rate_index = (UCHAR)(pRxBlk->pRxWI->MCS); if (rate_index < 0) rate_index = 0; if (rate_index > 255) rate_index = 255; ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; ph->rate.status = 0; ph->rate.len = 4; ph->rate.data = ralinkrate[rate_index]; ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; ph->frmlen.status = 0; ph->frmlen.len = 4; ph->frmlen.data = (u_int32_t)pRxBlk->DataSize; pOSPkt->pkt_type = PACKET_OTHERHOST; pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev); pOSPkt->ip_summed = CHECKSUM_NONE; netif_rx(pOSPkt); return; err_free_sk_buff: RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); return; }
NDIS_STATUS IgmpPktClone( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN INT IgmpPktInGroup, IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry, IN UCHAR QueIdx, IN UINT8 UserPriority, IN PNET_DEV pNetDev) { PNDIS_PACKET pSkbClone = NULL; PMEMBER_ENTRY pMemberEntry = NULL; MAC_TABLE_ENTRY *pMacEntry = NULL; STA_TR_ENTRY *tr_entry = NULL; USHORT Aid; SST Sst = SST_ASSOC; UCHAR PsMode = PWR_ACTIVE; UCHAR Rate; #ifndef MT_MAC unsigned long IrqFlags; #endif INT MacEntryIdx; BOOLEAN bContinue; PUCHAR pMemberAddr = NULL; bContinue = FALSE; if ((IgmpPktInGroup == IGMP_IN_GROUP) && (pGroupEntry == NULL)) return NDIS_STATUS_FAILURE; if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead; if (pMemberEntry) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } } else if (IgmpPktInGroup == IGMP_PKT) { PUCHAR src_addr = GET_OS_PKT_DATAPTR(pPacket); src_addr += 6; for(MacEntryIdx=1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); // TODO: shiang-usw, check get_netdev_from_bssid() here!! if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->wdev->wdev_idx) == pNetDev && (!NdisEqualMemory(src_addr, pMacEntry->Addr, MAC_ADDR_LEN))) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } } else return NDIS_STATUS_FAILURE; /* check all members of the IGMP group. */ while(bContinue == TRUE) { if (pMacEntry && (Sst == SST_ASSOC) && (pAd->MacTab.tr_entry[pMacEntry->wcid].PortSecured == WPA_802_1X_PORT_SECURED)) { OS_PKT_CLONE(pAd, pPacket, pSkbClone, MEM_ALLOC_FLAG); if ((pSkbClone) #ifdef DOT11V_WNM_SUPPORT && (pMacEntry->Beclone == FALSE) #endif /* DOT11V_WNM_SUPPORT */ ) { RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)pMacEntry->Aid); //copy APSendPacket() unicast check portion. #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) { tr_entry = &pAd->MacTab.tr_entry[pMacEntry->wcid]; if ((tr_entry->EntryType != ENTRY_CAT_MCAST) && (tr_entry->PsMode == PWR_SAVE)) { if (tr_entry->tx_queue[QID_AC_BE].Number+tr_entry->tx_queue[QID_AC_BK].Number+tr_entry->tx_queue[QID_AC_VI].Number+tr_entry->tx_queue[QID_AC_VO].Number > MAX_PACKETS_IN_PS_QUEUE) { DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): (wcid=%u)STA tx_queue full\n", __FUNCTION__, __LINE__,pMacEntry->wcid)); RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } } #if defined(RTMP_MAC) || defined(RLT_MAC) /* detect AC Category of tx packets to tune AC0(BE) TX_OP (MAC reg 0x1300) */ // TODO: shiang-usw, check this for REG access, it should not be here! if ((pAd->chipCap.hif_type == HIF_RTMP) || (pAd->chipCap.hif_type == HIF_RLT)) detect_wmm_traffic(pAd, UserPriority, 1); #endif /* defined(RTMP_MAC) || defined(RLT_MAC) */ RTMP_SET_PACKET_UP(pSkbClone, UserPriority); if (rtmp_enq_req(pAd, pSkbClone, QueIdx, tr_entry, FALSE, NULL) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): (wcid=%u)STA rtmp_enq_req() fail!\n", __FUNCTION__, __LINE__,pMacEntry->wcid)); RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } if (tr_entry->EntryType == ENTRY_CAT_MCAST) //should not be here!! { DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): (wcid=%u) ENTRY_CAT_MCAST !! ERROR check should not be here!\n", __FUNCTION__, __LINE__,pMacEntry->wcid)); if (pAd->MacTab.fAnyStationInPsm == 1) WLAN_MR_TIM_BCMC_SET(tr_entry->func_tb_idx); /* mark MCAST/BCAST TIM bit */ } else { if (IS_ENTRY_CLIENT(tr_entry) && (tr_entry->PsMode == PWR_SAVE)) { /* mark corresponding TIM bit in outgoing BEACON frame */ #ifdef UAPSD_SUPPORT if (UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(&pAd->MacTab.Content[tr_entry->wcid], QueIdx)) { /* 1. the station is UAPSD station; 2. one of AC is non-UAPSD (legacy) AC; 3. the destinated AC of the packet is UAPSD AC. */ /* So we can not set TIM bit due to one of AC is legacy AC */ } else #endif /* UAPSD_SUPPORT */ { WLAN_MR_TIM_BIT_SET(pAd, tr_entry->func_tb_idx, tr_entry->wcid); } } } } #endif /* MT_MAC */ } else { if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else if (IgmpPktInGroup == IGMP_PKT) { PUCHAR src_addr = GET_OS_PKT_DATAPTR(pPacket); src_addr += 6; for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->wdev->wdev_idx) == pNetDev && (!NdisEqualMemory(src_addr, pMacEntry->Addr, MAC_ADDR_LEN))) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } else bContinue = FALSE; #ifdef DOT11V_WNM_SUPPORT pMacEntry->Beclone = FALSE; #endif /* DOT11V_WNM_SUPPORT */ continue; } #ifndef MT_MAC /*did't queue to AC queue for MT_MAC */ if (PsMode == PWR_SAVE) { APInsertPsQueue(pAd, pSkbClone, pMacEntry, QueIdx); } else { if (pAd->TxSwQueue[QueIdx].Number >= pAd->TxSwQMaxLen) { #ifdef BLOCK_NET_IF StopNetIfQueue(pAd, QueIdx, pSkbClone); #endif /* BLOCK_NET_IF */ RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } #endif /* !MT_MAC */ #ifdef DOT11_N_SUPPORT RTMP_BASetup(pAd, tr_entry, UserPriority); #endif /* DOT11_N_SUPPORT */ } if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); // TODO: shiang-usw, check for pMacEntry->wdev->wdev_idx here! if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->wdev->wdev_idx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } else bContinue = FALSE; } return NDIS_STATUS_SUCCESS; }