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

📄 ar6000_cf.c

📁 Atheros Communications AR6001 WLAN Driver for SDIO installation Read Me March 26,2007 (based on
💻 C
字号:
//------------------------------------------------------------------------------
// <copyright file="ar6000_cf.c" company="Atheros">
//    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 HIF CF source
//
// Author(s): ="Atheros"
//==============================================================================

#include <windows.h>
#include <nkintr.h>
#include "giisr.h"
#include "ar6000_cf.h"
#include "ar6000_cf_internal.h"
#include "bus_driver.h"
#include "osapi.h"

CF_DEVICE   *cfDevice = NULL;
CF_FUNCTION  cfFunction;
#ifdef CEPC
HANDLE       isrHandler;
GIISR_INFO   Info;
PVOID	     giisrMappedAddress;
#endif // CEPC

extern void InterruptDone(DWORD);
extern boolean printMask;

NDIS_STATUS
busDriverInit (NDIS_HANDLE miniportHandle, 
               NDIS_HANDLE wrapperConfigurationContext, 
               A_UINT32   sysIntr,
               BUS_DRIVER_HANDLE *busDriverHandle)
{
    PNDIS_RESOURCE_LIST pNdisResourceList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR pResourceDesc;
    NDIS_PHYSICAL_ADDRESS           physicalAddress;
    A_UINT32						bufferSize;
    A_UINT32						dwResourceCount;
    NDIS_STATUS                     status=NDIS_STATUS_FAILURE;
    A_UINT32						addressSpace;

    *busDriverHandle = NULL;
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
                        "ar6000CFBusInit: Enter \n");

    cfDevice = A_MALLOC(sizeof(CF_DEVICE));
    if (cfDevice == NULL) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,
            "ar6000CFBusInit: Allocate Memory for CF_DEVICE failed\n");
        return status; 
	}
    A_MEMZERO(cfDevice,sizeof(CF_DEVICE));

    cfDevice->miniportHandle = miniportHandle;
    cfDevice->wrapperConfigurationContext=wrapperConfigurationContext;

	pNdisResourceList = NULL;
	bufferSize = 0;

	//	First call is just to determine buffer size
    NdisMQueryAdapterResources(
            &status,
            wrapperConfigurationContext,
            pNdisResourceList,
            &bufferSize);

    pNdisResourceList = A_MALLOC(bufferSize);

    if (pNdisResourceList == NULL) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR, 
            "ar6000CFBusInit: AllocateMemory for NDIS_RESOURCE_LIST failed\n");
        A_FREE(cfDevice);
        return NDIS_STATUS_FAILURE;
    }

    NdisMQueryAdapterResources(
            &status,
            wrapperConfigurationContext,
            pNdisResourceList,
            &bufferSize);

    if (status != NDIS_STATUS_SUCCESS) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR, 
            "ar6000CFBusInit: NdisMQueryAdapterResources failed \n");
        A_FREE(pNdisResourceList);
        A_FREE(cfDevice);
        return status; 
    }

    /* Search for I/O address and IRQ in assigned resources. */
    
    dwResourceCount = pNdisResourceList->Count;
    pResourceDesc = &(pNdisResourceList->PartialDescriptors[0]);

    while (dwResourceCount--) {
        switch(pResourceDesc->Type) {
            case CmResourceTypeInterrupt:
                cfDevice->interruptNumber = 
                    pResourceDesc->u.Interrupt.Vector;
                HIF_DEBUG_PRINTF(ATH_LOG_INF,
                    "ar6000CFBusInit: Interrupt Number = %u\n", cfDevice->interruptNumber);
                break;

            case CmResourceTypeMemory:
                cfDevice->memLen = pResourceDesc->u.Memory.Length;
                cfDevice->deviceMemBase = pResourceDesc->u.Memory.Start.LowPart;
                HIF_DEBUG_PRINTF(ATH_LOG_INF,
				    "ar6000CFBusInit: Physical Address = %x Length = %x\n", 
                        cfDevice->deviceMemBase,cfDevice->memLen);
                break;
        
            default:
                HIF_DEBUG_PRINTF(ATH_LOG_ERR,
                    "ar6000CFBusInit: Unexpected assigned resource type %u\n", 
                    pResourceDesc->Type);
                break;
        }
        pResourceDesc++;
    }

    A_FREE(pNdisResourceList);

    cfDevice->sysIntr =  sysIntr;
    HIF_DEBUG_PRINTF(ATH_LOG_INF,
        "ar6000CFBusInit: sysIntr = %u\n", cfDevice->sysIntr);
    
    NdisSetPhysicalAddressLow(physicalAddress, cfDevice->deviceMemBase);
    NdisSetPhysicalAddressHigh(physicalAddress, 0);

    cfDevice->ndisMapped = 1;
    status = NdisMMapIoSpace((PVOID *)&cfDevice->mappedMemBase,
                            cfDevice->miniportHandle,
                            physicalAddress,
                            cfDevice->memLen);
    if (status != NDIS_STATUS_SUCCESS) {
		HIF_DEBUG_PRINTF(ATH_LOG_ERR,
				"ar6000CFBusInit: NdisMmapIoSpace failed.. Trying MmMapIoSpace \n");
        /* NdisMmapIoSpace fails sometimes in WINCE, type MmMapIoSpace */
	    cfDevice->mappedMemBase = (A_UINT32) MmMapIoSpace(physicalAddress,
                                                          cfDevice->memLen,
                                                          FALSE);
        if (!cfDevice->mappedMemBase) {
            HIF_DEBUG_PRINTF(ATH_LOG_ERR,
                "ar6000CFBusInit: MmMapIoSpace failed \n");
            A_FREE(cfDevice);
            return NDIS_STATUS_FAILURE;
        } 
        cfDevice->ndisMapped = 0;
    } 

	 addressSpace = 0;
#ifdef CEPC
#if (UNDER_CE==600) 
	giisrMappedAddress = (PVOID)cfDevice->mappedMemBase;
#else
    if (!TransBusAddrToStatic(PCIBus,
						 0,
						 physicalAddress,
						 cfDevice->memLen,
						 &addressSpace,
						 &giisrMappedAddress)) 
    {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,
                "ar6000CFBusInit : TransBusAddrToStatic failed \n");
        A_FREE(cfDevice);
        return NDIS_STATUS_FAILURE;
    }
#endif //UNDER_CE
#endif //CEPC

    *busDriverHandle = (BUS_DRIVER_HANDLE)cfDevice;
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
                        "ar6000CFBusInit: Exit \n");
    return NDIS_STATUS_SUCCESS;
}


void
busDriverIsr (BUS_DRIVER_HANDLE busDriverHandle,A_BOOL *callDsr)
{
    CF_DEVICE *cfDevice;

    cfDevice = (CF_DEVICE *)busDriverHandle;
#ifdef DEBUG
    printMask = FALSE;
#endif //DEBUG
    if (cfDevice->interruptRegistered == FALSE) {
        InterruptDone(cfDevice->sysIntr);
        *callDsr = FALSE;
    } else {
	    cfFunction.pIsr((CF_DEVICE_HANDLE)cfDevice,callDsr);
    }
#ifdef DEBUG
    printMask = TRUE;
#endif //DEBUG
    return;
}

void
busDriverDsr (BUS_DRIVER_HANDLE busDriverHandle)
{
    CF_DEVICE *cfDevice;

    cfDevice = (CF_DEVICE *)busDriverHandle;
    cfFunction.pDsr((CF_DEVICE_HANDLE)cfDevice);
    return;
}

void
busDriverShutdown (BUS_DRIVER_HANDLE busDriverHandle)
{
    CF_DEVICE *cfDevice;

    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "ar6000CFShutdown: Enter \n");
    
    cfDevice = (CF_DEVICE *)busDriverHandle;
    
    // Remove the mapped space
    if (cfDevice->ndisMapped) {
        NdisMUnmapIoSpace(cfDevice->miniportHandle,
                          (PVOID)cfDevice->mappedMemBase,
                          cfDevice->memLen);
    } else {
        MmUnmapIoSpace((PVOID)cfDevice->mappedMemBase,
                       cfDevice->memLen);
    }
    A_FREE(cfDevice);
    cfDevice = NULL;
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "ar6000CFShutdown: Exit \n");
	return;
}

#ifdef POLL

A_UINT32 poll;

DWORD cfPollThread(LPVOID Context)
{
    CF_DEVICE    *cfDevice;
    A_BOOL       callDsr;

    cfDevice = (CF_DEVICE *)Context;

	while (poll) {
        busDriverIsr((BUS_DRIVER_HANDLE)cfDevice, &callDsr);
        if (callDsr) {
            busDriverDsr((BUS_DRIVER_HANDLE)cfDevice);
        }
        Sleep(1);
	} 

    return 0;
}

void startPollThread(CF_DEVICE *cfDevice)
{
    HANDLE hThread;

    poll = 1;
    hThread = CreateThread(NULL, 0, 
		        cfPollThread, (LPVOID)cfDevice, 0, NULL);
    CeSetThreadPriority(hThread, 200);
    CloseHandle(hThread);
    
    return;
}

void stopPollThread(CF_DEVICE *cfDevice)
{
    poll = 0;
}
#endif

A_STATUS
CF_MaskInterrupt(CF_DEVICE_HANDLE cfHandle) {
    CF_DEVICE    *cfDevice;

    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
                        "CF_MaskInterrupt \n");

    cfDevice = (CF_DEVICE *)cfHandle;
#ifdef POLL
    stopPollThread(cfDevice);
#else
    NdisMDeregisterInterrupt(&cfDevice->interruptObject);

#ifdef CEPC
    if (isrHandler) {
        FreeIntChainHandler(isrHandler);
    }
#endif // CEPC
#endif
    
    return A_OK;
}

A_STATUS
CF_UnMaskInterrupt(CF_DEVICE_HANDLE cfHandle) {
    CF_DEVICE    *cfDevice;
#ifndef POLL
    NDIS_STATUS   ndisStatus;
#endif
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
				"CF_UnMaskInterrupt \n");
	cfDevice = (CF_DEVICE *)cfHandle;
	
#ifdef POLL
    startPollThread(cfDevice);
#else
#ifdef CEPC
    isrHandler = LoadIntChainHandler(TEXT("giisr.dll"),TEXT("ISRHandler"),(BYTE)cfDevice->interruptNumber);
    if (!isrHandler) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,"CF_UnMaskInterrupt: Load int chain handler failed \n");
        return A_ERROR;
	}
	memset (&Info,0,sizeof(Info));
    Info.SysIntr = cfDevice->sysIntr;
    Info.CheckPort = TRUE;
    Info.PortIsIO = FALSE;
    Info.UseMaskReg = TRUE;
    Info.PortSize = sizeof(BYTE);

	Info.PortAddr = (DWORD)giisrMappedAddress + 0x00000400;
	Info.MaskAddr = (DWORD)giisrMappedAddress + 0x00000418;

	if (!KernelLibIoControl(isrHandler,IOCTL_GIISR_INFO,&Info,sizeof(Info),NULL,0,NULL))  {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,"CF_UnMaskInterrupt: KernelLibIoControl failed  \n");
		return A_ERROR;
    }
	
#endif // CEPC
    ndisStatus = NdisMRegisterInterrupt(&cfDevice->interruptObject,
                                    cfDevice->miniportHandle,
                                    cfDevice->interruptNumber,
                                    0, TRUE, TRUE, 0);

    if (ndisStatus != NDIS_STATUS_SUCCESS) { 
        return A_ERROR;
    }
    
#endif
    cfDevice->interruptRegistered= TRUE;

    return A_OK;
}

A_STATUS
CF_RegisterFunction (CF_FUNCTION *function)
{
    cfFunction.pName = function->pName;
    cfFunction.pProbe = function->pProbe;
    cfFunction.pRemove = function->pRemove;
    cfFunction.pIsr = function->pIsr;
    cfFunction.pDsr = function->pDsr;
    cfFunction.pInterruptPending = function->pInterruptPending;
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
            "CF_RegisterFunction \n");

    if (cfDevice == NULL) return A_ERROR;

    cfFunction.pProbe((CF_DEVICE_HANDLE)cfDevice);

    return A_OK;
}

A_STATUS
CF_UnregisterFunction (CF_FUNCTION *function)
{
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
            "CF_UnregisterFunction \n");

    AR_DEBUG_ASSERT(cfDevice != NULL);
    cfFunction.pRemove((CF_DEVICE_HANDLE)cfDevice);

    return A_OK;
}

static A_STATUS 
CF_BusRequest_8(CF_DEVICE_HANDLE cfHandle, CF_REQUEST *pReq)
{
    volatile A_UCHAR     *data, *base;
    A_UINT32     len, i;
    CF_DEVICE    *device;

    device = (CF_DEVICE *)cfHandle;

    if (device == NULL || pReq == NULL) {
        return A_ERROR;
    }

    data = (A_UCHAR *)pReq->pDataBuffer;
    base = (A_UCHAR *)(device->mappedMemBase + pReq->address);
    len = pReq->length;

    HIF_DEBUG_PRINTF(ATH_LOG_TRC,"CF_BusRequest_8 \n");

    if (pReq->flags & CFREQ_FLAGS_DATA_WRITE) {
        if (pReq->flags & CFREQ_FLAGS_FIXED_ADDRESS) {
            for (i = 0; i < len; i++) {
                *base = *data;
                data++;
            }
        }  else {
            for (i = 0; i < len; i++) {
                *base = *data;
                base++;
                data++;
            }
        }
    } else {
        if (pReq->flags & CFREQ_FLAGS_FIXED_ADDRESS) {
            for (i = 0; i < len; i++) {
                *data = *base;
                data++;
            }
        } else {
            for (i = 0; i < len; i++) {
                *data = *base;
                base++;
                data++;
            }
        }
    }
    
    return A_OK;
}

static A_STATUS 
CF_BusRequest_16(CF_DEVICE_HANDLE cfHandle, CF_REQUEST *pReq)
{
    volatile A_UINT16     *data, *base;
    A_UINT32     len, i;
    CF_DEVICE    *device;

    device = (CF_DEVICE *)cfHandle;

    if (device == NULL || pReq == NULL) {
        return A_ERROR;
    }

    HIF_DEBUG_PRINTF(ATH_LOG_TRC,"CF_BusRequest_16 \n");

    data = (A_UINT16 *)pReq->pDataBuffer;
    base = (A_UINT16 *)(device->mappedMemBase + pReq->address);
    len = pReq->length;

    /*
     * Assert on odd address and odd length 
     */
    
    AR_DEBUG_ASSERT(!(((A_UINT32)data)%2));
    AR_DEBUG_ASSERT(!(((A_UINT32)base)%2));
    AR_DEBUG_ASSERT(!(len%2));
    
    len = len/2;

    if (pReq->flags & CFREQ_FLAGS_DATA_WRITE) {
        if (pReq->flags & CFREQ_FLAGS_FIXED_ADDRESS) {
            for (i = 0; i < len; i++) {
                *base = *data;
                data++;
            }
        }  else {
            for (i = 0; i < len; i++) {
                *base = *data;
                base++;
                data++;
            }
        }

    } else {
        if (pReq->flags & CFREQ_FLAGS_FIXED_ADDRESS) {
            for (i = 0; i < len; i++) {
                *data = *base;
                data++;
            }
        } else {
            for (i = 0; i < len; i++) {
                *data = *base;
                base++;
                data++;
            }
        }
    }
    return A_OK;
}

A_STATUS
CF_BusRequest(CF_DEVICE_HANDLE cfHandle, CF_REQUEST *pReq,A_UINT32 bits)
{
    A_STATUS status = A_ERROR;
    
    switch (bits) {
    case 8:
        status = CF_BusRequest_8(cfHandle, pReq);
        break;
    case 16:
        status = CF_BusRequest_16(cfHandle, pReq);
        break;
    default:
        AR_DEBUG_ASSERT(0);
        break;
    }
    return status;
}

⌨️ 快捷键说明

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