|
@@ -30,6 +30,9 @@
|
|
#include <wmi_unified_param.h>
|
|
#include <wmi_unified_param.h>
|
|
#include <wlan_osif_priv.h>
|
|
#include <wlan_osif_priv.h>
|
|
#include <net/cfg80211.h>
|
|
#include <net/cfg80211.h>
|
|
|
|
+#ifdef IPA_OPT_WIFI_DP
|
|
|
|
+#include "init_deinit_lmac.h"
|
|
|
|
+#endif
|
|
#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
|
|
#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
|
|
#include <cdp_txrx_flow_ctrl_v2.h>
|
|
#include <cdp_txrx_flow_ctrl_v2.h>
|
|
#include <cdp_txrx_peer_ops.h>
|
|
#include <cdp_txrx_peer_ops.h>
|
|
@@ -41,6 +44,15 @@
|
|
#ifdef IPA_WDS_EASYMESH_FEATURE
|
|
#ifdef IPA_WDS_EASYMESH_FEATURE
|
|
#define IPA_TA_PEER_ID_ATTRI 2
|
|
#define IPA_TA_PEER_ID_ATTRI 2
|
|
#endif
|
|
#endif
|
|
|
|
+#ifdef IPA_OPT_WIFI_DP
|
|
|
|
+#define IPA_WDI_MAX_FILTER 2
|
|
|
|
+#define IPV6BYTES 16 /* IPV6 addr: 128bits/8 = 16bytes */
|
|
|
|
+#define IPV4BYTES 4 /* IPV4 addr: 32bits/8 = 4bytes */
|
|
|
|
+#define DP_MAX_SLEEP_TIME 100
|
|
|
|
+#define IPV4 0x0008
|
|
|
|
+#define IPV6 0xdd86
|
|
|
|
+#define IPV6ARRAY 4
|
|
|
|
+#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);
|
|
@@ -141,11 +153,18 @@ static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
#else
|
|
#else
|
|
|
|
+#ifdef IPA_OPT_WIFI_DP
|
|
|
|
+static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
|
|
|
|
+{
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+#else
|
|
static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
|
|
static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
|
|
{
|
|
{
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
-#endif
|
|
|
|
|
|
+#endif /* IPA_OPT_WIFI_DP */
|
|
|
|
+#endif /* MDM_PLATFORM */
|
|
|
|
|
|
/**
|
|
/**
|
|
* wlan_ipa_msg_free_fn() - Free an IPA message
|
|
* wlan_ipa_msg_free_fn() - Free an IPA message
|
|
@@ -620,6 +639,29 @@ static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef IPA_OPT_WIFI_DP
|
|
|
|
+/**
|
|
|
|
+ * wlan_ipa_wdi_init_set_opt_wifi_dp - set if optional wifi dp feature enabled_
|
|
|
|
+ * @ipa_ctxt: IPA context
|
|
|
|
+ * @out: IPA WDI out param
|
|
|
|
+ *
|
|
|
|
+ * Return: void
|
|
|
|
+ */
|
|
|
|
+static inline void wlan_ipa_wdi_init_set_opt_wifi_dp(
|
|
|
|
+ struct wlan_ipa_priv *ipa_ctxt,
|
|
|
|
+ qdf_ipa_wdi_init_out_params_t out)
|
|
|
|
+{
|
|
|
|
+ ipa_ctx->opt_wifi_datapath =
|
|
|
|
+ QDF_IPA_WDI_INIT_OUT_PARAMS_OPT_WIFI_DP(&out);
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static inline void wlan_ipa_wdi_init_set_opt_wifi_dp(
|
|
|
|
+ struct wlan_ipa_priv *ipa_ctxt,
|
|
|
|
+ qdf_ipa_wdi_init_out_params_t out)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
#ifdef IPA_WDS_EASYMESH_FEATURE
|
|
#ifdef IPA_WDS_EASYMESH_FEATURE
|
|
/**
|
|
/**
|
|
* wlan_ipa_update_wds_params() - IPA update WDS parameters
|
|
* wlan_ipa_update_wds_params() - IPA update WDS parameters
|
|
@@ -696,9 +738,12 @@ static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
|
|
ipa_ctx->is_smmu_enabled =
|
|
ipa_ctx->is_smmu_enabled =
|
|
QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
|
|
QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
|
|
ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
|
|
ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
|
|
|
|
+ wlan_ipa_wdi_init_set_opt_wifi_dp(ipa_ctx, &out);
|
|
|
|
|
|
ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d",
|
|
ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d",
|
|
ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl);
|
|
ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl);
|
|
|
|
+ ipa_info("opt_dp: enabled from IPA : %d",
|
|
|
|
+ ipa_ctx->opt_wifi_datapath);
|
|
|
|
|
|
if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
|
|
if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
|
|
ipa_debug("IPA uC READY");
|
|
ipa_debug("IPA uC READY");
|
|
@@ -1683,9 +1728,14 @@ QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx)
|
|
qdf_event_reset(&ipa_ctx->ipa_resource_comp);
|
|
qdf_event_reset(&ipa_ctx->ipa_resource_comp);
|
|
|
|
|
|
if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
|
|
if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
|
|
- cdp_ipa_enable_autonomy(ipa_ctx->dp_soc,
|
|
|
|
- ipa_ctx->dp_pdev_id);
|
|
|
|
- qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0);
|
|
|
|
|
|
+ if (ipa_ctx->opt_wifi_datapath) {
|
|
|
|
+ /* Default packet routing is to HOST REO rings */
|
|
|
|
+ ipa_info("opt_dp: enable pipes. Do not enable autonomy");
|
|
|
|
+ } else {
|
|
|
|
+ cdp_ipa_enable_autonomy(ipa_ctx->dp_soc,
|
|
|
|
+ ipa_ctx->dp_pdev_id);
|
|
|
|
+ qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
end:
|
|
end:
|
|
qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
|
|
qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
|
|
@@ -3903,6 +3953,59 @@ static void wlan_ipa_mcc_work_handler(void *data)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef IPA_OPT_WIFI_DP
|
|
|
|
+/**
|
|
|
|
+ * wlan_ipa_reg_flt_cbs() - register filter cbs with IPA to set up Rx CCE filter
|
|
|
|
+ * rules for optional wifi datapath
|
|
|
|
+ * @ipa_ctx: IPA context
|
|
|
|
+ *
|
|
|
|
+ *
|
|
|
|
+ * Return: QDF_STATUS enumeration
|
|
|
|
+ */
|
|
|
|
+static inline QDF_STATUS wlan_ipa_reg_flt_cbs(struct wlan_ipa_priv *ipa_ctx)
|
|
|
|
+{
|
|
|
|
+ QDF_STATUS status;
|
|
|
|
+
|
|
|
|
+ ipa_wdi_opt_dpath_flt_rsrv_cb flt_rsrv_cb =
|
|
|
|
+ &wlan_ipa_wdi_opt_dpath_flt_rsrv_cb;
|
|
|
|
+ ipa_wdi_opt_dpath_flt_rsrv_rel_cb
|
|
|
|
+ flt_rsrv_rel_cb = &wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb;
|
|
|
|
+ ipa_wdi_opt_dpath_flt_rem_cb flt_rem_cb =
|
|
|
|
+ &wlan_ipa_wdi_opt_dpath_flt_rem_cb;
|
|
|
|
+ ipa_wdi_opt_dpath_flt_add_cb flt_add_cb =
|
|
|
|
+ &wlan_ipa_wdi_opt_dpath_flt_add_cb;
|
|
|
|
+
|
|
|
|
+ ipa_info("opt_dp: ipa_reg_flt_cb");
|
|
|
|
+ status = qdf_ipa_wdi_register_flt_cb(ipa_ctx->hdl, flt_rsrv_cb,
|
|
|
|
+ flt_rsrv_rel_cb,
|
|
|
|
+ flt_add_cb,
|
|
|
|
+ flt_rem_cb);
|
|
|
|
+ return status;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * wlan_ipa_destroy_opt_wifi_flt_cb_event - destroy filter cb event
|
|
|
|
+ * @ipa_ctx: IPA context
|
|
|
|
+ *
|
|
|
|
+ *Return: void
|
|
|
|
+ */
|
|
|
|
+static inline void wlan_ipa_destroy_opt_wifi_flt_cb_event(
|
|
|
|
+ struct wlan_ipa_priv *ipa_ctx)
|
|
|
|
+{
|
|
|
|
+ qdf_event_destroy(&ipa_ctx->ipa_flt_evnt);
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static inline QDF_STATUS wlan_ipa_reg_flt_cbs(struct wlan_ipa_priv *ipa_ctx)
|
|
|
|
+{
|
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void wlan_ipa_destroy_opt_wifi_flt_cb_event(
|
|
|
|
+ struct wlan_ipa_priv *ipa_ctx)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* wlan_ipa_setup() - IPA initialization function
|
|
* wlan_ipa_setup() - IPA initialization function
|
|
* @ipa_ctx: IPA context
|
|
* @ipa_ctx: IPA context
|
|
@@ -3982,6 +4085,13 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
|
|
ipa_ctx->wdi_enabled = false;
|
|
ipa_ctx->wdi_enabled = false;
|
|
|
|
|
|
status = wlan_ipa_wdi_init(ipa_ctx);
|
|
status = wlan_ipa_wdi_init(ipa_ctx);
|
|
|
|
+
|
|
|
|
+ /* Register call backs for opt wifi dp */
|
|
|
|
+ if (ipa_ctx->opt_wifi_datapath) {
|
|
|
|
+ status = wlan_ipa_reg_flt_cbs(ipa_ctx);
|
|
|
|
+ ipa_info("opt_dp: Register cb status %d", status);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (status == QDF_STATUS_SUCCESS) {
|
|
if (status == QDF_STATUS_SUCCESS) {
|
|
/* Setup IPA system pipes */
|
|
/* Setup IPA system pipes */
|
|
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
|
|
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
|
|
@@ -4076,6 +4186,8 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
|
|
if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
|
|
if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
|
|
wlan_ipa_teardown_sys_pipe(ipa_ctx);
|
|
wlan_ipa_teardown_sys_pipe(ipa_ctx);
|
|
|
|
|
|
|
|
+ wlan_ipa_destroy_opt_wifi_flt_cb_event(ipa_ctx);
|
|
|
|
+
|
|
/* Teardown IPA sys_pipe for MCC */
|
|
/* Teardown IPA sys_pipe for MCC */
|
|
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
|
|
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
|
|
wlan_ipa_teardown_sys_pipe(ipa_ctx);
|
|
wlan_ipa_teardown_sys_pipe(ipa_ctx);
|
|
@@ -4222,7 +4334,7 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
|
|
ipa_info("TX buffers mapped to IPA");
|
|
ipa_info("TX buffers mapped to IPA");
|
|
cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id);
|
|
cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id);
|
|
wlan_ipa_init_metering(ipa_ctx);
|
|
wlan_ipa_init_metering(ipa_ctx);
|
|
-
|
|
|
|
|
|
+ wlan_ipa_add_rem_flt_cb_event(ipa_ctx);
|
|
if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx)))
|
|
if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx)))
|
|
ipa_err("Failed to init perf level");
|
|
ipa_err("Failed to init perf level");
|
|
|
|
|
|
@@ -4506,7 +4618,7 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
|
|
cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc,
|
|
cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc,
|
|
ipa_ctx->dp_pdev_id);
|
|
ipa_ctx->dp_pdev_id);
|
|
wlan_ipa_init_metering(ipa_ctx);
|
|
wlan_ipa_init_metering(ipa_ctx);
|
|
-
|
|
|
|
|
|
+ wlan_ipa_add_rem_flt_cb_event(ipa_ctx);
|
|
if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
|
|
if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
|
|
ipa_err("Failed to init perf level");
|
|
ipa_err("Failed to init perf level");
|
|
}
|
|
}
|
|
@@ -4752,3 +4864,321 @@ void wlan_ipa_flush_pending_vdev_events(struct wlan_ipa_priv *ipa_ctx,
|
|
|
|
|
|
qdf_mutex_release(&ipa_ctx->ipa_lock);
|
|
qdf_mutex_release(&ipa_ctx->ipa_lock);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+#ifdef IPA_OPT_WIFI_DP
|
|
|
|
+int wlan_ipa_wdi_opt_dpath_notify_flt_rsvd(bool response)
|
|
|
|
+{
|
|
|
|
+ ipa_info("opt_dp: IPA notify filter resrv response: %d", response);
|
|
|
|
+ return qdf_ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst(gp_ipa->hdl,
|
|
|
|
+ response);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int wlan_ipa_wdi_opt_dpath_flt_rsrv_cb(
|
|
|
|
+ void *ipa_ctx,
|
|
|
|
+ struct ipa_wdi_opt_dpath_flt_rsrv_cb_params *out_params)
|
|
|
|
+{
|
|
|
|
+ struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
|
|
|
+ struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ ipa_info("opt_dp: Send filter reserve req");
|
|
|
|
+ dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
|
|
|
+ dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_SETUP_REQUEST;
|
|
|
|
+ dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
|
|
|
|
+ for (i = 0; i < IPA_WDI_MAX_FILTER; i++) {
|
|
|
|
+ dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required = 0;
|
|
|
|
+ dp_flt_params->flt_addr_params[i].ipa_flt_in_use = false;
|
|
|
|
+ }
|
|
|
|
+ return cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int wlan_ipa_wdi_opt_dpath_flt_add_cb(
|
|
|
|
+ void *ipa_ctx,
|
|
|
|
+ struct ipa_wdi_opt_dpath_flt_add_cb_params *in_out)
|
|
|
|
+{
|
|
|
|
+ struct ipa_wdi_opt_dpath_flt_add_cb_params *ipa_flt =
|
|
|
|
+ (struct ipa_wdi_opt_dpath_flt_add_cb_params *)(in_out);
|
|
|
|
+ struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
|
|
|
+ int i, param_val, pdev_id;
|
|
|
|
+ uint8_t num_flts;
|
|
|
|
+ uint32_t src_ip_addr, dst_ip_addr;
|
|
|
|
+ uint32_t *host_ipv6;
|
|
|
|
+ int response = 0;
|
|
|
|
+ struct wlan_objmgr_pdev *pdev;
|
|
|
|
+ struct wlan_objmgr_psoc *psoc;
|
|
|
|
+ struct wifi_dp_flt_setup *dp_flt_param = NULL;
|
|
|
|
+ void *htc_handle;
|
|
|
|
+
|
|
|
|
+ pdev = ipa_obj->pdev;
|
|
|
|
+ psoc = wlan_pdev_get_psoc(pdev);
|
|
|
|
+ pdev_id = ipa_obj->dp_pdev_id;
|
|
|
|
+ num_flts = ipa_flt->num_tuples;
|
|
|
|
+
|
|
|
|
+ htc_handle = lmac_get_htc_hdl(psoc);
|
|
|
|
+ if (!htc_handle) {
|
|
|
|
+ ipa_err("HTC Handle is null");
|
|
|
|
+ return QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dp_flt_param = &(ipa_obj->dp_cce_super_rule_flt_param);
|
|
|
|
+
|
|
|
|
+ if (num_flts > IPA_WDI_MAX_FILTER) {
|
|
|
|
+ ipa_err("Wrong IPA flt count %d", num_flts);
|
|
|
|
+ return QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Disable Low power features before filter addition */
|
|
|
|
+ ipa_info("opt_dp: Disable low power features to add filter param");
|
|
|
|
+ param_val = 0;
|
|
|
|
+ response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
|
|
|
|
+ param_val);
|
|
|
|
+ if (response) {
|
|
|
|
+ ipa_err("Low power feature disable failed. status %d",
|
|
|
|
+ response);
|
|
|
|
+ return QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+ response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
|
|
|
|
+ ipa_info("opt_dp: Pcie link up status %d", response);
|
|
|
|
+
|
|
|
|
+ /* set filter tuple params for rx filter */
|
|
|
|
+ for (i = 0; i < num_flts; i++) {
|
|
|
|
+ ipa_flt->flt_info[i].out_hdl = (WLAN_HDL_FILTER1 + i);
|
|
|
|
+ dp_flt_param->flt_addr_params[i].valid = 1;
|
|
|
|
+ dp_flt_param->flt_addr_params[i].flt_hdl =
|
|
|
|
+ ipa_flt->flt_info[i].out_hdl;
|
|
|
|
+ dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required = 1;
|
|
|
|
+ dp_flt_param->flt_addr_params[i].ipa_flt_in_use = true;
|
|
|
|
+
|
|
|
|
+ if (ipa_flt->flt_info[i].version == 0) {
|
|
|
|
+ dp_flt_param->flt_addr_params[i].l3_type = IPV4;
|
|
|
|
+ } else if (ipa_flt->flt_info[i].version == 1) {
|
|
|
|
+ dp_flt_param->flt_addr_params[i].l3_type = IPV6;
|
|
|
|
+ } else {
|
|
|
|
+ ipa_err("Wrong IPA version %d",
|
|
|
|
+ ipa_flt->flt_info[i].version);
|
|
|
|
+ return QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dp_flt_param->flt_addr_params[i].l3_type == IPV4) {
|
|
|
|
+ src_ip_addr = qdf_ntohl(ipa_flt->flt_info[i].
|
|
|
|
+ ipv4_addr.ipv4_saddr);
|
|
|
|
+ dst_ip_addr = qdf_ntohl(ipa_flt->flt_info[i].
|
|
|
|
+ ipv4_addr.ipv4_daddr);
|
|
|
|
+ qdf_mem_copy(
|
|
|
|
+ dp_flt_param->flt_addr_params[i].src_ipv4_addr,
|
|
|
|
+ (&src_ip_addr),
|
|
|
|
+ IPV4BYTES);
|
|
|
|
+ qdf_mem_copy(
|
|
|
|
+ dp_flt_param->flt_addr_params[i].dst_ipv4_addr,
|
|
|
|
+ (&dst_ip_addr),
|
|
|
|
+ IPV4BYTES);
|
|
|
|
+ ipa_info("ipv4 src addr rxed from ipa 0x%x",
|
|
|
|
+ ipa_flt->flt_info[i].ipv4_addr.ipv4_saddr);
|
|
|
|
+ ipa_info("ipv4 sent to FW 0x%x", src_ip_addr);
|
|
|
|
+ } else if (dp_flt_param->flt_addr_params[i].l3_type == IPV6) {
|
|
|
|
+ host_ipv6 = (uint32_t *)dp_flt_param->flt_addr_params[i].
|
|
|
|
+ src_ipv6_addr;
|
|
|
|
+
|
|
|
|
+ for (j = 0; j < IPV6ARRAY; j++) {
|
|
|
|
+ src_ip_addr = qdf_ntohl(ipa_flt->flt_info[i].
|
|
|
|
+ ipv6_addr.ipv6_saddr[j]);
|
|
|
|
+ qdf_mem_copy(host_ipv6,
|
|
|
|
+ &src_ip_addr,
|
|
|
|
+ IPV6ARRAY);
|
|
|
|
+ host_ipv6++;
|
|
|
|
+ }
|
|
|
|
+ for (j = 0; j < IPV6ARRAY; j++) {
|
|
|
|
+ ipa_info("ipv6 src addr rxed from ipa 0x%x",
|
|
|
|
+ ipa_flt->flt_info[i].ipv6_addr.
|
|
|
|
+ ipv6_saddr[j]);
|
|
|
|
+ }
|
|
|
|
+ for (j = 0; j < IPV6ARRAY; j++)
|
|
|
|
+ ipa_info("ipv6 sent to FW 0x%x",
|
|
|
|
+ *((uint32_t *)dp_flt_param->flt_addr_params[i].
|
|
|
|
+ src_ipv6_addr + j));
|
|
|
|
+ /* Dest addr is currently not used in filter */
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dp_flt_param->op = HTT_RX_CCE_SUPER_RULE_INSTALL;
|
|
|
|
+ dp_flt_param->pdev_id = ipa_obj->dp_pdev_id;
|
|
|
|
+ dp_flt_param->num_filters = num_flts;
|
|
|
|
+ qdf_event_reset(&ipa_obj->ipa_flt_evnt);
|
|
|
|
+
|
|
|
|
+ ipa_info("opt_dp: op %d, pdev_id %d. num_flts %d,",
|
|
|
|
+ dp_flt_param->op, dp_flt_param->pdev_id, num_flts);
|
|
|
|
+ for (i = 0; i < num_flts; i++)
|
|
|
|
+ ipa_info("version %d, valid %d, src addr_ %08lx, evnt reqd %d",
|
|
|
|
+ dp_flt_param->flt_addr_params[i].l3_type,
|
|
|
|
+ dp_flt_param->flt_addr_params[i].valid,
|
|
|
|
+ dp_flt_param->flt_addr_params[i].src_ipv4_addr,
|
|
|
|
+ dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required);
|
|
|
|
+
|
|
|
|
+ cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_param);
|
|
|
|
+
|
|
|
|
+ qdf_wait_single_event(&ipa_obj->ipa_flt_evnt,
|
|
|
|
+ DP_MAX_SLEEP_TIME);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < num_flts; i++)
|
|
|
|
+ dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required = 0;
|
|
|
|
+
|
|
|
|
+ response = dp_flt_param->ipa_flt_evnt_response;
|
|
|
|
+ if (response != QDF_STATUS_SUCCESS) {
|
|
|
|
+ if (response == QDF_STATUS_E_TIMEOUT)
|
|
|
|
+ qdf_err("TIMEOUT_OCCURS");
|
|
|
|
+ else
|
|
|
|
+ qdf_err("Error on event wait for filter add cb");
|
|
|
|
+ }
|
|
|
|
+ return response;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int wlan_ipa_wdi_opt_dpath_flt_rem_cb(
|
|
|
|
+ void *ipa_ctx,
|
|
|
|
+ struct ipa_wdi_opt_dpath_flt_rem_cb_params *in)
|
|
|
|
+{
|
|
|
|
+ struct ipa_wdi_opt_dpath_flt_rem_cb_params *rem_flt =
|
|
|
|
+ (struct ipa_wdi_opt_dpath_flt_rem_cb_params *)(in);
|
|
|
|
+ struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
|
|
|
+ struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
|
|
|
+ struct wlan_objmgr_pdev *pdev;
|
|
|
|
+ struct wlan_objmgr_psoc *psoc;
|
|
|
|
+ int pdev_id;
|
|
|
|
+ uint8_t num_flts;
|
|
|
|
+ uint32_t i, j, response = 0, param_val = 0;
|
|
|
|
+ void *htc_handle;
|
|
|
|
+
|
|
|
|
+ pdev = ipa_obj->pdev;
|
|
|
|
+ psoc = wlan_pdev_get_psoc(pdev);
|
|
|
|
+ pdev_id = ipa_obj->dp_pdev_id;
|
|
|
|
+ num_flts = rem_flt->num_tuples;
|
|
|
|
+
|
|
|
|
+ htc_handle = lmac_get_htc_hdl(psoc);
|
|
|
|
+ if (!htc_handle) {
|
|
|
|
+ ipa_err("HTC Handle is null");
|
|
|
|
+ return QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+ /* Enable Low power features before filter deletion */
|
|
|
|
+ ipa_info("opt_dp: Enable low power features to delete filter param");
|
|
|
|
+ param_val = 1;
|
|
|
|
+ response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
|
|
|
|
+ param_val);
|
|
|
|
+ if (response) {
|
|
|
|
+ ipa_err("Low power feature enable failed. status %d", response);
|
|
|
|
+ return QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
|
|
|
|
+ ipa_info("opt_dp: Vote for PCIe link up");
|
|
|
|
+
|
|
|
|
+ dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
|
|
|
+ for (i = 0; i < num_flts; i++) {
|
|
|
|
+ for (j = 0; j < IPA_WDI_MAX_FILTER; j++) {
|
|
|
|
+ if (rem_flt->hdl_info[i] ==
|
|
|
|
+ dp_flt_params->flt_addr_params[j].flt_hdl) {
|
|
|
|
+ dp_flt_params->flt_addr_params[i].valid = 0;
|
|
|
|
+ qdf_mem_zero(dp_flt_params->flt_addr_params[i].
|
|
|
|
+ src_ipv4_addr,
|
|
|
|
+ IPV4BYTES);
|
|
|
|
+ qdf_mem_zero(dp_flt_params->flt_addr_params[i].
|
|
|
|
+ src_ipv6_addr,
|
|
|
|
+ IPV6BYTES);
|
|
|
|
+ dp_flt_params->flt_addr_params[i].
|
|
|
|
+ ipa_flt_evnt_required = 1;
|
|
|
|
+ dp_flt_params->flt_addr_params[i].ipa_flt_in_use
|
|
|
|
+ = false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_INSTALL;
|
|
|
|
+ dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
|
|
|
|
+ dp_flt_params->num_filters = IPA_WDI_MAX_FILTER;
|
|
|
|
+ qdf_event_reset(&ipa_obj->ipa_flt_evnt);
|
|
|
|
+
|
|
|
|
+ ipa_info("opt_dp: op %d, pdev_id %d. num_flts %d,",
|
|
|
|
+ dp_flt_params->op, dp_flt_params->pdev_id, num_flts);
|
|
|
|
+ for (i = 0; i < num_flts; i++)
|
|
|
|
+ ipa_info("version %d, valid %d, src addr_ %08lx, evnt_reqd %d",
|
|
|
|
+ dp_flt_params->flt_addr_params[i].l3_type,
|
|
|
|
+ dp_flt_params->flt_addr_params[i].valid,
|
|
|
|
+ dp_flt_params->flt_addr_params[i].src_ipv4_addr,
|
|
|
|
+ dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required);
|
|
|
|
+
|
|
|
|
+ cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
|
|
|
|
+
|
|
|
|
+ qdf_wait_single_event(&ipa_obj->ipa_flt_evnt,
|
|
|
|
+ DP_MAX_SLEEP_TIME);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < num_flts; i++)
|
|
|
|
+ dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required = 0;
|
|
|
|
+
|
|
|
|
+ response = dp_flt_params->ipa_flt_evnt_response;
|
|
|
|
+ if (response != QDF_STATUS_SUCCESS) {
|
|
|
|
+ if (response == QDF_STATUS_E_TIMEOUT)
|
|
|
|
+ qdf_err("TIMEOUT_OCCURS");
|
|
|
|
+ else
|
|
|
|
+ qdf_err("Error on event wait for filter rem cb");
|
|
|
|
+ }
|
|
|
|
+ return response;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb(void *ipa_ctx)
|
|
|
|
+{
|
|
|
|
+ struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
|
|
|
+ struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
|
|
|
+ for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
|
|
|
|
+ dp_flt_params->flt_addr_params[i].valid = 0;
|
|
|
|
+ dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_RELEASE;
|
|
|
|
+ dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
|
|
|
|
+ dp_flt_params->num_filters = IPA_WDI_MAX_FILTER;
|
|
|
|
+ return cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int wlan_ipa_wdi_opt_dpath_notify_flt_rlsd(int flt0_rslt,
|
|
|
|
+ int flt1_rslt)
|
|
|
|
+{
|
|
|
|
+ struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
|
|
|
+ struct wlan_ipa_priv *ipa_obj = gp_ipa;
|
|
|
|
+ bool result = false;
|
|
|
|
+
|
|
|
|
+ dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
|
|
|
+
|
|
|
|
+ if ((dp_flt_params->flt_addr_params[0].ipa_flt_in_use == true &&
|
|
|
|
+ flt0_rslt == 0) ||
|
|
|
|
+ (dp_flt_params->flt_addr_params[1].ipa_flt_in_use == true &&
|
|
|
|
+ flt1_rslt == 0))
|
|
|
|
+ result = false;
|
|
|
|
+ else {
|
|
|
|
+ dp_flt_params->flt_addr_params[0].ipa_flt_in_use = false;
|
|
|
|
+ dp_flt_params->flt_addr_params[1].ipa_flt_in_use = false;
|
|
|
|
+ result = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ipa_info("opt_dp: ipa_flt_event_release is_success: %d", result);
|
|
|
|
+ return qdf_ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst(ipa_obj->hdl,
|
|
|
|
+ result);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void wlan_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(int flt0_rslt, int flt1_rslt)
|
|
|
|
+{
|
|
|
|
+ struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
|
|
|
+ struct wlan_ipa_priv *ipa_obj = gp_ipa;
|
|
|
|
+
|
|
|
|
+ dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
|
|
|
+
|
|
|
|
+ if ((dp_flt_params->flt_addr_params[0].ipa_flt_evnt_required == 1 &&
|
|
|
|
+ flt0_rslt == 0) ||
|
|
|
|
+ (dp_flt_params->flt_addr_params[1].ipa_flt_evnt_required == 1 &&
|
|
|
|
+ flt1_rslt == 0))
|
|
|
|
+ dp_flt_params->ipa_flt_evnt_response =
|
|
|
|
+ QDF_STATUS_FILT_REQ_ERROR;
|
|
|
|
+ else
|
|
|
|
+ dp_flt_params->ipa_flt_evnt_response =
|
|
|
|
+ QDF_STATUS_SUCCESS;
|
|
|
|
+ ipa_info("opt_dp: ipa_flt_event_response set status: %d",
|
|
|
|
+ dp_flt_params->ipa_flt_evnt_response);
|
|
|
|
+ qdf_event_set(&ipa_obj->ipa_flt_evnt);
|
|
|
|
+}
|
|
|
|
+#endif /* IPA_OPT_WIFI_DP */
|