www.pudn.com > CEWifiDriverAR6000-21374.zip > hif.c


//------------------------------------------------------------------------------ 
//  
//    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. 
// 
//    The software is licensed “as-is.”  
//    You must not remove this notice, or any other, from this software. 
//  
//  
//  
//    Windows CE Wifi Driver for AR-6000 
//  
//------------------------------------------------------------------------------ 
//============================================================================== 
// HIF CF source 
// 
// Author(s): ="Atheros" 
//============================================================================== 
 
#include "hif_internal.h" 
#include "athtypes.h" 
 
/* ------ Forward declarations ------ */ 
 
static BOOL 
hifDeviceInserted(CF_DEVICE_HANDLE cfHandle); 
 
static VOID 
hifDeviceRemoved(CF_DEVICE_HANDLE cfHandle); 
 
static VOID 
hifISRHandler(CF_DEVICE_HANDLE cfHandle,A_BOOL *callDsr); 
 
static void 
hifDSRHandler(CF_DEVICE_HANDLE cfHandle); 
 
static HIF_DEVICE * 
addHifDevice(CF_DEVICE_HANDLE cfHandle); 
 
static HIF_DEVICE * 
getHifDevice(CF_DEVICE_HANDLE cfHandle); 
 
static VOID 
delHifDevice(CF_DEVICE_HANDLE cfHandle); 
 
/* ------ Global Variables ------ */ 
 
HIF_DEVICE hifDevice[HIF_MAX_DEVICES]; 
 
HTC_CALLBACKS htcCallbacks; 
 
CF_FUNCTION  cfFunction; 
 
 
void 
HIFRegisterCallbacks(HTC_CALLBACKS *callbacks) 
{ 
    A_STATUS    status; 
     
    /* Store the callback and event handlers */ 
    htcCallbacks.deviceInsertedHandler = callbacks->deviceInsertedHandler; 
    htcCallbacks.deviceRemovedHandler  = callbacks->deviceRemovedHandler; 
    htcCallbacks.deviceSuspendHandler  = callbacks->deviceSuspendHandler; 
    htcCallbacks.deviceResumeHandler   = callbacks->deviceResumeHandler; 
    htcCallbacks.deviceWakeupHandler   = callbacks->deviceWakeupHandler; 
    htcCallbacks.rwCompletionHandler   = callbacks->rwCompletionHandler; 
    htcCallbacks.deviceInterruptDisabler = callbacks->deviceInterruptDisabler; 
    htcCallbacks.deviceInterruptEnabler = callbacks->deviceInterruptEnabler; 
    htcCallbacks.dsrHandler            = callbacks->dsrHandler; 
 
    /* Register the callback handlers with the lower driver */ 
    cfFunction.pName      = "cf_wlan"; 
    cfFunction.pProbe     = hifDeviceInserted; 
    cfFunction.pRemove    = hifDeviceRemoved; 
    cfFunction.pIsr       = hifISRHandler; 
    cfFunction.pDsr       = hifDSRHandler; 
 
    status = CF_RegisterFunction(&cfFunction); 
 
    AR_DEBUG_ASSERT(status == A_OK); 
} 
 
A_STATUS  
HIFReadWrite(HIF_DEVICE *device,  
             A_UINT32 address,  
             A_UCHAR *buffer,  
             A_UINT32 length,  
             HIF_REQUEST *request,  
             void *context)  
{ 
    CF_REQUEST cfRequest; 
	A_STATUS   status; 
    A_UINT32   remainingLen; 
    A_UINT32   curPos; 
  
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "HIFReadWrite: Enter\n", device); 
     
	A_MEMZERO(&cfRequest, sizeof(CF_REQUEST)); 
 
	if (request->emode == HIF_SYNCHRONOUS) { 
		HIF_DEBUG_PRINTF(ATH_LOG_INF, "HIFReadWrite : Execution mode: Synchronous\n"); 
	} else if (request->emode == HIF_ASYNCHRONOUS) { 
		HIF_DEBUG_PRINTF(ATH_LOG_INF, ("HIFReadWrite: Execution mode:Asynchronous\n")); 
	} else { 
		HIF_DEBUG_PRINTF(ATH_LOG_ERR,  
					"Invalid execution mode: %d\n", request->emode); 
		return A_ERROR; 
	} 
 
    if (request->direction == HIF_WRITE) { 
        cfRequest.flags |= CFREQ_FLAGS_DATA_WRITE; 
        HIF_DEBUG_PRINTF(ATH_LOG_INF, ("HifReadWrite: Direction: Write\n")); 
    } else if (request->direction == HIF_READ) { 
        HIF_DEBUG_PRINTF(ATH_LOG_INF, ("HifReadWrite: Direction: Read\n")); 
    } else { 
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,  
                        "Invalid direction: %d\n", request->direction); 
        return A_ERROR; 
    } 
 
    if (request->amode == HIF_FIXED_ADDRESS) { 
		cfRequest.flags |= CFREQ_FLAGS_FIXED_ADDRESS; 
        HIF_DEBUG_PRINTF(ATH_LOG_INF, ("Address mode: Fixed\n")); 
    } else if (request->amode == HIF_INCREMENTAL_ADDRESS) { 
        HIF_DEBUG_PRINTF(ATH_LOG_INF, ("Address mode: Incremental\n")); 
    } else { 
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,  
                        "Invalid address mode: %d\n", request->amode); 
        return A_ERROR; 
    } 
 
	if (HIF_IS_MBOX_ADDR(address) ) { 
        address = address & ~(HIF_MBOX_WIDTH-1); 
 
#define BLK_SZ  (HIF_MBOX_WIDTH - 2) 
        remainingLen = length; 
        curPos = 0; 
 
        while (remainingLen > BLK_SZ) { 
		    cfRequest.address = address; 
		    cfRequest.length = BLK_SZ; 
			cfRequest.pDataBuffer = &buffer[curPos]; 
 
            if (request->dmode == HIF_BYTE_BASIS) { 
    		    status = CF_BusRequest(device->cfHandle, &cfRequest, 8); 
            } else { 
    		    status = CF_BusRequest(device->cfHandle, &cfRequest, 16); 
            } 
 
    		if (status != A_OK) { 
        		HIF_DEBUG_PRINTF(ATH_LOG_ERR, ("HIF Write failed\n")); 
        		return A_ERROR; 
    		} 
 
            curPos += BLK_SZ; 
            remainingLen -= BLK_SZ; 
		} 
		cfRequest.pDataBuffer = &buffer[curPos]; 
        cfRequest.address = address + HIF_MBOX_WIDTH - remainingLen; 
		cfRequest.length = remainingLen; 
 
#ifdef ONLY_16BIT 
    	status = CF_BusRequest(device->cfHandle, &cfRequest, 16); 
#else 
        if (request->dmode == HIF_BYTE_BASIS) { 
    		status = CF_BusRequest(device->cfHandle, &cfRequest, 8); 
        } else { 
    		status = CF_BusRequest(device->cfHandle, &cfRequest, 16); 
        } 
#endif 
 
   		if (status != A_OK) { 
        	HIF_DEBUG_PRINTF(ATH_LOG_ERR, ("HIF Write failed\n")); 
        	return A_ERROR; 
   		} 
 
	} else { 
		cfRequest.address = address; 
        cfRequest.pDataBuffer = buffer; 
	    cfRequest.length = length; 
#ifdef ONLY_16BIT 
    	status = CF_BusRequest(device->cfHandle, &cfRequest, 16); 
#else 
    	status = CF_BusRequest(device->cfHandle, &cfRequest, 8); 
#endif 
	} 
 
     
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "HIFReadWrite: Exit\n", device); 
 
    return status; 
} 
 
void 
HIFShutDownDevice(HIF_DEVICE *device) 
{ 
    A_STATUS status; 
     
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifShutDownDevice \n"); 
    /* Unregister with bus driver core */ 
    status = CF_UnregisterFunction(&cfFunction); 
} 
 
static void 
hifISRHandler(CF_DEVICE_HANDLE cfHandle,A_BOOL *callDsr) 
{ 
    A_STATUS    status; 
    HIF_DEVICE *device; 
 
    device = getHifDevice(cfHandle); 
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIsrHandler: Enter\n"); 
 
	status = htcCallbacks.deviceInterruptDisabler(device, callDsr); 
	AR_DEBUG_ASSERT(status == A_OK); 
         
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIsrHandler: Exit\n"); 
 
    return; 
} 
 
static void 
hifDSRHandler(CF_DEVICE_HANDLE cfHandle) 
{ 
    A_STATUS    status; 
    HIF_DEVICE *device; 
 
	device = getHifDevice(cfHandle); 
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDsrHandler: Enter\n"); 
 
    status = htcCallbacks.dsrHandler(device); 
     
    AR_DEBUG_ASSERT(status == A_OK); 
     
	htcCallbacks.deviceInterruptEnabler(device); 
 
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDsrHandler: Exit\n"); 
} 
 
 
static BOOL 
hifDeviceInserted(CF_DEVICE_HANDLE cfHandle) 
{ 
    HIF_DEVICE *device; 
 
    device = addHifDevice(cfHandle); 
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceInserted: Enter\n"); 
 
    HIF_DEBUG_PRINTF(ATH_LOG_INF, "hifDeviceInsetred: Device = %p\n",device); 
 
    /* Inform HTC */ 
    if ((htcCallbacks.deviceInsertedHandler(device)) != A_OK) { 
        HIF_DEBUG_PRINTF(ATH_LOG_ERR, "hifDeviceInserted: HTC failed device inserted\n"); 
        return FALSE; 
    } 
     
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceInserted: Exit\n"); 
 
    return TRUE; 
} 
 
void 
HIFAckInterrupt(HIF_DEVICE *device) 
{ 
	return; 
} 
 
void 
HIFUnMaskInterrupt(HIF_DEVICE *device) 
{ 
    CF_UnMaskInterrupt(device->cfHandle); 
    return; 
} 
 
void  
HIFMaskInterrupt(HIF_DEVICE *device) 
{ 
    CF_MaskInterrupt(device->cfHandle); 
    return; 
} 
 
static void 
hifDeviceRemoved(CF_DEVICE_HANDLE cfHandle) 
{ 
    A_STATUS status; 
    HIF_DEVICE *device; 
 
    device = getHifDevice(cfHandle); 
     
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceRemoved: Enter\n"); 
    HIF_DEBUG_PRINTF(ATH_LOG_INF, "hifDeviceRemoved: Device = %p\n",device); 
 
    /* Inform HTC */ 
    status = htcCallbacks.deviceRemovedHandler(device); 
     
    delHifDevice(cfHandle); 
     
    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceRemoved: Exit\n"); 
 
    AR_DEBUG_ASSERT(status == A_OK); 
} 
 
static HIF_DEVICE * 
addHifDevice(CF_DEVICE_HANDLE cfHandle) 
{ 
    hifDevice[0].cfHandle = cfHandle; 
    return &hifDevice[0]; 
} 
 
static HIF_DEVICE * 
getHifDevice(CF_DEVICE_HANDLE cfHandle) 
{ 
    return &hifDevice[0]; 
} 
 
static void 
delHifDevice(CF_DEVICE_HANDLE cfHandle) 
{ 
    hifDevice[0].cfHandle = NULL; 
}