diff options
| author | Yun Park <yunp@qca.qualcomm.com> | 2016-01-07 15:55:11 -0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-01-08 13:20:28 +0530 |
| commit | d220839fb3e668e043e95a73ff7f93ca343bd452 (patch) | |
| tree | 1ddc2c8ff46f7d59235cd55c6ab00cc925fd9610 | |
| parent | 057657e05ab2f93e348d184703b8fe130c199883 (diff) | |
qcacld-2.0: Optimize memory usage of intra BSS path
Use SKB clone instead of using SKB copy for forward packets.
Addtional fix to release SKB to IPA when dropping Rx packets from IPA.
Change-Id: Ibfacf855b53148fd6b254e281f7163d03e3753ec
CRs-Fixed: 950379
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_ipa.h | 7 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_ipa.c | 114 |
2 files changed, 77 insertions, 44 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_ipa.h b/CORE/HDD/inc/wlan_hdd_ipa.h index 60e8c8379a9a..19809be36482 100644 --- a/CORE/HDD/inc/wlan_hdd_ipa.h +++ b/CORE/HDD/inc/wlan_hdd_ipa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -44,6 +44,11 @@ #ifdef IPA_OFFLOAD #include <linux/ipa.h> +enum hdd_ipa_forward_type { + HDD_IPA_FORWARD_PKT_NONE = 0, + HDD_IPA_FORWARD_PKT_LOCAL_STACK = 1, + HDD_IPA_FORWARD_PKT_DISCARD = 2 +}; VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx); VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx); int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index 2d73dfdeeae1..21e43c7f944d 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -56,6 +56,7 @@ Include Files #ifdef IPA_UC_OFFLOAD #include "wma.h" #include "wma_api.h" +#include "wal_rx_desc.h" #endif /* IPA_UC_OFFLOAD */ #define HDD_IPA_DESC_BUFFER_RATIO 4 @@ -2962,9 +2963,65 @@ static int hdd_ipa_ipv4_changed(struct notifier_block *nb, return 0; } +#if defined(IPA_UC_OFFLOAD) && defined(INTRA_BSS_FWD_OFFLOAD) +/** + * 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 + * + */ -#define FW_RX_DESC_DISCARD_M 0x1 -#define FW_RX_DESC_FORWARD_M 0x2 +static enum hdd_ipa_forward_type hdd_ipa_intrabss_forward( + struct hdd_ipa_priv *hdd_ipa, + hdd_adapter_t *adapter, + uint8_t desc, + adf_nbuf_t skb) +{ + int xmit_status = -1; + int ret = HDD_IPA_FORWARD_PKT_NONE; + + if ((desc & FW_RX_DESC_FORWARD_M)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, + "Forward packet to Tx (fw_desc=%d)", desc); + hdd_ipa->ipa_tx_forward++; + + if ((desc & FW_RX_DESC_DISCARD_M)) { + xmit_status = hdd_softap_hard_start_xmit( + skb, adapter->dev); + 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) + xmit_status = hdd_softap_hard_start_xmit( + cloned_skb, adapter->dev); + else + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: tx skb alloc failed", + __func__); + ret = HDD_IPA_FORWARD_PKT_LOCAL_STACK; + } + + if (NETDEV_TX_OK == xmit_status) { + hdd_ipa->stats.num_tx_fwd_ok++; + } else { + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, + "Forward packet Tx fail"); + hdd_ipa->stats.num_tx_fwd_err++; + } + } + + return ret; +} +#endif static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) @@ -2978,11 +3035,10 @@ static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, #ifdef IPA_UC_OFFLOAD uint8_t session_id; #ifdef INTRA_BSS_FWD_OFFLOAD - adf_nbuf_t copy; uint8_t fw_desc; - int ret; #endif #endif + adf_nbuf_t buf; hdd_ipa = (struct hdd_ipa_priv *)priv; @@ -3037,7 +3093,7 @@ static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, * ap_isolate=1 in hostapd.conf */ if ((NULL != iface_context->tl_context) && - !WLANTL_disable_intrabss_fwd(iface_context->tl_context)) + !WLANTL_disable_intrabss_fwd(iface_context->tl_context)) { /* * When INTRA_BSS_FWD_OFFLOAD is enabled, FW will send @@ -3051,40 +3107,11 @@ static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, */ fw_desc = (uint8_t)skb->cb[1]; - if (fw_desc & FW_RX_DESC_FORWARD_M) { - HDD_IPA_LOG( - VOS_TRACE_LEVEL_INFO, - "Forward packet to Tx (fw_desc=%d)", - fw_desc); - copy = adf_nbuf_copy(skb); - if (copy) { - hdd_ipa->ipa_tx_forward++; - ret = hdd_softap_hard_start_xmit( - (struct sk_buff *)copy, - adapter->dev); - if (ret) { - HDD_IPA_LOG( - VOS_TRACE_LEVEL_ERROR, - "Forward packet Tx fail" - ); - hdd_ipa->stats. - num_tx_fwd_err++; - } else { - hdd_ipa->stats.num_tx_fwd_ok++; - } - } - } - - if (fw_desc & FW_RX_DESC_DISCARD_M) { - hdd_ipa->ipa_rx_internel_drop_count++; - hdd_ipa->ipa_rx_discard++; - adf_nbuf_free(skb); + if (HDD_IPA_FORWARD_PKT_DISCARD == + hdd_ipa_intrabss_forward(hdd_ipa, adapter, + fw_desc, skb)) break; - } - - } - else - { + } else { HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH, "Intra-BSS FWD is disabled-skip forward to Tx"); } @@ -3250,14 +3277,15 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, VOS_STATUS status = VOS_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 = (adf_nbuf_t) data; - dev_kfree_skb_any(skb); + HDD_IPA_LOG(VOS_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. |
