Example #1
0
A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks)
{
	SD_API_STATUS sdStatus;
	
    AR_DEBUG_ASSERT(callbacks != NULL);

    /* store the callback handlers */
    osdrvCallbacks = *callbacks;

    /* Register with bus driver core */
    NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, "AR6000: HIFInit registering \r\n");
    registered = 1;
#if defined(CONFIG_PM)
	// TODO about power management.
#endif /* CONFIG_PM */

    /* Register with bus driver core */
    sdFunction.pName      = "sdio_wlan";
    sdFunction.pProbe     = hifDeviceInserted;
    sdFunction.pRemove    = hifDeviceRemoved;

	
	A_MUTEX_INIT(&hif_lock);
	NdisAllocateSpinLock(&sLock);
	
    sdStatus = SDIORegisterFunction(&sdFunction);
    AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));	
    
    return A_OK;
}
Example #2
0
/*
 * Commit an address to either WINDOW_WRITE_ADDR_REG or to
 * WINDOW_READ_ADDR_REG.  We write the least significan byte (LSB)
 * last, since it triggers the read/write.
 */
static void
_WRITE_WINDOW_ADDR(HTC_TARGET *target, A_UINT32 whichreg, A_UINT32 value)
{
    A_UINT32 window_addr;
    HIF_REQUEST request;
    A_STATUS status;
    A_UINT32 address;

    window_addr = value;
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);

    address = getRegAddr(whichreg, ENDPOINT_UNUSED);
#ifdef ONLY_16BIT
    status = HIFReadWrite(target->device, address+2, 
                          (A_UCHAR *)&window_addr+2, 2, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);

    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&window_addr, 2, &request, NULL);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&window_addr, 2, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);
#else
    status = HIFReadWrite(target->device, address+1, 
                          (A_UCHAR *)&window_addr+1, 3, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);

    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&window_addr, 1, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);
#endif
}
Example #3
0
static void hifDeviceRemoved(struct sdio_func *func)
{
    A_STATUS status = A_OK;
    HIF_DEVICE *device;
    int ret;
    AR_DEBUG_ASSERT(func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n"));
    device = getHifDevice(func);
    if (device->claimedContext != NULL) {
        status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
    }
    do {
        if (device->is_suspend) {
            device->is_suspend = FALSE;
            break;
        }
        if (!IS_ERR(device->async_task)) {
            init_completion(&device->async_completion);
            device->async_shutdown = 1;
            up(&device->sem_async);
            wait_for_completion(&device->async_completion);
            device->async_task = NULL;
        }
        /* Disable the card */
        sdio_claim_host(device->func);
        ret = sdio_disable_func(device->func);
        sdio_release_host(device->func);
    } while (0);
    delHifDevice(device);
    AR_DEBUG_ASSERT(status == A_OK);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n"));
}
Example #4
0
/* ------ Functions ------ */
A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks)
{
    int status;
    AR_DEBUG_ASSERT(callbacks != NULL);

    A_REGISTER_MODULE_DEBUG_INFO(hif);

    /* store the callback handlers */
    osdrvCallbacks = *callbacks;

    /* Register with bus driver core */
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n"));
    registered = 1;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM)
    if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) {
        ar6k_driver.drv.pm = &ar6k_device_pm_ops;
    }
#endif /* CONFIG_PM */
    status = sdio_register_driver(&ar6k_driver);
    AR_DEBUG_ASSERT(status==0);

    if (status != 0) {
        return A_ERROR;
    }

    return A_OK;

}
Example #5
0
static void hifDeviceRemoved(struct sdio_func *func)
{
    A_STATUS status = A_OK;
    HIF_DEVICE *device;
    AR_DEBUG_ASSERT(func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n"));
    device = getHifDevice(func);
    if (device->claimedContext != NULL) {
        status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
    }

    if (device->is_suspend) {
        device->is_suspend = FALSE;
    } else {
        if (hifDisableFunc(device, func)!=0) {
            status = A_ERROR;
        }
    }
    CleanupHIFScatterResources(device);
     
    delHifDevice(device);
    AR_DEBUG_ASSERT(status == A_OK);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n"));
}
Example #6
0
void
HIFShutDownDevice(HIF_DEVICE *device)
{
    SD_API_STATUS sdStatus;
    //SDCONFIG_BUS_MODE_DATA busSettings;
	UCHAR         buffer;

	if (device == NULL) {
		HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid Handle passed\n");
		return;
	}
    /* Remove the allocated current if any */
	/*
	 * There is no equivalent for this one in WINCE
    status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_FREE_SLOT_CURRENT, 
                               NULL, 0);
    DBG_ASSERT(SDIO_SUCCESS(status));
	*/

    /* Disable the card */
	SDIODisconnectInterrupt(device->handle);
    sdStatus = SDSetCardFeature(device->handle, SD_IO_FUNCTION_DISABLE,
			                      NULL, 0);
    AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));

    /* Perform a soft I/O reset */
	sdStatus = SDReadWriteRegistersDirect(device->handle, SD_IO_WRITE, 0, 
					SD_IO_REG_IO_ABORT, 1, &buffer, 0);
    AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));

    /* 
     * WAR - Codetelligence driver does not seem to shutdown correctly in 1
     * bit mode. By default it configures the HC in the 4 bit. Its later in
     * our driver that we switch to 1 bit mode. If we try to shutdown, the
     * driver hangs so we revert to 4 bit mode, to be transparent to the 
     * underlying bus driver.
     */
	/*
	 * Not sure whether this is required for WINCE hence commenting
	 */
	/*
    if (sdio1bitmode) {
        ZERO_OBJECT(busSettings);
        busSettings.BusModeFlags = device->handle->pHcd->CardProperties.BusMode;
        SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags, 
                               SDCONFIG_BUS_WIDTH_4_BIT);

        // Issue config request to change the bus width to 4 bit
        status = SDLIB_IssueConfig(device->handle, SDCONFIG_BUS_MODE_CTRL,
                                   &busSettings, 
                                   sizeof(SDCONFIG_BUS_MODE_DATA));
        DBG_ASSERT(SDIO_SUCCESS(status));
    }
	*/

    /* Unregister with bus driver core */
    sdStatus = SDIOUnregisterFunction(&sdFunction);
    AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));
	return;
}
Example #7
0
void
htcServiceCPUInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    A_UINT8 cpu_int_status;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "CPU Interrupt\n");
    cpu_int_status = target->table.cpu_int_status &
                     target->table.cpu_int_status_enable;
    AR_DEBUG_ASSERT(cpu_int_status);
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
                    cpu_int_status);

    /* Figure out the interrupt number */
    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Interrupt Number: 0x%x\n", 
                    htcGetBitNumSet(cpu_int_status));

    /* Clear the interrupt */
    target->table.cpu_int_status = cpu_int_status; /* W1C */
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = getRegAddr(CPU_INT_STATUS_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          &target->table.cpu_int_status, 1, &request, NULL);

    AR_DEBUG_ASSERT(status == A_OK);
}
Example #8
0
SD_API_STATUS 
hifIRQHandler(SD_DEVICE_HANDLE hDevice, PVOID notUsed)
{
#ifndef CEPC
	A_STATUS         status;
    HIF_DEVICE      *device;
	A_BOOL			 callDSR;
#endif

    HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIRQHandler : Enter\n");

#ifndef CEPC
	/* Disable device interrupts */
	device = getHifDevice(hDevice);

	status = htcCallbacks.deviceInterruptDisabler(device, &callDSR);
	AR_DEBUG_ASSERT(status == A_OK);

	/* Call the DSR Handler if it is not a Spurious Interrupt */
	if (callDSR) {
		status = htcCallbacks.dsrHandler(device);
		AR_DEBUG_ASSERT(status == A_OK);
	}
#else
	NdisSetEvent(&hifIRQEvent);
#endif
	HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifIRQHandler : Exit\n");
	return SD_API_STATUS_SUCCESS;
}
Example #9
0
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;
}
Example #10
0
static A_STATUS DevServiceErrorInterrupt(AR6K_DEVICE *pDev)
{
    A_STATUS status;
    A_UINT8  error_int_status;
    A_UINT8  regBuffer[4];

    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error Interrupt\n"));
    error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F;
    AR_DEBUG_ASSERT(error_int_status);
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
                    error_int_status));

    if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
        /* Wakeup */
        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n"));
    }

    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
        /* Rx Underflow */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n"));
        if (pDev->TargetFailureCallback != NULL) {
            pDev->TargetFailureCallback(pDev->HTCContext, AR6K_TARGET_RX_ERROR);
        }
    }

    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
        /* Tx Overflow */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n"));
        if (pDev->TargetFailureCallback != NULL) {
            pDev->TargetFailureCallback(pDev->HTCContext, AR6K_TARGET_TX_ERROR);
        }
    }

        /* Clear the interrupt */
    pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */

        /* set up the register transfer buffer to hit the register 4 times , this is done
         * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
         * restrict bus transfer lengths to be a multiple of 4-bytes */

        /* set W1C value to clear the interrupt, this hits the register first */
    regBuffer[0] = error_int_status;
        /* the remaining 4 values are set to zero which have no-effect  */
    regBuffer[1] = 0;
    regBuffer[2] = 0;
    regBuffer[3] = 0;

    status = HIFReadWrite(pDev->HIFDevice,
                          ERROR_INT_STATUS_ADDRESS,
                          regBuffer,
                          4,
                          HIF_WR_SYNC_BYTE_FIX,
                          NULL);

    AR_DEBUG_ASSERT(status == A_OK);
    return status;
}
Example #11
0
A_STATUS htcInterruptEnabler(HIF_DEVICE *device) {

	A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
	HTC_TARGET *target;
	HTC_REG_REQUEST_ELEMENT *element;

    target = getTargetInstance(device);
    AR_DEBUG_ASSERT(target != NULL);
    HTC_DEBUG_PRINTF(ATH_LOG_TRC, 
                    "htcInterruptEnabler Enter target: 0x%p\n", target);

	target->table.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
                                      INT_STATUS_ENABLE_CPU_SET(0x01) |
                                      INT_STATUS_ENABLE_COUNTER_SET(0x01) |
                                      INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);
	/* Reenable Dragon Interrupts */
	element = allocateRegRequestElement(target);
    AR_DEBUG_ASSERT(element != NULL);
#ifdef ONLY_16BIT
    FILL_REG_BUFFER(element, (A_UINT16 *)&target->table.int_status_enable, 2, 
                    INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
#else
    FILL_REG_BUFFER(element, &target->table.int_status_enable, 1, 
                    INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
#endif

	HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
#ifdef ONLY_16BIT
    status = HIFReadWrite(target->device, address, 
                          &target->table.int_status_enable, 2, 
                          &request, element);
#else
    status = HIFReadWrite(target->device, address, 
                          &target->table.int_status_enable, 1, 
                          &request, element);
#endif

#ifndef HTC_SYNC
	AR_DEBUG_ASSERT(status == A_OK);
#else
	AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
	if ( status == A_OK ) {
		element->completionCB(element, status);
	}
#endif //HTC_SYNC


    HTC_DEBUG_PRINTF(ATH_LOG_TRC,"htcInterruptEnabler Exit\n");

	return A_OK;
}
Example #12
0
void HIFMaskInterrupt(HIF_DEVICE *device)
{
    SDIO_STATUS status;
    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->handle != NULL);

    /* Mask our function IRQ */
    status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_MASK_IRQ, 
                               NULL, 0);
    AR_DEBUG_ASSERT(SDIO_SUCCESS(status));

}
Example #13
0
A_STATUS
htcInterruptPending(HIF_DEVICE *device, A_BOOL *intPending)
{
    A_STATUS status;
    A_UINT32 address;
    HTC_TARGET *target;
    HIF_REQUEST request;
    A_UCHAR      intStatus[2] = {0,0};
    A_UCHAR      intMask[2] = {0,0};

    target = getTargetInstance(device);
    AR_DEBUG_ASSERT(target != NULL);
    HTC_DEBUG_PRINTF(ATH_LOG_TRC, 
                    "htcInterruptPending Enter target: 0x%p\n", target);

    // get the current interrupt status register
    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = getRegAddr(INT_STATUS_REG, ENDPOINT_UNUSED);

#ifdef ONLY_16BIT
    status = HIFReadWrite(target->device, address, 
                          intStatus, 2, &request, NULL);
#else
    status = HIFReadWrite(target->device, address, 
                          intStatus, 1, &request, NULL);
#endif
    AR_DEBUG_ASSERT(status == A_OK);

    // get the interrupt enable register value 
    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);

    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);

#ifdef ONLY_16BIT
    status = HIFReadWrite(target->device, address, 
                          intMask, 2, &request, NULL);
#else
    status = HIFReadWrite(target->device, address, 
                          intMask, 1, &request, NULL);
#endif
    AR_DEBUG_ASSERT(status == A_OK);
    if (!((intMask[0] & intStatus[0]) == 0)) {
	    *intPending = TRUE;
    } else {
	    *intPending = FALSE;
    }
    return A_OK;
}
Example #14
0
void HIFMaskInterrupt(HIF_DEVICE *device)
{
    int ret;;

    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));

    /* Mask our function IRQ */
    sdio_claim_host(device->func);
    ret = sdio_release_irq(device->func);
    sdio_release_host(device->func);
    AR_DEBUG_ASSERT(ret == 0);
}
Example #15
0
void 
hifRWCompletionHandler(SDREQUEST *request) 
{
    void *context;
    A_STATUS status = A_OK;
    HIF_DEVICE *device;
    BUS_REQUEST *busrequest;

    busrequest = (BUS_REQUEST *)request->pCompleteContext;
    AR_DEBUG_ASSERT(busrequest->request == request);
    device = busrequest->device;
    context = busrequest->context;
    if (!SDIO_SUCCESS(request->Status)) {
        status = A_ERROR;    
    }
    
        /* free the request, we have all the info we need */
    hifFreeBusRequest(device,busrequest);
    busrequest = NULL;
    
    if (device->shutdownInProgress) {
        device->htcCallbacks.rwCompletionHandler(context, A_ERROR);
        return;
    }
    
    device->htcCallbacks.rwCompletionHandler(context, status);
}
Example #16
0
static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev)
{
    A_UINT32 dummy;
    A_STATUS status;

    /* Send a target failure event to the application */
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n"));

    if (pDev->TargetFailureCallback != NULL) {
        pDev->TargetFailureCallback(pDev->HTCContext);
    }

    /* clear the interrupt , the debug error interrupt is
     * counter 0 */
        /* read counter to clear interrupt */
    status = HIFReadWrite(pDev->HIFDevice,
                          COUNT_DEC_ADDRESS,
                          (A_UINT8 *)&dummy,
                          4,
                          HIF_RD_SYNC_BYTE_INC,
                          NULL);

    AR_DEBUG_ASSERT(status == A_OK);
    return status;
}
/**
 * Returns a lexicographically sorted list of merged barcodes, each paired with
 * the 0-based index of corresponding barcode in the source vector.
 */
barcode_vec sort_barcodes(const fastq_pair_vec& barcodes)
{
    AR_DEBUG_ASSERT(!barcodes.empty());
    barcode_vec sorted_barcodes;

    const size_t max_key_1_len = barcodes.front().first.length();
    const size_t max_key_2_len = barcodes.front().second.length();
    for (auto it = barcodes.begin(); it != barcodes.end(); ++it) {
        if (it->first.length() != max_key_1_len) {
            throw barcode_error("mate 1 barcodes do not have the same length");
        } else if (it->second.length() != max_key_2_len) {
            throw barcode_error("mate 2 barcodes do not have the same length");
        }

        std::string barcode;
        barcode.reserve(max_key_1_len + max_key_2_len);
        barcode.append(it->first.sequence());
        barcode.append(it->second.sequence());

        sorted_barcodes.push_back(barcode_pair(barcode, it - barcodes.begin()));
    }

    std::sort(sorted_barcodes.begin(), sorted_barcodes.end());

    return sorted_barcodes;
}
Example #18
0
DWORD
hifIRQThread(void *Context)
{

	A_STATUS         status = A_OK;
	HIF_DEVICE      *device;

	device = (HIF_DEVICE *)Context;

	NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, " %s() is Running... \r\n",__FUNCTION__);


	while (TRUE) 
	{
		NdisWaitEvent(&hifIRQEvent, 0);
		NdisResetEvent(&hifIRQEvent);
		
		NDIS_DEBUG_PRINTF(DBG_TRACE, "%s() - Running  & ",__FUNCTION__);
		status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
		AR_DEBUG_ASSERT(status == A_OK);
		NDIS_DEBUG_PRINTF(DBG_TRACE, " Exit \r\n");
		
		SDIOConnectInterrupt(device->handle,hifIRQHandler);
				
	} // while
	return SD_API_STATUS_SUCCESS;
	
}
Example #19
0
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);
}
Example #20
0
    /* callback when a control message arrives on this endpoint */
void HTCControlRecv(void *Context, HTC_PACKET *pPacket)
{
    AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0);

    if (pPacket->Status == A_ECANCELED) {
        /* this is a flush operation, return the control packet back to the pool */
        HTC_FREE_CONTROL_RX((HTC_TARGET*)Context,pPacket);    
        return;
    }  
    
        /* the only control messages we are expecting are NULL messages (credit resports) */   
    if (pPacket->ActualLength > 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                        ("HTCControlRecv, got message with length:%d \n",
                        pPacket->ActualLength + (A_UINT32)HTC_HDR_LENGTH));

#ifdef ATH_DEBUG_MODULE
            /* dump header and message */
        DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
                       pPacket->ActualLength + HTC_HDR_LENGTH,
                       "Unexpected ENDPOINT 0 Message");
#endif
    }

    HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket,&((HTC_TARGET*)Context)->EndPoint[0]);
}
Example #21
0
void
HIFUnMaskInterrupt(HIF_DEVICE *device)
{
    int ret;;

    AR_DEBUG_ASSERT(device != NULL);
    AR_DEBUG_ASSERT(device->func != NULL);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));

    /* Register the IRQ Handler */
    sdio_claim_host(device->func);
    ret = sdio_claim_irq(device->func, hifIRQHandler);
    sdio_release_host(device->func);
    AR_DEBUG_ASSERT(ret == 0);
}
Example #22
0
void
HIFAckInterrupt(HIF_DEVICE *device)
{
    AR_DEBUG_ASSERT(device != NULL);

    /* Acknowledge our function IRQ */
}
Example #23
0
void
HIFShutDownDevice(HIF_DEVICE *device)
{
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
    if (device != NULL) {
        AR_DEBUG_ASSERT(device->func != NULL);
    } else {
            /* since we are unloading the driver anyways, reset all cards in case the SDIO card
             * is externally powered and we are unloading the SDIO stack.  This avoids the problem when
             * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
             * enumerated */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
        ResetAllCards();

        /* Unregister with bus driver core */
        if (registered) {
            registered = 0;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
                            ("AR6000: Unregistering with the bus driver\n"));
            sdio_unregister_driver(&ar6k_driver);
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
                            ("AR6000: Unregistered\n"));
        }
    }
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
}
void HTCSetCreditDistribution(HTC_HANDLE               HTCHandle,
                              void                     *pCreditDistContext,
                              HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
                              HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
                              HTC_SERVICE_ID           ServicePriorityOrder[],
                              int                      ListLength)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    int i;
    int ep;

    if (CreditInitFunc != NULL) {
            /* caller has supplied their own distribution functions */
        target->InitCredits = CreditInitFunc;
        AR_DEBUG_ASSERT(CreditDistFunc != NULL);
        target->DistributeCredits = CreditDistFunc;
        target->pCredDistContext = pCreditDistContext;
    } else {
        /* caller wants HTC to do distribution */
        /* if caller wants service to handle distributions then
         * it must set both of these to NULL! */
        AR_DEBUG_ASSERT(CreditDistFunc == NULL);
        target->InitCredits = HTCDefaultCreditInit;
        target->DistributeCredits = HTCDefaultCreditDist;
        target->pCredDistContext = target;
    }

        /* always add HTC control endpoint first, we only expose the list after the
         * first one, this is added for TX queue checking */
    AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);

        /* build the list of credit distribution structures in priority order
         * supplied by the caller, these will follow endpoint 0 */
    for (i = 0; i < ListLength; i++) {
            /* match services with endpoints and add the endpoints to the distribution list
             * in FIFO order */
        for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
            if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
                    /* queue this one to the list */
                AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
                break;
            }
        }
        AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
    }

}
Example #25
0
/* Makes a buffer available to the HTC module */
A_STATUS 
HTCBufferReceive(HTC_TARGET *target, 
                 HTC_ENDPOINT_ID endPointId,
                 A_UCHAR *buffer, 
                 A_UINT32 length,
                 void *cookie)
{
    A_STATUS status;
    HTC_ENDPOINT *endPoint;
    HTC_DATA_REQUEST_QUEUE *recvQueue;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, 
                    "HTCBufferReceive: Enter (endPointId: %d, buffer: 0x%p, length: %d, cookie: 0x%p)\n", endPointId, buffer, length, cookie);

    AR_DEBUG_ASSERT((endPointId >= ENDPOINT1) && (endPointId <= ENDPOINT4));

    /* Extract the end point instance */
    endPoint = &target->endPoint[endPointId];
    AR_DEBUG_ASSERT(endPoint != NULL);

    recvQueue = &endPoint->recvQueue;
    HTC_DEBUG_PRINTF(ATH_LOG_INF | ATH_LOG_RECV, "recvQueue: %p\n", 
                    recvQueue);

    /* Add this posted buffer to the pending receive queue */
    status = addToMboxQueue(recvQueue, buffer, length, 0, cookie);
    if (status != A_OK) {
        HTC_DEBUG_PRINTF(ATH_LOG_ERR | ATH_LOG_RECV,
                        "Mailbox (%d) Send queue full. Unable to add buffer\n", 
                        GET_ENDPOINT_ID(endPoint));
        return A_ERROR;
    }

    /* 
     * If this API was called as a result of a HTC_DATA_AVAILABLE event to
     * the upper layer, indicating that HTC is out of buffers, then we should
     * receive the frame in the buffer supplied otherwise we simply add the 
     * buffer to the Pending Receive Queue 
     */
    if (endPoint->rxLengthPending) {
        htcReceiveFrame(endPoint);
    }

    HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_RECV, 
                    "HTCBufferReceive: Exit\n");
    return A_OK;
}
Example #26
0
/* called by the HTC layer when it wants us to check if the device has any more pending
 * recv messages, this starts off a series of async requests to read interrupt registers  */
A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
{
    AR6K_DEVICE  *pDev = (AR6K_DEVICE *)context;
    A_STATUS      status = A_OK;
    HTC_PACKET   *pIOPacket;

    /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can
     * cause us to switch contexts */

   AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%X)\n", (A_UINT32)pDev));

   do {

        if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
                /* break the async processing chain right here, no need to continue.
                 * The DevDsrHandler() will handle things in a loop when things are driven
                 * synchronously  */
            break;
        }
            /* first allocate one of our HTC packets we created for async I/O
             * we reuse HTC packet definitions so that we can use the completion mechanism
             * in DevRWCompletionHandler() */
        pIOPacket = AR6KAllocIOPacket(pDev);

        if (NULL == pIOPacket) {
                /* there should be only 1 asynchronous request out at a time to read these registers
                 * so this should actually never happen */
            status = A_NO_MEMORY;
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

            /* stick in our completion routine when the I/O operation completes */
        pIOPacket->Completion = DevGetEventAsyncHandler;
        pIOPacket->pContext = pDev;

        if (pDev->GetPendingEventsFunc) {
                /* HIF layer has it's own mechanism, pass the IO to it.. */
            status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
                                                (HIF_PENDING_EVENTS_INFO *)pIOPacket->pBuffer,
                                                pIOPacket);

        } else {
                /* standard way, read the interrupt register table asynchronously again */
            status = HIFReadWrite(pDev->HIFDevice,
                                  HOST_INT_STATUS_ADDRESS,
                                  pIOPacket->pBuffer,
                                  AR6K_IRQ_PROC_REGS_SIZE,
                                  HIF_RD_ASYNC_BYTE_INC,
                                  pIOPacket);
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
   } while (FALSE);

   AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));

   return status;
}
Example #27
0
static HIF_DEVICE *
addHifDevice(struct sdio_func *func)
{
    HIF_DEVICE *hifdevice;
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
    AR_DEBUG_ASSERT(func != NULL);
    hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
    AR_DEBUG_ASSERT(hifdevice != NULL);
#if HIF_USE_DMA_BOUNCE_BUFFER
    hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
    AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL);
#endif
    hifdevice->func = func;
    sdio_set_drvdata(func, hifdevice);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice));
    return hifdevice;
}
Example #28
0
void
hifDeviceRemoved(SDFUNCTION *function, SDDEVICE *handle)
{
    A_STATUS   status = A_OK;
    HIF_DEVICE *device;
    AR_DEBUG_ASSERT(function != NULL);
    AR_DEBUG_ASSERT(handle != NULL);

        /* our device is the IRQ context we stored */
    device = (HIF_DEVICE *)handle->IrqContext;
    if (device->claimedContext != NULL) {
        status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
    }
        /* cleanup the instance */
    hifCleanupDevice(device);
    AR_DEBUG_ASSERT(status == A_OK);
}
Example #29
0
/* ------ Functions ------ */
A_STATUS
HIFInit(OSDRV_CALLBACKS *callbacks)
{
    SDIO_STATUS status;
    AR_DEBUG_ASSERT(callbacks != NULL);

    A_REGISTER_MODULE_DEBUG_INFO(hif);

    /* Store the callback and event handlers */
    osdrvCallbacks = *callbacks;

    /* Register with bus driver core */
    status = SDIO_RegisterFunction(&FunctionContext.function);
    AR_DEBUG_ASSERT(SDIO_SUCCESS(status));

    return SDIO_SUCCESS(status) ? A_OK : A_ERROR;
}
Example #30
0
A_STATUS
htcInterruptDisabler(HIF_DEVICE *device,A_BOOL *callDsr)
{
    A_STATUS status;
    A_UINT32 address;
    HTC_TARGET *target;
    HIF_REQUEST request;
    A_BOOL interruptPending;

    target = getTargetInstance(device);
    AR_DEBUG_ASSERT(target != NULL);
	
    HTC_DEBUG_PRINTF(ATH_LOG_TRC, 
	                    "htcInterruptDisabler Enter target: 0x%p\n", target);
    
    // Check for spurious interrupt
    status = htcInterruptPending (device, &interruptPending);
		
    if (!interruptPending){
        *callDsr=FALSE; 
    } else {
	    /* 
         * Disable the interrupts from Dragon.
         *  We do the interrupt servicing in the bottom half and reenable the
         *  Dragon interrupts at the end of the bottom-half
	     */
   
        target->table.int_status_enable = 0;
        HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
        address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
#ifdef ONLY_16BIT
        status = HIFReadWrite(target->device, address, 
                          &target->table.int_status_enable, 2, &request, NULL);
#else
        status = HIFReadWrite(target->device, address, 
                          &target->table.int_status_enable, 1, &request, NULL);
#endif
        AR_DEBUG_ASSERT(status == A_OK);
        *callDsr=TRUE;
    }

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcInterruptDisabler: Exit\n");
    return A_OK;
}