/* ======================================================================== Routine Description: This routine is used to do insert packet into power-saveing queue. Arguments: pAd: Pointer to our adapter pPacket: Pointer to send packet pMacEntry: portint to entry of MacTab. the pMacEntry store attribute of client (STA). QueIdx: Priority queue idex. Return Value: NDIS_STATUS_SUCCESS:If succes to queue the packet into TxSwQueue. NDIS_STATUS_FAILURE: If failed to do en-queue. ======================================================================== */ NDIS_STATUS RtmpInsertPsQueue( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN MAC_TABLE_ENTRY *pMacEntry, IN UCHAR QueIdx) { ULONG IrqFlags; #ifdef UAPSD_SUPPORT /* put the U-APSD packet to its U-APSD queue by AC ID */ UINT32 ac_id = QueIdx - QID_AC_BE; /* should be >= 0 */ if (UAPSD_MR_IS_UAPSD_AC(pMacEntry, ac_id)) { UAPSD_PacketEnqueue(pAd, pMacEntry, pPacket, ac_id); #ifdef DOT11Z_TDLS_SUPPORT TDLS_UAPSDP_TrafficIndSend(pAd, pMacEntry->Addr); #endif /* DOT11Z_TDLS_SUPPORT */ } else #endif /* UAPSD_SUPPORT */ { if (pMacEntry->PsQueue.Number >= MAX_PACKETS_IN_PS_QUEUE) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { DBGPRINT(RT_DEBUG_TRACE, ("legacy ps> queue a packet!\n")); RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueue(&pMacEntry->PsQueue, PACKET_TO_QUEUE_ENTRY(pPacket)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } #ifdef CONFIG_AP_SUPPORT /* mark corresponding TIM bit in outgoing BEACON frame */ #ifdef UAPSD_SUPPORT if (UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(pMacEntry, 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, pMacEntry->apidx, pMacEntry->Aid); } #endif /* CONFIG_AP_SUPPORT */ return NDIS_STATUS_SUCCESS; }
VOID MtEnqTxSwqFromPsQueue(RTMP_ADAPTER *pAd, UCHAR qidx, STA_TR_ENTRY *tr_entry) { ULONG IrqFlags = 0; //struct tx_swq_fifo *fifo_swq; QUEUE_ENTRY *pQEntry; QUEUE_HEADER *pAcPsQue; QUEUE_HEADER *pAcTxQue; #ifdef UAPSD_SUPPORT MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[tr_entry->wcid]; #endif /* UAPSD_SUPPORT */ //fifo_swq = &pAd->tx_swq[qidx]; pAcPsQue = &tr_entry->ps_queue; pAcTxQue = &tr_entry->tx_queue[qidx]; RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); #ifdef UAPSD_SUPPORT if (UAPSD_MR_IS_UAPSD_AC(pEntry, qidx)) { while(pAcPsQue->Head) { pQEntry = RemoveTailQueue(pAcPsQue); UAPSD_PacketEnqueue(pAd, pEntry, PACKET_TO_QUEUE_ENTRY(pQEntry), qidx, TRUE); } } else #endif /* UAPSD_SUPPORT */ { /*check and insert PS Token queue*/ if(pAcPsQue->Number > 0 && tr_entry->wcid > 0 && tr_entry->wcid < MAX_LEN_OF_TR_TABLE) { rtmp_ps_enq(pAd,tr_entry); DBGPRINT(RT_DEBUG_TRACE | DBG_FUNC_PS, ("pAcPsQue->Number=%d,PS:%d\n",pAcPsQue->Number,tr_entry->PsTokenFlag)); } while(pAcPsQue->Head) { pQEntry = RemoveTailQueue(pAcPsQue); if(tr_entry->enqCount > SQ_ENQ_NORMAL_MAX) { RELEASE_NDIS_PACKET(pAd, QUEUE_ENTRY_TO_PACKET(pQEntry), NDIS_STATUS_FAILURE); continue; } InsertHeadQueue(pAcTxQue, pQEntry); #ifdef LIMIT_GLOBAL_SW_QUEUE TR_ENQ_COUNT_INC(tr_entry, &pAd->TxSwQueue[qidx]); #else /* LIMIT_GLOBAL_SW_QUEUE */ TR_ENQ_COUNT_INC(tr_entry); #endif /* ! LIMIT_GLOBAL_SW_QUEUE */ } } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); return; }
/* ======================================================================== Routine Description: This routine is used to do insert packet into power-saveing queue. Arguments: pAd: Pointer to our adapter pPacket: Pointer to send packet pMacEntry: portint to entry of MacTab. the pMacEntry store attribute of client (STA). QueIdx: Priority queue idex. Return Value: NDIS_STATUS_SUCCESS:If succes to queue the packet into TxSwQueue. NDIS_STATUS_FAILURE: If failed to do en-queue. ======================================================================== */ NDIS_STATUS RtmpInsertPsQueue( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN MAC_TABLE_ENTRY *pMacEntry, IN UCHAR QueIdx) { ULONG IrqFlags; #ifdef UAPSD_SUPPORT /* put the U-APSD packet to its U-APSD queue by AC ID */ UINT32 ac_id = QueIdx - QID_AC_BE; /* should be >= 0 */ if (UAPSD_MR_IS_UAPSD_AC(pMacEntry, ac_id)) { UAPSD_PacketEnqueue(pAd, pMacEntry, pPacket, ac_id); #ifdef DOT11Z_TDLS_SUPPORT TDLS_UAPSDP_TrafficIndSend(pAd, pMacEntry->Addr); #endif /* DOT11Z_TDLS_SUPPORT */ } else #endif /* UAPSD_SUPPORT */ { if (pMacEntry->PsQueue.Number >= MAX_PACKETS_IN_PS_QUEUE) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { DBGPRINT(RT_DEBUG_TRACE, ("legacy ps> queue a packet!\n")); RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueue(&pMacEntry->PsQueue, PACKET_TO_QUEUE_ENTRY(pPacket)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } return NDIS_STATUS_SUCCESS; }
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; }
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; }
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; }