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

📄 car6k.cpp

📁 Atheros Communications AR6001 WLAN Driver for SDIO installation Read Me March 26,2007 (based on
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// <copyright file="car6k.cpp" company="Atheros and Microsoft">
//    Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
//    Copyright (c) 2006 Atheros Corporation.  All rights reserved.
//
//    The use and distribution terms for this software are covered by the
//    Microsoft Limited Permissive License (Ms-LPL) 
//    http://www.microsoft.com/resources/sharedsource/licensingbasics/limitedpermissivelicense.mspx 
//    which can be found in the file MS-LPL.txt at the root of this distribution.
//    By using this software in any fashion, you are agreeing to be bound by
//    the terms of this license.
//
//    You must not remove this notice, or any other, from this software.
// </copyright>
// 
// <summary>
//    Windows CE Wifi Driver for AR-6000
// </summary>
//------------------------------------------------------------------------------
//==============================================================================
// AR6000 NDIS Miniport class.
//
// Author(s): ="Atheros and Microsoft"
//==============================================================================

#include <windows.h>
#include <ndis.h>

#include "htc_internal.h"
#include "htc.h"
#include "hif.h"
#include "wmi_api.h"
#include "netbuf.h"
#include "ndisnetbuf.h"
extern "C" {
#include "bmi.h"
}

#include "cmini.hpp"
#include "c802_3mini.hpp"
#include "c802_11mini.hpp"
#include "car6k.hpp"
#include <pm.h>
#ifdef WINDOWS_MOBILE
#include <wrlspwr.h>
#include <winreg.h>
#endif
#include "osapi.h"

CAR6KMini::CAR6KMini()
{
	int i = 0;

	m_pHTCTarget   = NULL;
	m_tgtReady	   = false;
	m_HTCInited    = false;
	m_InitComplete = false;

	memset(m_PermanentAddress, 0, sizeof(m_PermanentAddress));
	memset(m_CurrentAddress, 0, sizeof(m_CurrentAddress));
	m_InfrastructureMode = Ndis802_11Infrastructure;
	m_AuthenticationMode = Ndis802_11AuthModeOpen;
	m_EncryptionStatus   = Ndis802_11EncryptionDisabled;

	m_RSSI         = 0;
	m_BitrateKpbs  = 54000;
	memset(m_ChannelList, 0, sizeof(m_ChannelList));
	m_cChannelList = 0;
	m_AssocReqLen = 0;
	m_AssocRespLen = 0;
	m_BeaconIeLen = 0;
	m_pAssocInfo = NULL;
	m_Halting = FALSE;

	m_AuthAlg = 0;

	m_pBSSIDList = NULL;
	m_cbBSSIDList = 0;
	m_pcbBSSIDListNeeded = NULL;

	m_pTransmitBufferArray = NULL;
	m_cbTransmitBufferArray = 0;
	m_TxPending = 0;
	m_RxPacketPool = NULL;


	for (i=0;i<4;i++) {
		memset(m_Key[i], 0, sizeof(m_Key[i]));
		m_cbKey[i] = 0;
		m_KeyIndex[i] = 0;
		m_KeyRSC[i] = 0;
	}

	m_NumDataEndpts = 0;
	m_RegCode = 0;
	m_TxPwr = 0;
	m_PowerState = NdisDeviceStateD0;
	
	//Default PowerMode set to Fast_PSP <--> REC_POWER
	m_80211_PowerMode = Ndis802_11PowerModeFast_PSP;
	//Default listen interval set to 10 beacon Intervals (100 TUs)
	m_ListenInterval = MIN_LISTEN_INTERVAL;

	m_NetworkTypeInUse = Ndis802_11OFDM24;
	m_RadioDisabled = FALSE;
	m_beaconInterval = 0;

#ifdef SUPPORT_WPA2
	m_pPMKID = NULL;
#endif

#ifdef NDIS_BUS_DRIVER
	m_pBusDriverHandle = NULL;
#endif

	m_PowerChangeEvent = NULL;
	m_ResumeWlanState = 1; // ON state
	m_LastSysState = POWER_STATE_ON;

	memset(&m_tgtStats, 0, sizeof(NDIS_802_11_STATISTICS));
	m_tgtStats.Length = sizeof(NDIS_802_11_STATISTICS);

	Init();
}

CAR6KMini::~CAR6KMini()
{
}

void 
CAR6KMini::Init()
{
	m_pWMI         = NULL;
	m_WMIReady     = false;
	m_HTCStarted   = false;

	m_Connected    = false;
	m_ConnectInProgress = false;
	m_ConnectedChannel  = 0;
	memset(m_PeerBSSID, 0, sizeof(m_PeerBSSID));

	m_WantToBeConnected = false;
	m_SSID.SsidLength = 0;
	m_WMIBssFilter  = NONE_BSS_FILTER;
	memset(m_SSID.Ssid, 0, sizeof(m_SSID.Ssid));

	m_GrpwiseCryptoIndex = 0;
	m_PairwiseCryptoType = NONE_CRYPT;
	m_GrpwiseCryptoType = NONE_CRYPT;

}

void
CAR6KMini::TargetAvailableEventHandler(
	HTC_TARGET      *pHTCTarget,
	HIF_DEVICE      *pHIFDevice)
//
//  This function processes an HTC_TARGET_AVAILABLE event indication
//  from the HTC layer.
//
{
	A_STATUS        status;

	m_pHTCTarget = pHTCTarget;
	m_pHIFDevice = pHIFDevice;

	NdisMSleep(1000000);

   	BMIInit();

   	status = BMIGetTargetId(m_pHIFDevice, &m_TargetId);
	if (A_OK != status) {
		goto done;
	}
	// the following code will display the version of firmware and driver
	// also it checks whether version mismatch between drier and firmware
	// incase of version mismatch, this will false the flag and return status failure
	// notification to NDIS
	{
		BYTE  byFirmwareMajor = 0;
		BYTE  byFirmwareMinor = 0;

		WORD wFirmware = m_TargetId >> 24;
		byFirmwareMajor = wFirmware >> 4;
		byFirmwareMinor = wFirmware & 0x0F;

		RETAILMSG (1,(L"FIRMWARE MAJOR VERSION ==> %x\n", byFirmwareMajor));
		RETAILMSG (1,(L"FIRMWARE MINOR VERSION ==> %x\n", byFirmwareMinor));

    }

	if (m_Config.defaultApp) {
		status = StartEndpoints();
		if (A_OK != status) {
			goto done;
		}
	}

	m_tgtReady = true;
done:
	NdisSetEvent(&m_tgtReadyEvent);

	return;
}

static void
AR6KTargetAvailableEventHandler(
	HTC_TARGET      *pHTCTarget, 
	HTC_ENDPOINT_ID  eid,
	HTC_EVENT_ID     evId, 
	HTC_EVENT_INFO  *evInfo, 
	void            *Context)
//
//  This function processes an HTC_TARGET_AVAILABLE event indication
//  from the HTC layer.
//
{
	CAR6KMini *pAdapter = (CAR6KMini *)Context;

	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +AR6KTargetAvailableEventHandler");

	pAdapter->TargetAvailableEventHandler(pHTCTarget,(HIF_DEVICE *)evInfo->buffer);

	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -AR6KTargetAvailableEventHandler");
}

void
CAR6KMini::TargetUnavailableEventHandler(
	HTC_TARGET      *pHTCTarget)
//
//  This function processes an HTC_TARGET_UNAVAILABLE event indication
//  from the HTC layer.
//
{
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +TargetUnavailableEventHandler");
	StopEndpoints();

	m_pHIFDevice = NULL;
	m_pHTCTarget = NULL;
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -TargetUnavailableEventHandler");
}

void
AR6KTargetUnavailableEventHandler(
	HTC_TARGET       *pHTCTarget,
	HTC_ENDPOINT_ID   eid,
	HTC_EVENT_ID      evId,
	HTC_EVENT_INFO   *evInfo, 
	void             *Context)
//
//  This function processes an HTC_TARGET_UNAVAILABLE event indication
//  from the HTC layer.
//
{
	CAR6KMini *pAdapter = (CAR6KMini *)Context;

	pAdapter->TargetUnavailableEventHandler(pHTCTarget);
}

void
CAR6KMini::ReceiveWMIControlPacket(
	HTC_EVENT_INFO  *evInfo)
//
//  This function processes data from an HTC_BUFFER_RECEIVED indication
//  on the WMI_CONTROL_MBOX endpoint.
//
{
	ndis_mini_buf_t *pb;

	NDIS_DEBUG_PRINTF(ATH_LOG_TRC,"AR6K: +ReceiveWMIControlPacket");

	pb = (ndis_mini_buf_t *)evInfo->cookie;
	ASSERT(pb);

	if (evInfo->status == A_OK) {
		// Append something to tail of buffer?
		a_netbuf_put(pb, (A_UINT8)(evInfo->actualLength + HTC_HEADER_LEN));

		// Remove HTC_HEADER_LEN bytes from the start of buffer
		a_netbuf_pull(pb, HTC_HEADER_LEN);

		Lock();

		wmi_control_rx((wmi_t *)m_pWMI, pb);

		Unlock();
	} else {
		NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - ReceiveWMIPacket Error in receiving : status = %x\n", evInfo->status);
	}

	a_netbuf_reset(pb);
    
	if ( A_OK != HTCBufferReceive(m_pHTCTarget, ENDPOINT1, a_netbuf_to_data(pb), AR6000_BUFFER_SIZE, pb)) {
		a_netbuf_free(pb);
	}
    
	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -ReceiveWMIControlPacket");
}

static void
AR6KHTCBufferReceivedEventHandler(
	HTC_TARGET      *target,
	HTC_ENDPOINT_ID  eid,
	HTC_EVENT_ID     evId,
	HTC_EVENT_INFO  *evInfo,
	void            *Context)
//
//  This function is called by the HTC layer to indicate that a buffer has been received,
//  that is an HTC_BUFFER_RECEIVED event has occurred.
//
//  evInfo contains information about the particular buffer that has been received.
//  In particular, evInfo->cookie contains the "cookie" parameter that was passed
//  to HTCBufferReceive.
//
//  The received buffer may contain either network traffic, or control information.
//
//
{
	CAR6KMini *pAdapter = (CAR6KMini *)Context;

	NDIS_DEBUG_PRINTF(ATH_LOG_INF, "AR6K: AR6KHTCBufferReceivedEventHandler MBOX=%u", eid);

      
	if (evInfo->status == A_ECANCELED) {
		ndis_mini_buf_t *pb = (ndis_mini_buf_t *)evInfo->cookie;
		NDIS_DEBUG_PRINTF(ATH_LOG_INF, "AR6K: AR6KHTCBufferReceivedEventHandler freeing buffer: pb = %x \n",(unsigned int)pb);
		a_netbuf_free(pb);
		return;
	}

	// Demux control packets from data traffic
	if (WMI_CONTROL_MBOX == eid)
	{
		// WMI Control packet (e.g. WMI_READY_EVENT)
		pAdapter->ReceiveWMIControlPacket(evInfo);
	}
	else
	{
		// WMI Data packet (e.g. IP data packet)
		pAdapter->ReceiveWMIDataPacket(evInfo);
	}
}

static void
AR6KHTCDataAvailableEventHandler(
	HTC_TARGET      *target,
	HTC_ENDPOINT_ID  eid,
	HTC_EVENT_ID     evId,
	HTC_EVENT_INFO  *evInfo,
	void            *Context)
//
//  This function is called by the HTC layer to indicate that an HTC_DATA_AVAILABLE
//  event has occurred. HTC generates this event indication when it has data available
//  to be received, but no buffers available to receive the data into.
//
//  This function will allocate buffers and pass them to HTC for use in receiving
//  the packet data. HTC will shortly thereafter send an HTC_BUFFER_RECEIVED
//  indication containing the packet data in these buffers.
//
{
	CAR6KMini *pAdapter = (CAR6KMini *)Context;

	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +AR6KHTCDataAvailableEventHandler");

	// Provide HTC with some more receive buffers
	// TODO - Impose some maximum cap
	pAdapter->AllocateHTCPacketBuffers(eid, AR6000_MAX_RX_BUFFERS);

	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: -AR6KHTCDataAvailableEventHandler");
}

void
CAR6KMini::HTCControlSendCompleted(
	PVOID cookie)
//
//  This function is called when an HTCBufferSend request completes on
//  the WMI_CONTROL_MBOX. It frees the buffer (that was allocated by WMI)
//  now that it is no longer needed.
//
{
	a_netbuf_free(cookie);
}

void
CAR6KMini::HTCBufferSentEvent(
	PVOID cookie)
//
//  This function is called when HTC is indicating that an HTCBufferSend request
//  has completed and we can free/reuse the buffer we passed in to the call.
//
{
	if ((PVOID)m_pTransmitBufferArray <= cookie 
	&&  cookie <= (PVOID)((PBYTE)m_pTransmitBufferArray + m_cbTransmitBufferArray))
	{
		// This was a transmit packet buffer that we sent
		HTCDataSendCompleted(cookie);
	}
	else
	{
		// This was a WMI control message. Usually they are WMI_CONTROL_MBOX,
		// but WMI_SYNC messages may also be sent on data MBOXes
		HTCControlSendCompleted(cookie);
	}
}

static void
AR6KHTCBufferSentEventHandler(
	HTC_TARGET        *target,
	HTC_ENDPOINT_ID    eid,
	HTC_EVENT_ID       evId,
	HTC_EVENT_INFO    *evInfo,
	void              *Context)
//
//  This function is called by the HTC layer to indicate that a buffer has been sent,
//  that is an HTC_BUFFER_SENT event has occurred.
//
//  evInfo contains information about the particular buffer that has been sent.
//  In particular, evInfo->cookie contains the "cookie" context that we passed in
//  to our call to HTCBufferSend.
//
{
	CAR6KMini *pAdapter = (CAR6KMini *)Context;
	PVOID      cookie = evInfo->cookie;

	pAdapter->HTCBufferSentEvent(cookie);
}

A_STATUS
CAR6KMini::RegisterEndpointEventHandlers(
	HTC_ENDPOINT_ID endPointId)


//
//  Connect the specified endpoint to its event handling functions for
//  Send and Receive events.
//
{
	A_STATUS        status;

	status = HTCEventReg(m_pHTCTarget, endPointId, HTC_BUFFER_RECEIVED, AR6KHTCBufferReceivedEventHandler, this);
	if (A_OK != status)
		goto done;

	status = HTCEventReg(m_pHTCTarget, endPointId, HTC_DATA_AVAILABLE, AR6KHTCDataAvailableEventHandler, this);
	if (A_OK != status)
		goto done;

	status = HTCEventReg(m_pHTCTarget, endPointId, HTC_BUFFER_SENT, AR6KHTCBufferSentEventHandler, this);
	if (A_OK != status)
		goto done;

	// Provide HTC with some initial receive buffers
	AllocateHTCPacketBuffers(endPointId, AR6000_MAX_RX_BUFFERS);

done:
    if (status != A_OK) {
	    NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: RegisterEndpointEventHandlers failed, error=%u\n", status);
    }
	return status;
}

A_STATUS
CAR6KMini::StartEndpoints()
//
//  This function initializes the endpoints used for communication
//  with the AR6000 SDIO card.
//
//  ENDPOINT1 is used for command/status packets.
//  ENDPOINT2 is used for data traffic (e.g. TCP/IP) packets.
//
{
	A_STATUS        status = A_ERROR;

	NDIS_DEBUG_PRINTF(ATH_LOG_TRC, "AR6K: +StartEndpoints");

	if (NULL == m_pHTCTarget)
		goto done;

#ifdef FLASH_18V
	// Change the flash access time for 1.8V flash to 150ns
	status = BMIWriteSOCRegister(m_pHIFDevice, 
                        0xac004004,
                        0x920100d1);
	if (A_OK != status) {
		goto done;
	}
#endif


	// Send a "BMI_DONE" command to the target, to get it out of
	// BMI mode and into normal operation.
	status = BMIDone(m_pHIFDevice);
	if (A_OK != status) {
		goto done;
	}
	
	if (!m_Config.byPassWmi) {
		NdisResetEvent(&m_WMIReadyEvent);
		m_pWMI = wmi_init(this);
		if (NULL == m_pWMI)
			goto done;
	}

	// Install handlers for HTC Send/Receive Events
	status = RegisterEndpointEventHandlers(ENDPOINT1);
	if (A_OK != status)
		goto done;

	status = RegisterEndpointEventHandlers(ENDPOINT2);
	if (A_OK != status)
		goto done;

#ifdef WMM
	status = RegisterEndpointEventHandlers(ENDPOINT3);
	if (A_OK != status)
		goto done;

	status = RegisterEndpointEventHandlers(ENDPOINT4);
	if (A_OK != status)
		goto done;
#endif //WMM

	status = HTCStart(m_pHTCTarget);
	if (A_OK != status) {
	    NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: HTCStart failed, error=%u\n", status);
		goto done;
    }

	m_HTCStarted = true;

	if (!m_Config.byPassWmi) {
		NdisWaitEvent(&m_WMIReadyEvent, AR6K_DEFAULT_MS_TO_WAIT_FOR_WMI_READY);
		if (!m_WMIReady) {
			NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - No WMI_READY event after %u ms, failing initialization\n", AR6K_DEFAULT_MS_TO_WAIT_FOR_WMI_READY);
			status = A_ERROR;
		}
	}

⌨️ 快捷键说明

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