示例#1
0
void RTMP_QueryNextPacketInfo(
	IN  PNDIS_PACKET *ppPacket,
	OUT PACKET_INFO  *pPacketInfo,
	OUT PUCHAR		 *pSrcBufVA,
	OUT	UINT		 *pSrcBufLen)
{
	PNDIS_PACKET pPacket = NULL;

	if (*ppPacket)
		pPacket = GET_OS_PKT_NEXT(*ppPacket);

	if (pPacket)
	{
		pPacketInfo->BufferCount = 1;
		pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
		pPacketInfo->PhysicalBufferCount = 1;
		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);

		*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
		*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
		*ppPacket = GET_OS_PKT_NEXT(pPacket);
	}
	else
	{
		pPacketInfo->BufferCount = 0;
		pPacketInfo->pFirstBuffer = NULL;
		pPacketInfo->PhysicalBufferCount = 0;
		pPacketInfo->TotalPacketLength = 0;

		*pSrcBufVA = NULL;
		*pSrcBufLen = 0;
		*ppPacket = NULL;
	}
}
示例#2
0
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;
}
示例#3
0
void RTMP_QueryPacketInfo(
	IN  PNDIS_PACKET pPacket,
	OUT PACKET_INFO  *pPacketInfo,
	OUT PUCHAR		 *pSrcBufVA,
	OUT	UINT		 *pSrcBufLen)
{
	pPacketInfo->BufferCount = 1;
	pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
	pPacketInfo->PhysicalBufferCount = 1;
	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);

	*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
	*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
}
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;
}
示例#5
0
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;

}
示例#6
0
文件: ap_nps.c 项目: 23171580/ralink
VOID RT28xx_UpdateTimToAsic(
	IN RTMP_ADAPTER *pAd,
	IN INT apidx,
	IN ULONG FrameLen)
{
	TIM_BUF_STRUC *tim_buf = NULL;
	UCHAR *buf;
	INT len;
	PNDIS_PACKET *pkt = NULL;

	IF_DEV_CONFIG_OPMODE_ON_AP(pAd) {
		tim_buf = &pAd->ApCfg.MBSSID[apidx].tim_buf;
	}

	if (!tim_buf) {
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): bcn_buf is NULL!\n", __FUNCTION__));
		return;
	}

	pkt = tim_buf->TimPkt;
	if (pkt) {
		buf = (UCHAR *)GET_OS_PKT_DATAPTR(pkt);
		len = FrameLen + pAd->chipCap.tx_hw_hdr_len;
		SET_OS_PKT_LEN(pkt, len);

		/* Now do hardware-depened kick out.*/
		HAL_KickOutMgmtTx(pAd, Q_IDX_BCN, pkt, buf, len);
		RTMP_SEM_UNLOCK(&pAd->BcnRingLock);

	} else {
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s(): TimPkt is NULL!\n", __FUNCTION__));
	}
}
示例#7
0
/*
	========================================================================

	Routine Description:
		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
		must have only one NDIS BUFFER
		return - byte copied. 0 means can't create NDIS PACKET
		NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket

	Arguments:
		pAd 	Pointer to our adapter
		pInsAMSDUHdr	EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
		*pSrcTotalLen			return total packet length. This lenght is calculated with 802.3 format packet.

	Return Value:
		NDIS_STATUS_SUCCESS
		NDIS_STATUS_FAILURE

	Note:

	========================================================================
*/
NDIS_STATUS RTMPCloneNdisPacket(
	IN	PRTMP_ADAPTER	pAd,
	IN	BOOLEAN			pInsAMSDUHdr,
	IN	PNDIS_PACKET	pInPacket,
	OUT PNDIS_PACKET   *ppOutPacket)
{

	struct sk_buff *pkt;

	ASSERT(pInPacket);
	ASSERT(ppOutPacket);

	// 1. Allocate a packet
	pkt = dev_alloc_skb(2048);

	if (pkt == NULL)
	{
		return NDIS_STATUS_FAILURE;
	}

 	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
	*ppOutPacket = OSPKT_TO_RTPKT(pkt);


	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);

	printk("###Clone###\n");

	return NDIS_STATUS_SUCCESS;
}
示例#8
0
PRTMP_SCATTER_GATHER_LIST
rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
{
	sg->NumberOfElements = 1;
	sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
	sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
	return (sg);
}
/*
	========================================================================
	Routine	Description:
		For each out-going packet, check the upper layer protocol type if need
		to handled by our APCLI convert engine. If yes, call corresponding handler 
		to handle it.
		
	Arguments:
		pAd		=>Pointer to our adapter
		pPkt 	=>pointer to the 802.11 header of outgoing packet 
		ifIdx   =>Interface Index want to dispatch to.

	Return Value:
		Success	=>
			TRUE
			Mapped mac address if found, else return specific default mac address 
			depends on the upper layer protocol type.
		Error	=>
			FALSE.

	Note:
		1.the pPktHdr must be a 802.3 packet.
		2.Maybe we need a TxD arguments?
		3.We check every packet here including group mac address becasue we need to
		  handle DHCP packet.
	========================================================================
 */
PUCHAR MATEngineTxHandle(
	IN PRTMP_ADAPTER	pAd,
	IN PNDIS_PACKET	    pPkt,
	IN UINT				ifIdx,
	IN UCHAR    OpMode)
{
	PUCHAR 		pLayerHdr = NULL, pPktHdr = NULL,  pMacAddr = NULL;
	UINT16		protoType, protoType_ori;
	int			i;
	struct _MATProtoOps 	*pHandle = NULL;
	PUCHAR  retSkb = NULL;
	BOOLEAN bVLANPkt = FALSE;


	if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED)
		return NULL;
	
	pPktHdr = GET_OS_PKT_DATAPTR(pPkt);
	if (!pPktHdr)
		return NULL;
	
	protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12));
	
	/* Get the upper layer protocol type of this 802.3 pkt. */
	protoType = OS_NTOHS(protoType_ori);

	/* handle 802.1q enabled packet. Skip the VLAN tag field to get the protocol type. */
	if (protoType == 0x8100)
	{
		protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12 + 4));
		protoType = OS_NTOHS(protoType_ori);
		bVLANPkt = TRUE;
	}

	
	/* For differnet protocol, dispatch to specific handler */
	for (i=0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++)
	{
		if (protoType == MATProtoTb[i].protocol)
		{
			pHandle = MATProtoTb[i].pHandle;	/* the pHandle must not be null! */
			pLayerHdr = bVLANPkt ? (pPktHdr + MAT_VLAN_ETH_HDR_LEN) : (pPktHdr + MAT_ETHER_HDR_LEN);
#ifdef CONFIG_AP_SUPPORT
#ifdef APCLI_SUPPORT
			IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
				pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].CurrentAddress[0];
#endif /* APCLI_SUPPORT */
#endif /* CONFIG_AP_SUPPORT */


			if (pHandle->tx!=NULL)
				retSkb = pHandle->tx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, pMacAddr);

			return retSkb;
		}
	}
	return retSkb;
}
示例#10
0
/* Delayed TCP Ack */
BOOLEAN delay_tcp_ack(RTMP_ADAPTER *pAd, UCHAR wcid, PNDIS_PACKET pPacket)
{
    PUCHAR	pSrcBuf;
    UINT32	pktLen, qlen;
    PMAC_TABLE_ENTRY pEntry;
    BOOLEAN	bDelay = FALSE;
    pEntry = &pAd->MacTab.Content[wcid];
    pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
    pktLen = GET_OS_PKT_LEN(pPacket);

    if (pAd->CommonCfg.ACKQEN == 1)
    {
        /* get Ethernet protocol field*/
        USHORT	TypeLen = OS_NTOHS(*((UINT16 *)(pSrcBuf + 12)));

        /* bypass VALN 802.1Q field */
        if(TypeLen == 0x8100)
            pSrcBuf += 4;
        else if ((TypeLen==0x9100) || (TypeLen==0x9200) || (TypeLen==0x9300))
            pSrcBuf += 8;

        if ((TypeLen == 0x0800) 		/* Type: IP (0x0800) */
                && (pSrcBuf[23] == 0x06) 	/* Protocol: TCP (0x06) */
                && (pktLen >= 48) && ((pSrcBuf[47]&0x10) == 0x10))	/* Flags: Ack bit is set */
        {
            skb_queue_tail(&pEntry->ack_queue, pPacket);
            qlen = skb_queue_len(&pEntry->ack_queue);
            bDelay = TRUE;

            if (qlen == 1)
            {
                if (pEntry->QueueAckTimerRunning == FALSE)
                {
                    DBGPRINT(RT_DEBUG_LOUD, ("found tcp ack..\n"));
                    RTMPSetTimer(&pEntry->QueueAckTimer, pAd->CommonCfg.AckWaitTime);
                    pEntry->QueueAckTimerRunning = TRUE;
                }
            }
            else if ((qlen >= pAd->CommonCfg.Acklen)
                     || ((pSrcBuf[47]&0x03) != 0)	/* Flags: FIN(bit0) or SYN(bit1) is set */
                     || (pktLen > 66))				/* TCP ACK with other payload in IPv4 format */
            {
                pAd->CommonCfg.AckNOTimeout += flush_tcp_ack_queue(pAd, pEntry, TRUE);
            }
        }
    }
    else
    {
        flush_tcp_ack_queue(pAd, pEntry, TRUE);
    }

    return bDelay;
}
示例#11
0
// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
NDIS_STATUS RTMPAllocateNdisPacket(
	IN	PRTMP_ADAPTER	pAd,
	OUT PNDIS_PACKET   *ppPacket,
	IN	PUCHAR			pHeader,
	IN	UINT			HeaderLen,
	IN	PUCHAR			pData,
	IN	UINT			DataLen)
{
	PNDIS_PACKET	pPacket;
	ASSERT(pData);
	ASSERT(DataLen);

	// 1. Allocate a packet
	pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
	if (pPacket == NULL)
 	{
		*ppPacket = NULL;
#ifdef DEBUG
		printk("RTMPAllocateNdisPacket Fail\n\n");
#endif
		return NDIS_STATUS_FAILURE;
	}

	// 2. clone the frame content
	if (HeaderLen > 0)
		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
	if (DataLen > 0)
		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);

	// 3. update length of packet
 	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);

	RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
//	printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
	*ppPacket = pPacket;
	return NDIS_STATUS_SUCCESS;
}
/*
	========================================================================
	Routine	Description:
		Depends on the Received packet, check the upper layer protocol type
		and search for specific mapping table to find out the real destination 
		MAC address.
		
	Arguments:
		pAd		=>Pointer to our adapter
		pPkt	=>pointer to the 802.11 header of receviced packet 
		infIdx	=>Interface Index want to dispatch to.

	Return Value:
		Success	=>
			Mapped mac address if found, else return specific default mac address 
			depends on the upper layer protocol type.
		Error	=>
			NULL

	Note:
	========================================================================
 */
PUCHAR MATEngineRxHandle(
	IN PRTMP_ADAPTER	pAd,
	IN PNDIS_PACKET		pPkt,
	IN UINT				infIdx)
{
	PUCHAR				pMacAddr = NULL;
	PUCHAR 		pLayerHdr = NULL, pPktHdr = NULL;
	UINT16		protoType;
	int			i =0;
	struct _MATProtoOps 	*pHandle = NULL;


	if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED)
		return NULL;

	pPktHdr = GET_OS_PKT_DATAPTR(pPkt);
	if (!pPktHdr)
		return NULL;

	/* If it's a multicast/broadcast packet, we do nothing. */
	if (IS_GROUP_MAC(pPktHdr))
		return NULL;

	/* Get the upper layer protocol type of this 802.3 pkt and dispatch to specific handler */
	protoType = OS_NTOHS(get_unaligned((PUINT16)(pPktHdr + 12)));
	
	for (i=0; i<MAX_MAT_SUPPORT_PROTO_NUM; i++)
	{
		if (protoType == MATProtoTb[i].protocol)
		{
			pHandle = MATProtoTb[i].pHandle;	/* the pHandle must not be null! */
			pLayerHdr = (pPktHdr + MAT_ETHER_HDR_LEN);
/*			RTMP_SEM_LOCK(&MATDBLock); */
			if(pHandle->rx!=NULL)
				pMacAddr = pHandle->rx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, NULL);
/*			RTMP_SEM_UNLOCK(&MATDBLock); */
			break;
		}
	}

	if (pMacAddr)
		NdisMoveMemory(pPktHdr, pMacAddr, MAC_ADDR_LEN);

	return NULL;

}
示例#13
0
void announce_802_3_packet(
	IN VOID *pAdSrc,
	IN PNDIS_PACKET pPacket,
	IN UCHAR OpMode)
{
	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pAdSrc;
	PNDIS_PACKET pRxPkt = pPacket;

	ASSERT(pPacket);
	MEM_DBG_PKT_FREE_INC(pPacket);



#ifdef CONFIG_STA_SUPPORT
#endif /* CONFIG_STA_SUPPORT */

    /* Push up the protocol stack */

#ifdef IKANOS_VX_1X0
{
	IKANOS_DataFrameRx(pAd, pRxPkt);
	return;
}
#endif /* IKANOS_VX_1X0 */

#ifdef INF_PPA_SUPPORT
	if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE ) 
	{
		RtmpOsPktInfPpaSend(pRxPkt);
		pRxPkt=NULL;
		return;
	}	  	
#endif /* INF_PPA_SUPPORT */


	

//+++Add by shiang for debug
if (0) {
		hex_dump("announce_802_3_packet", GET_OS_PKT_DATAPTR(pRxPkt), GET_OS_PKT_LEN(pRxPkt));
}
//---Add by shiang for debug

		RtmpOsPktProtocolAssign(pRxPkt);
		RtmpOsPktRcvHandle(pRxPkt);
}
示例#14
0
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;

}
示例#15
0
/* 
==========================================================================
	Description:
		Setup Frame format.
	NOTE:
		This routine should only be used in ATE mode.
==========================================================================
*/
INT ATESetUpFrame(
	IN PRTMP_ADAPTER pAd,
	IN UINT32 TxIdx)
{
	PATE_INFO pATEInfo = &(pAd->ate);
	UINT pos = 0;
	TXINFO_STRUC *pTxInfo;
	TXD_STRUC *pTxD;
#ifdef RT_BIG_ENDIAN
	TXD_STRUC *pDestTxD;
	UCHAR tx_hw_info[TXD_SIZE];
#endif /* RT_BIG_ENDIAN */
	PNDIS_PACKET pPacket=NULL;
	PUCHAR pDest=NULL;
	PVOID AllocVa=NULL;
	NDIS_PHYSICAL_ADDRESS AllocPa;
	HTTRANSMIT_SETTING	TxHTPhyMode;

	RTMP_TX_RING *pTxRing = &pAd->TxRing[QID_AC_BE];
	TXWI_STRUC *pTxWI = (TXWI_STRUC *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
	PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
	UINT8 TXWISize = pAd->chipCap.TXWISize;
#ifdef RALINK_QA
	PHEADER_802_11	pHeader80211;
#endif /* RALINK_QA */
	UCHAR bw, sgi, stbc, mcs, phy_mode, frag, cfack, ts, ampdu, ack, nseq, bawinsize, pkt_id, txop;
	USHORT byte_cnt;

	bw = sgi = stbc = mcs = phy_mode = frag = cfack = ts =0;
	ampdu = ack = nseq = bawinsize = pkt_id = txop = 0;
	byte_cnt = 0;
#ifdef RLT_MAC
	if (pAd->chipCap.hif_type == HIF_RLT)
	{
		bw = pATEInfo->TxWI.TXWI_N.BW;
		sgi = pATEInfo->TxWI.TXWI_N.ShortGI;
		stbc = pATEInfo->TxWI.TXWI_N.STBC;
		mcs = pATEInfo->TxWI.TXWI_N.MCS;
		phy_mode = pATEInfo->TxWI.TXWI_N.PHYMODE;
			
		frag = pATEInfo->TxWI.TXWI_N.FRAG;
		cfack = pATEInfo->TxWI.TXWI_N.CFACK,
		ts = pATEInfo->TxWI.TXWI_N.TS;
		ampdu = pATEInfo->TxWI.TXWI_N.AMPDU;
		ack = pATEInfo->TxWI.TXWI_N.ACK;
		nseq = pATEInfo->TxWI.TXWI_N.NSEQ;
		bawinsize =pATEInfo->TxWI.TXWI_N.BAWinSize;
		byte_cnt = pATEInfo->TxWI.TXWI_N.MPDUtotalByteCnt;
		pkt_id = pATEInfo->TxWI.TXWI_N.TxPktId;
		txop = pATEInfo->TxWI.TXWI_N.txop;
		cfack = pATEInfo->TxWI.TXWI_N.CFACK;
	}
#endif /* RLT_MAC */

	/* fill TxWI */
	TxHTPhyMode.field.BW = bw;
	TxHTPhyMode.field.ShortGI = sgi;
	TxHTPhyMode.field.STBC = stbc;
	TxHTPhyMode.field.MCS = mcs;
	TxHTPhyMode.field.MODE = phy_mode;

	if (pATEInfo->bQATxStart == TRUE) 
	{
		/* always use QID_AC_BE and FIFO_EDCA */
		ATEWriteTxWI(pAd, pTxWI, frag, cfack,
			ts, ampdu, ack,
			nseq, bawinsize, 0,
			byte_cnt, pkt_id, 0, 0,
			txop, cfack,
			&TxHTPhyMode);

#ifdef TXBF_SUPPORT
#ifdef RELEASE_EXCLUDE
		/* It will affect transmit data rate ??? But QA is tested... */
#endif /* RELEASE_EXCLUDE */
#ifdef RLT_MAC
		if (IS_MT76x0(pAd))
		{
			/* Must copy rsv bits to actual TxWI */
//			pTxWI->TXWI_N.rsv = pATEInfo->TxWI.TXWI_N.rsv;
			pTxWI->TXWI_N.iTxBF = pATEInfo->TxWI.TXWI_N.iTxBF;	
			pTxWI->TXWI_N.Sounding = pATEInfo->TxWI.TXWI_N.Sounding;
			pTxWI->TXWI_N.eTxBF = pATEInfo->TxWI.TXWI_N.eTxBF;
//			pTxWI->TXWI_N.Autofallback = pATEInfo->TxWI.TXWI_N.Autofallback;
			pTxWI->TXWI_N.NDPSndBW = pATEInfo->TxWI.TXWI_N.NDPSndBW;
			pTxWI->TXWI_N.NDPSndRate = pATEInfo->TxWI.TXWI_N.NDPSndRate;
		}
#endif /* RLT_MAC */
#endif /* TXBF_SUPPORT */
	}
	else
	{
		ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE,  FALSE, FALSE, FALSE, 
			4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);
	}
	
	/* fill 802.11 header */
#ifdef RALINK_QA
	if (pATEInfo->bQATxStart == TRUE) 
	{
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen);
	}
	else
#endif /* RALINK_QA */
	{
		pATEInfo->HLen = LENGTH_802_11;
#ifdef TXBF_SUPPORT
		TemplateFrame[0] = 0x08;	/* Data */
		TemplateFrame[1] = 0x00;
		if (pATEInfo->bTxBF && pATEInfo->txSoundingMode!=0)
		{
			/* QoS Data */
			pATEInfo->HLen = 32;
			TemplateFrame[0] = 0x88;
			TemplateFrame[1] = 0x80;
		
			switch (pATEInfo->txSoundingMode)
			{
			case 1:
				/* Data Sounding */
				TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0;
				TemplateFrame[29] = 0x00;	
				break;
			case 2:
			case 3:
				/* 2 or 3 Stream NDP */
				TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0;
				TemplateFrame[29] = 0x01;	/* NDP Announce */
				break;
			default:
				TemplateFrame[28] = TemplateFrame[29] = 0x0;
			}
		}
#endif /* TXBF_SUPPORT */
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize, TemplateFrame, pATEInfo->HLen);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, pATEInfo->Addr1, MAC_ADDR_LEN);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, pATEInfo->Addr2, MAC_ADDR_LEN);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, pATEInfo->Addr3, MAC_ADDR_LEN);
	}

#ifdef RT_BIG_ENDIAN
	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE);
#endif /* RT_BIG_ENDIAN */

	/* alloc buffer for payload */
#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) 
	{
		pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev,
			pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa);
	}
	else
#endif /* RALINK_QA */
	{
		pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev,
			pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa);
	}

	/* error check */
	if (pPacket == NULL)
	{
		pATEInfo->TxCount = 0;
		DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__));
		return -1;
	}
	pTxRing->Cell[TxIdx].pNdisPacket = pPacket;
	pDest = (PUCHAR) AllocVa;

#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) 
	{
		GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen;
#ifndef LINUX
		GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen;
#endif /* LIMUX */
	}
	else
#endif /* RALINK_QA */
	{
		GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - pATEInfo->HLen;
#ifndef LINUX
		GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - pATEInfo->HLen;
#endif /* LINUX */
	}

	/* prepare frame payload */
#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0))
	{
		/* copy pattern to payload */
		if ((pATEInfo->PLen != 0))
		{
			for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen)
			{
				memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen);
			}
		}
	}
	else
#endif /* RALINK_QA */
	{
		for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++)
		{
#ifdef RELEASE_EXCLUDE 
			/* kurtis: 0xAA ATE test EVM will be positive */
#endif /* RELEASE_EXCLUDE */
			/* default payload is 0xA5 */
			pDest[pos] = pATEInfo->Payload;
		}
	}

	/* build Tx descriptor */
#ifndef RT_BIG_ENDIAN
	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
	pTxInfo = (TXINFO_STRUC *)(pTxRing->Cell[TxIdx].AllocVa + sizeof(TXD_STRUC));
#else
	pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
	NdisMoveMemory(&tx_hw_info[0], (UCHAR *)pDestTxD, TXD_SIZE);
	pTxD = (TXD_STRUC *)&tx_hw_info[0];
	pTxInfo = (TXINFO_STRUC *)(&tx_hw_info[0] + sizeof(TXD_STRUC));
#endif /* !RT_BIG_ENDIAN */
	{
	/* prepare TxD */
	TX_BLK txblk;
	txblk.SrcBufLen = GET_OS_PKT_LEN(pPacket);
	txblk.pSrcBufData = AllocVa;
	NdisZeroMemory(pTxD, TXD_SIZE);
	/* build Tx descriptor */
	pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
	pTxD->SDLen0 = TXWISize + pATEInfo->HLen;
	pTxD->LastSec0 = 0;
	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, &txblk, 0, 1, RTMP_PCI_DMA_TODEVICE);
	pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket);
	pTxD->LastSec1 = 1;
	ral_write_txd(pAd, pTxD, pTxInfo, FALSE, FIFO_EDCA);
	}
#ifdef RALINK_QA
	if (pATEInfo->bQATxStart == TRUE)
	{
		pDest = (PUCHAR)pTxWI;
		pDest += TXWISize;
		pHeader80211 = (PHEADER_802_11)pDest;
		
		/* modify sequence number... */
		if (pATEInfo->TxDoneCount == 0)
			pATEInfo->seq = pHeader80211->Sequence;
		else
			pHeader80211->Sequence = ++pATEInfo->seq;
	}
#endif /* RALINK_QA */

#ifdef RT_BIG_ENDIAN
	RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE);
	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
#endif /* RT_BIG_ENDIAN */

	return 0;
}
示例#16
0
文件: ap_nps.c 项目: 23171580/ralink
VOID APMakeBssTimFrame(RTMP_ADAPTER *pAd, INT apidx)
{
	BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx];
	HEADER_802_11 TimHdr;
	LARGE_INTEGER FakeTimestamp;
	ULONG FrameLen = 0;
	UCHAR *pTimFrame, *ptr, *tmac_info;
	HTTRANSMIT_SETTING TimTransmit = {.word = 0};   /* MGMT frame PHY rate setting when operatin at HT rate. */
	UINT8 tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len;
	UCHAR Cat = 11;//Tim Category field
	UCHAR Act = 0;//Tim Action field
	UCHAR ChkBcn = 0;//Check Beacon field init from 0.

	if(!TimTransmitRequired(pAd, apidx, pMbss))
		return;

	if (pMbss->tim_buf.TimPkt == NULL) {
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s():Invalid TimPkt for MBSS[%d]\n",
					__func__, apidx));
		return;
	}

	tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->tim_buf.TimPkt);
	pTimFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len);

	ActHeaderInit(pAd,
			&TimHdr,
			BROADCAST_ADDR,
			pMbss->wdev.if_addr,
			pMbss->wdev.bssid);


	MakeOutgoingFrame(pTimFrame,			&FrameLen,
			sizeof(HEADER_802_11),		&TimHdr,
			1,				&Cat,
			1,				&Act,
			1,				&ChkBcn,
			TIMESTAMP_LEN,			&FakeTimestamp,
			END_OF_ARGS);

	TimTransmit.word = 0;

	pMbss->TimIELocationInTim = (UCHAR)FrameLen;

	/*
		step 2 - update TIM IE
		TODO: enlarge TIM bitmap to support up to 64 STAs
		TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time
	*/
	ptr = pTimFrame + (UCHAR)FrameLen;
	*ptr = IE_TIM;
	*(ptr+1) = 0x0e;
	*(ptr + 2) = pAd->ApCfg.DtimCount;
	*(ptr + 3) = pAd->ApCfg.DtimPeriod;

	*(ptr + 4) = 0xa0;
	*(ptr + 5) = 0xa0;
	*(ptr + 6) = 0xa0;
	*(ptr + 7) = 0xa0;
	*(ptr + 8) = 0xa0;
	*(ptr + 9) = 0xa0;
	*(ptr + 10) = 0xa0;
	*(ptr + 11) = 0xa0;
	*(ptr + 12) = 0xa0;
	*(ptr + 13) = 0xa0;
	*(ptr + 14) = 0xa0;
	*(ptr + 15) = 0xa0;


// 	/* find the smallest AID (PS mode) */
// 	TimFirst = 0; /* record first TIM byte != 0x00 */
// 	TimLast = 0;  /* record last  TIM byte != 0x00 */
// 	pTim = pMbss->TimBitmaps;
//
// 	for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++)
// 	{
// 		/* get the TIM indicating PS packets for 8 stations */
// 		UCHAR tim_1B = pTim[ID_1B];
//
// 		if (ID_1B == 0)
// 			tim_1B &= 0xfe; /* skip bit0 bc/mc */
//
// 		if (tim_1B == 0)
// 			continue; /* find next 1B */
//
// 		if (TimFirst == 0)
// 			TimFirst = ID_1B;
//
// 		TimLast = ID_1B;
// 	}
//
// 	/* fill TIM content to beacon buffer */
// 	if (TimFirst & 0x01)
// 		TimFirst --; /* find the even offset byte */
//
// 	*(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */
// 	*(ptr + 4) = TimFirst;
//
// 	for(i=TimFirst; i<=TimLast; i++)
// 		*(ptr + 5 + i - TimFirst) = pTim[i];
//
// 	/* bit0 means backlogged mcast/bcast */
// 	/* per spec, this bit in TIM frame shall always 0. */
// 	//TODO: MTK proprietary mechanism.
// 	//if (pAd->ApCfg.DtimCount == 0)
// 		//*(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01);
// 	*(ptr + 4) = 0;

	/* adjust TIM length according to the new TIM */
	FrameLen += 16;//(2 + *(ptr+1));

	/* When Beacon is use CCK to send, TIM shall use OFDM to send. and it's mandatory. */
	if (pAd->CommonCfg.Channel <= 14) {
		TimTransmit.field.MODE = MODE_OFDM;
		TimTransmit.field.MCS = MCS_RATE_6;
	}

	write_tmac_info_tim(pAd, apidx, tmac_info, &TimTransmit, FrameLen);

//	asic_write_bcn_buf(pAd,
//			tmac_info, TXWISize,
//			pTimFrame, FrameLen,
//			pAd->BeaconOffset[pMbss->bcn_buf.BcnBufIdx]);

	RT28xx_UpdateTimToAsic(pAd, apidx, FrameLen);

//+++Add by shiang for debug
	MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%s(): Dump the Beacon Packet of BSS%d!\n", __FUNCTION__, apidx));
	hex_dump("Initial BeaconBuf", tmac_info, FrameLen + tx_hw_hdr_len);
//---Add by shiang for debug
}

static UCHAR GetTimNum(RTMP_ADAPTER *pAd)
{
	int i;
	int NumTim;
	TIM_BUF_STRUC *tim_info;

	NumTim = 0;
	for (i=0; i<pAd->ApCfg.BssidNum; i++)
	{
		tim_info = &pAd->ApCfg.MBSSID[i].tim_buf;
		if (tim_info->bTimSntReq)
		{
			tim_info->TimBufIdx = NumTim;
			NumTim ++;
		}
	}

	return NumTim;
}
/*
	Must be run in Interrupt context
	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
 */
int RtmpUSBMgmtKickOut(
	IN RTMP_ADAPTER *pAd, 
	IN UCHAR QueIdx,
	IN PNDIS_PACKET pPacket,
	IN UCHAR *pSrcBufVA,
	IN UINT SrcBufLen)
{
	TXINFO_STRUC *pTxInfo;
	ULONG BulkOutSize;
	UCHAR padLen;
	PUCHAR pDest;
	ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
	TX_CONTEXT *pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	ULONG IrqFlags;

	
	pTxInfo = (TXINFO_STRUC *)(pSrcBufVA);

	/* Build our URB for USBD*/
	BulkOutSize = (SrcBufLen + 3) & (~3);
	rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
	
	BulkOutSize += 4; /* Always add 4 extra bytes at every packet.*/

//+++Add by shiang for debug
if (0) {
	DBGPRINT(RT_DEBUG_OFF, ("-->%s():shiang-6590, QueIdx=%d, SrcBufLen=%d\n", __FUNCTION__, QueIdx, SrcBufLen));
	dump_txinfo(pAd, pTxInfo);
	dumpTxWI(pAd, (TXWI_STRUC *)(pSrcBufVA + TXINFO_SIZE));
}
//---Add by shiang for debug

/* WY , it cause Tx hang on Amazon_SE , Max said the padding is useless*/
	/* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.*/
/*	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)*/
/*		BulkOutSize += 4;*/

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
	
	/* Now memzero all extra padding bytes.*/
	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
	OS_PKT_TAIL_BUF_EXTEND(pPacket, padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
	
	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));

	/* Length in TxInfo should be 8 less than bulkout size.*/
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;

#ifdef UAPSD_SUPPORT
		/*
			If the packet is QoS Null frame, we mark the packet with its WCID;
			If not, we mark the packet with bc/mc WCID = 0.

			We will handle it in rtusb_mgmt_dma_done_tasklet().

			Even AP send a QoS Null frame but not EOSP frame in USB mode,
			then we will call UAPSD_SP_Close() and we will check
			pEntry->bAPSDFlagSPStart() so do not worry about it.
		*/
#endif /* UAPSD_SUPPORT */

	/*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));*/

/*
	pAd->RalinkCounters.KickTxCount++;
	pAd->RalinkCounters.OneSecTxDoneCount++;

	if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
		needKickOut = TRUE;
*/

	/* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX*/
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
	
	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);	
	
	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	/*if (needKickOut)*/
	RTUSBKickBulkOut(pAd);
	
	return 0;
}
int	RTMPSendPackets(
	IN	NDIS_HANDLE		MiniportAdapterContext,
	IN	PPNDIS_PACKET	ppPacketArray,
	IN	UINT			NumberOfPackets,
	IN	UINT32			PktTotalLen,
	IN	RTMP_NET_ETH_CONVERT_DEV_SEARCH	Func)
{
	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)MiniportAdapterContext;
	PNDIS_PACKET pPacket = ppPacketArray[0];

	if (pPacket == NULL)
		goto done;

	/* RT2870STA does this in RTMPSendPackets() */
#ifdef RALINK_ATE
	if (ATE_ON(pAd))
	{
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
		return 0;
	}
#endif /* RALINK_ATE */

#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{
		/* Drop send request since we are in monitor mode */
		if (MONITOR_ON(pAd))
		{
			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
			return 0;
		}
	}
#endif /* CONFIG_STA_SUPPORT */

        /* EapolStart size is 18 */
	if (PktTotalLen < 14)
	{
		/*printk("bad packet size: %d\n", pkt->len); */
		hex_dump("bad packet", GET_OS_PKT_DATAPTR(pPacket), PktTotalLen);
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
		return 0;
	}



	RTMP_SET_PACKET_5VT(pPacket, 0);
/*	MiniportMMRequest(pAd, pkt->data, pkt->len); */
#ifdef CONFIG_5VT_ENHANCE
    if (*(int*)(GET_OS_PKT_CB(pPacket)) == BRIDGE_TAG) {
		RTMP_SET_PACKET_5VT(pPacket, 1);
    }
#endif


#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{

		STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
	}

#endif /* CONFIG_STA_SUPPORT */

done:
	return 0;
}
示例#19
0
/* 
==========================================================================
	Description:
		Setup Frame format.
	NOTE:
		This routine should only be used in ATE mode.
==========================================================================
*/
INT ATESetUpFrame(
	IN PRTMP_ADAPTER pAd,
	IN UINT32 TxIdx)
{
	PATE_INFO pATEInfo = &(pAd->ate);
	UINT pos = 0;
	PTXD_STRUC pTxD;
#ifdef RT_BIG_ENDIAN
    PTXD_STRUC      pDestTxD;
    TXD_STRUC       TxD;
#endif
	PNDIS_PACKET pPacket=NULL;
	PUCHAR pDest=NULL;
	PVOID AllocVa=NULL;
	NDIS_PHYSICAL_ADDRESS AllocPa;
	HTTRANSMIT_SETTING	TxHTPhyMode;

	PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
	PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
	PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
	UINT8 TXWISize = pAd->chipCap.TXWISize;

#ifdef RALINK_QA
	PHEADER_802_11	pHeader80211;
#endif /* RALINK_QA */

	/* fill TxWI */
	TxHTPhyMode.field.BW = pATEInfo->TxWI.BW;
	TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.ShortGI;
	TxHTPhyMode.field.STBC = pATEInfo->TxWI.STBC;
	TxHTPhyMode.field.MCS = pATEInfo->TxWI.MCS;
	TxHTPhyMode.field.MODE = pATEInfo->TxWI.PHYMODE;

	if (pATEInfo->bQATxStart == TRUE) 
	{
		/* always use QID_AC_BE and FIFO_EDCA */
		ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.FRAG, pATEInfo->TxWI.CFACK,
			pATEInfo->TxWI.TS, pATEInfo->TxWI.AMPDU, pATEInfo->TxWI.ACK,
			pATEInfo->TxWI.NSEQ, pATEInfo->TxWI.BAWinSize, 0,
			pATEInfo->TxWI.MPDUtotalByteCount, pATEInfo->TxWI.PacketId, 0, 0,
			pATEInfo->TxWI.txop/*IFS_HTTXOP*/, pATEInfo->TxWI.CFACK/*FALSE*/,
			&TxHTPhyMode);

	}
	else
	{
		ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE,  FALSE, FALSE, FALSE, 
			4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);

	}
	
	/* fill 802.11 header */
#ifdef RALINK_QA
	if (pATEInfo->bQATxStart == TRUE) 
	{
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen);
	}
	else
#endif /* RALINK_QA */
	{
		pATEInfo->HLen = LENGTH_802_11;
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize, TemplateFrame, pATEInfo->HLen);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, pATEInfo->Addr1, ETH_LENGTH_OF_ADDRESS);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, pATEInfo->Addr2, ETH_LENGTH_OF_ADDRESS);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, pATEInfo->Addr3, ETH_LENGTH_OF_ADDRESS);
	}

#ifdef RT_BIG_ENDIAN
	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE);
#endif /* RT_BIG_ENDIAN */

	/* alloc buffer for payload */
#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) 
	{
		pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev,
			pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa);
	}
	else
#endif /* RALINK_QA */
	{
		pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev,
			pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa);
	}

	if (pPacket == NULL)
	{
		pATEInfo->TxCount = 0;
		DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__));
		return -1;
	}

	pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket;
	pDest = (PUCHAR) AllocVa;

#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) 
	{
		GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen;
		GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen;
	}
	else
#endif /* RALINK_QA */
	{
		GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11;
		GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11;
	}

	/* prepare frame payload */
#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0))
	{
		/* copy pattern to payload */
		if ((pATEInfo->PLen != 0))
		{
			for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen)
			{
				memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen);
			}
		}
	}
	else
#endif /* RALINK_QA */
	{
		for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++)
		{
			/* default payload is 0xA5 */
			pDest[pos] = pATEInfo->Payload;
		}
	}

	/* build Tx descriptor */
#ifndef RT_BIG_ENDIAN
	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
#else
    pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
    TxD = *pDestTxD;
    pTxD = &TxD;
#endif /* !RT_BIG_ENDIAN */

#ifdef RALINK_QA
	if (pATEInfo->bQATxStart == TRUE)
	{
		/* prepare TxD */
		NdisZeroMemory(pTxD, TXD_SIZE);
		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
		/* build Tx descriptor */
		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
		pTxD->SDLen0 = TXWISize + pATEInfo->HLen;
		pTxD->SDPtr1 = AllocPa;
		pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket);
		pTxD->LastSec0 = (pTxD->SDLen1 == 0) ? 1 : 0;
		pTxD->LastSec1 = 1;

		pDest = (PUCHAR)pTxWI;
		pDest += TXWISize;
		pHeader80211 = (PHEADER_802_11)pDest;
		
		/* modify sequence number... */
		if (pATEInfo->TxDoneCount == 0)
			pATEInfo->seq = pHeader80211->Sequence;
		else
			pHeader80211->Sequence = ++pATEInfo->seq;
	}
	else
#endif /* RALINK_QA */
	{
		NdisZeroMemory(pTxD, TXD_SIZE);
		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
		/* build Tx descriptor */
		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
		pTxD->SDLen0 = TXWISize + LENGTH_802_11;
		pTxD->LastSec0 = 0;
		pTxD->SDPtr1 = AllocPa;
		pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket);
		pTxD->LastSec1 = 1;
	}

#ifdef RT_BIG_ENDIAN
	RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE);
	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
#endif /* RT_BIG_ENDIAN */

	return 0;
}
示例#20
0
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;
}
示例#21
0
VOID CFG80211_UpdateBeacon(
	VOID                                            *pAdOrg,
	UCHAR 										    *beacon_head_buf,
	UINT32											beacon_head_len,
	UCHAR 										    *beacon_tail_buf,
	UINT32											beacon_tail_len,
	BOOLEAN											isAllUpdate)
{
	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
	PCFG80211_CTRL pCfg80211_ctrl = &pAd->cfg80211_ctrl;
	HTTRANSMIT_SETTING BeaconTransmit;   /* MGMT frame PHY rate setting when operatin at Ht rate. */
	PUCHAR pBeaconFrame;	
	UCHAR *tmac_info, New_Tim_Len = 0;
	UINT32 beacon_len = 0;
	BSS_STRUCT *pMbss;
	struct wifi_dev *wdev;
	COMMON_CONFIG *pComCfg;
#ifdef RT_CFG80211_P2P_SUPPORT
	UINT apidx = CFG_GO_BSSID_IDX;
#else
	UINT apidx = MAIN_MBSSID;
#endif /*RT_CFG80211_P2P_SUPPORT*/
#ifdef RT_CFG80211_P2P_MULTI_CHAN_SUPPORT
	ULONG	Value;
	ULONG	TimeTillTbtt;
	ULONG	temp;
	INT		bufferoffset =0;	
	USHORT		bufferoffset2 =0;	
	CHAR 	temp_buf[512]={0};
	CHAR	P2POUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x9}; 
	INT	temp_len;
	INT P2P_IE=4;
	USHORT p2p_ie_len;
	UCHAR Count;
	ULONG StartTime;
#endif /* RT_CFG80211_P2P_MULTI_CHAN_SUPPORT */

	UCHAR tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len;
	UINT8 TXWISize = pAd->chipCap.TXWISize;

	pComCfg = &pAd->CommonCfg;
    pMbss = &pAd->ApCfg.MBSSID[apidx];
    wdev = &pMbss->wdev;
	

	if (!pMbss || !pMbss->bcn_buf.BeaconPkt)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("CFG80211 Beacon: BCN BUF NULL return!!\n"));
		return;
	}
	tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->bcn_buf.BeaconPkt);

#ifdef MT_MAC
        if (pAd->chipCap.hif_type == HIF_MT)
        {
                pBeaconFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len);
        }
        else
#endif /* MT_MAC */
        {
                pBeaconFrame = (UCHAR *)(tmac_info + TXWISize);
        }
	
	if (isAllUpdate) /* Invoke From CFG80211 OPS For setting Beacon buffer */
	{
		/* 1. Update the Buf before TIM IE */
		NdisCopyMemory(pBeaconFrame, beacon_head_buf, beacon_head_len);
		
		/* 2. Update the Location of TIM IE */
		pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon = beacon_head_len;
		
		/* 3. Store the Tail Part For appending later */
		if (pCfg80211_ctrl->beacon_tail_buf != NULL)
			 os_free_mem(NULL, pCfg80211_ctrl->beacon_tail_buf);
		
		os_alloc_mem(NULL, (UCHAR **)&pCfg80211_ctrl->beacon_tail_buf, beacon_tail_len);
		if (pCfg80211_ctrl->beacon_tail_buf != NULL)
		{
			NdisCopyMemory(pCfg80211_ctrl->beacon_tail_buf, beacon_tail_buf, beacon_tail_len);
			pCfg80211_ctrl->beacon_tail_len = beacon_tail_len;
		}		
		else
		{
			pCfg80211_ctrl->beacon_tail_len = 0;
			DBGPRINT(RT_DEBUG_ERROR, ("CFG80211 Beacon: MEM ALLOC ERROR\n"));
		}
		DBGPRINT(RT_DEBUG_ERROR, ("%s: %d isAllUpdate return!\n",__FUNCTION__, __LINE__)); 

		return;  	
	}
	else /* Invoke From Beacon Timer */
	{		
		if (pAd->ApCfg.DtimCount == 0)
			pAd->ApCfg.DtimCount = pAd->ApCfg.DtimPeriod - 1;
		else
			pAd->ApCfg.DtimCount -= 1;
#ifdef RT_CFG80211_P2P_MULTI_CHAN_SUPPORT
/*
	3 mode:  
		1. infra scan  7 channel  ( Duration(30+3) *7   interval (+120)  *   count  1 ),
		2. p2p find    3 channel   (Duration (65 ) *3     interval (+130))  * count 2   > 120 sec 
		3. mcc  tw channel switch (Duration )  (Infra time )  interval (+ GO time )  count 3  mcc enabel always;
*/

			if (pAd->cfg80211_ctrl.GONoASchedule.Count > 0)
			{
				if (pAd->cfg80211_ctrl.GONoASchedule.Count != 200 )
					pAd->cfg80211_ctrl.GONoASchedule.Count  --;
				NdisMoveMemory(temp_buf, pCfg80211_ctrl->beacon_tail_buf, pCfg80211_ctrl->beacon_tail_len);
				bufferoffset = rtstrstr2(temp_buf, P2POUIBYTE,pCfg80211_ctrl->beacon_tail_len,P2P_IE);
				while (bufferoffset2 <= (pCfg80211_ctrl->beacon_tail_len -bufferoffset -4 -bufferoffset2 -3))
				{
					if ( (pCfg80211_ctrl->beacon_tail_buf)[bufferoffset+4+bufferoffset2] == 12)
					{
						break;
					}
					else
					{
						bufferoffset2 = pCfg80211_ctrl->beacon_tail_buf[bufferoffset + 4 +1+bufferoffset2]+bufferoffset2;
						bufferoffset2 = bufferoffset2+3;
					}
				}

				NdisCopyMemory(&pCfg80211_ctrl->beacon_tail_buf[bufferoffset+4+bufferoffset2+5] , &pAd->cfg80211_ctrl.GONoASchedule.Count, 1);
				NdisCopyMemory(&pCfg80211_ctrl->beacon_tail_buf[bufferoffset+4+bufferoffset2+6], &pAd->cfg80211_ctrl.GONoASchedule.Duration, 4);
				NdisCopyMemory(&pCfg80211_ctrl->beacon_tail_buf[bufferoffset+4+bufferoffset2+10], &pAd->cfg80211_ctrl.GONoASchedule.Interval, 4);
				NdisCopyMemory(&pCfg80211_ctrl->beacon_tail_buf[bufferoffset+4+bufferoffset2+14], &pAd->cfg80211_ctrl.GONoASchedule.StartTime, 4);
			
			}

#endif /* RT_CFG80211_P2P_MULTI_CHAN_SUPPORT */



	}

#ifdef MT_MAC
	if (pAd->chipCap.hif_type == HIF_MT) 
	{
		//printk("bcnBuf State =====> %d \n", pMbss->bcn_buf.bcn_state);
		BOOLEAN is_pretbtt_int = FALSE;

#ifdef RTMP_PCI_SUPPORT
        USHORT FreeNum = GET_BCNRING_FREENO(pAd);
		if (FreeNum < 0) {
	    		DBGPRINT(RT_DEBUG_ERROR, ("%s()=>BSS0:BcnRing FreeNum is not enough!\n",
	                                        __FUNCTION__));
	    		return;
		}
#endif /* RTMP_PCI_SUPPORT */

        if (pMbss->bcn_buf.bcn_state != BCN_TX_IDLE) {
            DBGPRINT(RT_DEBUG_ERROR, ("%s()=>BSS0:BcnPkt not idle(%d)!\n",
                                    __FUNCTION__, pMbss->bcn_buf.bcn_state));
        	APCheckBcnQHandler(pAd, apidx, &is_pretbtt_int);
            if (is_pretbtt_int == FALSE)
			{
				DBGPRINT(RT_DEBUG_ERROR, ("==============> pretbtt_int not init \n"));
                return;
			}
		}
}
#endif /* MT_MAC */
	
	/* 4. Update the TIM IE */
	New_Tim_Len = CFG80211DRV_UpdateTimIE(pAd, apidx, pBeaconFrame, 
				pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon);

	/* 5. Update the Buffer AFTER TIM IE */
	if (pCfg80211_ctrl->beacon_tail_buf != NULL)
	{
		NdisCopyMemory(pBeaconFrame + pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon + New_Tim_Len, 
			       pCfg80211_ctrl->beacon_tail_buf, pCfg80211_ctrl->beacon_tail_len);
		
		beacon_len = pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon + pCfg80211_ctrl->beacon_tail_len 
			     + New_Tim_Len;
	}
	else
	{
		 DBGPRINT(RT_DEBUG_ERROR, ("BEACON ====> CFG80211_UpdateBeacon OOPS\n"));
		 return;
	}	 

 
    BeaconTransmit.word = 0;
	/* Should be Find the P2P IE Then Set Basic Rate to 6M */	
#ifdef RT_CFG80211_P2P_SUPPORT	
	if (RTMP_CFG80211_VIF_P2P_GO_ON(pAd)) 
	BeaconTransmit.field.MODE = MODE_OFDM; /* Use 6Mbps */
	else
#endif /*RT_CFG80211_P2P_SUPPORT*/		
		BeaconTransmit.field.MODE = MODE_CCK;
	
	BeaconTransmit.field.MCS = MCS_RATE_6;

	write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, beacon_len);

	/* CFG_TODO */		
	RT28xx_UpdateBeaconToAsic(pAd, apidx, beacon_len, 
			pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon);		
	
}
示例#22
0
int	RTMPSendPackets(
NDIS_HANDLE dev_hnd,
PPNDIS_PACKET ppPacketArray,
unsigned int NumberOfPackets,
unsigned int PktTotalLen,
RTMP_NET_ETH_CONVERT_DEV_SEARCH Func)
{
	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd;
	PNDIS_PACKET pPacket = ppPacketArray[0];


//	INC_COUNTER64(pAd->WlanCounters.TransmitCountFrmOs);
	pAd->WlanCounters.TransmitCountFrmOs++;

	if (pPacket == NULL)
		goto done;

	/* RT2870STA does this in RTMPSendPackets() */
#ifdef RALINK_ATE
	if (ATE_ON(pAd))
	{
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
		return 0;
	}
#endif /* RALINK_ATE */

#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{
		/* Drop send request since we are in monitor mode */
		if (MONITOR_ON(pAd))
		{
			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
			return 0;
		}
	}
#endif /* CONFIG_STA_SUPPORT */

        /* EapolStart size is 18 */
	if (PktTotalLen < 14)
	{
		/*printk("bad packet size: %d\n", pkt->len); */
		hex_dump("bad packet", GET_OS_PKT_DATAPTR(pPacket), PktTotalLen);
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
		return 0;
	}



	RTMP_SET_PACKET_5VT(pPacket, 0);
/*	MiniportMMRequest(pAd, pkt->data, pkt->len); */
#ifdef CONFIG_5VT_ENHANCE
    if (*(int*)(GET_OS_PKT_CB(pPacket)) == BRIDGE_TAG) {
		RTMP_SET_PACKET_5VT(pPacket, 1);
    }
#endif


#ifdef CONFIG_STA_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
	{

		STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
	}

#endif /* CONFIG_STA_SUPPORT */

done:
	return 0;
}
示例#23
0
int	RTMPSendPackets(
	IN NDIS_HANDLE dev_hnd,
	IN PPNDIS_PACKET ppPacketArray,
	IN UINT NumberOfPackets,
	IN UINT32 PktTotalLen,
	IN RTMP_NET_ETH_CONVERT_DEV_SEARCH Func)
{
	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd;
	PNDIS_PACKET pPacket = ppPacketArray[0];


	INC_COUNTER64(pAd->WlanCounters.TransmitCountFrmOs);

	if (pPacket == NULL)
		goto done;

	/* RT2870STA does this in RTMPSendPackets() */
#ifdef RALINK_ATE
	if (ATE_ON(pAd))
	{
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
		return 0;
	}
#endif /* RALINK_ATE */


        /* EapolStart size is 18 */
	if (PktTotalLen < 14)
	{
		/*printk("bad packet size: %d\n", pkt->len); */
		hex_dump("bad packet", GET_OS_PKT_DATAPTR(pPacket), PktTotalLen);
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
		return 0;
	}

#if !defined(CONFIG_RA_NAT_NONE)
	if(ra_sw_nat_hook_tx!= NULL)
	{
		unsigned long flags;

		RTMP_INT_LOCK(&pAd->page_lock, flags);
		ra_sw_nat_hook_tx(pPacket);
		RTMP_INT_UNLOCK(&pAd->page_lock, flags);
	}
#endif


	RTMP_SET_PACKET_5VT(pPacket, 0);
/*	MiniportMMRequest(pAd, pkt->data, pkt->len); */
#ifdef CONFIG_5VT_ENHANCE
    if (*(int*)(GET_OS_PKT_CB(pPacket)) == BRIDGE_TAG) {
		RTMP_SET_PACKET_5VT(pPacket, 1);
    }
#endif

#ifdef CONFIG_AP_SUPPORT
	IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
		APSendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
#endif /* CONFIG_AP_SUPPORT */


done:
	return 0;
}
示例#24
0
/*
	==========================================================================
	Description:
		Pre-build a BEACON frame in the shared memory
	==========================================================================
*/
VOID APMakeBssBeacon(RTMP_ADAPTER *pAd, INT apidx)
{
	BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx];
	UCHAR DsLen = 1, SsidLen;
	HEADER_802_11 BcnHdr;
	LARGE_INTEGER FakeTimestamp;
	ULONG FrameLen = 0;
	UCHAR *pBeaconFrame, *tmac_info;
#if defined(DOT11_N_SUPPORT) && defined(DOT11K_RRM_SUPPORT)
	UINT i;
#endif
	HTTRANSMIT_SETTING BeaconTransmit = {.word = 0};   /* MGMT frame PHY rate setting when operatin at HT rate. */
	UCHAR PhyMode, SupRateLen;
	UINT8 TXWISize = pAd->chipCap.TXWISize;
	UINT8 tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len;

	if(!BeaconTransmitRequired(pAd, apidx, pMbss))
		return;

	if (pMbss->bcn_buf.BeaconPkt == NULL) {
		DBGPRINT(RT_DEBUG_ERROR, ("%s():Invalid BeaconPkt for MBSS[%d]\n",
					__FUNCTION__, apidx));
		return;
	}

#ifdef MT_MAC
    if (pAd->chipCap.hif_type == HIF_MT) {
        return;
//Carter, 20140306 for MT7603, merge MakeAllBeacon into UpdateAllBeacon
    }
#endif
	tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->bcn_buf.BeaconPkt);
	if (pAd->chipCap.hif_type == HIF_MT)
	{
		pBeaconFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len);
	}
	else
	{
		pBeaconFrame = (UCHAR *)(tmac_info + TXWISize);
	}

	PhyMode = pMbss->wdev.PhyMode;
	SsidLen = (pMbss->bHideSsid) ? 0 : pMbss->SsidLen;
	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON,
						0, BROADCAST_ADDR,
						pMbss->wdev.if_addr,
						pMbss->wdev.bssid);

	/* for update framelen to TxWI later. */
	SupRateLen = pAd->CommonCfg.SupRateLen;
	if (PhyMode == WMODE_B)
		SupRateLen = 4;

	MakeOutgoingFrame(pBeaconFrame,                  &FrameLen,
					sizeof(HEADER_802_11),           &BcnHdr,
					TIMESTAMP_LEN,                   &FakeTimestamp,
					2,                               &pAd->CommonCfg.BeaconPeriod,
					2,                               &pMbss->CapabilityInfo,
					1,                               &SsidIe,
					1,                               &SsidLen,
					SsidLen,                      pMbss->Ssid,
					1,                               &SupRateIe,
					1,                               &SupRateLen,
					SupRateLen,                pAd->CommonCfg.SupRate,
					1,                               &DsIe,
					1,                               &DsLen,
					1,                               &pAd->CommonCfg.Channel,
					END_OF_ARGS);

	if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B))
	{
		ULONG TmpLen;
		MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
						1,                               &ExtRateIe,
						1,                               &pAd->CommonCfg.ExtRateLen,
						pAd->CommonCfg.ExtRateLen,           pAd->CommonCfg.ExtRate,
						END_OF_ARGS);
		FrameLen += TmpLen;
	}


    /* add country IE, power constraint IE */
	if (pAd->CommonCfg.bCountryFlag)
	{
		ULONG TmpLen, TmpLen2=0;
		UCHAR *TmpFrame = NULL;
		UCHAR CountryIe = IE_COUNTRY;

		os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256);
		if (TmpFrame != NULL)
		{
			NdisZeroMemory(TmpFrame, 256);

			/* prepare channel information */
#ifdef EXT_BUILD_CHANNEL_LIST
			BuildBeaconChList(pAd, TmpFrame, &TmpLen2);
#else
			{
				UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
				MakeOutgoingFrame(TmpFrame+TmpLen2,     &TmpLen,
									1,                 	&pAd->ChannelList[0].Channel,
									1,                 	&pAd->ChannelListNum,
									1,                 	&MaxTxPower,
									END_OF_ARGS);
				TmpLen2 += TmpLen;
			}
#endif /* EXT_BUILD_CHANNEL_LIST */


			/* need to do the padding bit check, and concatenate it */
			if ((TmpLen2%2) == 0)
			{
				UCHAR	TmpLen3 = TmpLen2+4;
				MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
				                  1,                 	&CountryIe,
				                  1,                 	&TmpLen3,
				                  3,                 	pAd->CommonCfg.CountryCode,
				                  TmpLen2+1,				TmpFrame,
				                  END_OF_ARGS);
			}
			else
			{
				UCHAR	TmpLen3 = TmpLen2+3;
				MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
				                  1,                 	&CountryIe,
				                  1,                 	&TmpLen3,
				                  3,                 	pAd->CommonCfg.CountryCode,
				                  TmpLen2,				TmpFrame,
				                  END_OF_ARGS);
			}
			FrameLen += TmpLen;

			os_free_mem(NULL, TmpFrame);
		}
		else
			DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
	}


#ifdef DOT11_N_SUPPORT
	/* AP Channel Report */
	{
		UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT;
		ULONG	TmpLen;

		/*
			802.11n D2.0 Annex J, USA regulatory
				class 32, channel set 1~7
				class 33, channel set 5-11
		*/
		UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7};
        UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11};
		UCHAR rclasslen = 8; /*sizeof(rclass32); */
		if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN))
		{
			MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
							  1,                    &APChannelReportIe,
							  1,                    &rclasslen,
							  rclasslen,            rclass32,
   							  1,                    &APChannelReportIe,
							  1,                    &rclasslen,
							  rclasslen,            rclass33,
							  END_OF_ARGS);
			FrameLen += TmpLen;
		}
	}

#endif /* DOT11_N_SUPPORT */


	BeaconTransmit.word = 0;

	write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, FrameLen);

	/* step 6. move BEACON TXD and frame content to on-chip memory */
	asic_write_bcn_buf(pAd,
						tmac_info, TXWISize,
						pBeaconFrame, FrameLen,
						pAd->BeaconOffset[pMbss->bcn_buf.BcnBufIdx]);

	pMbss->TimIELocationInBeacon = (UCHAR)FrameLen;
	pMbss->bcn_buf.cap_ie_pos = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2;

    //pMbss->bcn_buf.bcn_state = BCN_TX_IDLE;
//+++Add by shiang for debug
//---Add by shiang for debug
}


/*
	==========================================================================
	Description:
		Update the BEACON frame in the shared memory. Because TIM IE is variable
		length. other IEs after TIM has to shift and total frame length may change
		for each BEACON period.
	Output:
		pAd->ApCfg.MBSSID[apidx].CapabilityInfo
		pAd->ApCfg.ErpIeContent
	==========================================================================
*/
VOID APUpdateBeaconFrame(RTMP_ADAPTER *pAd, INT apidx)
{
	UCHAR *pBeaconFrame, *tmac_info;
	UCHAR *ptr;
	ULONG FrameLen;
	ULONG UpdatePos = 0;
	UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2;
	UCHAR ID_1B, TimFirst, TimLast, *pTim;
	BSS_STRUCT *pMbss;
	COMMON_CONFIG *pComCfg;
	BOOLEAN bHasWpsIE = FALSE;
	UINT  i;
	HTTRANSMIT_SETTING	BeaconTransmit = {.word = 0};   /* MGMT frame PHY rate setting when operatin at Ht rate. */
	struct wifi_dev *wdev;
	UCHAR tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len;
	UINT8 TXWISize = pAd->chipCap.TXWISize;

	UCHAR DsLen = 1, SsidLen;
	HEADER_802_11 BcnHdr;
	LARGE_INTEGER FakeTimestamp;
	UCHAR PhyMode = 0, SupRateLen;

	pComCfg = &pAd->CommonCfg;
	pMbss = &pAd->ApCfg.MBSSID[apidx];
	wdev = &pMbss->wdev;

	if (!pMbss || !pMbss->bcn_buf.BeaconPkt)
		return;

	tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->bcn_buf.BeaconPkt);
	if (pAd->chipCap.hif_type == HIF_MT)
	{
		pBeaconFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len);
	}
	else
	{
		pBeaconFrame = (UCHAR *)(tmac_info + TXWISize);
	}

	if(!BeaconTransmitRequired(pAd, apidx, pMbss))
		return;


#ifdef CONFIG_FPGA_MODE
	if (pAd->fpga_ctl.fpga_on & 0x1) {
		if (pAd->fpga_ctl.tx_kick_cnt == 0)
			return;
	}

#ifdef MT_MAC
	if (pAd->fpga_ctl.no_bcn) {
		DBGPRINT(RT_DEBUG_OFF, ("%s():Bcn Tx is blocked!\n", __FUNCTION__));
		return;
	}
#endif /* MT_MAC */
#endif /* CONFIG_FPGA_MODE */

#ifdef MT_MAC
	if (pAd->chipCap.hif_type == HIF_MT) {
		BOOLEAN is_pretbtt_int = FALSE;

#ifdef RTMP_PCI_SUPPORT
		USHORT FreeNum = GET_BCNRING_FREENO(pAd);
        if (FreeNum <= 0) {
            DBGPRINT(RT_DEBUG_ERROR, ("%s()=>BSS%d:BcnRing FreeNum is not enough!\n",
						__FUNCTION__, apidx));
            return;
        }
#endif /* RTMP_PCI_SUPPORT */

	if (pMbss->bcn_buf.bcn_state != BCN_TX_IDLE) {
#ifdef RTMP_PCI_SUPPORT
		APCheckBcnQHandler(pAd, apidx, &is_pretbtt_int);
#endif /* RTMP_PCI_SUPPORT */
		if (is_pretbtt_int == FALSE)
			return;
	}

        PhyMode = pMbss->wdev.PhyMode;
        SsidLen = (pMbss->bHideSsid) ? 0 : pMbss->SsidLen;
        MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON,
                            0, BROADCAST_ADDR,
                            pMbss->wdev.if_addr,
                            pMbss->wdev.bssid);

        /* for update framelen to TxWI later. */
        SupRateLen = pAd->CommonCfg.SupRateLen;
        if (PhyMode == WMODE_B)
            SupRateLen = 4;

        MakeOutgoingFrame(pBeaconFrame,                  &FrameLen,
                        sizeof(HEADER_802_11),           &BcnHdr,
                        TIMESTAMP_LEN,                   &FakeTimestamp,
                        2,                               &pAd->CommonCfg.BeaconPeriod,
                        2,                               &pMbss->CapabilityInfo,
                        1,                               &SsidIe,
                        1,                               &SsidLen,
                        SsidLen,                      pMbss->Ssid,
                        1,                               &SupRateIe,
                        1,                               &SupRateLen,
                        SupRateLen,                pAd->CommonCfg.SupRate,
                        1,                               &DsIe,
                        1,                               &DsLen,
                        1,                               &pAd->CommonCfg.Channel,
                        END_OF_ARGS);

        if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B))
        {
            ULONG TmpLen;
            MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
                            1,                               &ExtRateIe,
                            1,                               &pAd->CommonCfg.ExtRateLen,
                            pAd->CommonCfg.ExtRateLen,           pAd->CommonCfg.ExtRate,
                            END_OF_ARGS);
            FrameLen += TmpLen;
        }


        /* add country IE, power constraint IE */
        if (pAd->CommonCfg.bCountryFlag)
        {
            ULONG TmpLen, TmpLen2=0;
            UCHAR *TmpFrame = NULL;
            UCHAR CountryIe = IE_COUNTRY;

            os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256);
            if (TmpFrame != NULL)
            {
                NdisZeroMemory(TmpFrame, 256);

                /* prepare channel information */
#ifdef EXT_BUILD_CHANNEL_LIST
                BuildBeaconChList(pAd, TmpFrame, &TmpLen2);
#else
                {
                    UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
                    MakeOutgoingFrame(TmpFrame+TmpLen2,     &TmpLen,
                                        1,                 	&pAd->ChannelList[0].Channel,
                                        1,                 	&pAd->ChannelListNum,
                                        1,                 	&MaxTxPower,
                                        END_OF_ARGS);
                    TmpLen2 += TmpLen;
                }
#endif /* EXT_BUILD_CHANNEL_LIST */


                /* need to do the padding bit check, and concatenate it */
                if ((TmpLen2%2) == 0)
                {
                    UCHAR	TmpLen3 = TmpLen2+4;
                    MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
                                    1,                 	&CountryIe,
                                    1,                 	&TmpLen3,
                                    3,                 	pAd->CommonCfg.CountryCode,
                                    TmpLen2+1,				TmpFrame,
                                    END_OF_ARGS);
                }
                else
                {
                    UCHAR	TmpLen3 = TmpLen2+3;
                    MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
                                    1,                 	&CountryIe,
                                    1,                 	&TmpLen3,
                                    3,                 	pAd->CommonCfg.CountryCode,
                                    TmpLen2,				TmpFrame,
                                    END_OF_ARGS);
                }
                FrameLen += TmpLen;

                os_free_mem(NULL, TmpFrame);
            }
            else
                DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
        }


#ifdef DOT11_N_SUPPORT
        /* AP Channel Report */
        {
            UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT;
            ULONG	TmpLen;

            /*
                802.11n D2.0 Annex J, USA regulatory
                    class 32, channel set 1~7
                    class 33, channel set 5-11
            */
            UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7};
            UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11};
            UCHAR rclasslen = 8; /*sizeof(rclass32); */
            if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN))
            {
                MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
                                1,                    &APChannelReportIe,
                                1,                    &rclasslen,
                                rclasslen,            rclass32,
                                1,                    &APChannelReportIe,
                                1,                    &rclasslen,
                                rclasslen,            rclass33,
                                END_OF_ARGS);
                FrameLen += TmpLen;
            }
        }
#endif /* DOT11_N_SUPPORT */


        BeaconTransmit.word = 0;

        //write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, FrameLen);

        pMbss->TimIELocationInBeacon = (UCHAR)FrameLen;
        pMbss->bcn_buf.cap_ie_pos = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2;

        FrameLen = UpdatePos = pMbss->TimIELocationInBeacon;
        PhyMode = wdev->PhyMode;



	}
#endif /* MT_MAC */

	/*
		step 1 - update BEACON's Capability
	*/
	ptr = pBeaconFrame + pMbss->bcn_buf.cap_ie_pos;

		//prevent little/big endian issue. and let asic_write_bcn_buf() handle it.
	*(UINT16 *)ptr = pMbss->CapabilityInfo;
		/*
		step 2 - update TIM IE
		TODO: enlarge TIM bitmap to support up to 64 STAs
		TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time
	*/
	ptr = pBeaconFrame + pMbss->TimIELocationInBeacon;
	*ptr = IE_TIM;
	*(ptr + 2) = pAd->ApCfg.DtimCount;
	*(ptr + 3) = pAd->ApCfg.DtimPeriod;

	/* find the smallest AID (PS mode) */
	TimFirst = 0; /* record first TIM byte != 0x00 */
	TimLast = 0;  /* record last  TIM byte != 0x00 */
	pTim = pMbss->TimBitmaps;

	for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++)
	{
		/* get the TIM indicating PS packets for 8 stations */
		UCHAR tim_1B = pTim[ID_1B];

		if (ID_1B == 0)
			tim_1B &= 0xfe; /* skip bit0 bc/mc */

		if (tim_1B == 0)
			continue; /* find next 1B */

		if (TimFirst == 0)
			TimFirst = ID_1B;

		TimLast = ID_1B;
	}

	/* fill TIM content to beacon buffer */
	if (TimFirst & 0x01)
		TimFirst --; /* find the even offset byte */

	*(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */
	*(ptr + 4) = TimFirst;

	for(i=TimFirst; i<=TimLast; i++)
		*(ptr + 5 + i - TimFirst) = pTim[i];

	/* bit0 means backlogged mcast/bcast */
    if (pAd->ApCfg.DtimCount == 0)
		*(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01);

	/* adjust BEACON length according to the new TIM */
	FrameLen += (2 + *(ptr+1));

	/* move RSN IE from below to here for Ralink Win7 v3.0.0.61 version parse beacon issue. */
	/* sync the order with BRCM's AP. */
	if ((wdev->AuthMode == Ndis802_11AuthModeWPA) ||
		(wdev->AuthMode == Ndis802_11AuthModeWPAPSK))
		RSNIe = IE_WPA;
	else if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) ||
		(wdev->AuthMode == Ndis802_11AuthModeWPA2PSK))
		RSNIe = IE_WPA2;
#ifdef WAPI_SUPPORT
	else if ((wdev->AuthMode == Ndis802_11AuthModeWAICERT) ||
		(wdev->AuthMode == Ndis802_11AuthModeWAIPSK))
		RSNIe = IE_WAPI;
#endif /* WAPI_SUPPORT */

	/* Append RSN_IE when  WPA OR WPAPSK, */
	if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
		(wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
	{
		ULONG TmpLen;
		MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TmpLen,
						  1,                            &RSNIe,
						  1,                            &pMbss->RSNIE_Len[0],
						  pMbss->RSNIE_Len[0],      pMbss->RSN_IE[0],
						  1,                            &RSNIe2,
						  1,                            &pMbss->RSNIE_Len[1],
						  pMbss->RSNIE_Len[1],      pMbss->RSN_IE[1],
						  END_OF_ARGS);
		FrameLen += TmpLen;
	}
	else if (wdev->AuthMode >= Ndis802_11AuthModeWPA)
	{
		ULONG TmpLen;
		{
			MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TmpLen,
						  1,                            &RSNIe,
						  1,                            &pMbss->RSNIE_Len[0],
						  pMbss->RSNIE_Len[0],      pMbss->RSN_IE[0],
						  END_OF_ARGS);
			FrameLen += TmpLen;
		}
	}

#ifdef HOSTAPD_SUPPORT
	if (pMbss->HostapdWPS && (pMbss->WscIEBeacon.ValueLen))
		bHasWpsIE = TRUE;
#endif

#ifdef WSC_AP_SUPPORT
    /* add Simple Config Information Element */
    if (((pMbss->WscControl.WscConfMode >= 1) && (pMbss->WscIEBeacon.ValueLen)))
		bHasWpsIE = TRUE;
#endif /* WSC_AP_SUPPORT */

	if (bHasWpsIE)
	{
		ULONG WscTmpLen = 0;

		MakeOutgoingFrame(pBeaconFrame+FrameLen, &WscTmpLen,
						pMbss->WscIEBeacon.ValueLen, pMbss->WscIEBeacon.Value,
						END_OF_ARGS);
		FrameLen += WscTmpLen;
	}

#ifdef WSC_AP_SUPPORT
    if ((pMbss->WscControl.WscConfMode != WSC_DISABLE) &&
#ifdef DOT1X_SUPPORT
        (pMbss->wdev.IEEE8021X == FALSE) &&
#endif /* DOT1X_SUPPORT */
        (pMbss->wdev.WepStatus == Ndis802_11WEPEnabled))
    {
        /*
            Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based
            or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP
            network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't
            receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and
            prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">>
            A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network.
            The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero)
            http:msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp
        */
        ULONG TempLen = 0;
        UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00};
        MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TempLen,
						  7,                            PROVISION_SERVICE_IE,
                          END_OF_ARGS);
        FrameLen += TempLen;
    }
#endif /* WSC_AP_SUPPORT */


	/* Update ERP */
    if ((pComCfg->ExtRateLen) && (PhyMode != WMODE_B))
    {
        /* fill ERP IE */
        ptr = (UCHAR *)pBeaconFrame + FrameLen; /* pTxD->DataByteCnt; */
        *ptr = IE_ERP;
        *(ptr + 1) = 1;
        *(ptr + 2) = pAd->ApCfg.ErpIeContent;
		FrameLen += 3;
	}

#ifdef A_BAND_SUPPORT
	/* fill up Channel Switch Announcement Element */
	if ((pComCfg->Channel > 14)
		&& (pComCfg->bIEEE80211H == 1)
		&& (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE))
	{
		ptr = pBeaconFrame + FrameLen;
		*ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
		*(ptr + 1) = 3;
		*(ptr + 2) = 1;
		*(ptr + 3) = pComCfg->Channel;
		*(ptr + 4) = (pAd->Dot11_H.CSPeriod - pAd->Dot11_H.CSCount - 1);
		ptr += 5;
		FrameLen += 5;

#ifdef DOT11_N_SUPPORT
		/* Extended Channel Switch Announcement Element */
		if (pComCfg->bExtChannelSwitchAnnouncement)
		{
			HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE	HtExtChannelSwitchIe;
			build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe);
			NdisMoveMemory(ptr, &HtExtChannelSwitchIe, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE));
			ptr += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE);
			FrameLen += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE);
		}

#ifdef DOT11_VHT_AC
		if (WMODE_CAP_AC(PhyMode)) {
			INT tp_len, wb_len = 0;
			UCHAR *ch_sw_wrapper;
			VHT_TXPWR_ENV_IE txpwr_env;


			*ptr = IE_CH_SWITCH_WRAPPER;
			ch_sw_wrapper = (UCHAR *)(ptr + 1); // reserve for length
			ptr += 2; // skip len

			if (pComCfg->RegTransmitSetting.field.BW == BW_40) {
				WIDE_BW_CH_SWITCH_ELEMENT wb_info;

				*ptr = IE_WIDE_BW_CH_SWITCH;
				*(ptr + 1) = sizeof(WIDE_BW_CH_SWITCH_ELEMENT);
				ptr += 2;
				NdisZeroMemory(&wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT));
				if (pComCfg->vht_bw == VHT_BW_2040)
					wb_info.new_ch_width = 0;
				else
					wb_info.new_ch_width = 1;

				if (pComCfg->vht_bw == VHT_BW_80) {
					wb_info.center_freq_1 = vht_cent_ch_freq(pAd, pComCfg->Channel);
					wb_info.center_freq_2 = 0;
				}
				NdisMoveMemory(ptr, &wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT));
				wb_len = sizeof(WIDE_BW_CH_SWITCH_ELEMENT);
				ptr += wb_len;
				wb_len += 2;
			}

			*ptr = IE_VHT_TXPWR_ENV;
			NdisZeroMemory(&txpwr_env, sizeof(VHT_TXPWR_ENV_IE));
			tp_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env);
			*(ptr + 1) = tp_len;
			ptr += 2;
			NdisMoveMemory(ptr, &txpwr_env, tp_len);
			ptr += tp_len;
			tp_len += 2;
			*ch_sw_wrapper = wb_len + tp_len;

			FrameLen += (2 + wb_len + tp_len);
		}
#endif /* DOT11_VHT_AC */

#endif /* DOT11_N_SUPPORT */
	}
#endif /* A_BAND_SUPPORT */

#ifdef DOT11_N_SUPPORT
	/* step 5. Update HT. Since some fields might change in the same BSS. */
	if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable))
	{
		ULONG TmpLen;
		UCHAR HtLen, HtLen1;
		/*UCHAR i; */

		HT_CAPABILITY_IE HtCapabilityTmp;
#ifdef RT_BIG_ENDIAN
		ADD_HT_INFO_IE	addHTInfoTmp;
/*		USHORT	b2lTmp, b2lTmp2; // no use */
#endif

		/* add HT Capability IE */
		HtLen = sizeof(pComCfg->HtCapability);
		HtLen1 = sizeof(pComCfg->AddHTInfo);
#ifndef RT_BIG_ENDIAN
		NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen);
		HtCapabilityTmp.HtCapInfo.ChannelWidth = pComCfg->AddHTInfo.AddHtInfo.RecomWidth;

		MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
								  1,                                &HtCapIe,
								  1,                                &HtLen,
								 HtLen,          &HtCapabilityTmp,
								  1,                                &AddHtInfoIe,
								  1,                                &HtLen1,
								 HtLen1,          &pComCfg->AddHTInfo,
						  END_OF_ARGS);
#else
		NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen);
		HtCapabilityTmp.HtCapInfo.ChannelWidth = pComCfg->AddHTInfo.AddHtInfo.RecomWidth;
		*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
		{
			EXT_HT_CAP_INFO extHtCapInfo;

			NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
			*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
			NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
		}
#else
		*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif /* UNALIGNMENT_SUPPORT */

		NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1);
		*(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
		*(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));

		MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
								  1,                                &HtCapIe,
								  1,                                &HtLen,
								 HtLen,                   &HtCapabilityTmp,
								  1,                                &AddHtInfoIe,
								  1,                                &HtLen1,
								 HtLen1,                   &addHTInfoTmp,
						  END_OF_ARGS);
#endif
		FrameLen += TmpLen;

#ifdef DOT11N_DRAFT3
	 	/*
			P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE
		*/
	 	if ((pComCfg->Channel <= 14) &&
			(pComCfg->HtCapability.HtCapInfo.ChannelWidth == 1))
	 	{
			OVERLAP_BSS_SCAN_IE  OverlapScanParam;
			ULONG	TmpLen;
			UCHAR	OverlapScanIE, ScanIELen;

			OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM;
			ScanIELen = 14;
			OverlapScanParam.ScanPassiveDwell = cpu2le16(pComCfg->Dot11OBssScanPassiveDwell);
			OverlapScanParam.ScanActiveDwell = cpu2le16(pComCfg->Dot11OBssScanActiveDwell);
			OverlapScanParam.TriggerScanInt = cpu2le16(pComCfg->Dot11BssWidthTriggerScanInt);
			OverlapScanParam.PassiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanPassiveTotalPerChannel);
			OverlapScanParam.ActiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanActiveTotalPerChannel);
			OverlapScanParam.DelayFactor = cpu2le16(pComCfg->Dot11BssWidthChanTranDelayFactor);
			OverlapScanParam.ScanActThre = cpu2le16(pComCfg->Dot11OBssScanActivityThre);

			MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
								1,			&OverlapScanIE,
								1,			&ScanIELen,
								ScanIELen,	&OverlapScanParam,
								END_OF_ARGS);

			FrameLen += TmpLen;
	 	}
#endif /* DOT11N_DRAFT3 */

#ifdef CONFIG_HOTSPOT
	if (pMbss->HotSpotCtrl.HotSpotEnable)
 	{
		ULONG	TmpLen;

		/* Indication element */
		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
						  pMbss->HotSpotCtrl.HSIndicationIELen,
						  pMbss->HotSpotCtrl.HSIndicationIE, END_OF_ARGS);

		FrameLen += TmpLen;

		/* Interworking element */
		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
						  pMbss->HotSpotCtrl.InterWorkingIELen,
						  pMbss->HotSpotCtrl.InterWorkingIE, END_OF_ARGS);

		FrameLen += TmpLen;

		/* Advertisement Protocol element */
		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
						  pMbss->HotSpotCtrl.AdvertisementProtoIELen,
						  pMbss->HotSpotCtrl.AdvertisementProtoIE, END_OF_ARGS);

		FrameLen += TmpLen;

		/* Roaming Consortium element */
		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
						  pMbss->HotSpotCtrl.RoamingConsortiumIELen,
						  pMbss->HotSpotCtrl.RoamingConsortiumIE, END_OF_ARGS);

		FrameLen += TmpLen;

		/* P2P element */
		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
						  pMbss->HotSpotCtrl.P2PIELen,
						  pMbss->HotSpotCtrl.P2PIE, END_OF_ARGS);

		FrameLen += TmpLen;

 	}
#endif

#ifdef DOT11_VHT_AC
		if (WMODE_CAP_AC(PhyMode) && (pComCfg->Channel > 14))
		{
			int _len = build_vht_ies(pAd, (UCHAR *)(pBeaconFrame+FrameLen), SUBTYPE_BEACON);
			FrameLen += _len;
		}
#endif /* DOT11_VHT_AC */
	}
#endif /* DOT11_N_SUPPORT */

	/* 7.3.2.27 Extended Capabilities IE */
	{
		ULONG TmpLen, infoPos;
		PUCHAR pInfo;
		UCHAR extInfoLen;
		BOOLEAN	bNeedAppendExtIE = FALSE;
		EXT_CAP_INFO_ELEMENT	extCapInfo;


		extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT);
		NdisZeroMemory(&extCapInfo, extInfoLen);

#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
		/* P802.11n_D1.10, HT Information Exchange Support */
		if (WMODE_CAP_N(PhyMode) && (pComCfg->Channel <= 14) &&
			(pMbss->wdev.DesiredHtPhyInfo.bHtEnable) &&
			(pComCfg->bBssCoexEnable == TRUE)
		)
		{
			extCapInfo.BssCoexistMgmtSupport = 1;
		}
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */

#ifdef CONFIG_DOT11V_WNM
		if (pMbss->WNMCtrl.ProxyARPEnable)
			extCapInfo.proxy_arp = 1;

#endif /* CONFIG_DOT11V_WNM */

#ifdef CONFIG_HOTSPOT
		if (pMbss->HotSpotCtrl.HotSpotEnable)
			extCapInfo.interworking = 1;
#endif /* CONFIG_HOTSPOT */

#ifdef DOT11_VHT_AC
		if (WMODE_CAP_AC(PhyMode) &&
			(pAd->CommonCfg.Channel > 14))
			extCapInfo.operating_mode_notification = 1;
#endif /* DOT11_VHT_AC */

		pInfo = (PUCHAR)(&extCapInfo);
		for (infoPos = 0; infoPos < extInfoLen; infoPos++)
		{
			if (pInfo[infoPos] != 0)
			{
				bNeedAppendExtIE = TRUE;
				break;
			}
		}

		if (bNeedAppendExtIE == TRUE)
		{
			MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
							1, &ExtCapIe,
							1, &extInfoLen,
							extInfoLen, &extCapInfo,
							END_OF_ARGS);
			FrameLen += TmpLen;
		}
	}

#ifdef WFA_VHT_PF
	if (pAd->force_vht_op_mode == TRUE)
	{
		ULONG TmpLen;
		UCHAR operating_ie = IE_OPERATING_MODE_NOTIFY, operating_len = 1;
		OPERATING_MODE operating_mode;

		operating_mode.rx_nss_type = 0;
		operating_mode.rx_nss = (pAd->vht_pf_op_ss - 1);
		operating_mode.ch_width = pAd->vht_pf_op_bw;

		MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
						  1,	&operating_ie,
						  1,	&operating_len,
						  1,	&operating_mode,
						  END_OF_ARGS);
		FrameLen += TmpLen;
	}
#endif /* WFA_VHT_PF */

	/* add WMM IE here */
	if (pMbss->wdev.bWmmCapable)
	{
		ULONG TmpLen;
		UCHAR i;
		UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0};
		UINT8 AIFSN[4];

		WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;

#ifdef UAPSD_SUPPORT
        UAPSD_MR_IE_FILL(WmeParmIe[8], &pMbss->wdev.UapsdInfo);
#endif /* UAPSD_SUPPORT */

		NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN));


		for (i=QID_AC_BE; i<=QID_AC_VO; i++)
		{
			WmeParmIe[10+ (i*4)] = (i << 5)                                         +     /* b5-6 is ACI */
								   ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4)     +     /* b4 is ACM */
								   (AIFSN[i] & 0x0f);              /* b0-3 is AIFSN */
			WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4)           +     /* b5-8 is CWMAX */
								   (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f);              /* b0-3 is CWMIN */
			WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff);        /* low byte of TXOP */
			WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8);          /* high byte of TXOP */
		}

		MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
						  26,                            WmeParmIe,
						  END_OF_ARGS);
		FrameLen += TmpLen;
	}

#ifdef AP_QLOAD_SUPPORT
	if (pAd->phy_ctrl.FlgQloadEnable != 0)
	{
		FrameLen += QBSS_LoadElementAppend(pAd, pBeaconFrame+FrameLen);
	}
#endif /* AP_QLOAD_SUPPORT */

#ifdef A_BAND_SUPPORT
	/*
		Only 802.11a APs that comply with 802.11h are required to include a
		Power Constrint Element(IE=32) in beacons and probe response frames
	*/
	if (((pComCfg->Channel > 14) && pComCfg->bIEEE80211H == TRUE)
		)
	{
		ULONG TmpLen;
		UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT;
		UINT8 PwrConstraintLen = 1;
		UINT8 PwrConstraint = pComCfg->PwrConstraint;

		/* prepare power constraint IE */
		MakeOutgoingFrame(pBeaconFrame+FrameLen,	&TmpLen,
						1,							&PwrConstraintIE,
						1,							&PwrConstraintLen,
						1,							&PwrConstraint,
						END_OF_ARGS);
		FrameLen += TmpLen;

#ifdef DOT11_VHT_AC
		if (WMODE_CAP_AC(PhyMode)) {
			ULONG TmpLen;
			UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV;
			UINT8 ie_len;
			VHT_TXPWR_ENV_IE txpwr_env;

			ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env);
			MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
						1,							&vht_txpwr_env_ie,
						1,							&ie_len,
						ie_len,						&txpwr_env,
						END_OF_ARGS);
			FrameLen += TmpLen;
		}
#endif /* DOT11_VHT_AC */

	}
#endif /* A_BAND_SUPPORT */


#ifdef DOT11_N_SUPPORT
	if (WMODE_CAP_N(PhyMode) &&
		(wdev->DesiredHtPhyInfo.bHtEnable))
	{
		ULONG TmpLen;
		UCHAR HtLen, HtLen1;
#ifdef RT_BIG_ENDIAN
		HT_CAPABILITY_IE HtCapabilityTmp;
		ADD_HT_INFO_IE	addHTInfoTmp;
#endif
		/* add HT Capability IE */
		HtLen = sizeof(pComCfg->HtCapability);
		HtLen1 = sizeof(pComCfg->AddHTInfo);

		if (pAd->bBroadComHT == TRUE)
		{
			UCHAR epigram_ie_len;
			UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33};
			UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34};


			epigram_ie_len = HtLen + 4;
#ifndef RT_BIG_ENDIAN
			MakeOutgoingFrame(pBeaconFrame + FrameLen,      &TmpLen,
						  1,                                &WpaIe,
						  1,                                &epigram_ie_len,
						  4,                                &BROADCOM_HTC[0],
						  HtLen,          					&pComCfg->HtCapability,
						  END_OF_ARGS);
#else
			NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen);
			*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
		{
			EXT_HT_CAP_INFO extHtCapInfo;

			NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
			*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
			NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
		}
#else
			*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif /* UNALIGNMENT_SUPPORT */

			MakeOutgoingFrame(pBeaconFrame + FrameLen,       &TmpLen,
						1,                               &WpaIe,
						1,                               &epigram_ie_len,
						4,                               &BROADCOM_HTC[0],
						HtLen,                           &HtCapabilityTmp,
						END_OF_ARGS);
#endif

			FrameLen += TmpLen;

			epigram_ie_len = HtLen1 + 4;
#ifndef RT_BIG_ENDIAN
			MakeOutgoingFrame(pBeaconFrame + FrameLen,        &TmpLen,
						  1,                                &WpaIe,
						  1,                                &epigram_ie_len,
						  4,                                &BROADCOM_AHTINFO[0],
						  HtLen1, 							&pComCfg->AddHTInfo,
						  END_OF_ARGS);
#else
			NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1);
			*(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
			*(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));

			MakeOutgoingFrame(pBeaconFrame + FrameLen,         &TmpLen,
							1,                             &WpaIe,
							1,                             &epigram_ie_len,
							4,                             &BROADCOM_AHTINFO[0],
							HtLen1,                        &addHTInfoTmp,
							END_OF_ARGS);
#endif
			FrameLen += TmpLen;
		}
	}
#endif /* DOT11_N_SUPPORT */

   	/* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */
{
	ULONG TmpLen;
	UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00};

	if (pComCfg->bAggregationCapable)
		RalinkSpecificIe[5] |= 0x1;
	if (pComCfg->bPiggyBackCapable)
		RalinkSpecificIe[5] |= 0x2;
#ifdef DOT11_N_SUPPORT
	if (pComCfg->bRdg)
		RalinkSpecificIe[5] |= 0x4;
#endif /* DOT11_N_SUPPORT */
	MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
						9,                   RalinkSpecificIe,
						END_OF_ARGS);
	FrameLen += TmpLen;

}


	/* step 6. Since FrameLen may change, update TXWI. */
#ifdef A_BAND_SUPPORT
	if (pAd->CommonCfg.Channel > 14) {
		BeaconTransmit.field.MODE = MODE_OFDM;
		BeaconTransmit.field.MCS = MCS_RATE_6;
	}
#endif /* A_BAND_SUPPORT */

	write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, FrameLen);

        /* step 6. move BEACON TXD and frame content to on-chip memory */
        asic_write_bcn_buf(pAd,
                            tmac_info, TXWISize,
                            pBeaconFrame, FrameLen,
                            pAd->BeaconOffset[pMbss->bcn_buf.BcnBufIdx]);

#if defined(MT7603_FPGA) || defined(MT7628_FPGA)
	// TODO: shiang-7603, we use different way to update beacon packet!
	if (0)//IS_MT7603(pAd))
	{
		hex_dump("Beacon_TMAC_INFO", (UCHAR *)tmac_info, tx_hw_hdr_len);
		dump_tmac_info(pAd, tmac_info);
		hex_dump("BeaconFrame", pBeaconFrame, FrameLen);
	}
#endif /* MT7603_FPGA */

	/* step 7. move BEACON TXWI and frame content to on-chip memory */
	RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos);


	{
	    UINT32   Lowpart, Highpart;

	    AsicGetTsfTime(pAd, &Highpart, &Lowpart);
	    pMbss->WriteBcnDoneTime[pMbss->timer_loop] = Lowpart;
	}

}
示例#25
0
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)
	{
		   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);
			if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)
				&& get_netdev_from_bssid(pAd, pMacEntry->apidx) == 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) && (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED))
		{
			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)
				{
		   			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->apidx) == 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;	

				continue;
			}

			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 != 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;
}
示例#26
0
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;
}
示例#27
0
/*
	Must be run in Interrupt context
	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
 */
int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
		       u8 QueIdx,
		       void *pPacket,
		       u8 *pSrcBufVA, u32 SrcBufLen)
{
	struct rt_txinfo *pTxInfo;
	unsigned long BulkOutSize;
	u8 padLen;
	u8 *pDest;
	unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
	struct rt_tx_context *pMLMEContext =
	    (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	unsigned long IrqFlags;

	pTxInfo = (struct rt_txinfo *)(pSrcBufVA);

	/* Build our URB for USBD */
	BulkOutSize = SrcBufLen;
	BulkOutSize = (BulkOutSize + 3) & (~3);
	RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE),
			TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);

	BulkOutSize += 4;	/* Always add 4 extra bytes at every packet. */

	/* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */
	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
		BulkOutSize += 4;

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));

	/* Now memzero all extra padding bytes. */
	pDest = (u8 *)(pSrcBufVA + SrcBufLen);
	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer =
	    (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket));

	/* Length in TxInfo should be 8 less than bulkout size. */
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;

	/*for debug */
	/*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */

	/*pAd->RalinkCounters.KickTxCount++; */
	/*pAd->RalinkCounters.OneSecTxDoneCount++; */

	/*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */
	/*      needKickOut = TRUE; */

	/* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);

	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	/*if (needKickOut) */
	RTUSBKickBulkOut(pAd);

	return 0;
}
/*
	Must be run in Interrupt context
	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
 */
int RtmpUSBMgmtKickOut(
	IN RTMP_ADAPTER 	*pAd,
	IN UCHAR 			QueIdx,
	IN PNDIS_PACKET		pPacket,
	IN PUCHAR			pSrcBufVA,
	IN UINT 			SrcBufLen)
{
	PTXINFO_STRUC	pTxInfo;
	ULONG			BulkOutSize;
	UCHAR			padLen;
	PUCHAR			pDest;
	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	unsigned long	IrqFlags;


	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);

	// Build our URB for USBD
	BulkOutSize = SrcBufLen;
	BulkOutSize = (BulkOutSize + 3) & (~3);
	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);

	BulkOutSize += 4; // Always add 4 extra bytes at every packet.

	// If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
		BulkOutSize += 4;

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));

	// Now memzero all extra padding bytes.
	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));

	// Length in TxInfo should be 8 less than bulkout size.
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;


	//for debug
	//hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));

	//pAd->RalinkCounters.KickTxCount++;
	//pAd->RalinkCounters.OneSecTxDoneCount++;

	//if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
	//	needKickOut = TRUE;

	// Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);

	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	//if (needKickOut)
	RTUSBKickBulkOut(pAd);

	return 0;
}
示例#29
0
int RtmpUSBMgmtKickOut(
	IN RTMP_ADAPTER 	*pAd,
	IN UCHAR 			QueIdx,
	IN PNDIS_PACKET		pPacket,
	IN PUCHAR			pSrcBufVA,
	IN UINT 			SrcBufLen)
{
	PTXINFO_STRUC	pTxInfo;
	ULONG			BulkOutSize;
	UCHAR			padLen;
	PUCHAR			pDest;
	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	unsigned long	IrqFlags;


	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);

	
	BulkOutSize = SrcBufLen;
	BulkOutSize = (BulkOutSize + 3) & (~3);
	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);

	BulkOutSize += 4; 

	
	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
		BulkOutSize += 4;

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));

	
	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));

	
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;


	
	

	
	

	
	

	
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);

	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	
	RTUSBKickBulkOut(pAd);

	return 0;
}
/* 
==========================================================================
	Description:
		Setup Frame format.
	NOTE:
		This routine should only be used in ATE mode.
==========================================================================
*/
INT ATESetUpFrame(
	IN PRTMP_ADAPTER pAd,
	IN UINT32 TxIdx)
{
	PATE_INFO pATEInfo = &(pAd->ate);
	UINT pos = 0;
	PTXD_STRUC pTxD;
#ifdef RT_BIG_ENDIAN
    PTXD_STRUC      pDestTxD;
    TXD_STRUC       TxD;
#endif
	PNDIS_PACKET pPacket=NULL;
	PUCHAR pDest=NULL;
	PVOID AllocVa=NULL;
	NDIS_PHYSICAL_ADDRESS AllocPa;
	HTTRANSMIT_SETTING	TxHTPhyMode;

	PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
	PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
	PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
	UINT8 TXWISize = pAd->chipCap.TXWISize;

#ifdef RALINK_QA
	PHEADER_802_11	pHeader80211;
#endif /* RALINK_QA */

	/* fill TxWI */
	TxHTPhyMode.field.BW = pATEInfo->TxWI.BW;
	TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.ShortGI;
	TxHTPhyMode.field.STBC = pATEInfo->TxWI.STBC;
	TxHTPhyMode.field.MCS = pATEInfo->TxWI.MCS;
	TxHTPhyMode.field.MODE = pATEInfo->TxWI.PHYMODE;

	if (pATEInfo->bQATxStart == TRUE) 
	{
		/* always use QID_AC_BE and FIFO_EDCA */
		ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.FRAG, pATEInfo->TxWI.CFACK,
			pATEInfo->TxWI.TS, pATEInfo->TxWI.AMPDU, pATEInfo->TxWI.ACK,
			pATEInfo->TxWI.NSEQ, pATEInfo->TxWI.BAWinSize, 0,
			pATEInfo->TxWI.MPDUtotalByteCount, pATEInfo->TxWI.PacketId, 0, 0,
			pATEInfo->TxWI.txop/*IFS_HTTXOP*/, pATEInfo->TxWI.CFACK/*FALSE*/,
			&TxHTPhyMode);

#ifdef TXBF_SUPPORT
		if (IS_RT2883(pAd) || IS_RT3883(pAd))
		{
			/* Must copy rsv bits to actual TxWI */
			pTxWI->rsv = pATEInfo->TxWI.rsv;
			pTxWI->iTxBF = pATEInfo->TxWI.iTxBF;	
			pTxWI->Sounding = pATEInfo->TxWI.Sounding;
			pTxWI->eTxBF = pATEInfo->TxWI.eTxBF;
			pTxWI->Autofallback = pATEInfo->TxWI.Autofallback;
			pTxWI->NDPSndBW = pATEInfo->TxWI.NDPSndBW;
			pTxWI->NDPSndRate = pATEInfo->TxWI.NDPSndRate;
		}
#endif /* TXBF_SUPPORT */
	}
	else
	{
		ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE,  FALSE, FALSE, FALSE, 
			4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);

#ifdef TXBF_SUPPORT
		if (pATEInfo->bTxBF == 1)
		{
			if (IS_RT2883(pAd) || IS_RT3883(pAd))
			{
				pTxWI->rsv = 0;
				pTxWI->iTxBF = pATEInfo->TxWI.iTxBF;	
				pTxWI->Sounding = (pATEInfo->txSoundingMode == 1 ? 1 : 0);
				pTxWI->eTxBF = pATEInfo->TxWI.eTxBF;
				pTxWI->Autofallback = pATEInfo->TxWI.Autofallback;
				pTxWI->NDPSndBW = pATEInfo->TxWI.BW;
				if (pATEInfo->txSoundingMode == 3)
					pTxWI->NDPSndRate = 2;
				else if (pATEInfo->txSoundingMode == 2)
					pTxWI->NDPSndRate = 1;
				else
					pTxWI->NDPSndRate = 0;
			}
		}
#endif /* TXBF_SUPPORT */
	}
	
	/* fill 802.11 header */
#ifdef RALINK_QA
	if (pATEInfo->bQATxStart == TRUE) 
	{
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen);
	}
	else
#endif /* RALINK_QA */
	{
		pATEInfo->HLen = LENGTH_802_11;
#ifdef TXBF_SUPPORT
		TemplateFrame[0] = 0x08;	/* Data */
		TemplateFrame[1] = 0x00;
		if (pATEInfo->bTxBF && pATEInfo->txSoundingMode!=0)
		{
			/* QoS Data */
			pATEInfo->HLen = 32;
			TemplateFrame[0] = 0x88;
			TemplateFrame[1] = 0x80;
		
			switch (pATEInfo->txSoundingMode)
			{
			case 1:
				/* Data Sounding */
				TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0;
				TemplateFrame[29] = 0x00;	
				break;
			case 2:
			case 3:
				/* 2 or 3 Stream NDP */
				TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0;
				TemplateFrame[29] = 0x01;	/* NDP Announce */
				break;
			default:
				TemplateFrame[28] = TemplateFrame[29] = 0x0;
			}
		}
#endif /* TXBF_SUPPORT */
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize, TemplateFrame, pATEInfo->HLen);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, pATEInfo->Addr1, ETH_LENGTH_OF_ADDRESS);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, pATEInfo->Addr2, ETH_LENGTH_OF_ADDRESS);
		NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, pATEInfo->Addr3, ETH_LENGTH_OF_ADDRESS);
	}

#ifdef RT_BIG_ENDIAN
	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE);
#endif /* RT_BIG_ENDIAN */

	/* alloc buffer for payload */
#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) 
	{
		pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev,
			pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa);
	}
	else
#endif /* RALINK_QA */
	{
		pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev,
			pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa);
	}

	if (pPacket == NULL)
	{
		pATEInfo->TxCount = 0;
		DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__));
		return -1;
	}

	pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket;
	pDest = (PUCHAR) AllocVa;

#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) 
	{
		GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen;
#ifndef LINUX
		GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen;
#endif /* LIMUX */
	}
	else
#endif /* RALINK_QA */
	{
		GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11;
#ifndef LINUX
		GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11;
#endif /* LINUX */
	}

	/* prepare frame payload */
#ifdef RALINK_QA
	if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0))
	{
		/* copy pattern to payload */
		if ((pATEInfo->PLen != 0))
		{
			for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen)
			{
				memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen);
			}
		}
	}
	else
#endif /* RALINK_QA */
	{
		for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++)
		{
			/* default payload is 0xA5 */
			pDest[pos] = pATEInfo->Payload;
		}
	}

	/* build Tx descriptor */
#ifndef RT_BIG_ENDIAN
	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
#else
    pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
    TxD = *pDestTxD;
    pTxD = &TxD;
#endif /* !RT_BIG_ENDIAN */

#ifdef RALINK_QA
	if (pATEInfo->bQATxStart == TRUE)
	{
		/* prepare TxD */
		NdisZeroMemory(pTxD, TXD_SIZE);
		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
		/* build Tx descriptor */
		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
		pTxD->SDLen0 = TXWISize + pATEInfo->HLen;
		pTxD->SDPtr1 = AllocPa;
		pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket);
		pTxD->LastSec0 = (pTxD->SDLen1 == 0) ? 1 : 0;
		pTxD->LastSec1 = 1;

		pDest = (PUCHAR)pTxWI;
		pDest += TXWISize;
		pHeader80211 = (PHEADER_802_11)pDest;
		
		/* modify sequence number... */
		if (pATEInfo->TxDoneCount == 0)
			pATEInfo->seq = pHeader80211->Sequence;
		else
			pHeader80211->Sequence = ++pATEInfo->seq;
	}
	else
#endif /* RALINK_QA */
	{
		NdisZeroMemory(pTxD, TXD_SIZE);
		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
		/* build Tx descriptor */
		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
		pTxD->SDLen0 = TXWISize + LENGTH_802_11;
		pTxD->LastSec0 = 0;
		pTxD->SDPtr1 = AllocPa;
		pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket);
		pTxD->LastSec1 = 1;
	}

#ifdef RT_BIG_ENDIAN
	RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE);
	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
#endif /* RT_BIG_ENDIAN */

	return 0;
}