qcacmn: Handle RX exception from IPA on WDS-EXT netdev

When WDS_EXT feature is enable, Host needs to redirect
the data packets to WDS extended netdevice.

Change is added the support for forwarding the RX packets
when received from IPA as an exception by deriving the
correct netdevice interface.

Change-Id: I083a1acc72023f3ebe6ea36ec05a5706f89c16bc
CRs-Fixed: 3597357
This commit is contained in:
Gaurav Saini
2023-09-11 14:34:54 +05:30
committed by Rahul Choudhary
parent f58bde59f4
commit b64de0cf4a
11 changed files with 200 additions and 3 deletions

View File

@@ -2992,6 +2992,28 @@ cdp_wds_ext_get_peer_osif_handle(
(soc, vdev_id, mac, osif_peer);
}
/**
* cdp_wds_ext_set_bit() - set wds-ext peer bit
* @soc: soc handle
* @mac: peer mac address
*
* Return: QDF_STATUS
*/
static inline QDF_STATUS
cdp_wds_ext_set_bit(ol_txrx_soc_handle soc, uint8_t *mac)
{
if (!soc || !soc->ops) {
dp_cdp_debug("Invalid Instance");
QDF_BUG(0);
return QDF_STATUS_E_FAULT;
}
if (!soc->ops->cmn_drv_ops ||
!soc->ops->cmn_drv_ops->set_wds_ext_peer_bit)
return QDF_STATUS_E_FAULT;
return soc->ops->cmn_drv_ops->set_wds_ext_peer_bit(soc, mac);
}
#endif /* QCA_SUPPORT_WDS_EXTENDED */
/**

View File

@@ -650,6 +650,33 @@ cdp_ipa_set_perf_level(ol_txrx_soc_handle soc, int client,
return QDF_STATUS_SUCCESS;
}
#ifdef QCA_SUPPORT_WDS_EXTENDED
/**
* cdp_ipa_rx_wdsext_iface() - Forward RX exception packets to wdsext interface
* @soc: data path soc handle
* @peer_id: Peer id to get respective peer
* @skb: socket buffer
*
* Return: true if packets sent to wds ext interface, else false.
*/
static inline bool
cdp_ipa_rx_wdsext_iface(ol_txrx_soc_handle soc, uint8_t peer_id,
qdf_nbuf_t skb)
{
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
return false;
}
if (soc->ops->ipa_ops->ipa_rx_wdsext_iface)
return soc->ops->ipa_ops->ipa_rx_wdsext_iface(soc, peer_id,
skb);
return false;
}
#endif
/**
* cdp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path
*

View File

@@ -710,6 +710,8 @@ struct cdp_cmn_ops {
uint8_t vdev_id,
uint8_t *mac,
ol_osif_peer_handle *osif_peer);
QDF_STATUS (*set_wds_ext_peer_bit)(ol_txrx_soc_handle soc,
uint8_t *mac);
#endif /* QCA_SUPPORT_WDS_EXTENDED */
void (*txrx_drain)(ol_txrx_soc_handle soc);
int (*get_free_desc_poolsize)(struct cdp_soc_t *soc);
@@ -2204,6 +2206,7 @@ struct cdp_throttle_ops {
* @ipa_rx_buf_smmu_pool_mapping: Create SMMU mapping for Rx
* @ipa_set_smmu_mapped: Set IPA SMMU mapped value
* @ipa_get_smmu_mapped: Get IPA SMMU mapped value
* @ipa_rx_wdsext_iface: Forward RX exception packets to wdsext interface
* @ipa_rx_super_rule_setup: Setup cce super rules based on filter tuple
* @ipa_ast_create: Create/Update ast entry
* @ipa_get_wdi_version: Get WDI version
@@ -2308,6 +2311,11 @@ struct cdp_ipa_ops {
QDF_STATUS (*ipa_set_smmu_mapped)(struct cdp_soc_t *soc_hdl, int val);
int (*ipa_get_smmu_mapped)(struct cdp_soc_t *soc_hdl);
#ifdef QCA_SUPPORT_WDS_EXTENDED
bool (*ipa_rx_wdsext_iface)(struct cdp_soc_t *soc_hdl,
uint8_t peer_id,
qdf_nbuf_t nbuf_head);
#endif
#ifdef IPA_OPT_WIFI_DP
QDF_STATUS (*ipa_rx_super_rule_setup)(struct cdp_soc_t *soc_hdl,
void *flt_params);

View File

@@ -4416,6 +4416,16 @@ QDF_STATUS dp_wds_ext_get_peer_osif_handle(
uint8_t *mac,
ol_osif_peer_handle *osif_peer);
/**
* dp_wds_ext_set_peer_bit(): function to set wds-ext peer bit
* @soc: Datapath soc handle
* @mac: Peer mac address
*
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_INVAL if peer is not found
*/
QDF_STATUS dp_wds_ext_set_peer_bit(ol_txrx_soc_handle soc, uint8_t *mac);
#endif /* QCA_SUPPORT_WDS_EXTENDED */
#ifdef DP_MEM_PRE_ALLOC

View File

@@ -3560,6 +3560,37 @@ QDF_STATUS dp_ipa_set_perf_level(int client, uint32_t max_supported_bw_mbps,
return QDF_STATUS_SUCCESS;
}
#ifdef QCA_SUPPORT_WDS_EXTENDED
/**
* dp_ipa_rx_wdsext_iface() - Forward RX exception packets to wdsext interface
* @soc_hdl: data path soc handle
* @peer_id: Peer id to get respective peer
* @skb: socket buffer
*
* Return: true on success, else false
*/
bool dp_ipa_rx_wdsext_iface(struct cdp_soc_t *soc_hdl, uint8_t peer_id,
qdf_nbuf_t skb)
{
struct dp_txrx_peer *txrx_peer;
dp_txrx_ref_handle txrx_ref_handle = NULL;
struct dp_soc *dp_soc = cdp_soc_t_to_dp_soc(soc_hdl);
bool status = false;
txrx_peer = dp_tgt_txrx_peer_get_ref_by_id(soc_hdl, peer_id,
&txrx_ref_handle,
DP_MOD_ID_IPA);
if (qdf_likely(txrx_peer)) {
if (dp_rx_deliver_to_stack_ext(dp_soc, txrx_peer->vdev,
txrx_peer, skb)
status = true;
dp_txrx_peer_unref_delete(txrx_ref_handle, DP_MOD_ID_IPA);
}
return status;
}
#endif
/**
* dp_ipa_intrabss_send() - send IPA RX intra-bss frames
* @pdev: pdev

View File

@@ -362,6 +362,19 @@ int dp_ipa_pcie_link_up(struct cdp_soc_t *soc_hdl);
void dp_ipa_pcie_link_down(struct cdp_soc_t *soc_hdl);
#endif
#ifdef QCA_SUPPORT_WDS_EXTENDED
/**
* dp_ipa_rx_wdsext_iface() - Forward RX exception packets to wdsext interface
* @soc_hdl: data path SoC handle
* @peer_id: Peer ID to get respective peer
* @skb: socket buffer
*
* Return: bool
*/
bool dp_ipa_rx_wdsext_iface(struct cdp_soc_t *soc_hdl, uint8_t peer_id,
qdf_nbuf_t skb);
#endif
/**
* dp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path
*

View File

@@ -12272,6 +12272,7 @@ static struct cdp_cmn_ops dp_ops_cmn = {
#ifdef QCA_SUPPORT_WDS_EXTENDED
.set_wds_ext_peer_rx = dp_wds_ext_set_peer_rx,
.get_wds_ext_peer_osif_handle = dp_wds_ext_get_peer_osif_handle,
.set_wds_ext_peer_bit = dp_wds_ext_set_peer_bit,
#endif /* QCA_SUPPORT_WDS_EXTENDED */
#if defined(FEATURE_RUNTIME_PM) || defined(DP_POWER_SAVE)
@@ -13142,6 +13143,9 @@ static struct cdp_ipa_ops dp_ops_ipa = {
.ipa_rx_buf_smmu_pool_mapping = dp_ipa_rx_buf_pool_smmu_mapping,
.ipa_set_smmu_mapped = dp_ipa_set_smmu_mapped,
.ipa_get_smmu_mapped = dp_ipa_get_smmu_mapped,
#ifdef QCA_SUPPORT_WDS_EXTENDED
.ipa_rx_wdsext_iface = dp_ipa_rx_wdsext_iface,
#endif
#ifdef QCA_ENHANCED_STATS_SUPPORT
.ipa_update_peer_rx_stats = dp_ipa_update_peer_rx_stats,
#endif
@@ -14046,6 +14050,29 @@ QDF_STATUS dp_wds_ext_get_peer_osif_handle(
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dp_wds_ext_set_peer_bit(ol_txrx_soc_handle soc, uint8_t *mac)
{
struct dp_txrx_peer *txrx_peer = NULL;
struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
mac, 0, DP_VDEV_ALL,
DP_MOD_ID_IPA);
if (!peer) {
dp_cdp_debug("%pK: Peer is NULL!\n", (struct dp_soc *)soc);
return QDF_STATUS_E_INVAL;
}
txrx_peer = dp_get_txrx_peer(peer);
if (!txrx_peer) {
dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
return QDF_STATUS_E_INVAL;
}
qdf_atomic_test_and_set_bit(WDS_EXT_PEER_INIT_BIT,
&txrx_peer->wds_ext.init);
dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
return QDF_STATUS_SUCCESS;
}
#endif /* QCA_SUPPORT_WDS_EXTENDED */
/**

View File

@@ -2013,7 +2013,7 @@ static inline int dp_rx_drop_nbuf_list(struct dp_pdev *pdev,
*
* Return: true if packet is delivered to netdev per STA.
*/
static inline bool
bool
dp_rx_deliver_to_stack_ext(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_txrx_peer *txrx_peer, qdf_nbuf_t nbuf_head)
{

View File

@@ -3478,6 +3478,20 @@ dp_rx_is_list_ready(qdf_nbuf_t nbuf_head,
return false;
}
/**
* dp_rx_deliver_to_stack_ext() - Deliver to netdev per sta
* @soc: core txrx main context
* @vdev: vdev
* @txrx_peer: txrx peer
* @nbuf_head: skb list head
*
* Return: true if packet is delivered to netdev per STA.
*/
bool
dp_rx_deliver_to_stack_ext(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_txrx_peer *txrx_peer,
qdf_nbuf_t nbuf_head);
#else
static inline bool
dp_rx_is_list_ready(qdf_nbuf_t nbuf_head,

View File

@@ -25,6 +25,7 @@
#include "wlan_ipa_priv.h"
#include "wlan_ipa_public_struct.h"
#define WLAN_IPA_NBUF_CB_PEER_ID_OFFSET 5
/**
* wlan_ipa_is_enabled() - Is IPA enabled?
* @ipa_cfg: IPA config

View File

@@ -1298,9 +1298,11 @@ wlan_ipa_send_to_nw_queue(struct wlan_ipa_iface_context *iface_ctx,
}
#endif /* QCA_IPA_LL_TX_FLOW_CONTROL */
#if defined(IPA_OFFLOAD) && defined(QCA_SUPPORT_WDS_EXTENDED)
/**
* wlan_ipa_send_skb_to_network() - Send skb to kernel
* @skb: network buffer
* @peer_id: Peer id to get respective peer
* @iface_ctx: IPA interface context
*
* Called when a network buffer is received which should not be routed
@@ -1309,7 +1311,46 @@ wlan_ipa_send_to_nw_queue(struct wlan_ipa_iface_context *iface_ctx,
* Return: None
*/
static void
wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
wlan_ipa_send_skb_to_network(qdf_nbuf_t skb, uint8_t peer_id,
struct wlan_ipa_iface_context *iface_ctx)
{
struct wlan_ipa_priv *ipa_ctx;
ipa_ctx = iface_ctx->ipa_ctx;
if (!iface_ctx->dev) {
ipa_debug_rl("Invalid interface");
ipa_ctx->ipa_rx_internal_drop_count++;
dev_kfree_skb_any(skb);
return;
}
skb->destructor = wlan_ipa_uc_rt_debug_destructor;
if (wlan_ipa_send_to_nw_defer(iface_ctx, skb)) {
wlan_ipa_send_to_nw_queue(iface_ctx, skb);
} else {
if (!cdp_ipa_rx_wdsext_iface(ipa_ctx->dp_soc, peer_id, skb)) {
if (ipa_ctx->send_to_nw)
ipa_ctx->send_to_nw(skb, iface_ctx->dev);
}
ipa_ctx->ipa_rx_net_send_count++;
}
}
#else
/**
* wlan_ipa_send_skb_to_network() - Send skb to kernel
* @skb: network buffer
* @peer_id: Peer id to get respective peer
* @iface_ctx: IPA interface context
*
* Called when a network buffer is received which should not be routed
* to the IPA module.
*
* Return: None
*/
static void
wlan_ipa_send_skb_to_network(qdf_nbuf_t skb, uint8_t peer_id,
struct wlan_ipa_iface_context *iface_ctx)
{
struct wlan_ipa_priv *ipa_ctx;
@@ -1334,6 +1375,7 @@ wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
ipa_ctx->ipa_rx_net_send_count++;
}
}
#endif
/**
* wlan_ipa_eapol_intrabss_fwd_check() - Check if eapol pkt intrabss fwd is
@@ -1550,6 +1592,7 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
struct wlan_ipa_iface_context *iface_context;
bool is_eapol_wapi = false;
struct qdf_mac_addr peer_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
uint8_t peer_id;
ipa_ctx = (struct wlan_ipa_priv *)priv;
if (!ipa_ctx) {
@@ -1668,7 +1711,8 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
iface_context->session_id);
}
wlan_ipa_send_skb_to_network(skb, iface_context);
peer_id = (uint8_t)skb->cb[WLAN_IPA_NBUF_CB_PEER_ID_OFFSET];
wlan_ipa_send_skb_to_network(skb, peer_id, iface_context);
break;
default: