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; }
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; }
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; }