Esempio n. 1
0
A_STATUS 
bmiBufferReceive(HIF_DEVICE *device, 
                 A_UCHAR *buffer, 
                 A_UINT32 length) 
{
    A_STATUS status;
    A_UINT32 address;
    A_UINT32 timeout;
#ifdef ONLY_16BIT
    A_UINT16 cmdCredits;
#else
    A_UCHAR cmdCredits;
#endif
    HIF_REQUEST request;

    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
    address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
    status = HIFReadWrite(device, address, (A_UCHAR *)&cmdCredits, 
                    sizeof(cmdCredits), &request, NULL);
    if (status != A_OK) {
        BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to decrement the command credit count register\n");
        return A_ERROR;
    }

    timeout = BMI_COMMUNICATION_TIMEOUT;
    while(timeout--) {
        if (cmdCredits == 1) {
            HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, 
                              HIF_SYNCHRONOUS, HIF_BYTE_BASIS, 
                              HIF_FIXED_ADDRESS);
            address = HIF_MBOX_END_ADDR(ENDPOINT1);
            status = HIFReadWrite(device, address, buffer, length, 
                                  &request, NULL);
            if (status != A_OK) {
                BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to read the BMI data from the device\n");
                return A_ERROR;
            }
            break;
        }

        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, 
                          HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
        address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
        status = HIFReadWrite(device, address, (A_UCHAR *)&cmdCredits, 
                    sizeof(cmdCredits), &request, NULL);
        if (status != A_OK) {
            BMI_DEBUG_PRINTF(ATH_LOG_ERR,"Unable to decrement the command credit count register\n");
            return A_ERROR;
        }
        status = A_ERROR;
        A_MDELAY(1);
    }

    if (status != A_OK) {
        BMI_DEBUG_PRINTF(ATH_LOG_ERR,"BMI Communication timeout\n");
    }

    return status;
}
Esempio n. 2
0
    /* set the window address register */
A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
{
    A_STATUS status;

        /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
         * last to initiate the access cycle */
    status = HIFReadWrite(hifDevice,
                          RegisterAddr+1,  /* write upper 3 bytes */
                          ((A_UCHAR *)(&Address))+1,
                          sizeof(A_UINT32)-1,
                          HIF_WR_SYNC_BYTE_INC,
                          NULL);

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
             RegisterAddr, Address));
        return status;
    }

        /* write the LSB of the register, this initiates the operation */
    status = HIFReadWrite(hifDevice,
                          RegisterAddr,
                          (A_UCHAR *)(&Address),
                          sizeof(A_UINT8),
                          HIF_WR_SYNC_BYTE_INC,
                          NULL);

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
            RegisterAddr, Address));
        return status;
    }

    return A_OK;
}
Esempio n. 3
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
}
A_STATUS
ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval)
{
    A_STATUS status;
    A_UCHAR vals[4];
    A_UCHAR register_selection[4];

    register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff);
    status = HIFReadWrite(hifDevice,
                          CPU_DBG_SEL_ADDRESS,
                          register_selection,
                          4,
                          HIF_WR_SYNC_BYTE_FIX,
                          NULL);

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
        return status;
    }

    status = HIFReadWrite(hifDevice,
                          CPU_DBG_ADDRESS,
                          (A_UCHAR *)vals,
                          sizeof(vals),
                          HIF_RD_SYNC_BYTE_INC,
                          NULL);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n"));
        return status;
    }

    *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24;

    return status;
}
/* set the window address register (using 4-byte register access ).
 * This mitigates host interconnect issues with non-4byte aligned bus requests, some
 * interconnects use bus adapters that impose strict limitations.
 * Since diag window access is not intended for performance critical operations, the 4byte mode should
 * be satisfactory even though it generates 4X the bus activity.  */
static A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
{
    A_STATUS status;
    static A_UINT8 addrValue[4];
    A_INT32 i;
    static A_UINT32 address;

    address = Address;


    /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
     * last to initiate the access cycle */

    for (i = 1; i <= 3; i++) {
        /* fill the buffer with the address byte value we want to hit 4 times*/
        addrValue[0] = ((A_UINT8 *)&Address)[i];
        addrValue[1] = addrValue[0];
        addrValue[2] = addrValue[0];
        addrValue[3] = addrValue[0];

        /* hit each byte of the register address with a 4-byte write operation to the same address,
         * this is a harmless operation */
        status = HIFReadWrite(hifDevice,
                              RegisterAddr+i,
                              addrValue,
                              4,
                              HIF_WR_SYNC_BYTE_FIX,
                              NULL);
        if (status != A_OK) {
            break;
        }
    }

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
                                      Address, RegisterAddr));
        return status;
    }

    /* write the address register again, this time write the whole 4-byte value.
     * The effect here is that the LSB write causes the cycle to start, the extra
     * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */
    status = HIFReadWrite(hifDevice,
                          RegisterAddr,
                          (A_UCHAR *)(&address),
                          4,
                          HIF_WR_SYNC_BYTE_INC,
                          NULL);

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
                                      Address, RegisterAddr));
        return status;
    }

    return A_OK;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
File: bmi.c Progetto: layerfsd/WLAN
/* BMI Access routines */
A_STATUS
bmiBufferSend(HIF_DEVICE *device,
              A_UCHAR *buffer,
              A_UINT32 length)
{
    A_STATUS status;
    A_UINT32 timeout;
    A_UINT32 address;
    static A_UINT32 cmdCredits;
    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];

    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
                       &mboxAddress[0], sizeof(mboxAddress));

    cmdCredits = 0;
    timeout = BMI_COMMUNICATION_TIMEOUT;

    while(timeout-- && !cmdCredits) {
        /* Read the counter register to get the command credits */
        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
        /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
         * a decrement, while the remaining 3 bytes has no effect.  The rationale behind this is to
         * make all HIF accesses 4-byte aligned */
        status = HIFReadWrite(device, address, (A_UINT8 *)&cmdCredits, 4,
            HIF_RD_SYNC_BYTE_INC, NULL);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
            return A_ERROR;
        }
        /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
        cmdCredits &= 0xFF;
    }

    if (cmdCredits) {
        address = mboxAddress[ENDPOINT1];
        status = HIFReadWrite(device, address, buffer, length,
            HIF_WR_SYNC_BYTE_INC, NULL);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
            return A_ERROR;
        }
    } else {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n"));
        return A_ERROR;
    }

    return status;
}
static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev)
{
    u32 dummy;
    int 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);
    }

    if (pDev->GMboxEnabled) {
        DevNotifyGMboxTargetFailure(pDev);
    }

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

    A_ASSERT(status == 0);
    return status;
}
Esempio n. 10
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;
}
Esempio n. 11
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);
}
Esempio n. 12
0
/*
 * Write to the AR6000 through its diagnostic window.
 * No cooperation from the Target is required for this.
 */
A_STATUS
ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
{
    A_STATUS status;

        /* set write data */
    status = HIFReadWrite(hifDevice,
                          WINDOW_DATA_ADDRESS,
                          (A_UCHAR *)data,
                          sizeof(A_UINT32),
                          HIF_WR_SYNC_BYTE_INC,
                          NULL);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data));
		printk("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data);
        return status;
    }
	   /* set window register, which starts the write cycle */
#if 1
     
	status = ar6000_SetAddressWindowRegister(hifDevice,
                                           WINDOW_WRITE_ADDR_ADDRESS,
                                           *address);
	return status;
#else
    return ar6000_SetAddressWindowRegister(hifDevice,
                                           WINDOW_WRITE_ADDR_ADDRESS,
                                           *address);
#endif

    }
void DumpAR6KDevState(AR6K_DEVICE *pDev)
{
    int                    status;
    AR6K_IRQ_ENABLE_REGISTERS   regs;
    AR6K_IRQ_PROC_REGISTERS     procRegs;

    LOCK_AR6K(pDev);
        /* copy into our temp area */
    A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
    UNLOCK_AR6K(pDev);

        /* load the register table from the device */
    status = HIFReadWrite(pDev->HIFDevice,
                          HOST_INT_STATUS_ADDRESS,
                          (u8 *)&procRegs,
                          AR6K_IRQ_PROC_REGS_SIZE,
                          HIF_RD_SYNC_BYTE_INC,
                          NULL);

    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
            ("DumpAR6KDevState : Failed to read register table (%d) \n",status));
        return;
    }

    DevDumpRegisters(pDev,&procRegs,&regs);

    if (pDev->GMboxInfo.pStateDumpCallback != NULL) {
        pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
    }

        /* dump any bus state at the HIF layer */
    HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0);

}
Esempio n. 14
0
/*
 * Read from the AR6000 through its diagnostic window.
 * No cooperation from the Target is required for this.
 */
A_STATUS
ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
{
    A_STATUS status;

        /* set window register to start read cycle */
    status = ar6000_SetAddressWindowRegister(hifDevice,
                                             WINDOW_READ_ADDR_ADDRESS,
                                             *address);

    if (status != A_OK) {
        return status;
    }

        /* read the data */
    status = HIFReadWrite(hifDevice,
                          WINDOW_DATA_ADDRESS,
                          (A_UCHAR *)data,
                          sizeof(A_UINT32),
                          HIF_RD_SYNC_BYTE_INC,
                          NULL);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
        return status;
    }

    return status;
}
Esempio n. 15
0
A_STATUS
htcBlkSzNegCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
                        A_STATUS status)
{
    HTC_TARGET *target;
    HTC_ENDPOINT *endPoint;
    HIF_REQUEST request;
    HTC_MBOX_BUFFER *mboxBuffer;
    HTC_REG_REQUEST_ELEMENT *regElement;
    A_UINT32 address;

    /* Get the context */
    mboxBuffer = GET_MBOX_BUFFER(element);
    AR_DEBUG_ASSERT(mboxBuffer != NULL);
    endPoint = mboxBuffer->endPoint;
    AR_DEBUG_ASSERT(endPoint != NULL);
    target = endPoint->target;
    AR_DEBUG_ASSERT(target != NULL);

    /* Recycle the request element */
    RECYCLE_DATA_REQUEST_ELEMENT(element);
    element->completionCB = htcTxCompletionCB;

    if (status == A_OK) {
        /* Mark the state to be ready */
        endPoint->enabled = TRUE;
        
        /* Set the state of the target as ready */
        if (target->endPoint[ENDPOINT1].enabled &&
            target->endPoint[ENDPOINT2].enabled &&
            target->endPoint[ENDPOINT3].enabled &&
            target->endPoint[ENDPOINT4].enabled )
        {
            /* Send the INT_WLAN interrupt to the target */
            target->table.int_wlan = 1;
            HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, 
                              HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, 
                              HIF_FIXED_ADDRESS);
            address = getRegAddr(INT_WLAN_REG, ENDPOINT_UNUSED);
            regElement = allocateRegRequestElement(target);
            AR_DEBUG_ASSERT(regElement != NULL);
            FILL_REG_BUFFER(regElement, &target->table.int_wlan, sizeof(target->table.int_wlan),
                            INT_WLAN_REG, ENDPOINT_UNUSED);
            status = HIFReadWrite(target->device, address, 
                                  (A_UCHAR *)&target->table.int_wlan, 
                                  sizeof(target->table.int_wlan), &request, regElement);
#ifndef HTC_SYNC
            AR_DEBUG_ASSERT(status == A_OK);
#else
			AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
			if(status == A_OK) {
				regElement->completionCB(regElement, status);
			}
#endif
        }
    }

    return A_OK;
}
Esempio n. 16
0
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(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);

    UNLOCK_AR6K(pDev);

        /* always synchronous */
    status = HIFReadWrite(pDev->HIFDevice,
                          INT_STATUS_ENABLE_ADDRESS,
                          &regs.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;
}
Esempio n. 17
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;
}
Esempio n. 18
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;
}
Esempio n. 19
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;
}
A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
{
    A_STATUS status;
    A_UINT8 addrValue[4];
    A_INT32 i;
    for (i = 1; i <= 3; i++) {
        addrValue[0] = ((A_UINT8 *)&Address)[i];
        addrValue[1] = addrValue[0];
        addrValue[2] = addrValue[0];
        addrValue[3] = addrValue[0];
        status = HIFReadWrite(hifDevice,
                              RegisterAddr+i,
                              addrValue,
                              4,
                              HIF_WR_SYNC_BYTE_FIX,
                              NULL);
        if (status != A_OK) {
            break;
        }
    }

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
             RegisterAddr, Address));
        return status;
    }

    status = HIFReadWrite(hifDevice,
                          RegisterAddr,
                          (A_UCHAR *)(&Address),
                          4,
                          HIF_WR_SYNC_BYTE_INC,
                          NULL);

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
            RegisterAddr, Address));
        return status;
    }

    return A_OK;



}
Esempio n. 21
0
int DevSetupGMbox(struct ar6k_device *pDev)
{
    int    status = 0;
    u8 muxControl[4];
    
    do {
        
        if (0 == pDev->MailBoxInfo.GMboxAddress) {
            break;    
        }
    
        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n",
                    pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize));
                    
        status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
        
        if (status) {
            break;    
        }
       
            /* write to mailbox look ahead mux control register, we want the
             * GMBOX lookaheads to appear on lookaheads 2 and 3 
             * the register is 1-byte wide so we need to hit it 4 times to align the operation 
             * to 4-bytes */            
        muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3;
        muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3;
        muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3;
        muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3;
                
        status = HIFReadWrite(pDev->HIFDevice,
                              GMBOX_LOOKAHEAD_MUX_REG,
                              muxControl,
                              sizeof(muxControl),
                              HIF_WR_SYNC_BYTE_FIX,  /* hit this register 4 times */
                              NULL);
        
        if (status) {
            break;    
        }
        
        status = GMboxProtocolInstall(pDev);
        
        if (status) {
            break;    
        }
        
        pDev->GMboxEnabled = true;
        
    } while (false);
    
    return status;
}
Esempio n. 22
0
int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending)
{
    int    status          = 0;
    u8     host_int_status = 0x0;
    u32 counter         = 0x0;

    if(TimeoutInMs < 100)
    {
        TimeoutInMs = 100;
    }

    counter = TimeoutInMs / 100;

    do
    {
        //Read the Host Interrupt Status Register
        status = HIFReadWrite(pDev->HIFDevice,
                              HOST_INT_STATUS_ADDRESS,
                             &host_int_status,
                              sizeof(u8),
                              HIF_RD_SYNC_BYTE_INC,
                              NULL);
        if (status)
        {
            AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status));
            break;
        }

        host_int_status = !status ? (host_int_status & (1 << 0)):0;
        if(!host_int_status)
        {
            status          = 0;
           *pbIsRecvPending = false;
            break;
        }
        else
        {
            *pbIsRecvPending = true;
        }

        A_MDELAY(100);

        counter--;

    }while(counter);
    return status;
}
Esempio n. 23
0
A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending)
{
    A_STATUS    status          = A_OK;
    A_UCHAR     host_int_status = 0x0;
    A_UINT32    counter         = 0x0;

    if(TimeoutInMs < 100)
    {
        TimeoutInMs = 100;
    }

    counter = TimeoutInMs / 100;

    do
    {
        //Read the Host Interrupt Status Register
        status = HIFReadWrite(pDev->HIFDevice,
                              HOST_INT_STATUS_ADDRESS,
                             &host_int_status,
                              sizeof(A_UCHAR),
                              HIF_RD_SYNC_BYTE_INC,
                              NULL);
        if(A_FAILED(status))
        {
            AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status));
            break;
        }

        host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)):0;
        if(!host_int_status)
        {
            status          = A_OK;
           *pbIsRecvPending = FALSE;
            break;
        }
        else
        {
            *pbIsRecvPending = TRUE;
        }

        A_MDELAY(100);

        counter--;

    }while(counter);
    return status;
}
Esempio n. 24
0
static int hifDeviceSuspend(struct device *dev)
{
	struct sdio_func *func = dev_to_sdio_func(dev);
    A_STATUS status = A_OK;
    HIF_DEVICE *device;   
    device = getHifDevice(func);
    if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
        status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext);
    }
    if (status == A_OK) {
        int oldresetvalue = reset_sdio_on_unload;
        reset_sdio_on_unload = 1;
        hifDisableFunc(device, func);
        reset_sdio_on_unload = oldresetvalue;
        device->is_suspend = TRUE;
    } else if (status == A_EBUSY) {
        A_INT32 cnt = 10;
        A_UINT8 host_int_status;
	    do {            		    
		    while (atomic_read(&device->irqHandling)) {
			    /* wait until irq handler finished all the jobs */
			    schedule_timeout(HZ/10);
		    }
		    /* check if there is any pending irq due to force done */
		    host_int_status = 0;
		    status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
				    (A_UINT8 *)&host_int_status, sizeof(host_int_status),
				    HIF_RD_SYNC_BYTE_INC, NULL);
		    host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0;
		    if (host_int_status) {
			    schedule(); /* schedule for next dsrHandler */
		    }
	    } while (host_int_status && --cnt > 0);

        if (host_int_status && cnt == 0) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
                            ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n",
					        __FUNCTION__));
        }
#if 1
        status = A_OK; /* assume that sdio host controller will take care the power of wifi chip */
#else
        return -EBUSY; /* Return -EBUSY if customer use all android patch of mmc stack provided by us */ 
#endif 
    }
    return A_SUCCESS(status) ? 0 : status;
}
Esempio n. 25
0
/* poll the mailbox credit counter until we get a credit or timeout */
static A_STATUS GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits)
{
    A_STATUS status = A_OK;
    int      timeout = TEST_CREDITS_RECV_TIMEOUT;
    A_UINT8  credits = 0;
    A_UINT32 address;

    while (TRUE) 
	{

		/* Read the counter register to get credits, this auto-decrements  */
        address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4;
        status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits),
                              HIF_RD_SYNC_BYTE_FIX, NULL);
        if (status != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("Unable to decrement the command credit count register (mbox=%d)\n",mbox));
            status = A_ERROR;
            break;
        }

        if (credits) {
            break;
        }

        timeout--;

        if (timeout <= 0) {
              AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address));
            status = A_ERROR;
            break;
        }

         /* delay a little, target may not be ready */
         A_MDELAY(1000);

    }

    if (status == A_OK) {
        *pCredits = credits;
    }

    return status;
}
Esempio n. 26
0
void
htcServiceErrorInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    A_UINT8 error_int_status;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Error Interrupt\n");
    error_int_status = target->table.error_int_status &
                       target->table.error_status_enable;
    AR_DEBUG_ASSERT(error_int_status);
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
                    error_int_status);

    if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
        /* Wakeup */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Wakeup\n");
    }
        
    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
        /* Rx Underflow */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Rx Underflow\n");
    }
        
    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
        /* Tx Overflow */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Tx Overflow\n");
    }

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

    AR_DEBUG_ASSERT(status == A_OK);
}
Esempio n. 27
0
/* send the ordered buffers to the target */
static A_STATUS SendBuffers(AR6K_DEVICE *pDev, int mbox)
{
    A_STATUS         status = A_OK;
    A_UINT32         request = HIF_WR_SYNC_BLOCK_INC;
    BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH];
    int              i;
    int              totalBytes = 0;
    int              paddedLength;
    int              totalwPadding = 0;

    AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox));

        /* fill buffer with counting pattern */
    InitBuffers(FILL_COUNTING);

        /* assemble the order in which we send */
    AssembleBufferList(sendList);

    for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) {

            /* we are doing block transfers, so we need to pad everything to a block size */
        paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) &
                       (~(g_BlockSizes[mbox] - 1));

            /* send each buffer synchronously */
        status = HIFReadWrite(pDev->HIFDevice,
                              g_MailboxAddrs[mbox],
                              sendList[i].pBuffer,
                              paddedLength,
                              request,
                              NULL);
        if (status != A_OK) {
            break;
        }
        totalBytes += sendList[i].length;
        totalwPadding += paddedLength;
    }

    AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox));

    return status;
}
Esempio n. 28
0
A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength) 
{
    
    A_UINT32 paddedLength;
    A_STATUS status;
    A_BOOL   sync = (pPacket->Completion == NULL) ? TRUE : FALSE;

        /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
                    
    if (paddedLength > pPacket->BufferLength) {
        A_ASSERT(FALSE);
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
                    paddedLength,ReadLength,pPacket->BufferLength));
        if (pPacket->Completion != NULL) {
            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
            return A_OK;
        }
        return A_EINVAL;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
                ("DevGMboxRead (0x%X : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
                (A_UINT32)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
                paddedLength,
                pDev->MailBoxInfo.GMboxAddress,
                sync ? "SYNC" : "ASYNC"));

    status = HIFReadWrite(pDev->HIFDevice,
                          pDev->MailBoxInfo.GMboxAddress,
                          pPacket->pBuffer,
                          paddedLength,
                          sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */

    if (sync) {
        pPacket->Status = status;
    }

    return status;
}
Esempio n. 29
0
int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength)
{
    
    u32 paddedLength;
    int status;
    bool   sync = (pPacket->Completion == NULL) ? true : false;

        /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
                    
    if (paddedLength > pPacket->BufferLength) {
        A_ASSERT(false);
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
                    paddedLength,ReadLength,pPacket->BufferLength));
        if (pPacket->Completion != NULL) {
            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
            return 0;
        }
        return A_EINVAL;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
                ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
                (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
                paddedLength,
                pDev->MailBoxInfo.GMboxAddress,
                sync ? "SYNC" : "ASYNC"));

    status = HIFReadWrite(pDev->HIFDevice,
                          pDev->MailBoxInfo.GMboxAddress,
                          pPacket->pBuffer,
                          paddedLength,
                          sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */

    if (sync) {
        pPacket->Status = status;
    }

    return status;
}
Esempio n. 30
0
int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes)
{

    int                    status = 0;
    struct ar6k_irq_proc_registers     procRegs;
    int                         maxCopy;
  
    do {
            /* on entry the caller provides the length of the lookahead buffer */
        if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) {
            A_ASSERT(false);
            status = A_EINVAL;
            break;    
        }
        
        maxCopy = *pLookAheadBytes;
        *pLookAheadBytes = 0;
            /* load the register table from the device */
        status = HIFReadWrite(pDev->HIFDevice,
                              HOST_INT_STATUS_ADDRESS,
                              (u8 *)&procRegs,
                              AR6K_IRQ_PROC_REGS_SIZE,
                              HIF_RD_SYNC_BYTE_INC,
                              NULL);

        if (status) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status));
            break;
        }
        
        if (procRegs.gmbox_rx_avail > 0) {
            int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail;
            memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes);
            *pLookAheadBytes = bytes;
        }
        
    } while (false);
       
    return status; 
}