⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmm.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
字号:
#include "precomp.h"
#include "pkfuncs.h"

UCHAR  wmm_tos2ac[16][8] = {
	{	// 0 0 0 0	all enabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 0 0 1	AC_PRIO_BE disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 0 1 0	AC_PRIO_BK should NOT be disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 0 1 1	AC_PRIO_BE disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 1 0 0	AC_PRIO_VI disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 1 0 1	AC_PRIO_VI & BE	disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 1 1 0	AC_PRIO_VI disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 0 1 1 1	AC_PRIO_VI & BE	disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_VO,
		AC_PRIO_VO
	},
	{	// 1 0 0 0	AC_PRIO_VO disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI
	},
	{	// 1 0 0 1	AC_PRIO_VO & BE disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI
	},
	{	// 1 0 1 0	AC_PRIO_VO disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI
	},
	{	// 1 0 1 1	AC_PRIO_VO & BE disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI,
		AC_PRIO_VI
	},
	{	// 1 1 0 0	AC_PRIO_VO & VI disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE
	},
	{	// 1 1 0 1	AC_PRIO_VO & VI & BE disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK
	},
	{	// 1 1 1 0	AC_PRIO_VO & VI disabled
		AC_PRIO_BE,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE,
		AC_PRIO_BE
	},
	{	// 1 1 1 1	AC_PRIO_VO & VI & BE disabled
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK,
		AC_PRIO_BK
	}
};

static UCHAR wmm_tos2priority[8] = {
/*	Priority   DSCP   DSCP   DSCP	WMM
		    P2     P1     P0 	AC    */
	0x00,	/*  0	   0	  0	AC_BE */
	0x04,	/*  0	   0	  1	AC_BK */
	0x02,	/*  0	   1	  0	AC_BK */
	0x06,	/*  0	   1	  1	AC_BE */
	0x01,	/*  1	   0	  0	AC_VI */
	0x05,	/*  1	   0	  1	AC_VI */
	0x03,	/*  1	   1	  0	AC_VO */
	0x07	/*  1	   1	  1	AC_VO */
};

#ifdef WMM

int wlan_wmm_enable_ioctl(PMRVDRV_ADAPTER Adapter, PVOID InformationBuffer)
{
    NDIS_STATUS     Status;
    PNDIS_PACKET    pPacket;
    POID_MRVL_DS_WMM_STATE pWmmState;

    pWmmState = (POID_MRVL_DS_WMM_STATE)InformationBuffer;

//    DBGPRINT(DBG_WMM, ("wlan_wmm_enable_ioctl state %x \n", pWmmState->State));
//    DBGPRINT(DBG_WMM, ("wmm state size %d \n", sizeof(POID_MRVL_DS_WMM_STATE)));

    switch (pWmmState->State)
    {
	case CMD_DISABLED: /* disable */
	     if (Adapter->MediaConnectStatus == NdisMediaStateConnected)
		return FALSE; 

	     Adapter->WmmDesc.required = 0;

	     if (!Adapter->WmmDesc.enabled)
 		  return FALSE; 
	     else
		  Adapter->WmmDesc.enabled = 0;

	     if (Adapter->SentPacket) 
	     {
		 Status = NDIS_STATUS_FAILURE;
		 pPacket = Adapter->SentPacket;
  		 NDIS_SET_PACKET_STATUS(pPacket, Status);
		 NdisMSendComplete(
			Adapter->MrvDrvAdapterHdl,
			pPacket,
			Status);
		 Adapter->SentPacket = NULL;
	     }

		/* Release all skb's in all the queues */
	     wmm_cleanup_queues(Adapter);
		
	     Adapter->CurrentPacketFilter &= ~HostCmd_ACT_MAC_WMM_ENABLE;

	     SetMacPacketFilter(Adapter, Adapter->CurrentPacketFilter);
	break;

	case CMD_ENABLED: /* enable */
	     if (Adapter->MediaConnectStatus == NdisMediaStateConnected)
	     {
//                DBGPRINT(DBG_WMM, ("The media is already connected \n"));
		return FALSE; 
             } 
	     Adapter->WmmDesc.required = 1;
//             DBGPRINT(DBG_WMM, ("Enable Firmware WMM \n"));

		break;
	}

	return TRUE;
}


int wmm_lists_empty(PMRVDRV_ADAPTER Adapter)
{
	int i;

#if 1 
  for (i = AC_PRIO_BE; i < MAX_AC_QUEUES; i++)
    if (!IsTxQEmpty(&Adapter->TXPRYQ[i]))
      return 0; 
#else
	for (i = AC_PRIO_VO; i >= AC_PRIO_BE; --i)
		if (!IsQEmpty(&Adapter->WmmDesc.TxPktQ[i]))
			return 0;
#endif

	return 1;
}

void wmm_cleanup_queues(PMRVDRV_ADAPTER Adapter)
{
#if 1 
  PTXQ_KEEPER  pTxQKeeper;
  PTXQ_NODE    pTQNode;
#else
	int 		i;
	PQ_KEEPER       Q;
#endif
	PNDIS_PACKET	pPacket;
	NDIS_STATUS     Status;

        Status = NDIS_STATUS_FAILURE;
#if 1 
  while(1)
  { 
    TxPacketDeQueue(Adapter, &pTxQKeeper, &pTQNode); 
    if( pTQNode == NULL )
        return;

    pPacket = pTQNode -> pPacket;   
    NDIS_SET_PACKET_STATUS(pPacket, Status);
    NdisMSendComplete(
                      Adapter->MrvDrvAdapterHdl,
                      pPacket,
                      Status);    

    PushFreeTxQNode(Adapter->TxFreeQ,pTQNode);  
    Adapter->TxPacketCount--;
  } // end of for loop
#else
	for (i = AC_PRIO_BE; i <= AC_PRIO_VO; i++)

	{
	   Q = &Adapter->WmmDesc.TxPktQ[i];
	   while (!IsQEmpty(Q))
	   {
		pPacket = (PNDIS_PACKET)PopFirstQNode(Q);
  		NDIS_SET_PACKET_STATUS(pPacket, Status);
		NdisMSendComplete(
		        Adapter->MrvDrvAdapterHdl,
			pPacket,
			Status);
	   } // end of while loop
	} // end of for loop
#endif 

}

UCHAR wmm_get_tos(PNDIS_PACKET pPacket)
{
     UCHAR tos = 0, temp;
     PNDIS_BUFFER pBuffer, pNextBuffer;
     UINT BufferCount, TotalPktLen;
     UINT Length1, Length2;
     PVOID pVirtualAddr1=NULL, pVirtualAddr2=NULL;
     USHORT type;
     PUCHAR ptr;
     
     NdisQueryPacket(pPacket, NULL, &BufferCount, &pBuffer, &TotalPktLen);    
     
     
     if(TotalPktLen >= MIN_IP_PKT_LEN)
     {
     	  NdisQueryBuffer(pBuffer, pVirtualAddr1, &Length1);
          ptr = (PUCHAR)pVirtualAddr1;
     	  if(Length1 < 16)
     	  { 
     	      NdisGetNextBuffer(pBuffer, &pNextBuffer);
     	      NdisQueryBuffer(pNextBuffer, pVirtualAddr2, &Length2);
              type = ptr[12] << 8;
              switch(Length1)
              {
              	  case 13:
              	       ptr = (PUCHAR)pVirtualAddr2;
              	       type |= ptr[0];
              	       temp = ptr[2];
              	  break;
              	  case 14:
              	       type |= ptr[13];
              	       ptr = (PUCHAR)pVirtualAddr2;
                       temp = ptr[1];              	       
              	  break;
              	  case 15:
              	       type |= ptr[13];
              	       ptr = (PUCHAR)pVirtualAddr2;
                       temp = ptr[0];              	       
              	  break;
              	
              }	
     	  }
     	  else
     	  {
               type |= ptr[13];
               temp = ptr[15];     	  	
     	  }	    
          
         
         if(type = 0x0800)  // IP packet
            tos = temp;
     }

     return tos;	
	
}	

#ifdef WMM_USE_NDIS_EXT

/*
typedef struct _NDIS_PACKET_8021Q_INFO {
    union {
        struct {
            UINT32  UserPriority:3;
            UINT32  CanonicalFormatId:1;
            UINT32  VlanId:12;
            UINT32  Reserved:16;
        } TagHeader;
        PVOID  Value;
    };
} NDIS_PACKET_8021Q_INFO, *PNDIS_PACKET_8021Q_INFO;

// the value is deinfed in XP DDK ndis.h. MSFT will provide a formal header file later.
#define Ieee8021QInfo       6
*/
UCHAR wmm_get_pkt_priority( PNDIS_PACKET Packet )
{
    PNDIS_PACKET_EXTENSION pNdisExt;
    UINT        nPriority;

    pNdisExt = NDIS_PACKET_EXTENSION_FROM_PACKET( Packet );
    if ( pNdisExt )
    {
        nPriority = (UINT) pNdisExt->NdisPacketInfo[Ieee8021pPriority];
        //DbgWmmMsg( (L"WMM- pkt priority=%d\n", nPriority) );
        return nPriority;
    }
    else
    {
        return 0;
    }
}

UCHAR wmm_get_pkt_priority_2( PNDIS_PACKET Packet )
{
    //PNDIS_PACKET_EXTENSION  pExtInfo;
    PNDIS_PACKET_8021Q_INFO pQosInfo;

    pQosInfo = NULL;
    pQosInfo = NDIS_PER_PACKET_INFO_FROM_PACKET( Packet, Ieee8021QInfo );

/*
    pExtInfo = NDIS_PACKET_EXTENSION_FROM_PACKET( Packet );
    if ( pExtInfo )
        pQosInfo = pExtInfo
*/
    if ( pQosInfo )
        {
            //DbgWmmMsg( (L"WMM- pkt priority=%d\n", pQosInfo->TagHeader.UserPriority) );
            return pQosInfo->TagHeader.UserPriority;
        }
    else
        {
            //DbgWmmMsg( (L"WMM- pkt priority=No 8021q info\n") );
            return 0;
        }
}
#endif // WMM_USE_NDIS_EXT

// tt ++ wmm
VOID wmm_update_status_from_cmd_resp( PMRVDRV_ADAPTER Adapter )
{
    int     i;
    PHostCmd_DS_802_11_WMM_GET_STATUS   pCmdResp;

    pCmdResp = (PHostCmd_DS_802_11_WMM_GET_STATUS) Adapter->CurCmd->BufVirtualAddr;

    for (Adapter->WmmDesc.acstatus=0, i=0; i<MAX_AC_QUEUES; i++)
    {
        Adapter->WmmDesc.acstatus |= (pCmdResp->Status[i].Disabled ? 1 : 0) << (MAX_AC_QUEUES - 1 - i);
    }
    
    DbgWmmMsg( (L"+wmm+ WMM status change: %d %d %d %d [acstatus=0x%x]\n", 
        pCmdResp->Status[0].Disabled, pCmdResp->Status[1].Disabled, 
        pCmdResp->Status[2].Disabled, pCmdResp->Status[3].Disabled,
        Adapter->WmmDesc.acstatus ) );

}

/*
    nAC = AC_PRIO_BE to AC_PRIO_VO, if = 0xff, means set policy for all AC
*/
VOID wmm_set_ack_policy( PMRVDRV_ADAPTER Adapter, UCHAR nAC, UCHAR nPolicy )
{
    OID_MRVL_DS_WMM_ACK_POLICY AckPolicy;

    if ( nAC >= AC_PRIO_BE && nAC <= AC_PRIO_VO )
    {
        AckPolicy.AC = nAC;
        AckPolicy.AckPolicy = nPolicy;
        
        DbgWmmMsg( (L"+wmm+ Set wmm Ack policy for AC=%d, policy=%d\n", nAC, nPolicy) );
        PrepareAndSendCommand(
                Adapter,
                HostCmd_CMD_802_11_WMM_ACK_POLICY,
                HostCmd_ACT_SET,
                HostCmd_OPTION_USE_INT,
                (NDIS_OID)0,
                HostCmd_PENDING_ON_NONE,
                0,
                FALSE,
                NULL,
                NULL,
                NULL,
                &AckPolicy);
    }
    else if ( nAC == 0xff )
    {
        DbgWmmMsg( (L"+wmm+ Set wmm Ack policy for all AC, !!NOT implement yet!!\n") );
    }
    else
    {
        DbgWmmMsg( (L"+wmm+ Wrong AC (%d) for setting Ack policy\n", nAC) );
    }
    
}

NDIS_STATUS wmm_set_sleep_period( PMRVDRV_ADAPTER Adapter, USHORT nPeriod )
{
    OID_MRVL_DS_WMM_SLEEP_PERIOD    OidSleepPeriod;
    NDIS_STATUS         nStatus;
    
    if ( nPeriod < 10 || nPeriod > 60 )
        return NDIS_STATUS_FAILURE;

    OidSleepPeriod.period = nPeriod;

    DbgWmmMsg( (L"+wmm+ Set SLEEP PERIOD = %d ms\n", OidSleepPeriod.period ) );

    nStatus = PrepareAndSendCommand(
                Adapter,
                HostCmd_CMD_802_11_SLEEP_PERIOD,
                HostCmd_ACT_SET,
                HostCmd_OPTION_USE_INT,
                (NDIS_OID)0,
                HostCmd_PENDING_ON_NONE,
                0,
                FALSE,
                NULL,
                NULL,
                NULL,
                &OidSleepPeriod);

    if ( nStatus == NDIS_STATUS_SUCCESS )
        Adapter->sleepperiod = nPeriod;

    return nStatus;
    
}
// tt --

#if 0          
#ifdef WMM_ADD_PKT   
#define wmm_map_and_add_pkt TxPacketEnQueue
#else
void wmm_map_and_add_pkt(PMRVDRV_ADAPTER Adapter, PNDIS_PACKET packet)
{
	UCHAR	tos, ac;

        tos = wmm_get_tos(packet);
	ac = wmm_tos2ac[Adapter->WmmDesc.acstatus][tos];

	/* Access control of the current packet not the Lowest */
	if(ac > AC_PRIO_BE)
		Adapter->WmmDesc.fw_notify = 1;

	InsertQNodeAtTail(&Adapter->WmmDesc.TxPktQ[ac], packet);
}
#endif

void wmm_pop_highest_prio_skb(PMRVDRV_ADAPTER Adapter)
{
	int i;
	PQ_KEEPER       Q;

	for(i = AC_PRIO_VO; i >= AC_PRIO_BE; --i)
	{
	   Q = &Adapter->WmmDesc.TxPktQ[i];	
	    if(!IsQEmpty(Q))
	   {
		Adapter->CurrentTxPkt = (PNDIS_PACKET)PopFirstQNode(Q);
		break;
	   }
	}
}
#endif

#endif // WMM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -