summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrashanth Bhatta <bhattap@qca.qualcomm.com>2014-06-10 12:15:06 -0700
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-06-11 12:23:22 -0700
commitf91d8a5cc2b8fbccd9c61cb1d0c97cd7a397757d (patch)
tree8a9058839a2fa8e149d8026c7cf8fef200b47d20
parente64977fe9c9eecb8b89f07eb0326c821b25a7104 (diff)
qcacld: ipa: Handle duplicate WLAN_AP_CONNECT event
As part of DFS testing, when a RADAR pulses are detected, SAP module would trigger eSAP_START_BSS_EVENT events with updated channel. While handling this event in HDD, WLAN_AP_CONNECT would be called multiple times for the same interface. Now added fix to handle the multiple indications gracefully. Also along with this change, added a fix in TX path where in, in CAC period all the packets needs to be dropped as during CAC period, AP shouldn't try to send any packet over the air. Change-Id: I6ef2a43468d023d826fe3ea55eba326f1051a96b CRs-fixed: 677686
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c
index 6241785f2733..8ab721415eec 100644
--- a/CORE/HDD/src/wlan_hdd_ipa.c
+++ b/CORE/HDD/src/wlan_hdd_ipa.c
@@ -1077,50 +1077,63 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt,
struct hdd_ipa_iface_context *iface_context;
adf_nbuf_t skb;
v_U8_t interface_id;
+ hdd_adapter_t *adapter = NULL;
- if (evt == IPA_RECEIVE) {
-
- iface_context = (struct hdd_ipa_iface_context *) priv;
- ipa_tx_desc = (struct ipa_rx_data *)data;
- skb = ipa_tx_desc->skb;
+ if (evt != IPA_RECEIVE) {
+ skb = (adf_nbuf_t) data;
+ dev_kfree_skb_any(skb);
+ return;
+ }
- hdd_ipa = iface_context->hdd_ipa;
+ iface_context = (struct hdd_ipa_iface_context *) priv;
+ ipa_tx_desc = (struct ipa_rx_data *)data;
+ skb = ipa_tx_desc->skb;
- adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
- NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
- NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
- NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr;
+ hdd_ipa = iface_context->hdd_ipa;
- NBUF_OWNER_PRIV_DATA(skb) = data;
+ adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
+ NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
+ NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
+ NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr;
- HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8);
+ NBUF_OWNER_PRIV_DATA(skb) = data;
- hdd_ipa->stats.tx_ipa_recv++;
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8);
- adf_os_spin_lock_bh(&iface_context->interface_lock);
- if (!iface_context->adapter) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, "Interface Down");
- ipa_free_skb(ipa_tx_desc);
- adf_os_spin_unlock_bh(&iface_context->interface_lock);
- return;
- }
+ hdd_ipa->stats.tx_ipa_recv++;
- interface_id = iface_context->adapter->sessionId;
- ++iface_context->adapter->stats.tx_packets;
- iface_context->adapter->stats.tx_bytes += ipa_tx_desc->skb->len;
+ adf_os_spin_lock_bh(&iface_context->interface_lock);
+ adapter = iface_context->adapter;
+ if (!adapter) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, "Interface Down");
+ ipa_free_skb(ipa_tx_desc);
+ adf_os_spin_unlock_bh(&iface_context->interface_lock);
+ return;
+ }
+ /*
+ * During CAC period, data packets shouldn't be sent over the air so
+ * drop all the packets here
+ */
+ if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx) {
+ ipa_free_skb(ipa_tx_desc);
adf_os_spin_unlock_bh(&iface_context->interface_lock);
+ return;
+ }
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext,
- iface_context->tl_context, ipa_tx_desc->skb, interface_id);
- if (skb) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "TLSHIM tx fail");
- ipa_free_skb(ipa_tx_desc);
- return;
- }
- } else {
- skb = (adf_nbuf_t) data;
- dev_kfree_skb_any(skb);
+ interface_id = adapter->sessionId;
+ ++adapter->stats.tx_packets;
+ adapter->stats.tx_bytes += ipa_tx_desc->skb->len;
+
+ adf_os_spin_unlock_bh(&iface_context->interface_lock);
+
+ skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext,
+ iface_context->tl_context, ipa_tx_desc->skb,
+ interface_id);
+ if (skb) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "TLSHIM tx fail");
+ ipa_free_skb(ipa_tx_desc);
+ return;
}
}
@@ -1492,6 +1505,14 @@ static int hdd_ipa_setup_iface(struct hdd_ipa_priv *hdd_ipa,
void *tl_context = NULL;
int i, ret = 0;
+ /* Lower layer may send multiple START_BSS_EVENT in DFS mode or during
+ * channel change indication. Since these indications are sent by lower
+ * layer as SAP updates and IPA doesn't have to do anything for these
+ * updates so ignoring!
+ */
+ if (WLAN_HDD_SOFTAP == adapter->device_mode && adapter->ipa_context)
+ return 0;
+
for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
if (hdd_ipa->iface_context[i].adapter == NULL) {
iface_context = &(hdd_ipa->iface_context[i]);