From cc923e27712de6bff51a3847cb8ea9fa56b0f2f7 Mon Sep 17 00:00:00 2001 From: Leo Chang Date: Thu, 16 Jun 2016 15:29:03 -0700 Subject: [PATCH] qcacld-3.0: IPA WDI TX buffer allocation on coherent memory IPA WDI TX buffer should be used by IPA HW/WLAN FWHW during WLAN activated. This memory is not used by HLOS. Then coherent memory allocation is better for usage. Change-Id: Icc96c54aca9fc986c231ac3173f54cf7c7f253aa CRs-fixed: 1019762 --- core/dp/htt/htt_tx.c | 86 ++++++++++++++++++++++++------------- core/dp/htt/htt_types.h | 3 +- core/hdd/src/wlan_hdd_ipa.c | 12 +++--- 3 files changed, 66 insertions(+), 35 deletions(-) diff --git a/core/dp/htt/htt_tx.c b/core/dp/htt/htt_tx.c index 2131d7bda430..b2d9362dfdc6 100644 --- a/core/dp/htt/htt_tx.c +++ b/core/dp/htt/htt_tx.c @@ -66,6 +66,17 @@ */ #define HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT 0x07C04001 +#ifdef QCA_WIFI_3_0 +#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 20 +#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET 64 +#define IPA_UC_TX_BUF_TSO_HDR_SIZE 6 +#define IPA_UC_TX_BUF_PADDR_HI_MASK 0x0000001F +#define IPA_UC_TX_BUF_PADDR_HI_OFFSET 32 +#else +#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 16 +#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET 32 +#endif /* QCA_WIFI_3_0 */ + #if HTT_PADDR64 #define HTT_TX_DESC_FRAG_FIELD_HI_UPDATE(frag_filed_ptr) \ do { \ @@ -1057,29 +1068,25 @@ int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev, unsigned int uc_tx_partition_base) { unsigned int tx_buffer_count; - qdf_nbuf_t buffer_vaddr; + void *buffer_vaddr; qdf_dma_addr_t buffer_paddr; uint32_t *header_ptr; - uint32_t *ring_vaddr; -#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 20 -#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET 64 -#define IPA_UC_TX_BUF_TSO_HDR_SIZE 6 + qdf_dma_addr_t *ring_vaddr; - ring_vaddr = pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr; + ring_vaddr = (qdf_dma_addr_t *)pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr; /* Allocate TX buffers as many as possible */ for (tx_buffer_count = 0; tx_buffer_count < (uc_tx_buf_cnt - 1); tx_buffer_count++) { - buffer_vaddr = qdf_nbuf_alloc(pdev->osdev, - uc_tx_buf_sz, 0, 4, false); + + buffer_vaddr = qdf_mem_alloc_consistent(pdev->osdev, + pdev->osdev->dev, uc_tx_buf_sz, &buffer_paddr); if (!buffer_vaddr) { - qdf_print("%s: TX BUF alloc fail, loop index: %d", - __func__, tx_buffer_count); + qdf_print("IPA WDI TX buffer alloc fail %d allocated\n", + tx_buffer_count); return tx_buffer_count; } - /* Init buffer */ - qdf_mem_zero(qdf_nbuf_data(buffer_vaddr), uc_tx_buf_sz); - header_ptr = (uint32_t *) qdf_nbuf_data(buffer_vaddr); + header_ptr = buffer_vaddr; /* HTT control header */ *header_ptr = HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT; @@ -1089,8 +1096,6 @@ int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev, *header_ptr |= ((uint16_t) uc_tx_partition_base + tx_buffer_count) << 16; - qdf_nbuf_map(pdev->osdev, buffer_vaddr, QDF_DMA_BIDIRECTIONAL); - buffer_paddr = qdf_nbuf_get_frag_paddr(buffer_vaddr, 0); header_ptr++; /* Frag Desc Pointer */ @@ -1100,7 +1105,8 @@ int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev, header_ptr++; /* 64bits descriptor, high 32bits */ - *header_ptr = 0; + *header_ptr = (buffer_paddr >> IPA_UC_TX_BUF_PADDR_HI_OFFSET) & + IPA_UC_TX_BUF_PADDR_HI_MASK; header_ptr++; /* chanreq, peerid */ @@ -1115,9 +1121,11 @@ int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev, *ring_vaddr = buffer_paddr; pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[tx_buffer_count] = buffer_vaddr; + pdev->ipa_uc_tx_rsc.paddr_strg[tx_buffer_count] = + buffer_paddr; /* Memory barrier to ensure actual value updated */ - ring_vaddr += 2; + ring_vaddr++; } return tx_buffer_count; } @@ -1132,8 +1140,6 @@ int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev, qdf_dma_addr_t buffer_paddr; uint32_t *header_ptr; uint32_t *ring_vaddr; -#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 16 -#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET 32 ring_vaddr = pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr; /* Allocate TX buffers as many as possible */ @@ -1211,7 +1217,7 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev, } /* Allocate TX COMP Ring */ - tx_comp_ring_size = uc_tx_buf_cnt * sizeof(qdf_nbuf_t); + tx_comp_ring_size = uc_tx_buf_cnt * sizeof(qdf_dma_addr_t); pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr = qdf_mem_alloc_consistent( pdev->osdev, pdev->osdev->dev, @@ -1227,15 +1233,28 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev, /* Allocate TX BUF vAddress Storage */ pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg = - (qdf_nbuf_t *) qdf_mem_malloc(uc_tx_buf_cnt * - sizeof(qdf_nbuf_t)); + qdf_mem_malloc(uc_tx_buf_cnt * + sizeof(*pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg)); if (!pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg) { qdf_print("%s: TX BUF POOL vaddr storage alloc fail", __func__); return_code = -ENOBUFS; goto free_tx_comp_base; } qdf_mem_zero(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg, - uc_tx_buf_cnt * sizeof(qdf_nbuf_t)); + uc_tx_buf_cnt * + sizeof(*pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg)); + + pdev->ipa_uc_tx_rsc.paddr_strg = + qdf_mem_malloc(uc_tx_buf_cnt * + sizeof(pdev->ipa_uc_tx_rsc.paddr_strg)); + if (!pdev->ipa_uc_tx_rsc.paddr_strg) { + qdf_print("%s: TX BUF POOL paddr storage alloc fail", __func__); + return_code = -ENOBUFS; + goto free_tx_comp_base; + } + qdf_mem_zero(pdev->ipa_uc_tx_rsc.paddr_strg, + uc_tx_buf_cnt * + sizeof(*pdev->ipa_uc_tx_rsc.paddr_strg)); pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt = htt_tx_ipa_uc_wdi_tx_buf_alloc( pdev, uc_tx_buf_sz, uc_tx_buf_cnt, uc_tx_partition_base); @@ -1264,6 +1283,15 @@ free_tx_ce_idx: return return_code; } +/** + * htt_tx_ipa_uc_detach() - Free WDI TX resources + * @pdev: htt context + * + * Remove IPA WDI TX resources during device detach + * Free all of allocated resources + * + * Return: 0 success + */ int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev) { uint16_t idx; @@ -1294,17 +1322,17 @@ int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev) /* Free each single buffer */ for (idx = 0; idx < pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) { if (pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[idx]) { - qdf_nbuf_unmap(pdev->osdev, - pdev->ipa_uc_tx_rsc. - tx_buf_pool_vaddr_strg[idx], - QDF_DMA_FROM_DEVICE); - qdf_nbuf_free(pdev->ipa_uc_tx_rsc. - tx_buf_pool_vaddr_strg[idx]); + qdf_mem_free_consistent( + pdev->osdev, pdev->osdev->dev, + ol_cfg_ipa_uc_tx_buf_size(pdev->ctrl_pdev), + pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[idx], + pdev->ipa_uc_tx_rsc.paddr_strg[idx], 0); } } /* Free storage */ qdf_mem_free(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg); + qdf_mem_free(pdev->ipa_uc_tx_rsc.paddr_strg); return 0; } diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h index 6d2af7ad80af..38eaaecdb32a 100644 --- a/core/dp/htt/htt_types.h +++ b/core/dp/htt/htt_types.h @@ -130,7 +130,8 @@ struct htt_ipa_uc_tx_resource_t { struct uc_shared_mem_t tx_comp_base; uint32_t tx_comp_idx_paddr; - qdf_nbuf_t *tx_buf_pool_vaddr_strg; + void **tx_buf_pool_vaddr_strg; + qdf_dma_addr_t *paddr_strg; uint32_t alloc_tx_buf_cnt; }; diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index 1c0b99ba3602..5f9f30ab14f2 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -62,7 +62,6 @@ #define HDD_IPA_IPV6_NAME_EXT "_ipv6" #define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 1000 -#define HDD_IPA_UC_WLAN_HDR_DES_MAC_OFFSET 12 #define HDD_IPA_UC_WLAN_8023_HDR_SIZE 14 /* WDI TX and RX PIPE */ #define HDD_IPA_UC_NUM_WDI_PIPE 2 @@ -179,9 +178,6 @@ struct hdd_ipa_uc_tx_hdr { struct ethhdr eth; } __packed; -#define HDD_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header) -#define HDD_IPA_WLAN_IPA_HEADER sizeof(struct frag_header) - /** * struct hdd_ipa_cld_hdr - IPA CLD Header * @reserved: reserved fields @@ -474,12 +470,17 @@ uint32_t wlan_hdd_stub_addr_to_priv(void *ptr) BUG_ON(ptr == NULL); return ipa_priv; } + +#define HDD_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header) +#define HDD_IPA_WLAN_IPA_HEADER sizeof(struct ipa_header) #define HDD_IPA_WLAN_CLD_HDR_LEN sizeof(struct hdd_ipa_cld_hdr) #define HDD_IPA_UC_WLAN_CLD_HDR_LEN 0 #define HDD_IPA_WLAN_TX_HDR_LEN sizeof(struct hdd_ipa_tx_hdr) #define HDD_IPA_UC_WLAN_TX_HDR_LEN sizeof(struct hdd_ipa_uc_tx_hdr) #define HDD_IPA_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_rx_hdr) #define HDD_IPA_UC_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_uc_rx_hdr) +#define HDD_IPA_UC_WLAN_HDR_DES_MAC_OFFSET \ + (HDD_IPA_WLAN_FRAG_HEADER + HDD_IPA_WLAN_IPA_HEADER) #define HDD_IPA_FW_RX_DESC_DISCARD_M 0x1 #define HDD_IPA_FW_RX_DESC_FORWARD_M 0x2 @@ -1987,7 +1988,8 @@ struct sk_buff *hdd_ipa_tx_packet_ipa(hdd_context_t *hdd_ctx, if (HDD_IPA_UC_NUM_WDI_PIPE != hdd_ipa->activated_fw_pipe) return skb; - if (skb_headroom(skb) < sizeof(struct ipa_header)) + if (skb_headroom(skb) < + (sizeof(struct ipa_header) + sizeof(struct frag_header))) return skb; ipa_header = (struct ipa_header *) skb_push(skb,