qcacmn: Easymesh feature support

Current IPA/WLAN driver does not support the WDS feature.
Packets are dropped if they came via end-node which is not
in direct connection with root AP.

Fix is to enable WDS support and update the same to IPA
driver and create/update AST entries for end-node in
roaming, new src port learn case. Send WDS support to IPA
at wdi init and AP client connect event.

CRs-Fixed: 3226348
Change-Id: I26211613334b33d0d601629405597be329a56774
This commit is contained in:
Devender Kumar
2022-06-27 15:28:13 +05:30
committed by Madan Koyyalamudi
parent b1461c9317
commit 3035192763
7 changed files with 308 additions and 37 deletions

View File

@@ -568,6 +568,13 @@ void ipa_init_deinit_lock(void);
*/ */
void ipa_init_deinit_unlock(void); void ipa_init_deinit_unlock(void);
/**
* ipa_is_wds_enabled() - IPA wds status
*
* Return: true if WDS is enabled otherwise false
*/
bool ipa_is_wds_enabled(void);
#else /* Not IPA_OFFLOAD */ #else /* Not IPA_OFFLOAD */
typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev); typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev); typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev);

View File

@@ -38,6 +38,9 @@
#define IPA_SPS_DESC_SIZE 8 #define IPA_SPS_DESC_SIZE 8
#define IPA_DEFAULT_HDL 0 #define IPA_DEFAULT_HDL 0
#ifdef IPA_WDS_EASYMESH_FEATURE
#define IPA_TA_PEER_ID_ATTRI 2
#endif
static struct wlan_ipa_priv *gp_ipa; static struct wlan_ipa_priv *gp_ipa;
static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx); static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
@@ -78,6 +81,9 @@ static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
unsigned long data); unsigned long data);
static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
unsigned long data); unsigned long data);
static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx,
qdf_ipa_wdi_init_in_params_t *in);
static void wlan_ipa_msg_wds_update(bool ipa_wds, qdf_ipa_wlan_msg_t *msg);
/** /**
* wlan_ipa_uc_sta_is_enabled() - Is STA mode IPA uC offload enabled? * wlan_ipa_uc_sta_is_enabled() - Is STA mode IPA uC offload enabled?
@@ -518,6 +524,42 @@ static inline bool wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx,
return ipa_ctx->is_smmu_enabled && qdf_mem_smmu_s1_enabled(osdev); return ipa_ctx->is_smmu_enabled && qdf_mem_smmu_s1_enabled(osdev);
} }
#ifdef IPA_WDS_EASYMESH_FEATURE
/**
* wlan_ipa_ast_notify_cb() - IPA AST create/update CB
* @priv: IPA context
* @data: Structure used for updating the AST table
*
* Will be called by IPA context.
*
* Return: None
*/
static void wlan_ipa_ast_notify_cb(void *priv, void *data)
{
qdf_ipa_ast_info_type_t *ast_info;
struct wlan_ipa_priv *ipa_ctx;
if (!data) {
dp_err("Invalid IPA AST data context");
return;
}
if (!priv) {
dp_err("Invalid IPA context");
return;
}
ast_info = (qdf_ipa_ast_info_type_t *)data;
ipa_ctx = (struct wlan_ipa_priv *)priv;
cdp_ipa_ast_create(ipa_ctx->dp_soc, ast_info);
}
#else
static inline void wlan_ipa_ast_notify_cb(void *priv, void *data)
{
}
#endif
static inline QDF_STATUS static inline QDF_STATUS
wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx, wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
qdf_device_t osdev) qdf_device_t osdev)
@@ -544,9 +586,9 @@ wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
&ipa_ctx->tx_pipe_handle, &ipa_ctx->tx_pipe_handle,
&ipa_ctx->rx_pipe_handle, &ipa_ctx->rx_pipe_handle,
wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev), wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev),
sys_in, ipa_ctx->over_gsi, sys_in, ipa_ctx->over_gsi, ipa_ctx->hdl,
ipa_ctx->hdl, (qdf_ipa_wdi_hdl_t)ipa_ctx->instance_id,
(qdf_ipa_wdi_hdl_t)ipa_ctx->instance_id); wlan_ipa_ast_notify_cb);
qdf_mem_free(sys_in); qdf_mem_free(sys_in);
@@ -574,6 +616,48 @@ static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
} }
#endif #endif
#ifdef IPA_WDS_EASYMESH_FEATURE
/**
* wlan_ipa_update_wds_params();
* @ipa_ctx: IPA context
* @in: IPA wdi init in params
*
* This function is to update wds status to IPA in wdi init params
*
* Return: None
*/
static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx,
qdf_ipa_wdi_init_in_params_t *in)
{
QDF_IPA_WDI_INIT_IN_PARAMS_WDS_UPDATE(in) = ipa_ctx->config->ipa_wds;
}
/**
* wlan_ipa_msg_wds_update();
* @ipa_wds: IPA WDS status
* @msg: Meta data message for IPA
*
* This function is to update wds status to IPA in meta message
*
* Return: None
*/
static void wlan_ipa_msg_wds_update(bool ipa_wds,
qdf_ipa_wlan_msg_t *msg)
{
QDF_IPA_WLAN_MSG_WDS_UPDATE(msg) = ipa_wds;
}
#else
static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx,
qdf_ipa_wdi_init_in_params_t *in)
{
}
static void wlan_ipa_msg_wds_update(bool ipa_wds,
qdf_ipa_wlan_msg_t *msg)
{
}
#endif
/** /**
* wlan_ipa_wdi_init() - IPA WDI init * wlan_ipa_wdi_init() - IPA WDI init
* @ipa_ctx: IPA context * @ipa_ctx: IPA context
@@ -595,8 +679,8 @@ static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
QDF_IPA_WDI_INIT_IN_PARAMS_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb; QDF_IPA_WDI_INIT_IN_PARAMS_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb;
QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx; QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx;
QDF_IPA_WDI_INIT_IN_PARAMS_INSTANCE_ID(&in) = ipa_ctx->instance_id; QDF_IPA_WDI_INIT_IN_PARAMS_INSTANCE_ID(&in) = ipa_ctx->instance_id;
wlan_ipa_update_wds_params(ipa_ctx, &in);
wlan_ipa_wdi_init_metering(ipa_ctx, &in); wlan_ipa_wdi_init_metering(ipa_ctx, &in);
ret = qdf_ipa_wdi_init(&in, &out); ret = qdf_ipa_wdi_init(&in, &out);
if (ret) { if (ret) {
ipa_err("ipa_wdi_init failed with ret=%d", ret); ipa_err("ipa_wdi_init failed with ret=%d", ret);
@@ -1123,6 +1207,38 @@ wlan_ipa_get_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac)
return false; return false;
} }
#ifdef IPA_WDS_EASYMESH_FEATURE
static inline uint8_t
wlan_ipa_get_peer_auth_state(ol_txrx_soc_handle dp_soc, uint8_t *peer_mac,
struct wlan_ipa_iface_context *iface)
{
uint8_t is_authenticated = false;
struct cdp_ast_entry_info ast_info = {0};
if (ipa_is_wds_enabled()) {
cdp_peer_get_ast_info_by_soc(dp_soc, peer_mac,
&ast_info);
peer_mac = &ast_info.peer_mac_addr[0];
is_authenticated = wlan_ipa_get_peer_state(dp_soc,
iface->session_id,
peer_mac);
}
return is_authenticated;
}
#else
static inline uint8_t
wlan_ipa_get_peer_auth_state(ol_txrx_soc_handle dp_soc, uint8_t *peer_mac,
struct wlan_ipa_iface_context *iface)
{
uint8_t is_authenticated = false;
is_authenticated = wlan_ipa_get_peer_state(dp_soc, iface->session_id,
peer_mac);
return is_authenticated;
}
#endif
static inline bool static inline bool
wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc, wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc,
struct wlan_ipa_iface_context *iface, struct wlan_ipa_iface_context *iface,
@@ -1135,9 +1251,11 @@ wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc,
peer_mac); peer_mac);
if (is_authenticated) if (is_authenticated)
return is_authenticated; return is_authenticated;
is_authenticated = wlan_ipa_get_peer_state(dp_soc,
iface->session_id, is_authenticated = wlan_ipa_get_peer_auth_state(dp_soc,
peer_mac); peer_mac,
iface);
if (is_authenticated) if (is_authenticated)
wlan_ipa_set_sap_client_auth(iface->ipa_ctx, wlan_ipa_set_sap_client_auth(iface->ipa_ctx,
peer_mac, peer_mac,
@@ -2461,6 +2579,118 @@ wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id,
mac_addr, QDF_MAC_ADDR_SIZE); mac_addr, QDF_MAC_ADDR_SIZE);
} }
#ifdef IPA_WDS_EASYMESH_FEATURE
/** wlan_ipa_set_peer_id() - Set ta_peer_id in IPA
* @ipa_ctx: ipa context
* @meta: Meta data for IPA
* @net_dev: Interface net device
* @type: WLAN IPA event
* @mac_addr: mac_addr of peer
*
* Return: QDF STATUS
*/
static QDF_STATUS
wlan_ipa_set_peer_id(struct wlan_ipa_priv *ipa_ctx,
qdf_ipa_msg_meta_t *meta,
qdf_netdev_t net_dev,
qdf_ipa_wlan_event type,
uint8_t *mac_addr)
{
uint8_t ta_peer_id;
struct cdp_ast_entry_info peer_ast_info = {0};
struct cdp_soc_t *cdp_soc;
qdf_ipa_wlan_msg_ex_t *msg_ex;
QDF_STATUS status;
QDF_IPA_MSG_META_MSG_LEN(meta) =
(sizeof(qdf_ipa_wlan_msg_ex_t) +
sizeof(qdf_ipa_wlan_hdr_attrib_val_t) *
IPA_TA_PEER_ID_ATTRI);
msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(meta));
if (!msg_ex)
return QDF_STATUS_E_NOMEM;
strlcpy(msg_ex->name, net_dev->name, IPA_RESOURCE_NAME_MAX);
msg_ex->num_of_attribs = IPA_TA_PEER_ID_ATTRI;
ipa_info("Num of attribute set to: %d", IPA_TA_PEER_ID_ATTRI);
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
msg_ex->attribs[0].offset =
WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
} else {
msg_ex->attribs[0].offset =
WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET;
}
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE);
msg_ex->attribs[1].attrib_type = WLAN_HDR_ATTRIB_TA_PEER_ID;
cdp_soc = (struct cdp_soc_t *)ipa_ctx->dp_soc;
status = cdp_peer_get_ast_info_by_soc(cdp_soc, mac_addr,
&peer_ast_info);
if (QDF_IS_STATUS_ERROR(status)) {
qdf_mem_free(msg_ex);
return QDF_STATUS_E_FAILURE;
}
ta_peer_id = peer_ast_info.peer_id;
ipa_info("ta_peer_id set to: %d", ta_peer_id);
msg_ex->attribs[1].u.ta_peer_id = ta_peer_id;
if (qdf_ipa_send_msg(meta, msg_ex, wlan_ipa_msg_free_fn)) {
ipa_info("%s: Evt: %d send ipa msg fail",
net_dev->name, type);
qdf_mem_free(msg_ex);
return QDF_STATUS_E_FAILURE;
}
ipa_ctx->stats.num_send_msg++;
return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS
wlan_ipa_set_peer_id(struct wlan_ipa_priv *ipa_ctx,
qdf_ipa_msg_meta_t *meta,
qdf_netdev_t net_dev,
qdf_ipa_wlan_event type,
uint8_t *mac_addr)
{
qdf_ipa_wlan_msg_ex_t *msg_ex;
QDF_IPA_MSG_META_MSG_LEN(meta) =
(sizeof(qdf_ipa_wlan_msg_ex_t) +
sizeof(qdf_ipa_wlan_hdr_attrib_val_t));
msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(meta));
if (!msg_ex)
return QDF_STATUS_E_NOMEM;
strlcpy(msg_ex->name, net_dev->name, IPA_RESOURCE_NAME_MAX);
msg_ex->num_of_attribs = 1;
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
msg_ex->attribs[0].offset =
WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
} else {
msg_ex->attribs[0].offset = WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET;
}
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE);
if (qdf_ipa_send_msg(meta, msg_ex, wlan_ipa_msg_free_fn)) {
ipa_info("%s: Evt: %d send ipa msg fail",
net_dev->name, type);
qdf_mem_free(msg_ex);
return QDF_STATUS_E_FAILURE;
}
ipa_ctx->stats.num_send_msg++;
return QDF_STATUS_SUCCESS;
}
#endif
/** /**
* __wlan_ipa_wlan_evt() - IPA event handler * __wlan_ipa_wlan_evt() - IPA event handler
* @net_dev: Interface net device * @net_dev: Interface net device
@@ -2492,6 +2722,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_pdev *pdev;
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
bool ipa_wds = false;
ipa_debug("%s: EVT: %d, MAC: "QDF_MAC_ADDR_FMT", session_id: %u", ipa_debug("%s: EVT: %d, MAC: "QDF_MAC_ADDR_FMT", session_id: %u",
net_dev->name, type, QDF_MAC_ADDR_REF(mac_addr), session_id); net_dev->name, type, QDF_MAC_ADDR_REF(mac_addr), session_id);
@@ -2764,6 +2995,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
ipa_debug("vdev_to_iface[%u]=%u", ipa_debug("vdev_to_iface[%u]=%u",
session_id, session_id,
ipa_ctx->vdev_to_iface[session_id]); ipa_ctx->vdev_to_iface[session_id]);
ipa_wds = ipa_ctx->config->ipa_wds;
qdf_mutex_release(&ipa_ctx->event_lock); qdf_mutex_release(&ipa_ctx->event_lock);
break; break;
@@ -2971,34 +3203,11 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
qdf_mutex_release(&ipa_ctx->event_lock); qdf_mutex_release(&ipa_ctx->event_lock);
QDF_IPA_SET_META_MSG_TYPE(&meta, type); QDF_IPA_SET_META_MSG_TYPE(&meta, type);
QDF_IPA_MSG_META_MSG_LEN(&meta) =
(sizeof(qdf_ipa_wlan_msg_ex_t) +
sizeof(qdf_ipa_wlan_hdr_attrib_val_t));
msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
if (!msg_ex)
return QDF_STATUS_E_NOMEM;
strlcpy(msg_ex->name, net_dev->name, status = wlan_ipa_set_peer_id(ipa_ctx, &meta, net_dev,
IPA_RESOURCE_NAME_MAX); type, (uint8_t *)mac_addr);
msg_ex->num_of_attribs = 1; if (QDF_IS_STATUS_ERROR(status))
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
msg_ex->attribs[0].offset =
WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
} else {
msg_ex->attribs[0].offset =
WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET;
}
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr,
IPA_MAC_ADDR_SIZE);
if (qdf_ipa_send_msg(&meta, msg_ex, wlan_ipa_msg_free_fn)) {
ipa_info("%s: Evt: %d send ipa msg fail",
net_dev->name, type);
qdf_mem_free(msg_ex);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
}
ipa_ctx->stats.num_send_msg++;
ipa_debug("sap_num_connected_sta=%d", ipa_debug("sap_num_connected_sta=%d",
ipa_ctx->sap_num_connected_sta); ipa_ctx->sap_num_connected_sta);
@@ -3103,6 +3312,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN); qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN);
QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex; QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex;
wlan_ipa_msg_wds_update(ipa_wds, msg);
ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg), ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg),
QDF_IPA_MSG_META_MSG_TYPE(&meta)); QDF_IPA_MSG_META_MSG_TYPE(&meta));

View File

@@ -845,6 +845,8 @@ void ipa_component_config_update(struct wlan_objmgr_psoc *psoc)
cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD); cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD);
g_ipa_config->ipa_force_voting = g_ipa_config->ipa_force_voting =
cfg_get(psoc, CFG_DP_IPA_ENABLE_FORCE_VOTING); cfg_get(psoc, CFG_DP_IPA_ENABLE_FORCE_VOTING);
g_ipa_config->ipa_wds =
cfg_get(psoc, CFG_DP_IPA_WDS_STATUS);
} }
void ipa_component_config_free(void) void ipa_component_config_free(void)
@@ -895,3 +897,7 @@ void ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev,
wlan_ipa_flush_pending_vdev_events(ipa_obj, vdev_id); wlan_ipa_flush_pending_vdev_events(ipa_obj, vdev_id);
} }
bool ipa_is_wds_enabled(void)
{
return g_ipa_config ? g_ipa_config->ipa_wds : 0;
}

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -198,6 +199,25 @@
512, \ 512, \
CFG_VALUE_OR_DEFAULT, "IPA tx buffer count") CFG_VALUE_OR_DEFAULT, "IPA tx buffer count")
/*
* <ini>
* gIPAWds - IPA WDS Enable
* @Default: false
*
* This ini specifies to enable WDS for IPA
*
* Related: N/A
*
* Supported Feature: IPA
*
* Usage: Internal
*
* </ini>
*/
#define CFG_DP_IPA_WDS_STATUS \
CFG_INI_BOOL("gIPAWds", \
false, "Ctrl to enable WDS for EasyMesh")
#define CFG_IPA \ #define CFG_IPA \
CFG(CFG_DP_IPA_OFFLOAD_CONFIG) \ CFG(CFG_DP_IPA_OFFLOAD_CONFIG) \
CFG(CFG_DP_IPA_DESC_SIZE) \ CFG(CFG_DP_IPA_DESC_SIZE) \
@@ -205,6 +225,6 @@
CFG(CFG_DP_IPA_MEDIUM_BANDWIDTH_MBPS) \ CFG(CFG_DP_IPA_MEDIUM_BANDWIDTH_MBPS) \
CFG(CFG_DP_IPA_LOW_BANDWIDTH_MBPS) \ CFG(CFG_DP_IPA_LOW_BANDWIDTH_MBPS) \
CFG(CFG_DP_IPA_ENABLE_FORCE_VOTING) \ CFG(CFG_DP_IPA_ENABLE_FORCE_VOTING) \
CFG(CFG_DP_IPA_UC_TX_BUF_COUNT) CFG(CFG_DP_IPA_UC_TX_BUF_COUNT) \
CFG(CFG_DP_IPA_WDS_STATUS)
#endif /* _CFG_IPA_H_ */ #endif /* _CFG_IPA_H_ */

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -40,6 +40,7 @@
* @ipa_bw_medium: IPA bandwidth medium threshold * @ipa_bw_medium: IPA bandwidth medium threshold
* @ipa_bw_low: IPA bandwidth low threshold * @ipa_bw_low: IPA bandwidth low threshold
* @ipa_force_voting: support force bw voting * @ipa_force_voting: support force bw voting
* @ipa_wds: WDS support for IPA
*/ */
struct wlan_ipa_config { struct wlan_ipa_config {
uint32_t ipa_config; uint32_t ipa_config;
@@ -52,6 +53,7 @@ struct wlan_ipa_config {
uint32_t ipa_bw_medium; uint32_t ipa_bw_medium;
uint32_t ipa_bw_low; uint32_t ipa_bw_low;
bool ipa_force_voting; bool ipa_force_voting;
bool ipa_wds;
}; };
/** /**

View File

@@ -449,6 +449,18 @@ void ucfg_ipa_update_tx_stats(struct wlan_objmgr_pdev *pdev, uint64_t sta_tx,
*/ */
void ucfg_ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev, void ucfg_ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev,
uint8_t vdev_id); uint8_t vdev_id);
/**
* ucfg_ipa_is_wds_enabled() - get IPA AP WDS status
*
* IPA driver requires WDS status for adding filter rules
* to support easymesh feature, IPA expectes wds status
* with WLAN_IPA_AP_CONNECT event.
*
* Return: true - WDS is enabled
* false - WDS is not enabled
*/
bool ucfg_ipa_is_wds_enabled(void);
#else #else
static inline void ucfg_ipa_set_pld_enable(bool flag) static inline void ucfg_ipa_set_pld_enable(bool flag)
{ {
@@ -701,5 +713,11 @@ void ucfg_ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev,
uint8_t vdev_id) uint8_t vdev_id)
{ {
} }
static inline
bool ucfg_ipa_is_wds_enabled(void)
{
return 0;
}
#endif /* IPA_OFFLOAD */ #endif /* IPA_OFFLOAD */
#endif /* _WLAN_IPA_UCFG_API_H_ */ #endif /* _WLAN_IPA_UCFG_API_H_ */

View File

@@ -347,3 +347,10 @@ void ucfg_ipa_flush_pending_vdev_events(struct wlan_objmgr_pdev *pdev,
} }
qdf_export_symbol(ucfg_ipa_flush_pending_vdev_events); qdf_export_symbol(ucfg_ipa_flush_pending_vdev_events);
bool ucfg_ipa_is_wds_enabled(void)
{
return ipa_is_wds_enabled();
}
qdf_export_symbol(ucfg_ipa_is_wds_enabled);