static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) { long long address; u32 addr; devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev, BRCMF_DMA_D2H_SCRATCH_BUF_LEN, &devinfo->shared.scratch_dmahandle, GFP_KERNEL); if (!devinfo->shared.scratch) goto fail; memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); brcmf_dma_flush(devinfo->shared.scratch, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); addr = devinfo->shared.tcm_base_address + BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; address = (long long)(long)devinfo->shared.scratch_dmahandle; brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); addr = devinfo->shared.tcm_base_address + BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET; brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); devinfo->shared.ringupd = dma_alloc_coherent(&devinfo->pdev->dev, BRCMF_DMA_D2H_RINGUPD_BUF_LEN, &devinfo->shared.ringupd_dmahandle, GFP_KERNEL); if (!devinfo->shared.ringupd) goto fail; memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); brcmf_dma_flush(devinfo->shared.ringupd, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); addr = devinfo->shared.tcm_base_address + BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; address = (long long)(long)devinfo->shared.ringupd_dmahandle; brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); addr = devinfo->shared.tcm_base_address + BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET; brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); return 0; fail: brcmf_err("Allocating scratch buffers failed\n"); brcmf_pcie_release_scratchbuffers(devinfo); return -ENOMEM; }
static int brcmf_msgbuf_tx_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len) { struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; struct brcmf_commonring *commonring; struct msgbuf_ioctl_req_hdr *request; u16 buf_len; void *ret_ptr; int err; commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; brcmf_commonring_lock(commonring); ret_ptr = brcmf_commonring_reserve_for_write(commonring); if (!ret_ptr) { brcmf_err("Failed to reserve space in commonring\n"); brcmf_commonring_unlock(commonring); return -ENOMEM; } msgbuf->reqid++; request = (struct msgbuf_ioctl_req_hdr *)ret_ptr; request->msg.msgtype = MSGBUF_TYPE_IOCTLPTR_REQ; request->msg.ifidx = (u8)ifidx; request->msg.flags = 0; request->msg.request_id = cpu_to_le32(BRCMF_IOCTL_REQ_PKTID); request->cmd = cpu_to_le32(cmd); request->output_buf_len = cpu_to_le16(len); request->trans_id = cpu_to_le16(msgbuf->reqid); buf_len = min_t(u16, len, BRCMF_TX_IOCTL_MAX_MSG_SIZE); request->input_buf_len = cpu_to_le16(buf_len); request->req_buf_addr.high_addr = cpu_to_le32(msgbuf->ioctbuf_phys_hi); request->req_buf_addr.low_addr = cpu_to_le32(msgbuf->ioctbuf_phys_lo); if (buf) memcpy(msgbuf->ioctbuf, buf, buf_len); else memset(msgbuf->ioctbuf, 0, buf_len); brcmf_dma_flush(ioctl_buf, buf_len); err = brcmf_commonring_write_complete(commonring); brcmf_commonring_unlock(commonring); return err; }