📄 miniport.c
字号:
NDIS_STATUS iStatus;
ULONG i;
static ULONG ulReset = 0;
DBG_LEV1(("iMiniportReset(), count = %d%s\n", ++ulReset,
(psCFG->boResetEnable? "": " (disabled)") ));
if (psCFG->boResetEnable == FALSE)
{
*AddressingReset = FALSE;
psAdapter->boNeedReset = FALSE;
vHALwriteRegister( psHAL, HAL_ADDR_interrupt_host_to_arm, 0xFF );
return NDIS_STATUS_SUCCESS;
}
#ifdef TARGET_ASIC_CA
psHAL->boNDISRequestedReset = TRUE;
if (psAdapter->boResetInProgress == FALSE)
{
// Disable interrupt.
vHALdisableInterrupt( &psAdapter->sHAL );
psAdapter->boResetInProgress = TRUE;
psAdapter->boNeedReset = FALSE;
// Stop the device.
vHALstop( &psAdapter->sHAL );
// Flush TX queues
vHALflushTxQueues( psAdapter );
// Change back to stopped state.
psAdapter->eNetState = NET_STOPPED;
psAdapter->boSendNoResourcesFlag = FALSE;
psAdapter->ulRxIndicatedPending = 0;
// Clear Bssid List (may be switching between 802.11a & 802.11b/g modes)
for ( i = 0; i<psWlan->ulNumOfBssidBuf; i++ )
{
psWlan->sBssidList[i].llTimeStamp = 0;
}
// Set media state to disconnected.
if ( psAdapter->eMediaState == NdisMediaStateConnected )
{
vENDindicateConnectionStatus( psAdapter, NdisMediaStateDisconnected );
}
// Clear pending OID request.
if ( psPendingOID->ulOid )
{
psPendingOID->ulOid = 0;
NdisMQueryInformationComplete( psAdapter->hMiniportAdapterHandle, NDIS_STATUS_FAILURE );
}
// If scan in progress, clear the flag.
if ( psWlan->boScanInProgress )
{
psWlan->boScanInProgress = FALSE;
}
// Clear change network structure.
NdisZeroMemory( &psWlan->sChangeNetwork, sizeof(CHANGE_NETWORK) );
// Reset filter.
psWlan->boNonEAPOLPktFilter = FALSE;
// Set radio flag to on.
psWlan->boRadioOn = TRUE;
// Set a timer (700ms) to complete the reset.
NdisMSetTimer( &psAdapter->sResetTimer, 700 );
}
*AddressingReset = TRUE;
iStatus = NDIS_STATUS_PENDING;
#else
psAdapter->boNeedReset = FALSE;
*AddressingReset = FALSE;
iStatus = NDIS_STATUS_SUCCESS;
#endif // TARGET_ASIC_CA
return iStatus;
}
/*****************************************************************************
**
** NAME boMiniportCheckForHang
**
** PARAMETERS MiniportAdapterContext Pointer to Adapter context.
**
** RETURNS TRUE if NIC is not operating, otherwise FALSE.
**
** DESCRIPTION This timer function checks the state of the NIC.
**
******************************************************************************/
BOOLEAN
boMiniportCheckForHang(
IN NDIS_HANDLE MiniportAdapterContext)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
PWLAN_CONTEXT psWlan = &psAdapter->sWlan;
PHAL_CONTEXT psHAL = &psAdapter->sHAL;
PHAL_CARD_STATUS psCardStatus = &psHAL->sCardStatus;
static BOOLEAN boFirst = TRUE;
static ULONG i = 0;
// Update card status and other info if needed.
if ( boFirst && psHAL->eState == HAL_RUNNING )
{
boFirst = FALSE;
// Send a Get MIB (MIB_SW_VERSION) request to update card status.
vHALsendGetMibReq( psHAL, MIB_SW_VERSION );
// Send a Get MIB (MIB_UWA_PROGRAM_VER) request to update card status.
vHALsendGetMibReq( psHAL, MIB_UWA_PROGRAM_VER );
// Send a Get MIB (MIB_OPERATIONAL_RATE_SET) request to Target.
vHALsendGetMibReq( psHAL, MIB_OPERATIONAL_RATE_SET );
}
// Check RSSI.
if ( psAdapter->eNetState == NET_CONNECTED && psWlan->ulInfraMode == Ndis802_11Infrastructure )
{
if ( (psWlan->ulPowerMode == Ndis802_11PowerModeCAM) || (i % 10 == 0) )
{
vHALsendGetRssiReq( psHAL, (IEEE_ADDR *)psWlan->ucBSSID );
}
i ++;
}
else
{
psWlan->lRssi = 0;
i = 0;
}
// Check Tx REQ message hang.
if ( psHAL->boTxReqMsgFlag == TRUE )
psHAL->boTxReqMsgFlag ++;
else if ( psHAL->boTxReqMsgFlag )
{
DBG_LEV1(("Tx REQ message hung!\n"));
psAdapter->boNeedReset = TRUE;
}
// MIC error handling timer.
if ( psWlan->eMicErrorState )
{
if ( psAdapter->eNetState == NET_DISCONNECTED &&
psWlan->eMicErrorState != MICERR_DISASSOC )
{
DBG_LEV1(("Disconnected, current MIC error state %d.\n", psWlan->eMicErrorState));
// If disconnected, back to initial state if only one MIC error indicated;
// go to disassociated state (remain disassociated for 60 seconds) if two
// MIC errors indicated within 60 seconds.
if ( psWlan->eMicErrorState == MICERR_ONEERROR )
psWlan->eMicErrorState = MICERR_INIT;
else
{
psWlan->eMicErrorState = MICERR_DISASSOC;
psWlan->ulMicErrorTimer = 0;
psWlan->boNonEAPOLPktFilter = FALSE;
}
}
if ( psWlan->eMicErrorState == MICERR_ONEERROR ||
psWlan->eMicErrorState == MICERR_DISASSOC )
{
// If timeout (60 seconds), back to initial state.
psWlan->ulMicErrorTimer += END_CHECKFORHANG_INTERVAL;
if ( psWlan->ulMicErrorTimer >= END_MIC_ERROR_TIMEOUT )
{
DBG_LEV1(("Timeout, back to initial state, %d.\n", psWlan->eMicErrorState));
psWlan->eMicErrorState = MICERR_INIT;
}
}
}
return (psAdapter->boNeedReset);
}
/*****************************************************************************
**
** NAME uiPriorityIndex()
**
** PARAMETERS Pointer to NDIS_PACKET
**
** RETURNS 802.11 WMM packet priority (0-3).
**
** DESCRIPTION Queries the 802.1P packet priority and maps to an 802.11
** priority.
**
******************************************************************************/
static UINT uiPriorityIndex( IN PNDIS_PACKET Packet )
{
UINT uiPriority;
// See table 14 of the WMM Specification for mapping of 802.1D
// priorities to WMM priorities
uiPriority = (IEEE8021PPRIORITY)NDIS_PER_PACKET_INFO_FROM_PACKET(
Packet,
Ieee8021pPriority);
if (uiPriority >= 6)
{
return 3;
}
if (uiPriority >= 4)
{
return 2;
}
if (uiPriority == 0 || uiPriority == 3)
{
return 1;
}
return 0;
}
/*****************************************************************************
**
** NAME vMiniportSendPackets
**
** PARAMETERS MiniportAdapterContext Pointer to Adapter context.
** PacketArray Array of PNDIS_PACKETS.
** NumberOfPackets Number of packets in the array.
**
** RETURNS na
**
** DESCRIPTION This routine is the entry point to send packets on Miniport.
** Status will be set to each packet in the PacketArray.
**
******************************************************************************/
VOID
vMiniportSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
PWLAN_CONTEXT psWlan = &psAdapter->sWlan;
PHAL_CONTEXT psHAL = &psAdapter->sHAL;
UINT uiLoop;
BOOLEAN boFilter = FALSE;
DBG_LEV2(("vMiniportSendPackets(), num = %d\n", NumberOfPackets));
// If no connection, block any further Tx.
if ( psAdapter->eNetState != NET_CONNECTED )
{
DBG_LEV2(("Block Tx while no connection!\n"));
for ( uiLoop=0; uiLoop < NumberOfPackets; uiLoop++ )
{
NDIS_SET_PACKET_STATUS( PacketArray[uiLoop], NDIS_STATUS_FAILURE );
}
return;
}
for ( uiLoop=0; uiLoop < NumberOfPackets; uiLoop++ )
{
// Only 802.1X EAPOL packets may be sent if filter on.
if ( psWlan->boNonEAPOLPktFilter == TRUE )
{
boFilter = boENDcheckFilterPacket( PacketArray[uiLoop] );
// Adjust MIC error state after sending the next 802.1X EAPOL packet.
if ( psWlan->eMicErrorState == MICERR_FILTERON && !boFilter )
{
psWlan->eMicErrorState = MICERR_TXEAPOL;
DBG_LEV1(("Send the next 802.1X EAPOL packet.\n"));
}
}
if ( !boFilter )
{
UINT uiIdx;
UINT uiNxtTail;
uiIdx = uiPriorityIndex(PacketArray[uiLoop]);
uiNxtTail = (psHAL->ulQueueTails[uiIdx] + 1) % HAL_TX_QUEUE_LEN;
if (uiNxtTail != psHAL->ulQueueHeads[uiIdx])
{
// room in queue ...
psHAL->apTxQueues[uiIdx][uiNxtTail] = PacketArray[uiLoop];
NDIS_SET_PACKET_STATUS(PacketArray[uiLoop], NDIS_STATUS_PENDING);
psHAL->ulQueueTails[uiIdx] = uiNxtTail;
}
else
{
DBG_LEV3(("Full TX queue\n"));
// queue full ...
for (; uiLoop < NumberOfPackets; uiLoop++ )
{
NDIS_SET_PACKET_STATUS( PacketArray[uiLoop], NDIS_STATUS_RESOURCES );
}
}
}
else
{
NDIS_SET_PACKET_STATUS( PacketArray[uiLoop], NDIS_STATUS_SUCCESS );
}
}
if ( !psAdapter->boSendNoResourcesFlag )
{
// push to imem as many as possible
while (bHAL_PickAndSendPacket(psAdapter) == TRUE);
}
}
/*****************************************************************************
**
** NAME vMiniportReturnPacket
**
** PARAMETERS MiniportAdapterContext Pointer to Adapter context.
** psPacket Pointer to packet being returned.
**
** RETURNS na
**
** DESCRIPTION This function is called by NDIS to return a packet to driver
** after a call to NdisMIndicateReceivePacket() returned pending.
**
******************************************************************************/
VOID
vMiniportReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET psPacket)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
PNDIS_BUFFER pCurbuf;
PUCHAR pucDataBuffer;
DBG_LEV3(("vMiniportReturnPacket()\n"));
if ( psPacket )
{
NdisQueryPacket( psPacket, NULL, NULL, &pCurbuf, NULL );
(ULONG)pucDataBuffer = *(PULONG)(psPacket->MiniportReserved);
// Free allocated NDIS buffer.
NdisFreeBuffer( pCurbuf );
// Free allocated NDIS packet.
NdisFreePacket( psPacket );
// Free allocated buffer memory.
NdisFreeMemory( pucDataBuffer, psAdapter->sHAL.ulTxRxBufSize + 31, 0 );
psAdapter->ulRxIndicatedPending--;
}
}
/*****************************************************************************
**
** NAME iENDgetDeviceHandleSDIO
**
** PARAMETERS psAdapter Pointer to Adapter context.
** hRegistryHandle Registry handle.
**
** RETURNS NDIS_STATUS_SUCCESS or error code.
**
** DESCRIPTION This function reads active path key and gets SDIO device handle.
**
******************************************************************************/
NDIS_STATUS
iENDgetDeviceHandleSDIO( OUT PEND_CONTEXT psAdapter, IN NDIS_HANDLE hRegistryHandle )
{
NDIS_STATUS iStatus;
NDIS_STRING nsActivePathKey = NDIS_STRING_CONST("ActivePath");
PNDIS_CONFIGURATION_PARAMETER psConfigParm;
NDIS_CONFIGURATION_PARAMETER sWriteConfigParm;
PVOID pvBuffer = NULL;
// Read active path key.
NdisReadConfiguration( &iStatus, &psConfigParm, hRegistryHandle, &nsActivePathKey, NdisParameterString );
if ( iStatus == NDIS_STATUS_SUCCESS )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -