Exemple #1
0
int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength)
{
    u32 paddedLength;
    bool   sync = (pPacket->Completion == NULL) ? true : false;
    int status;
    u32 address;
    
       /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
                ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
                WriteLength,
                pDev->MailBoxInfo.GMboxAddress,
                sync ? "SYNC" : "ASYNC"));
                
        /* last byte of packet has to hit the EOM marker */
    address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength;
    
    status = HIFReadWrite(pDev->HIFDevice,
                          address,
                          pPacket->pBuffer,
                          paddedLength,     /* the padded length */
                          sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */

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

    return status;
}
Exemple #2
0
A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength) 
{
    A_UINT32 paddedLength;
    A_BOOL   sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
    A_STATUS status;
    A_UINT32 address;
    
       /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
                ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
                WriteLength,
                pDev->MailBoxInfo.GMboxAddress,
                sync ? "SYNC" : "ASYNC"));
                
        /* last byte of packet has to hit the EOM marker */
    address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength;
    
    status = HIFReadWrite(pDev->HIFDevice,
                          address,
                          pPacket->pBuffer,
                          paddedLength,     /* the padded length */
                          sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */

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

    return status;
}
Exemple #3
0
A_STATUS HIFDevSendBuffer(HIF_SDIO_DEVICE *pDev, unsigned int transferID, a_uint8_t pipe,
        unsigned int nbytes, adf_nbuf_t buf)
{
    A_STATUS status;
    A_UINT32 paddedLength;
    int frag_count = 0, i, head_data_len;
    struct HIFSendContext *pSendContext;
    unsigned char *pData;
    A_UINT32 request = HIF_WR_ASYNC_BLOCK_INC;
    A_UINT8 mboxIndex = HIFDevMapPipeToMailBox(pDev, pipe);

    paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, nbytes);
#ifdef ENABLE_MBOX_DUMMY_SPACE_FEATURE
    A_ASSERT(paddedLength - nbytes < HIF_DUMMY_SPACE_MASK + 1);
    /*
     * two most significant bytes to save dummy data count
     * data written into the dummy space will not put into the final mbox FIFO
     *
     */
    request |= ((paddedLength - nbytes) << 16);
#endif

    frag_count = adf_nbuf_get_num_frags(buf);

    if (frag_count > 1){
        /* header data length should be total sending length substract internal data length of netbuf */
        /*
         * | HIFSendContext | fragments except internal buffer | netbuf->data
         */
        head_data_len = sizeof(struct HIFSendContext) +
                (nbytes - adf_nbuf_get_frag_len(buf, frag_count - 1));
    } else {
        /*
         * | HIFSendContext | netbuf->data
         */
        head_data_len = sizeof(struct HIFSendContext);
    }

    /* Check whether head room is enough to save extra head data */
    if ((head_data_len <= adf_nbuf_headroom(buf)) &&
                (adf_nbuf_tailroom(buf) >= (paddedLength - nbytes))){
        pSendContext = (struct HIFSendContext*)adf_nbuf_push_head(buf, head_data_len);
        pSendContext->bNewAlloc = FALSE;
    } else {
        pSendContext = (struct HIFSendContext*)adf_os_mem_alloc(NULL,
                sizeof(struct HIFSendContext) + paddedLength);
        pSendContext->bNewAlloc = TRUE;
    }

    pSendContext->netbuf = buf;
    pSendContext->pDev = pDev;
    pSendContext->transferID = transferID;
    pSendContext->head_data_len = head_data_len;
    /*
     * Copy data to head part of netbuf or head of allocated buffer.
     * if buffer is new allocated, the last buffer should be copied also.
     * It assume last fragment is internal buffer of netbuf
     * sometime total length of fragments larger than nbytes
     */
    pData = (unsigned char *)pSendContext + sizeof(struct HIFSendContext);
    for (i = 0; i < (pSendContext->bNewAlloc ? frag_count : frag_count - 1); i ++){
        int frag_len = adf_nbuf_get_frag_len(buf, i);
        unsigned char *frag_addr = adf_nbuf_get_frag_vaddr(buf, i);
        if (frag_len > nbytes){
            frag_len = nbytes;
        }
        memcpy(pData, frag_addr, frag_len);
        pData += frag_len;
        nbytes -= frag_len;
        if (nbytes <= 0) {
            break;
        }
    }

    /* Reset pData pointer and send out */
    pData = (unsigned char *)pSendContext + sizeof(struct HIFSendContext);
    status = HIFReadWrite(pDev->HIFDevice,
            pDev->MailBoxInfo.MboxProp[mboxIndex].ExtendedAddress,
            (char*) pData,
            paddedLength,
            request,
            (void*)pSendContext);

    if (status == A_PENDING){
        /*
         * it will return A_PENDING in native HIF implementation,
         * which should be treated as successful result here.
         */
        status = A_OK;
    }
    /* release buffer or move back data pointer when failed */
    if (status != A_OK){
        if (pSendContext->bNewAlloc){
            adf_os_mem_free(pSendContext);
        } else {
            adf_nbuf_pull_head(buf, head_data_len);
        }
    }

    return status;
}