static BOOLEAN StaAllowToSendPacket(RTMP_ADAPTER *pAd, struct wifi_dev *wdev, PNDIS_PACKET pPacket, UCHAR *pWcid) { BOOLEAN allowToSend; if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) { return FALSE; } else { if (ADHOC_ON(pAd)) { RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID); } if (INFRA_ON(pAd) && (0)) { MAC_TABLE_ENTRY *pEntry; PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); pEntry = MacTableLookup(pAd, pSrcBufVA); if (pEntry && (IS_ENTRY_DLS(pEntry))) { *pWcid = pEntry->wcid; } else { *pWcid = 0; } } else { *pWcid = 0; } allowToSend = TRUE; } return allowToSend; }
VOID MeshClonePacket( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN UINT8 MeshSrc, IN UINT8 MeshLinkIdx) { INT idx; PUCHAR pSA = NULL; PUCHAR pDA = NULL; for (idx = 0; idx < MAX_MESH_LINKS; idx++) { if ((MeshSrc == MESH_FORWARD) && (MeshLinkIdx == idx)) continue; pSA = GET_OS_PKT_DATAPTR(pPacket) + MAC_ADDR_LEN; if (MAC_ADDR_EQUAL(pAd->MeshTab.MeshLink[idx].Entry.PeerMacAddr, pSA)) continue; pDA = GET_OS_PKT_DATAPTR(pPacket); if (IS_MULTICAST_MAC_ADDR(pDA) && (MultipathEntryLookUp(pAd, idx, pSA) != NULL)) continue; if (PeerLinkValidCheck(pAd, idx) == TRUE) { PNDIS_PACKET pPacketClone; /* pPacketClone = skb_clone(RTPKT_TO_OSPKT(pPacket), GFP_ATOMIC); */ OS_PKT_CLONE(pAd, pPacket, pPacketClone, GFP_ATOMIC); if (pPacketClone == NULL) continue; RTMP_SET_PACKET_NET_DEVICE_MESH(pPacketClone, 0); RTMP_SET_PACKET_SOURCE(pPacketClone, PKTSRC_NDIS); RTMP_SET_PACKET_MOREDATA(pPacketClone, FALSE); RTMP_SET_PACKET_WCID(pPacketClone, pAd->MeshTab.MeshLink[idx].Entry.MacTabMatchWCID); RTMP_SET_MESH_ROUTE_ID(pPacketClone, BMCAST_ROUTE_ID); RTMP_SET_MESH_SOURCE(pPacketClone, MeshSrc); #ifdef CONFIG_AP_SUPPORT APSendPacket(pAd, pPacketClone); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT STASendPacket(pAd, pPacketClone); #endif /* CONFIG_STA_SUPPORT */ } } return; }
/* ======================================================================== Routine Description: Early checking and OS-depened parsing for Tx packet to AP device. Arguments: NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd. PPNDIS_PACKET ppPacketArray The packet array need to do transmission. UINT NumberOfPackets Number of packet in packet array. Return Value: NONE Note: This function do early checking and classification for send-out packet. You only can put OS-depened & AP related code in here. ======================================================================== */ VOID wdev_tx_pkts(NDIS_HANDLE dev_hnd, PPNDIS_PACKET pkt_list, UINT pkt_cnt, struct wifi_dev *wdev) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd; PNDIS_PACKET pPacket; BOOLEAN allowToSend; UCHAR wcid = MCAST_WCID; UINT Index; for (Index = 0; Index < pkt_cnt; Index++) { pPacket = pkt_list[Index]; if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { /* Drop send request since hardware is in reset state */ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); continue; } if ((wdev->allow_data_tx == TRUE) && (wdev->tx_pkt_allowed)) allowToSend = wdev->tx_pkt_allowed(pAd, wdev, pPacket, &wcid); else allowToSend = FALSE; if (allowToSend == TRUE) { RTMP_SET_PACKET_WCID(pPacket, wcid); RTMP_SET_PACKET_WDEV(pPacket, wdev->wdev_idx); NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING); pAd->RalinkCounters.PendingNdisPacketCount++; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef DELAYED_TCP_ACK if(!delay_tcp_ack(pAd, wcid, pPacket)) #endif /* DELAYED_TCP_ACK */ APSendPacket(pAd, pPacket); } #endif /* CONFIG_AP_SUPPORT */ } else {
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; }
/* ======================================================================== Routine Description: Early checking and OS-depened parsing for Tx packet to AP device. Arguments: NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd. PPNDIS_PACKET ppPacketArray The packet array need to do transmission. UINT NumberOfPackets Number of packet in packet array. Return Value: NONE Note: This function do early checking and classification for send-out packet. You only can put OS-depened & AP related code in here. ======================================================================== */ INT wdev_tx_pkts(NDIS_HANDLE dev_hnd, PPNDIS_PACKET pkt_list, UINT pkt_cnt, struct wifi_dev *wdev) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd; PNDIS_PACKET pPacket; BOOLEAN allowToSend; UCHAR wcid = MAX_LEN_OF_MAC_TABLE; UINT Index; #ifdef CONFIG_FPGA_MODE BOOLEAN force_tx; #endif /* CONFIG_FPGA_MODE */ for (Index = 0; Index < pkt_cnt; Index++) { pPacket = pkt_list[Index]; if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { /* Drop send request since hardware is in reset state */ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); continue; } #ifdef CONFIG_FPGA_MODE force_tx = FALSE; if (pAd->fpga_ctl.fpga_on & 0x1) { if (pAd->fpga_ctl.tx_kick_cnt > 0) { if (pAd->fpga_ctl.tx_kick_cnt < 0xffff) { pAd->fpga_ctl.tx_kick_cnt--; } force_tx = TRUE; } } #endif /* CONFIG_FPGA_MODE */ if (((wdev->allow_data_tx == TRUE) #ifdef CONFIG_FPGA_MODE || (force_tx == TRUE) #endif /* CONFIG_FPGA_MODE */ ) && (wdev->tx_pkt_allowed)) { allowToSend = wdev->tx_pkt_allowed(pAd, wdev, pPacket, &wcid); } else { allowToSend = FALSE; //RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } #ifdef CONFIG_FPGA_MODE if (force_tx == TRUE && allowToSend == TRUE) { //int dump_len = GET_OS_PKT_LEN(pPacket); DBGPRINT(RT_DEBUG_INFO, ("%s():send Packet!wcid=%d, wdev_idx=%d, pktLen=%d\n", __FUNCTION__, wcid, wdev->wdev_idx, GET_OS_PKT_LEN(pPacket))); //hex_dump("wdev_tx_pkts():802.3 packet", GET_OS_PKT_DATAPTR(pPacket), dump_len > 255 ? 255 : dump_len); } #endif /* CONFIG_FPGA_MODE */ if (allowToSend == TRUE) { RTMP_SET_PACKET_WCID(pPacket, wcid); RTMP_SET_PACKET_WDEV(pPacket, wdev->wdev_idx); NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING); pAd->RalinkCounters.PendingNdisPacketCount++; if (wdev->tx_pkt_handle) wdev->tx_pkt_handle(pAd, pPacket); else { DBGPRINT(RT_DEBUG_ERROR, ("%s():tx_pkt_handle not assigned!\n", __FUNCTION__)); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } } else RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, WCID_ALL, MAX_TX_PROCESS); return 0; }