summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/hdd/inc/wlan_hdd_ipa.h12
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c93
2 files changed, 73 insertions, 32 deletions
diff --git a/core/hdd/inc/wlan_hdd_ipa.h b/core/hdd/inc/wlan_hdd_ipa.h
index b2bf9803e6da..5a2caf9e6f35 100644
--- a/core/hdd/inc/wlan_hdd_ipa.h
+++ b/core/hdd/inc/wlan_hdd_ipa.h
@@ -62,6 +62,18 @@ enum hdd_ipa_wlan_event {
#include <wlan_hdd_assoc.h> /* hdd_context_t */
/**
+ * enum hdd_ipa_forward_type: Type of forward packet received from IPA
+ * @HDD_IPA_FORWARD_PKT_NONE: No forward packet
+ * @HDD_IPA_FORWARD_PKT_LOCAL_STACK: Packet forwarded to kernel network stack
+ * @HDD_IPA_FORWARD_PKT_DISCARD: Discarded packet before sending to kernel stack
+ */
+enum hdd_ipa_forward_type {
+ HDD_IPA_FORWARD_PKT_NONE = 0,
+ HDD_IPA_FORWARD_PKT_LOCAL_STACK = 1,
+ HDD_IPA_FORWARD_PKT_DISCARD = 2
+};
+
+/**
* FIXME: Temporary hack - until IPA functionality gets restored
*
*/
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 1005d0fa9d12..2288bbb4e371 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -55,6 +55,7 @@
#include "wma.h"
#include "wma_api.h"
+#include "wal_rx_desc.h"
#include "cdp_txrx_ipa.h"
@@ -486,9 +487,6 @@ static uint32_t wlan_hdd_stub_addr_to_priv(void *ptr)
#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
-
#define HDD_IPA_GET_IFACE_ID(_data) \
(((struct hdd_ipa_cld_hdr *) (_data))->iface_id)
@@ -2645,35 +2643,29 @@ static void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb,
static void hdd_ipa_forward(struct hdd_ipa_priv *hdd_ipa,
hdd_adapter_t *adapter, qdf_nbuf_t skb)
{
- qdf_nbuf_t copy;
struct hdd_ipa_pm_tx_cb *pm_tx_cb;
- copy = qdf_nbuf_copy(skb);
- if (!copy) {
- HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "copy packet alloc fail");
- return;
- }
-
qdf_spin_lock_bh(&hdd_ipa->pm_lock);
/* WLAN subsystem is in suspend, put int queue */
if (hdd_ipa->suspended) {
qdf_spin_unlock_bh(&hdd_ipa->pm_lock);
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
"TX in SUSPEND PUT QUEUE");
- qdf_mem_set(copy->cb, sizeof(copy->cb), 0);
- pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)copy->cb;
+ qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
+ pm_tx_cb = (struct hdd_ipa_pm_tx_cb *)skb->cb;
pm_tx_cb->exception = true;
pm_tx_cb->adapter = adapter;
qdf_spin_lock_bh(&hdd_ipa->pm_lock);
- qdf_nbuf_queue_add(&hdd_ipa->pm_queue_head, copy);
+ qdf_nbuf_queue_add(&hdd_ipa->pm_queue_head, skb);
qdf_spin_unlock_bh(&hdd_ipa->pm_lock);
hdd_ipa->stats.num_tx_queued++;
} else {
/* Resume, put packet into WLAN TX */
qdf_spin_unlock_bh(&hdd_ipa->pm_lock);
- if (hdd_softap_hard_start_xmit(copy, adapter->dev)) {
+ if (hdd_softap_hard_start_xmit(skb, adapter->dev)) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
"packet tx fail");
+ hdd_ipa->stats.num_tx_bcmc_err++;
} else {
hdd_ipa->stats.num_tx_bcmc++;
hdd_ipa->ipa_tx_forward++;
@@ -2682,6 +2674,53 @@ static void hdd_ipa_forward(struct hdd_ipa_priv *hdd_ipa,
}
/**
+ * hdd_ipa_intrabss_forward() - Forward intra bss packets.
+ * @hdd_ipa: pointer to HDD IPA struct
+ * @adapter: hdd adapter pointer
+ * @desc: Firmware descriptor
+ * @skb: Data buffer
+ *
+ * Return:
+ * HDD_IPA_FORWARD_PKT_NONE
+ * HDD_IPA_FORWARD_PKT_DISCARD
+ * HDD_IPA_FORWARD_PKT_LOCAL_STACK
+ *
+ */
+
+static enum hdd_ipa_forward_type hdd_ipa_intrabss_forward(
+ struct hdd_ipa_priv *hdd_ipa,
+ hdd_adapter_t *adapter,
+ uint8_t desc,
+ qdf_nbuf_t skb)
+{
+ int ret = HDD_IPA_FORWARD_PKT_NONE;
+
+ if ((desc & FW_RX_DESC_FORWARD_M)) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
+ "Forward packet to Tx (fw_desc=%d)", desc);
+ hdd_ipa->ipa_tx_forward++;
+
+ if ((desc & FW_RX_DESC_DISCARD_M)) {
+ hdd_ipa_forward(hdd_ipa, adapter, skb);
+ hdd_ipa->ipa_rx_internel_drop_count++;
+ hdd_ipa->ipa_rx_discard++;
+ ret = HDD_IPA_FORWARD_PKT_DISCARD;
+ } else {
+ struct sk_buff *cloned_skb = skb_clone(skb, GFP_ATOMIC);
+ if (cloned_skb)
+ hdd_ipa_forward(hdd_ipa, adapter, cloned_skb);
+ else
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "%s: tx skb alloc failed",
+ __func__);
+ ret = HDD_IPA_FORWARD_PKT_LOCAL_STACK;
+ }
+ }
+
+ return ret;
+}
+
+/**
* hdd_ipa_w2i_cb() - WLAN to IPA callback handler
* @priv: pointer to private data registered with IPA (we register a
* pointer to the global IPA context)
@@ -2771,19 +2810,10 @@ static void __hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
* only when DISCARD bit is not set.
*/
fw_desc = (uint8_t)skb->cb[1];
- if (fw_desc & HDD_IPA_FW_RX_DESC_FORWARD_M) {
- HDD_IPA_DP_LOG(
- QDF_TRACE_LEVEL_DEBUG,
- "Forward packet to Tx (fw_desc=%d)",
- fw_desc);
- hdd_ipa_forward(hdd_ipa, adapter, skb);
- }
- if (fw_desc & HDD_IPA_FW_RX_DESC_DISCARD_M) {
- HDD_IPA_INCREASE_INTERNAL_DROP_COUNT(hdd_ipa);
- hdd_ipa->ipa_rx_discard++;
- kfree_skb(skb);
+ if (HDD_IPA_FORWARD_PKT_DISCARD ==
+ hdd_ipa_intrabss_forward(hdd_ipa, adapter,
+ fw_desc, skb))
break;
- }
} else {
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
"Intra-BSS FWD is disabled-skip forward to Tx");
@@ -3006,17 +3036,16 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt,
QDF_STATUS status = QDF_STATUS_SUCCESS;
iface_context = (struct hdd_ipa_iface_context *)priv;
+ ipa_tx_desc = (struct ipa_rx_data *)data;
+ hdd_ipa = iface_context->hdd_ipa;
+
if (evt != IPA_RECEIVE) {
- skb = (qdf_nbuf_t) data;
- dev_kfree_skb_any(skb);
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "Event is not IPA_RECEIVE");
+ ipa_free_skb(ipa_tx_desc);
iface_context->stats.num_tx_drop++;
return;
}
- ipa_tx_desc = (struct ipa_rx_data *)data;
-
- hdd_ipa = iface_context->hdd_ipa;
-
/*
* When SSR is going on or driver is unloading, just drop the packets.
* During SSR, there is no use in queueing the packets as STA has to