summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrhan K AKYILDIZ <oka@codeaurora.org>2017-03-23 13:12:46 -0700
committerManjunathappa Prakash <prakashpm@codeaurora.org>2017-03-24 20:15:20 -0700
commitdddba6cd2e6697a8544d16bad78fda5b581cbde1 (patch)
tree4fa743bff746a1451368647964d35d295c024f67
parented27fd1eafc02c18e0fec5d88ce1d440ac07f17e (diff)
qcacld-3.0: Support > 32 bit paddrs in rx_hash
Currently, rx-hash calculation and hash look-up is performed only on lower 32 bits. On some systems with a particular memory map, we have observed that one could have buffers coming from memory map regions that only differ at the higher (>32) bits. For such systems, make sure that the hash entry storage and comparison operations are done on the whole paddr range. Change-Id: I279f673ee465a811d20606b260be084f984135d5 CRs-Fixed: 2024095
-rw-r--r--core/dp/htt/htt_internal.h6
-rw-r--r--core/dp/htt/htt_rx.c44
-rw-r--r--core/dp/htt/htt_types.h2
3 files changed, 39 insertions, 13 deletions
diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h
index d230c3241431..894070934185 100644
--- a/core/dp/htt/htt_internal.h
+++ b/core/dp/htt/htt_internal.h
@@ -534,10 +534,12 @@ void htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev);
#endif
int
-htt_rx_hash_list_insert(struct htt_pdev_t *pdev, uint32_t paddr,
+htt_rx_hash_list_insert(struct htt_pdev_t *pdev,
+ qdf_dma_addr_t paddr,
qdf_nbuf_t netbuf);
-qdf_nbuf_t htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, uint32_t paddr);
+qdf_nbuf_t
+htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, qdf_dma_addr_t paddr);
#ifdef IPA_OFFLOAD
int
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c
index eadcebd6d322..63521badd733 100644
--- a/core/dp/htt/htt_rx.c
+++ b/core/dp/htt/htt_rx.c
@@ -361,6 +361,22 @@ htt_rx_paddr_mark_high_bits(qdf_dma_addr_t paddr)
return paddr;
}
+#ifdef HTT_PADDR64
+static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
+{
+ qdf_dma_addr_t ret = paddr;
+
+ if (sizeof(paddr) > 4)
+ ret &= 0x1fffffffff;
+ return ret;
+}
+#else /* not 64 bits */
+static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
+{
+ return paddr;
+}
+#endif /* HTT_PADDR64 */
+
#ifdef ENABLE_DEBUG_ADDRESS_MARKING
static qdf_dma_addr_t
htt_rx_paddr_unmark_high_bits(qdf_dma_addr_t paddr)
@@ -384,7 +400,7 @@ htt_rx_paddr_unmark_high_bits(qdf_dma_addr_t paddr)
}
/* clear markings for further use */
- paddr &= (uint64_t)0x1ffffffff; /* LS 37 bits */
+ paddr = htt_paddr_trim_to_37(paddr);
}
return paddr;
}
@@ -491,7 +507,7 @@ moretofill:
paddr = htt_rx_paddr_mark_high_bits(paddr);
if (pdev->cfg.is_full_reorder_offload) {
if (qdf_unlikely(htt_rx_hash_list_insert(
- pdev, (uint32_t)paddr, rx_netbuf))) {
+ pdev, paddr, rx_netbuf))) {
QDF_TRACE(QDF_MODULE_ID_HTT,
QDF_TRACE_LEVEL_ERROR,
"%s: hash insert failed!", __func__);
@@ -949,7 +965,8 @@ htt_rx_in_order_netbuf_pop(htt_pdev_handle pdev, qdf_dma_addr_t paddr)
{
HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
pdev->rx_ring.fill_cnt--;
- return htt_rx_hash_list_lookup(pdev, (uint32_t)(paddr & 0xffffffff));
+ paddr = htt_paddr_trim_to_37(paddr);
+ return htt_rx_hash_list_lookup(pdev, paddr);
}
/* FIX ME: this function applies only to LL rx descs.
@@ -3066,7 +3083,8 @@ static inline void htt_list_remove(struct htt_list_node *node)
Note: this function is not thread-safe
Returns 0 - success, 1 - failure */
int
-htt_rx_hash_list_insert(struct htt_pdev_t *pdev, uint32_t paddr,
+htt_rx_hash_list_insert(struct htt_pdev_t *pdev,
+ qdf_dma_addr_t paddr,
qdf_nbuf_t netbuf)
{
int i;
@@ -3075,6 +3093,9 @@ htt_rx_hash_list_insert(struct htt_pdev_t *pdev, uint32_t paddr,
qdf_spin_lock_bh(&(pdev->rx_ring.rx_hash_lock));
+ /* get rid of the marking bits if they are available */
+ paddr = htt_paddr_trim_to_37(paddr);
+
i = RX_HASH_FUNCTION(paddr);
/* Check if there are any entries in the pre-allocated free list */
@@ -3121,10 +3142,13 @@ hli_end:
return rc;
}
-/* Given a physical address this function will find the corresponding network
- buffer from the hash table.
- Note: this function is not thread-safe */
-qdf_nbuf_t htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, uint32_t paddr)
+/*
+ * Given a physical address this function will find the corresponding network
+ * buffer from the hash table.
+ * paddr is already stripped off of higher marking bits.
+ */
+qdf_nbuf_t htt_rx_hash_list_lookup(struct htt_pdev_t *pdev,
+ qdf_dma_addr_t paddr)
{
uint32_t i;
struct htt_list_node *list_iter = NULL;
@@ -3167,8 +3191,8 @@ qdf_nbuf_t htt_rx_hash_list_lookup(struct htt_pdev_t *pdev, uint32_t paddr)
qdf_spin_unlock_bh(&(pdev->rx_ring.rx_hash_lock));
if (netbuf == NULL) {
- qdf_print("rx hash: %s: no entry found for 0x%x!!!\n",
- __func__, paddr);
+ qdf_print("rx hash: %s: no entry found for %p!\n",
+ __func__, (void *)paddr);
HTT_ASSERT_ALWAYS(0);
}
diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h
index 251be6c1fe0b..24116769fb2b 100644
--- a/core/dp/htt/htt_types.h
+++ b/core/dp/htt/htt_types.h
@@ -102,7 +102,7 @@ struct htt_list_node {
};
struct htt_rx_hash_entry {
- A_UINT32 paddr;
+ qdf_dma_addr_t paddr;
qdf_nbuf_t netbuf;
A_UINT8 fromlist;
struct htt_list_node listnode;