diff options
| author | Prashanth Bhatta <bhattap@qca.qualcomm.com> | 2014-06-10 12:15:06 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-06-11 12:23:22 -0700 |
| commit | f91d8a5cc2b8fbccd9c61cb1d0c97cd7a397757d (patch) | |
| tree | 8a9058839a2fa8e149d8026c7cf8fef200b47d20 | |
| parent | e64977fe9c9eecb8b89f07eb0326c821b25a7104 (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.c | 87 |
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]); |
