Beispiel #1
0
A_STATUS
BMIGetTargetInfo(A_VOID *pCxt, struct bmi_target_info *targ_info)
{
    A_UINT32 cid;

    if (bmiDone) {
        return A_ERROR;
    }

    cid = A_CPU2LE32(BMI_GET_TARGET_INFO);

    if(A_OK != bmiBufferSend(pCxt, (A_UCHAR *)&cid, sizeof(cid))){    
        return A_ERROR;
    }

    if(A_OK != bmiBufferReceive(pCxt, (A_UCHAR *)&targ_info->target_ver,
                                                sizeof(targ_info->target_ver), TRUE)){
    	return A_ERROR;                                            
    }    
    
    targ_info->target_ver = A_LE2CPU32(targ_info->target_ver);

    if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
        /* Determine how many bytes are in the Target's targ_info */
        if(A_OK != bmiBufferReceive(pCxt, (A_UCHAR *)&targ_info->target_info_byte_count,
                                            sizeof(targ_info->target_info_byte_count), TRUE)){
			return A_ERROR;
		}                                            
        
        targ_info->target_info_byte_count = A_LE2CPU32(targ_info->target_info_byte_count);

        /*
         * The Target's targ_info doesn't match the Host's targ_info.
         * We need to do some backwards compatibility work to make this OK.
         */
        A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));

        /* Read the remainder of the targ_info */
        if(A_OK != bmiBufferReceive(pCxt,
                        ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count),
                        sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE)){
            return A_ERROR;
        }
        
        targ_info->target_ver = A_LE2CPU32(targ_info->target_ver);
        targ_info->target_type = A_LE2CPU32(targ_info->target_type);
    } else {
    	return A_ERROR;
    } 

    return A_OK;
}
Beispiel #2
0
static A_STATUS
bmiBufferSend(A_VOID *pCxt,
              A_UCHAR *buffer,
              A_UINT32 length)
{
	A_NETBUF_DECLARE req;
	A_VOID *pReq = (A_VOID*)&req;
	A_STATUS status;
    A_UINT32 timeout;
    A_UINT32 address;
    //A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);    
   	
   	A_NETBUF_CONFIGURE(pReq, pBMICmdCredits, 0, sizeof(A_UINT32), sizeof(A_UINT32));
   	
   	*pBMICmdCredits = 0;
    timeout = BMI_COMMUNICATION_TIMEOUT;

    while(timeout-- && !(*pBMICmdCredits)) {
        /* Read the counter register to get the command credits */
        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + BMI_ENDPOINT) * 4;
        ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, address, A_TRUE, sizeof(A_UINT32));
        /* 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 */
        if(A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))){
			break;
		}
		
        
        /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
        
		*pBMICmdCredits = A_LE2CPU32(*pBMICmdCredits);        
        
        (*pBMICmdCredits) &= 0xFF;
    }
    
    if (*pBMICmdCredits) {
        A_NETBUF_CONFIGURE(pReq, buffer, 0, length, length);        
        address = Hcd_GetMboxAddress(pCxt, BMI_ENDPOINT, length);        
        address &= ATH_TRANS_ADDR_MASK;
        A_NETBUF_SET_ELEM(pReq, A_REQ_ADDRESS, address);
        A_NETBUF_SET_ELEM(pReq, A_REQ_TRANSFER_LEN, length);
        /* init the packet read params/cmd incremental vs fixed address etc. */
        A_NETBUF_SET_ELEM(pReq, A_REQ_COMMAND, (ATH_TRANS_WRITE | ATH_TRANS_DMA));        
        status = Hcd_Request(pCxt, pReq);
        if (status != A_OK) {
            return A_ERROR;
        }
    } else {
        return A_ERROR;
    }

    
    return status;
}             
Beispiel #3
0
/*  Strrcl_ChipUpFinish - Utility function to complete the chip_up process.
 *	 when WMI_READY is received from chip this function clears the chipDown
 * 	 boolean and sends the wmi store recall command to the chip so that its
 *	 associated State can be refreshed.
 *      void *pCxt - the driver context.
 *****************************************************************************/
static A_STATUS Strrcl_ChipUpFinish(void *pCxt)
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    WMI_STORERECALL_RECALL_CMD *pDsetInfo;
    uint32_t dset_info_len;

    if (pDCxt->wmiReady == true)
    {
        switch (pDCxt->strrclState)
        {
            case STRRCL_ST_ACTIVE:
                /* clear the chipDown boolean to allow outside activity to resume */
                pDCxt->chipDown = false;

                if (A_OK != STACK_INIT(pCxt))
                {
                    break;
                }

                pDCxt->strrclState = STRRCL_ST_ACTIVE_B;
            // INTENTIONAL FALL_THRU
            case STRRCL_ST_ACTIVE_B:
/* send recall */
#if 0
		    pEv = (WMI_STORERECALL_STORE_EVENT*)pDCxt->strrclCxt;

            if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pEv->length), &pEv->data[0])){
                break; //try again later this is likely because a previous wmi cmd has not finished.
            }
#elifndef ENABLE_LARGE_DSET

		    setup_host_dset(pCxt);

		    pDsetData = pDCxt->tempStorage;

            if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pDCxt->strrclCxtLen), pDsetData)){
                break; //try again later this is likely because a previous wmi cmd has not finished.
            }
#else
                setup_host_dset(pCxt);

                pDsetInfo = (WMI_STORERECALL_RECALL_CMD *)pDCxt->tempStorage;
                if (pDsetInfo->length == 0)
                {
                    dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD);
                }
                else
                {
                    dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD) - sizeof(uint8_t);
                    dset_info_len += sizeof(WMI_STORERECALL_RECALL_DSET) * pDsetInfo->length;
                }

                if (A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, dset_info_len, pDsetInfo))
                {
                    break; // try again later this is likely because a previous wmi cmd has not finished.
                }
#endif

                pDCxt->strrclCxt = NULL;
                pDCxt->strrclCxtLen = 0;

                //            pDCxt->strrclState = STRRCL_ST_AWAIT_FW;

                pDCxt->strrclState = STRRCL_ST_INIT;
                pDCxt->strrclBlock = false;

                /* Indicate completion to the custom layer */
                API_STORE_RECALL_EVENT(pCxt);

                /* clear this function from the driver's temporary calls */
                pDCxt->asynchRequest = NULL;
                /* Since we are setting MAX_PERF before going to store-recall we need to set the state
                   after we wakes up */
                restore_power_state(pDCxt, 1); /* POWER_STATE_MOVED_FOR_STRRCL */

                break; // done!!
            default:
                A_ASSERT(0); // should never happen
#if DRIVER_CONFIG_DISABLE_ASSERT
                break;
#endif
        }
    }

    return A_OK;
}
Beispiel #4
0
/*  Driver_DumpAssertInfo - Collects assert information from chip and writes
 *	 it to stdout.
 *      void *pCxt - the driver context.
 *		uint32_t *pData - buffer to store UINT32 results
 *		uint16_t *pLength - IN/OUT param to store length of buffer for IN and
 *		 length of contents for OUT.
 *****************************************************************************/
A_STATUS
Driver_DumpAssertInfo(void *pCxt, uint32_t *pData, uint16_t *pLength)
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    uint32_t address;
    uint32_t regDumpArea = 0;
    A_STATUS status = A_ERROR;
    uint32_t regDumpCount = 0;

    do
    {
        if (*pLength < REGISTER_DUMP_LEN_MAX)
        {
            break;
        }
        /* clear it */
        *pLength = 0;
        /* the reg dump pointer is copied to the host interest area */
        address = HOST_INTEREST_ITEM_ADDRESS(hi_failure_state);
        address = TARG_VTOP(address);

        if (pDCxt->targetType == TARGET_TYPE_AR4100 || pDCxt->targetType == TARGET_TYPE_AR400X)
        {
            regDumpCount = REG_DUMP_COUNT_AR4100;
        }
        else
        {
            A_ASSERT(0); /* should never happen */
#if DRIVER_CONFIG_DISABLE_ASSERT
            break;
#endif
        }

        /* read RAM location through diagnostic window */
        if (A_OK != (status = Driver_ReadRegDiag(pCxt, &address, &regDumpArea)))
        {
            A_ASSERT(0); /* should never happen */
#if DRIVER_CONFIG_DISABLE_ASSERT
            break;
#endif
        }

        regDumpArea = A_LE2CPU32(regDumpArea);

        if (regDumpArea == 0)
        {
            /* no reg dump */
            break;
        }

        regDumpArea = TARG_VTOP(regDumpArea);

        /* fetch register dump data */
        if (A_OK !=
            (status = Driver_ReadDataDiag(pCxt, regDumpArea, (uint8_t *)&pData[0], regDumpCount * (sizeof(uint32_t)))))
        {
            A_ASSERT(0); /* should never happen */
#if DRIVER_CONFIG_DISABLE_ASSERT
            break;
#endif
        }

        *pLength = regDumpCount;
    } while (0);

    return status;
}