A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev) { A_STATUS status; AR6K_IRQ_ENABLE_REGISTERS regs; LOCK_AR6K(pDev); /* Enable all the interrupts except for the internal AR6000 CPU interrupt */ pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) | INT_STATUS_ENABLE_CPU_SET(0x01) | INT_STATUS_ENABLE_COUNTER_SET(0x01); if (NULL == pDev->GetPendingEventsFunc) { pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); } else { /* The HIF layer provided us with a pending events function which means that * the detection of pending mbox messages is handled in the HIF layer. * This is the case for the SPI2 interface. * In the normal case we enable MBOX interrupts, for the case * with HIFs that offer this mechanism, we keep these interrupts * masked */ pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); } /* Set up the CPU Interrupt Status Register */ pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00); /* Set up the Error Interrupt Status Register */ pDev->IrqEnableRegisters.error_status_enable = ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) | ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01); /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */ pDev->IrqEnableRegisters.counter_int_status_enable = COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK); /* copy into our temp area */ A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); UNLOCK_AR6K(pDev); /* always synchronous */ status = HIFReadWrite(pDev->HIFDevice, INT_STATUS_ENABLE_ADDRESS, ®s.int_status_enable, AR6K_IRQ_ENABLE_REGS_SIZE, HIF_WR_SYNC_BYTE_INC, NULL); if (status != A_OK) { /* Can't write it for some reason */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to update interrupt control registers err: %d\n", status)); } return status; }
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; }
/* Enables Dragon interrupts */ A_STATUS HTCStart(HTC_TARGET *target) { A_STATUS status; A_UINT32 address; HIF_REQUEST request; HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStart Enter\n"); /* make sure htc ready event is cleared, the event could be stale (already set) from previous start/stop cycles */ A_RESET_WAIT_EVENT(&htcEvent); /* Unmask the host controller interrupts */ HIFUnMaskInterrupt(target->device); /* Enable all the interrupts except for the dragon interrupt */ 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); /* Set up the CPU Interrupt Status Register */ target->table.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00); /* Set up the Error Interrupt Status Register */ target->table.error_status_enable = ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) | ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01); /* Set up the Counter Interrupt Status Register */ target->table.counter_int_status_enable = COUNTER_INT_STATUS_ENABLE_BIT_SET(0xFF); /* Write to the register */ HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS); address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED); status = HIFReadWrite(target->device, address, &target->table.int_status_enable, 4, &request, NULL); if (status != A_OK) { /* Can't write it for some reason */ HTC_DEBUG_PRINTF(ATH_LOG_ERR, "Failed to enable INT_STATUS_ENABLE | CPU_INT_STATUS_ENABLE | ERROR_STATUS_ENABLE | COUNTER_INT_STATUS_ENABLE, err: %d\n", status); HTCStop(target); return status; } #ifdef DEBUG txcreditintrenable[ENDPOINT1] += 1; txcreditintrenable[ENDPOINT2] += 1; txcreditintrenable[ENDPOINT3] += 1; txcreditintrenable[ENDPOINT4] += 1; txcreditintrenableaggregate[ENDPOINT1] += 1; txcreditintrenableaggregate[ENDPOINT2] += 1; txcreditintrenableaggregate[ENDPOINT3] += 1; txcreditintrenableaggregate[ENDPOINT4] += 1; #endif /* DEBUG */ /* Wait on a timed semaphore that will get signalled once the block size negotiation with the target has completed. Furthermore, we have to do it only once during the lifetime of the target detection */ if (!target->ready) { HTC_DEBUG_PRINTF(ATH_LOG_INF, "Waiting for the block size negotiation to finish\n"); A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(&htcEvent, (target->ready == TRUE), HTC_TARGET_RESPONSE_TIMEOUT); if (target->ready) { status = A_OK; } else { status = A_ERROR; HTC_DEBUG_PRINTF(ATH_LOG_ERR, "Failed to negotiate the block sizes\n"); HTCStop(target); } } HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStart Exit\n"); return status; }