|
@@ -135,7 +135,7 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
|
|
BRCMF_PCIE_MB_INT_D2H3_DB1)
|
|
|
|
|
|
#define BRCMF_PCIE_MIN_SHARED_VERSION 5
|
|
|
-#define BRCMF_PCIE_MAX_SHARED_VERSION 5
|
|
|
+#define BRCMF_PCIE_MAX_SHARED_VERSION 6
|
|
|
#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF
|
|
|
#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000
|
|
|
#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000
|
|
@@ -166,17 +166,6 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
|
|
#define BRCMF_RING_MEM_SZ 16
|
|
|
#define BRCMF_RING_STATE_SZ 8
|
|
|
|
|
|
-#define BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET 4
|
|
|
-#define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8
|
|
|
-#define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12
|
|
|
-#define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16
|
|
|
-#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET 20
|
|
|
-#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET 28
|
|
|
-#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET 36
|
|
|
-#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET 44
|
|
|
-#define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0
|
|
|
-#define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52
|
|
|
-
|
|
|
#define BRCMF_DEF_MAX_RXBUFPOST 255
|
|
|
|
|
|
#define BRCMF_CONSOLE_BUFADDR_OFFSET 8
|
|
@@ -231,7 +220,9 @@ struct brcmf_pcie_shared_info {
|
|
|
struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
|
|
|
struct brcmf_pcie_ringbuf *flowrings;
|
|
|
u16 max_rxbufpost;
|
|
|
- u32 nrof_flowrings;
|
|
|
+ u16 max_flowrings;
|
|
|
+ u16 max_submissionrings;
|
|
|
+ u16 max_completionrings;
|
|
|
u32 rx_dataoffset;
|
|
|
u32 htod_mb_data_addr;
|
|
|
u32 dtoh_mb_data_addr;
|
|
@@ -241,6 +232,7 @@ struct brcmf_pcie_shared_info {
|
|
|
dma_addr_t scratch_dmahandle;
|
|
|
void *ringupd;
|
|
|
dma_addr_t ringupd_dmahandle;
|
|
|
+ u8 version;
|
|
|
};
|
|
|
|
|
|
struct brcmf_pcie_core_info {
|
|
@@ -284,6 +276,36 @@ struct brcmf_pcie_ringbuf {
|
|
|
u8 id;
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * struct brcmf_pcie_dhi_ringinfo - dongle/host interface shared ring info
|
|
|
+ *
|
|
|
+ * @ringmem: dongle memory pointer to ring memory location
|
|
|
+ * @h2d_w_idx_ptr: h2d ring write indices dongle memory pointers
|
|
|
+ * @h2d_r_idx_ptr: h2d ring read indices dongle memory pointers
|
|
|
+ * @d2h_w_idx_ptr: d2h ring write indices dongle memory pointers
|
|
|
+ * @d2h_r_idx_ptr: d2h ring read indices dongle memory pointers
|
|
|
+ * @h2d_w_idx_hostaddr: h2d ring write indices host memory pointers
|
|
|
+ * @h2d_r_idx_hostaddr: h2d ring read indices host memory pointers
|
|
|
+ * @d2h_w_idx_hostaddr: d2h ring write indices host memory pointers
|
|
|
+ * @d2h_r_idx_hostaddr: d2h ring reaD indices host memory pointers
|
|
|
+ * @max_flowrings: maximum number of tx flow rings supported.
|
|
|
+ * @max_submissionrings: maximum number of submission rings(h2d) supported.
|
|
|
+ * @max_completionrings: maximum number of completion rings(d2h) supported.
|
|
|
+ */
|
|
|
+struct brcmf_pcie_dhi_ringinfo {
|
|
|
+ __le32 ringmem;
|
|
|
+ __le32 h2d_w_idx_ptr;
|
|
|
+ __le32 h2d_r_idx_ptr;
|
|
|
+ __le32 d2h_w_idx_ptr;
|
|
|
+ __le32 d2h_r_idx_ptr;
|
|
|
+ struct msgbuf_buf_addr h2d_w_idx_hostaddr;
|
|
|
+ struct msgbuf_buf_addr h2d_r_idx_hostaddr;
|
|
|
+ struct msgbuf_buf_addr d2h_w_idx_hostaddr;
|
|
|
+ struct msgbuf_buf_addr d2h_r_idx_hostaddr;
|
|
|
+ __le16 max_flowrings;
|
|
|
+ __le16 max_submissionrings;
|
|
|
+ __le16 max_completionrings;
|
|
|
+};
|
|
|
|
|
|
static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = {
|
|
|
BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM,
|
|
@@ -1054,26 +1076,35 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
|
|
|
{
|
|
|
struct brcmf_pcie_ringbuf *ring;
|
|
|
struct brcmf_pcie_ringbuf *rings;
|
|
|
- u32 ring_addr;
|
|
|
u32 d2h_w_idx_ptr;
|
|
|
u32 d2h_r_idx_ptr;
|
|
|
u32 h2d_w_idx_ptr;
|
|
|
u32 h2d_r_idx_ptr;
|
|
|
- u32 addr;
|
|
|
u32 ring_mem_ptr;
|
|
|
u32 i;
|
|
|
u64 address;
|
|
|
u32 bufsz;
|
|
|
- u16 max_sub_queues;
|
|
|
u8 idx_offset;
|
|
|
-
|
|
|
- ring_addr = devinfo->shared.ring_info_addr;
|
|
|
- brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr);
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES;
|
|
|
- max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr);
|
|
|
+ struct brcmf_pcie_dhi_ringinfo ringinfo;
|
|
|
+ u16 max_flowrings;
|
|
|
+ u16 max_submissionrings;
|
|
|
+ u16 max_completionrings;
|
|
|
+
|
|
|
+ memcpy_fromio(&ringinfo, devinfo->tcm + devinfo->shared.ring_info_addr,
|
|
|
+ sizeof(ringinfo));
|
|
|
+ if (devinfo->shared.version >= 6) {
|
|
|
+ max_submissionrings = le16_to_cpu(ringinfo.max_submissionrings);
|
|
|
+ max_flowrings = le16_to_cpu(ringinfo.max_flowrings);
|
|
|
+ max_completionrings = le16_to_cpu(ringinfo.max_completionrings);
|
|
|
+ } else {
|
|
|
+ max_submissionrings = le16_to_cpu(ringinfo.max_flowrings);
|
|
|
+ max_flowrings = max_submissionrings -
|
|
|
+ BRCMF_NROF_H2D_COMMON_MSGRINGS;
|
|
|
+ max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
|
|
|
+ }
|
|
|
|
|
|
if (devinfo->dma_idx_sz != 0) {
|
|
|
- bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) *
|
|
|
+ bufsz = (max_submissionrings + max_completionrings) *
|
|
|
devinfo->dma_idx_sz * 2;
|
|
|
devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz,
|
|
|
&devinfo->idxbuf_dmahandle,
|
|
@@ -1083,14 +1114,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
|
|
|
}
|
|
|
|
|
|
if (devinfo->dma_idx_sz == 0) {
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET;
|
|
|
- d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET;
|
|
|
- d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET;
|
|
|
- h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET;
|
|
|
- h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
|
|
|
+ d2h_w_idx_ptr = le32_to_cpu(ringinfo.d2h_w_idx_ptr);
|
|
|
+ d2h_r_idx_ptr = le32_to_cpu(ringinfo.d2h_r_idx_ptr);
|
|
|
+ h2d_w_idx_ptr = le32_to_cpu(ringinfo.h2d_w_idx_ptr);
|
|
|
+ h2d_r_idx_ptr = le32_to_cpu(ringinfo.h2d_r_idx_ptr);
|
|
|
idx_offset = sizeof(u32);
|
|
|
devinfo->write_ptr = brcmf_pcie_write_tcm16;
|
|
|
devinfo->read_ptr = brcmf_pcie_read_tcm16;
|
|
@@ -1103,34 +1130,42 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
|
|
|
devinfo->read_ptr = brcmf_pcie_read_idx;
|
|
|
|
|
|
h2d_w_idx_ptr = 0;
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET;
|
|
|
address = (u64)devinfo->idxbuf_dmahandle;
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
|
|
|
-
|
|
|
- h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset;
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET;
|
|
|
- address += max_sub_queues * idx_offset;
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
|
|
|
-
|
|
|
- d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset;
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET;
|
|
|
- address += max_sub_queues * idx_offset;
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
|
|
|
+ ringinfo.h2d_w_idx_hostaddr.low_addr =
|
|
|
+ cpu_to_le32(address & 0xffffffff);
|
|
|
+ ringinfo.h2d_w_idx_hostaddr.high_addr =
|
|
|
+ cpu_to_le32(address >> 32);
|
|
|
+
|
|
|
+ h2d_r_idx_ptr = h2d_w_idx_ptr +
|
|
|
+ max_submissionrings * idx_offset;
|
|
|
+ address += max_submissionrings * idx_offset;
|
|
|
+ ringinfo.h2d_r_idx_hostaddr.low_addr =
|
|
|
+ cpu_to_le32(address & 0xffffffff);
|
|
|
+ ringinfo.h2d_r_idx_hostaddr.high_addr =
|
|
|
+ cpu_to_le32(address >> 32);
|
|
|
+
|
|
|
+ d2h_w_idx_ptr = h2d_r_idx_ptr +
|
|
|
+ max_submissionrings * idx_offset;
|
|
|
+ address += max_submissionrings * idx_offset;
|
|
|
+ ringinfo.d2h_w_idx_hostaddr.low_addr =
|
|
|
+ cpu_to_le32(address & 0xffffffff);
|
|
|
+ ringinfo.d2h_w_idx_hostaddr.high_addr =
|
|
|
+ cpu_to_le32(address >> 32);
|
|
|
|
|
|
d2h_r_idx_ptr = d2h_w_idx_ptr +
|
|
|
- BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET;
|
|
|
- address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
|
|
|
- brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
|
|
|
+ max_completionrings * idx_offset;
|
|
|
+ address += max_completionrings * idx_offset;
|
|
|
+ ringinfo.d2h_r_idx_hostaddr.low_addr =
|
|
|
+ cpu_to_le32(address & 0xffffffff);
|
|
|
+ ringinfo.d2h_r_idx_hostaddr.high_addr =
|
|
|
+ cpu_to_le32(address >> 32);
|
|
|
+
|
|
|
+ memcpy_toio(devinfo->tcm + devinfo->shared.ring_info_addr,
|
|
|
+ &ringinfo, sizeof(ringinfo));
|
|
|
brcmf_dbg(PCIE, "Using host memory indices\n");
|
|
|
}
|
|
|
|
|
|
- addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET;
|
|
|
- ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
|
|
|
+ ring_mem_ptr = le32_to_cpu(ringinfo.ringmem);
|
|
|
|
|
|
for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) {
|
|
|
ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr);
|
|
@@ -1161,20 +1196,19 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
|
|
|
ring_mem_ptr += BRCMF_RING_MEM_SZ;
|
|
|
}
|
|
|
|
|
|
- devinfo->shared.nrof_flowrings =
|
|
|
- max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS;
|
|
|
- rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring),
|
|
|
- GFP_KERNEL);
|
|
|
+ devinfo->shared.max_flowrings = max_flowrings;
|
|
|
+ devinfo->shared.max_submissionrings = max_submissionrings;
|
|
|
+ devinfo->shared.max_completionrings = max_completionrings;
|
|
|
+ rings = kcalloc(max_flowrings, sizeof(*ring), GFP_KERNEL);
|
|
|
if (!rings)
|
|
|
goto fail;
|
|
|
|
|
|
- brcmf_dbg(PCIE, "Nr of flowrings is %d\n",
|
|
|
- devinfo->shared.nrof_flowrings);
|
|
|
+ brcmf_dbg(PCIE, "Nr of flowrings is %d\n", max_flowrings);
|
|
|
|
|
|
- for (i = 0; i < devinfo->shared.nrof_flowrings; i++) {
|
|
|
+ for (i = 0; i < max_flowrings; i++) {
|
|
|
ring = &rings[i];
|
|
|
ring->devinfo = devinfo;
|
|
|
- ring->id = i + BRCMF_NROF_COMMON_MSGRINGS;
|
|
|
+ ring->id = i + BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
|
|
|
brcmf_commonring_register_cb(&ring->commonring,
|
|
|
brcmf_pcie_ring_mb_ring_bell,
|
|
|
brcmf_pcie_ring_mb_update_rptr,
|
|
@@ -1357,17 +1391,16 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
|
|
|
{
|
|
|
struct brcmf_pcie_shared_info *shared;
|
|
|
u32 addr;
|
|
|
- u32 version;
|
|
|
|
|
|
shared = &devinfo->shared;
|
|
|
shared->tcm_base_address = sharedram_addr;
|
|
|
|
|
|
shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr);
|
|
|
- version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK;
|
|
|
- brcmf_dbg(PCIE, "PCIe protocol version %d\n", version);
|
|
|
- if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
|
|
|
- (version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
|
|
|
- brcmf_err("Unsupported PCIE version %d\n", version);
|
|
|
+ shared->version = (u8)(shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK);
|
|
|
+ brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version);
|
|
|
+ if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
|
|
|
+ (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
|
|
|
+ brcmf_err("Unsupported PCIE version %d\n", shared->version);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -1661,18 +1694,18 @@ static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
|
|
|
bus->msgbuf->commonrings[i] =
|
|
|
&devinfo->shared.commonrings[i]->commonring;
|
|
|
|
|
|
- flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings),
|
|
|
+ flowrings = kcalloc(devinfo->shared.max_flowrings, sizeof(*flowrings),
|
|
|
GFP_KERNEL);
|
|
|
if (!flowrings)
|
|
|
goto fail;
|
|
|
|
|
|
- for (i = 0; i < devinfo->shared.nrof_flowrings; i++)
|
|
|
+ for (i = 0; i < devinfo->shared.max_flowrings; i++)
|
|
|
flowrings[i] = &devinfo->shared.flowrings[i].commonring;
|
|
|
bus->msgbuf->flowrings = flowrings;
|
|
|
|
|
|
bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset;
|
|
|
bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost;
|
|
|
- bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings;
|
|
|
+ bus->msgbuf->max_flowrings = devinfo->shared.max_flowrings;
|
|
|
|
|
|
init_waitqueue_head(&devinfo->mbdata_resp_wait);
|
|
|
|