diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h index fcf22a5601ec..0ee805a0d521 100644 --- a/components/ipa/core/inc/wlan_ipa_priv.h +++ b/components/ipa/core/inc/wlan_ipa_priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -357,6 +357,7 @@ struct wlan_ipa_iface_context { * @num_tx_dequeued: Number of TX dequeued * @num_max_pm_queue: Number of packets in PM queue * @num_rx_excep: Number of RX IPA exception packets + * @num_rx_no_iface_eapol: No of EAPOL pkts before iface setup * @num_tx_fwd_ok: Number of TX forward packet success * @num_tx_fwd_err: Number of TX forward packet failures */ @@ -377,6 +378,7 @@ struct wlan_ipa_stats { uint64_t num_tx_dequeued; uint64_t num_max_pm_queue; uint64_t num_rx_excep; + uint64_t num_rx_no_iface_eapol; uint64_t num_tx_fwd_ok; uint64_t num_tx_fwd_err; }; diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 434f51568fab..523e3b096825 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -19,6 +19,7 @@ /* Include Files */ #include "wlan_ipa_core.h" #include "wlan_ipa_main.h" +#include "wlan_hdd_main.h" #include #include "cdp_txrx_ipa.h" #include "wal_rx_desc.h" @@ -902,6 +903,50 @@ wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx, #endif /* CONFIG_IPA_WDI_UNIFIED_API */ +/** + * wlan_ipa_send_sta_eapol_to_nw() - Send Rx EAPOL pkt for STA to Kernel + * @skb: network buffer + * + * Called when a EAPOL packet is received via IPA Exception path + * before wlan_ipa_setup_iface is done for STA. + * + * Return: 0 on success, err_code for failure. + */ +static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb) +{ + struct wlan_ipa_priv *ipa_ctx = gp_ipa; + struct hdd_context *hdd_ctx; + struct hdd_adapter *adapter; + struct ethhdr *eh; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + ipa_err_rl("Invalid hdd_context"); + return -EINVAL; + } + + eh = (struct ethhdr *)qdf_nbuf_data(skb); + adapter = hdd_get_adapter_by_macaddr(hdd_ctx, eh->h_dest); + if (hdd_validate_adapter(adapter)) { + ipa_err_rl("Invalid adapter"); + return -EINVAL; + } + if (adapter->device_mode != QDF_STA_MODE) { + ipa_err_rl("device_mode is not STA"); + return -EINVAL; + } + + skb->destructor = wlan_ipa_uc_rt_debug_destructor; + + if (ipa_ctx->send_to_nw) + ipa_ctx->send_to_nw(skb, adapter->dev); + + ipa_ctx->ipa_rx_net_send_count++; + ipa_ctx->stats.num_rx_no_iface_eapol++; + + return 0; +} + /** * wlan_ipa_send_skb_to_network() - Send skb to kernel * @skb: network buffer @@ -966,13 +1011,24 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { session_id = (uint8_t)skb->cb[0]; iface_id = ipa_ctx->vdev_to_iface[session_id]; + ipa_ctx->stats.num_rx_excep++; + qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN); } else { iface_id = WLAN_IPA_GET_IFACE_ID(skb->data); + qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN); } + if (iface_id >= WLAN_IPA_MAX_IFACE) { - ipa_err_rl("Invalid iface_id: %u,session id: %x %x %x %x. Dropped!", + ipa_err_rl("Invalid iface_id %u,session_id %x %x %x %x", iface_id, session_id, (uint8_t)skb->cb[1], (uint8_t)skb->cb[2], (uint8_t)skb->cb[3]); + + if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) { + ipa_err_rl("EAPOL pkt. Sending to NW!"); + if (!wlan_ipa_send_sta_eapol_to_nw(skb)) + break; + } + ipa_err_rl("Pkt Dropped!"); ipa_ctx->ipa_rx_internal_drop_count++; dev_kfree_skb_any(skb); return; @@ -986,13 +1042,6 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, dev_kfree_skb_any(skb); return; } - - if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { - ipa_ctx->stats.num_rx_excep++; - qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN); - } else { - qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN); - } iface_context->stats.num_rx_ipa_excep++; /* Disable to forward Intra-BSS Rx packets when