From 178d7f7753c5080ca7496dfada8158ab9841ac4e Mon Sep 17 00:00:00 2001 From: Amit Mehta Date: Thu, 3 Feb 2022 22:51:30 -0800 Subject: [PATCH] qcacld-3.0: Add RPS indication APIs to DP component Add APIS to configure RPS indication. Change-Id: I5d5a3d2a20989daae3c904afb25a028bd2e37956 CRs-Fixed: 3165005 --- components/dp/core/inc/wlan_dp_main.h | 85 ++++++ components/dp/core/src/wlan_dp_main.c | 269 ++++++++++++++++++ .../dp/dispatcher/inc/wlan_dp_public_struct.h | 2 + .../dp/dispatcher/inc/wlan_dp_ucfg_api.h | 42 ++- .../dp/dispatcher/src/wlan_dp_ucfg_api.c | 22 ++ 5 files changed, 419 insertions(+), 1 deletion(-) diff --git a/components/dp/core/inc/wlan_dp_main.h b/components/dp/core/inc/wlan_dp_main.h index 0db0898a4a..5767a231c7 100644 --- a/components/dp/core/inc/wlan_dp_main.h +++ b/components/dp/core/inc/wlan_dp_main.h @@ -27,6 +27,8 @@ #include "wlan_dp_priv.h" #include "wlan_dp_objmgr.h" +#define NUM_RX_QUEUES 5 + /** * dp_allocate_ctx() - Allocate DP context * @@ -236,4 +238,87 @@ void dp_dettach_ctx(void); */ struct wlan_dp_psoc_context *dp_get_context(void); +/** + * dp_send_rps_ind() - send rps indication to daemon + * @dp_intf: DP interface + * + * If RPS feature enabled by INI, send RPS enable indication to daemon + * Indication contents is the name of interface to find correct sysfs node + * Should send all available interfaces + * + * Return: none + */ +void dp_send_rps_ind(struct wlan_dp_intf *dp_intf); + +/** + * dp_try_send_rps_ind() - try to send rps indication to daemon. + * @vdev: vdev handle + * + * If RPS flag is set in DP context then send rsp indication. + * + * Return: none + */ +void dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev); + +/** + * dp_send_rps_disable_ind() - send rps disable indication to daemon + * @dp_intf: DP interface + * + * Return: none + */ +void dp_send_rps_disable_ind(struct wlan_dp_intf *dp_intf); + +#ifdef QCA_CONFIG_RPS +/** + * dp_set_rps() - Enable/disable RPS for mode specified + * @vdev_id: vdev id which RPS needs to be enabled + * @enable: Set true to enable RPS in SAP mode + * + * Callback function registered with ipa + * + * Return: none + */ +void dp_set_rps(uint8_t vdev_id, bool enable); +#else +void dp_set_rps(uint8_t vdev_id, bool enable) +{ +} +#endif + +/** + * dp_set_rx_mode_rps() - Enable/disable RPS in SAP mode + * @enable: Set true to enable RPS in SAP mode + * + * Callback function registered with core datapath + * + * Return: none + */ +void dp_set_rx_mode_rps(bool enable); + +/** + * dp_set_rps_cpu_mask - set RPS CPU mask for interfaces + * @dp_ctx: pointer to struct dp_context + * + * Return: none + */ +void dp_set_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx); + +/** + * dp_try_set_rps_cpu_mask() - try to set RPS CPU mask + * @psoc: psoc handle + * + * If RPS flag is set in DP context then set RPS CPU mask. + * + * Return: none + */ +void dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc); + +/** + * dp_clear_rps_cpu_mask - clear RPS CPU mask for interfaces + * @dp_ctx: pointer to struct dp_context + * + * Return: none + */ +void dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx); + #endif diff --git a/components/dp/core/src/wlan_dp_main.c b/components/dp/core/src/wlan_dp_main.c index f053ce6281..509e8bc61e 100644 --- a/components/dp/core/src/wlan_dp_main.c +++ b/components/dp/core/src/wlan_dp_main.c @@ -23,6 +23,11 @@ #include "wlan_dp_main.h" #include "wlan_dp_public_struct.h" #include "cfg_ucfg_api.h" +#include "wlan_dp_bus_bandwidth.h" +#include +#include +#include +#include "wlan_objmgr_vdev_obj.h" /* Global DP context */ static struct wlan_dp_psoc_context *gp_dp_ctx; @@ -317,3 +322,267 @@ struct wlan_dp_psoc_context *dp_get_context(void) { return gp_dp_ctx; } + +/** + * dp_hex_string_to_u16_array() - convert a hex string to a uint16 array + * @str: input string + * @int_array: pointer to input array of type uint16 + * @len: pointer to number of elements which the function adds to the array + * @int_array_max_len: maximum number of elements in input uint16 array + * + * This function is used to convert a space separated hex string to an array of + * uint16_t. For example, an input string str = "a b c d" would be converted to + * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4. + * This assumes that input value int_array_max_len >= 4. + * + * Return: QDF_STATUS_SUCCESS - if the conversion is successful + * non zero value - if the conversion is a failure + */ +static QDF_STATUS +dp_hex_string_to_u16_array(char *str, uint16_t *int_array, uint8_t *len, + uint8_t int_array_max_len) +{ + char *s = str; + uint32_t val = 0; + + if (!str || !int_array || !len) + return QDF_STATUS_E_INVAL; + + dp_debug("str %pK intArray %pK intArrayMaxLen %d", + s, int_array, int_array_max_len); + + *len = 0; + + while ((s) && (*len < int_array_max_len)) { + /* + * Increment length only if sscanf successfully extracted one + * element. Any other return value means error. Ignore it. + */ + if (sscanf(s, "%x", &val) == 1) { + int_array[*len] = (uint16_t)val; + dp_debug("s %pK val %x intArray[%d]=0x%x", + s, val, *len, int_array[*len]); + *len += 1; + } + s = strpbrk(s, " "); + if (s) + s++; + } + return QDF_STATUS_SUCCESS; +} + +/** + * dp_get_interface() - to get dp interface matching the mode + * @dp_ctx: dp context + * @mode: interface mode + * + * This routine will return the pointer to dp interface matching + * with the passed mode. + * + * Return: pointer to interface or null + */ +static struct +wlan_dp_intf *dp_get_interface(struct wlan_dp_psoc_context *dp_ctx, + enum QDF_OPMODE mode) +{ + struct wlan_dp_intf *dp_intf; + struct wlan_dp_intf *dp_intf_next; + + dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { + if (!dp_intf) + continue; + + if (dp_intf->device_mode == mode) + return dp_intf; + } + + return NULL; +} + +void dp_send_rps_ind(struct wlan_dp_intf *dp_intf) +{ + int i; + uint8_t cpu_map_list_len = 0; + struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; + struct wlan_rps_data rps_data; + struct cds_config_info *cds_cfg; + + cds_cfg = cds_get_ini_config(); + if (!cds_cfg) { + dp_err("cds_cfg is NULL"); + return; + } + + rps_data.num_queues = NUM_RX_QUEUES; + + dp_info("cpu_map_list '%s'", dp_ctx->dp_cfg.cpu_map_list); + + /* in case no cpu map list is provided, simply return */ + if (!strlen(dp_ctx->dp_cfg.cpu_map_list)) { + dp_info("no cpu map list found"); + goto err; + } + + if (QDF_STATUS_SUCCESS != + dp_hex_string_to_u16_array(dp_ctx->dp_cfg.cpu_map_list, + rps_data.cpu_map_list, + &cpu_map_list_len, + WLAN_SVC_IFACE_NUM_QUEUES)) { + dp_err("invalid cpu map list"); + goto err; + } + + rps_data.num_queues = + (cpu_map_list_len < rps_data.num_queues) ? + cpu_map_list_len : rps_data.num_queues; + + for (i = 0; i < rps_data.num_queues; i++) { + dp_info("cpu_map_list[%d] = 0x%x", + i, rps_data.cpu_map_list[i]); + } + + strlcpy(rps_data.ifname, qdf_netdev_get_devname(dp_intf->dev), + sizeof(rps_data.ifname)); + dp_ctx->dp_ops.dp_send_svc_nlink_msg(cds_get_radio_index(), + WLAN_SVC_RPS_ENABLE_IND, + &rps_data, sizeof(rps_data)); + + cds_cfg->rps_enabled = true; + + return; + +err: + dp_info("Wrong RPS configuration. enabling rx_thread"); + cds_cfg->rps_enabled = false; +} + +void dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_dp_intf *dp_intf = dp_get_vdev_priv_obj(vdev); + + if (!dp_intf) { + dp_err("dp interface is NULL"); + return; + } + if (dp_intf->dp_ctx->rps) + dp_send_rps_ind(dp_intf); +} + +void dp_send_rps_disable_ind(struct wlan_dp_intf *dp_intf) +{ + struct wlan_rps_data rps_data; + struct cds_config_info *cds_cfg; + + cds_cfg = cds_get_ini_config(); + + if (!cds_cfg) { + dp_err("cds_cfg is NULL"); + return; + } + + rps_data.num_queues = NUM_RX_QUEUES; + + dp_info("Set cpu_map_list 0"); + + qdf_mem_zero(&rps_data.cpu_map_list, sizeof(rps_data.cpu_map_list)); + + strlcpy(rps_data.ifname, qdf_netdev_get_devname(dp_intf->dev), + sizeof(rps_data.ifname)); + dp_intf->dp_ctx->dp_ops.dp_send_svc_nlink_msg(cds_get_radio_index(), + WLAN_SVC_RPS_ENABLE_IND, + &rps_data, sizeof(rps_data)); + + cds_cfg->rps_enabled = false; +} + +#ifdef QCA_CONFIG_RPS +void dp_set_rps(uint8_t vdev_id, bool enable) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_dp_psoc_context *dp_ctx; + struct wlan_dp_intf *dp_intf; + + dp_ctx = dp_get_context(); + if (!dp_ctx) + return; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(dp_ctx->psoc, + vdev_id, WLAN_DP_ID); + if (!vdev) + return; + + dp_intf = dp_get_vdev_priv_obj(vdev); + if (!dp_intf) { + dp_err_rl("DP interface not found for vdev_id: %d", vdev_id); + return; + } + + dp_info("Set RPS to %d for vdev_id %d", enable, vdev_id); + if (!dp_ctx->rps) { + if (enable) + dp_send_rps_ind(dp_intf); + else + dp_send_rps_disable_ind(dp_intf); + } +} +#endif + +void dp_set_rx_mode_rps(bool enable) +{ + struct wlan_dp_psoc_context *dp_ctx; + struct wlan_dp_intf *dp_intf; + struct cds_config_info *cds_cfg; + + dp_ctx = dp_get_context(); + cds_cfg = cds_get_ini_config(); + if (!dp_ctx || !cds_cfg) + return; + + dp_intf = dp_get_interface(dp_ctx, QDF_SAP_MODE); + if (!dp_intf) + return; + + if (!dp_intf->dp_ctx->rps && cds_cfg->uc_offload_enabled) { + if (enable && !cds_cfg->rps_enabled) + dp_send_rps_ind(dp_intf); + else if (!enable && cds_cfg->rps_enabled) + dp_send_rps_disable_ind(dp_intf); + } +} + +void dp_set_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx) +{ + struct wlan_dp_intf *dp_intf; + struct wlan_dp_intf *dp_intf_next; + + dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { + if (!dp_intf) + continue; + + dp_send_rps_ind(dp_intf); + } +} + +void dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc); + + if (!dp_ctx) { + dp_err("dp context is NULL"); + return; + } + dp_set_rps_cpu_mask(dp_ctx); +} + +void dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx) +{ + struct wlan_dp_intf *dp_intf; + struct wlan_dp_intf *dp_intf_next; + + dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { + if (!dp_intf) + continue; + + dp_send_rps_disable_ind(dp_intf); + } +} diff --git a/components/dp/dispatcher/inc/wlan_dp_public_struct.h b/components/dp/dispatcher/inc/wlan_dp_public_struct.h index c9698e9d22..26293e7430 100644 --- a/components/dp/dispatcher/inc/wlan_dp_public_struct.h +++ b/components/dp/dispatcher/inc/wlan_dp_public_struct.h @@ -196,6 +196,7 @@ union wlan_tp_data { * @wlan_dp_get_ap_client_count: Callback to get client count connected to AP * @wlan_dp_sta_ndi_connected: Callback to get NDI connected status * @dp_any_adapter_connected: Callback to check if any adapter is connected + * @dp_send_svc_nlink_msg: Callback API to send svc nlink message * @osif_dp_send_tcp_param_update_event: OS IF callback to send TCP param */ struct wlan_dp_psoc_callbacks { @@ -212,6 +213,7 @@ struct wlan_dp_psoc_callbacks { bool (*wlan_dp_sta_ndi_connected)(hdd_cb_handle context, uint8_t vdev_id); bool (*dp_any_adapter_connected)(hdd_cb_handle context); + void (*dp_send_svc_nlink_msg)(int radio, int type, void *data, int len); void (*osif_dp_send_tcp_param_update_event)(struct wlan_objmgr_psoc *psoc, diff --git a/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h b/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h index 5065764212..14bcd4388e 100644 --- a/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h +++ b/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h @@ -159,6 +159,45 @@ void ucfg_dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc); void ucfg_dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc, struct bbm_params *params); +/** + * ucfg_dp_set_rx_mode_rps() - Enable/disable RPS in SAP mode + * @enable: Set true to enable RPS in SAP mode + * + * Callback function registered with datapath + * + * Return: none + */ +void ucfg_dp_set_rx_mode_rps(bool enable); + +/** + * ucfg_dp_try_send_rps_ind() - send rps indication to daemon + * @vdev: vdev handle + * + * If RPS feature enabled by INI, send RPS enable indication to daemon + * Indication contents is the name of interface to find correct sysfs node + * Should send all available interfaces + * + * Return: none + */ +void ucfg_dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_dp_reg_ipa_rsp_ind() - Resiter RSP IND cb with IPA component + * @psoc: psoc handle + * @cb_obj: Callback object + * + * Returns: None + */ +void ucfg_dp_reg_ipa_rsp_ind(struct wlan_objmgr_pdev *pdev); + +/** + * ucfg_dp_try_set_rps_cpu_mask - set RPS CPU mask for interfaces + * @psoc: psoc handle + * + * Return: none + */ +void ucfg_dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc); + /** * ucfg_dp_register_hdd_callbacks() - Resiter HDD callbacks with DP component * @psoc: psoc handle @@ -168,4 +207,5 @@ void ucfg_dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc, */ void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, struct wlan_dp_psoc_callbacks *cb_obj); -#endif + +#endif /* _WLAN_DP_UCFG_API_H_ */ diff --git a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c index be20750a73..96e3dabe23 100644 --- a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c +++ b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c @@ -21,6 +21,7 @@ */ #include "wlan_dp_ucfg_api.h" +#include "wlan_ipa_ucfg_api.h" #include "wlan_dp_main.h" #include "wlan_dp_objmgr.h" #include "cdp_txrx_cmn.h" @@ -486,6 +487,26 @@ void ucfg_dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc, dp_bbm_apply_independent_policy(psoc, params); } +void ucfg_dp_set_rx_mode_rps(bool enable) +{ + dp_set_rx_mode_rps(enable); +} + +void ucfg_dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev) +{ + dp_try_send_rps_ind(vdev); +} + +void ucfg_dp_reg_ipa_rsp_ind(struct wlan_objmgr_pdev *pdev) +{ + ucfg_ipa_reg_rps_enable_cb(pdev, dp_set_rps); +} + +void ucfg_dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc) +{ + dp_try_set_rps_cpu_mask(psoc); +} + void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, struct wlan_dp_psoc_callbacks *cb_obj) { @@ -504,4 +525,5 @@ void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, cb_obj->wlan_dp_sta_ndi_connected; dp_ctx->dp_ops.dp_any_adapter_connected = cb_obj->dp_any_adapter_connected; + dp_ctx->dp_ops.dp_send_svc_nlink_msg = cb_obj->dp_send_svc_nlink_msg; }