/* disable all device interrupts */ A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev) { /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while * we zero out our shadow registers in DevDisableInterrupts()*/ HIFMaskInterrupt(pDev->HIFDevice); return DevDisableInterrupts(pDev); }
/* disable all device interrupts */ int DevMaskInterrupts(struct ar6k_device *pDev) { /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while * we zero out our shadow registers in DevDisableInterrupts()*/ HIFMaskInterrupt(pDev->HIFDevice); return DevDisableInterrupts(pDev); }
/* enable device interrupts */ A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) { /* for good measure, make sure interrupt are disabled before unmasking at the HIF * layer. * The rationale here is that between device insertion (where we clear the interrupts the first time) * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets. * The AR6K interrupt enables reset back to an "enabled" state when this happens. * */ DevDisableInterrupts(pDev); /* Unmask the host controller interrupts */ HIFUnMaskInterrupt(pDev->HIFDevice); return DevEnableInterrupts(pDev); }
/* enable device interrupts */ int DevUnmaskInterrupts(struct ar6k_device *pDev) { /* for good measure, make sure interrupt are disabled before unmasking at the HIF * layer. * The rationale here is that between device insertion (where we clear the interrupts the first time) * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets. * The AR6K interrupt enables reset back to an "enabled" state when this happens. * */ int IntStatus = 0; DevDisableInterrupts(pDev); #ifdef THREAD_X // Tobe verified... IntStatus = DevEnableInterrupts(pDev); /* Unmask the host controller interrupts */ HIFUnMaskInterrupt(pDev->HIFDevice); #else /* Unmask the host controller interrupts */ HIFUnMaskInterrupt(pDev->HIFDevice); IntStatus = DevEnableInterrupts(pDev); #endif return IntStatus; }
A_STATUS DevSetup(AR6K_DEVICE *pDev) { A_UINT32 blocksizes[AR6K_MAILBOXES]; A_STATUS status = A_OK; int i; HTC_CALLBACKS htcCallbacks; do { DL_LIST_INIT(&pDev->ScatterReqHead); /* initialize our free list of IO packets */ INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList); A_MUTEX_INIT(&pDev->Lock); A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); /* the device layer handles these */ htcCallbacks.rwCompletionHandler = DevRWCompletionHandler; htcCallbacks.dsrHandler = DevDsrHandler; htcCallbacks.context = pDev; status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks); if (A_FAILED(status)) { break; } pDev->HifAttached = TRUE; /* get the addresses for all 4 mailboxes */ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo)); if (status != A_OK) { A_ASSERT(FALSE); break; } /* carve up register I/O packets (these are for ASYNC register I/O ) */ for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) { HTC_PACKET *pIOPacket; pIOPacket = &pDev->RegIOBuffers[i].HtcPacket; SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket, pDev, pDev->RegIOBuffers[i].Buffer, AR6K_REG_IO_BUFFER_SIZE, 0); /* don't care */ AR6KFreeIOPacket(pDev,pIOPacket); } /* get the block sizes */ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); if (status != A_OK) { A_ASSERT(FALSE); break; } /* note: we actually get the block size of a mailbox other than 0, for SDIO the block * size on mailbox 0 is artificially set to 1. So we use the block size that is set * for the other 3 mailboxes */ pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; /* must be a power of 2 */ A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0); /* assemble mask, used for padding to a block */ pDev->BlockMask = pDev->BlockSize - 1; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n", pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX])); pDev->GetPendingEventsFunc = NULL; /* see if the HIF layer implements the get pending events function */ HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_PENDING_EVENTS_FUNC, &pDev->GetPendingEventsFunc, sizeof(pDev->GetPendingEventsFunc)); /* assume we can process HIF interrupt events asynchronously */ pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC; /* see if the HIF layer overrides this assumption */ HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_IRQ_PROC_MODE, &pDev->HifIRQProcessingMode, sizeof(pDev->HifIRQProcessingMode)); switch (pDev->HifIRQProcessingMode) { case HIF_DEVICE_IRQ_SYNC_ONLY: AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n")); /* see if HIF layer wants HTC to yield */ HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_IRQ_YIELD_PARAMS, &pDev->HifIRQYieldParams, sizeof(pDev->HifIRQYieldParams)); if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) { AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requests that DSR yield per %d RECV packets \n", pDev->HifIRQYieldParams.RecvPacketYieldCount)); pDev->DSRCanYield = TRUE; } break; case HIF_DEVICE_IRQ_ASYNC_SYNC: AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n")); break; default: A_ASSERT(FALSE); } pDev->HifMaskUmaskRecvEvent = NULL; /* see if the HIF layer implements the mask/unmask recv events function */ HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, &pDev->HifMaskUmaskRecvEvent, sizeof(pDev->HifMaskUmaskRecvEvent)); AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n", (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent)); status = DevDisableInterrupts(pDev); if (A_FAILED(status)) { break; } status = DevSetupGMbox(pDev); } while (FALSE); if (A_FAILED(status)) { if (pDev->HifAttached) { HIFDetachHTC(pDev->HIFDevice); pDev->HifAttached = FALSE; } } return status; }
/* Start HTC, enable interrupts and let the target know host has finished setup */ A_STATUS HTCStart(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_PACKET *pPacket; A_STATUS status; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); printk("HTCStart Enter\n"); /* make sure interrupts are disabled at the chip level, * this function can be called again from a reboot of the target without shutting down HTC */ DevDisableInterrupts(&target->Device); /* make sure state is cleared again */ target->HTCStateFlags = 0; /* now that we are starting, push control receive buffers into the * HTC control endpoint */ while (1) { pPacket = HTC_ALLOC_CONTROL_RX(target); if (NULL == pPacket) { break; } HTCAddReceivePkt((HTC_HANDLE)target,pPacket); } do { AR_DEBUG_ASSERT(target->InitCredits != NULL); AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL); AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL); /* call init credits callback to do the distribution , * NOTE: the first entry in the distribution list is ENDPOINT_0, so * we pass the start of the list after this one. */ target->InitCredits(target->pCredDistContext, target->EpCreditDistributionListHead->pNext, target->TargetCredits); if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) { DumpCreditDistStates(target); } /* the caller is done connecting to services, so we can indicate to the * target that the setup phase is complete */ status = HTCSendSetupComplete(target); if (A_FAILED(status)) { break; } /* unmask interrupts */ status = DevUnmaskInterrupts(&target->Device); if (A_FAILED(status)) { HTCStop(target); } } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); printk("HTCStart Exit\n"); return status; }