diff --git a/components/dp/core/inc/wlan_dp_priv.h b/components/dp/core/inc/wlan_dp_priv.h index 574f21b075..7116e79871 100644 --- a/components/dp/core/inc/wlan_dp_priv.h +++ b/components/dp/core/inc/wlan_dp_priv.h @@ -55,9 +55,9 @@ * required */ enum dp_rtpm_tput_policy_state { - RTPM_TPUT_POLICY_STATE_INVALID, - RTPM_TPUT_POLICY_STATE_REQUIRED, - RTPM_TPUT_POLICY_STATE_NOT_REQUIRED + DP_RTPM_TPUT_POLICY_STATE_INVALID, + DP_RTPM_TPUT_POLICY_STATE_REQUIRED, + DP_RTPM_TPUT_POLICY_STATE_NOT_REQUIRED }; /** @@ -294,6 +294,7 @@ struct wlan_dp_intf { * @cur_rx_level: Current Rx level * @rtpm_tput_policy_ctx: Runtime Tput policy context * @txrx_hist: TxRx histogram + * @bbm_ctx: bus bandwidth manager context */ struct wlan_dp_psoc_context { struct wlan_objmgr_psoc *psoc; @@ -350,7 +351,6 @@ struct wlan_dp_psoc_context { struct dp_rtpm_tput_policy_context rtpm_tput_policy_ctx; #endif #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ - #ifdef WLAN_NS_OFFLOAD /* IPv6 notifier callback for handling NS offload on change in IP */ struct notifier_block ipv6_notifier; @@ -360,6 +360,9 @@ struct wlan_dp_psoc_context { struct tx_rx_histogram *txrx_hist; uint32_t rx_high_ind_cnt; +#ifdef FEATURE_BUS_BANDWIDTH_MGR + struct bbm_context *bbm_ctx; +#endif }; #endif /* end of _WLAN_DP_PRIV_STRUCT_H_ */ diff --git a/components/dp/core/src/wlan_dp_bus_bandwidth.c b/components/dp/core/src/wlan_dp_bus_bandwidth.c index a6714aaf80..7589ea1657 100644 --- a/components/dp/core/src/wlan_dp_bus_bandwidth.c +++ b/components/dp/core/src/wlan_dp_bus_bandwidth.c @@ -25,19 +25,459 @@ #include "wlan_dp_bus_bandwidth.h" #include "wlan_dp_main.h" #include +#include "pld_common.h" #include "cds_api.h" +#ifdef FEATURE_BUS_BANDWIDTH_MGR +/** + * bus_bw_table_default - default table which provides bus bandwidth level + * corresonding to a given connection mode and throughput level. + */ +static bus_bw_table_type bus_bw_table_default = { + [QCA_WLAN_802_11_MODE_11B] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1, + BUS_BW_LEVEL_2, BUS_BW_LEVEL_3, + BUS_BW_LEVEL_4, BUS_BW_LEVEL_6, + BUS_BW_LEVEL_7, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11G] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_5, + BUS_BW_LEVEL_5, BUS_BW_LEVEL_5, + BUS_BW_LEVEL_5, BUS_BW_LEVEL_5, + BUS_BW_LEVEL_5, BUS_BW_LEVEL_5}, + [QCA_WLAN_802_11_MODE_11A] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_5, + BUS_BW_LEVEL_5, BUS_BW_LEVEL_5, + BUS_BW_LEVEL_5, BUS_BW_LEVEL_5, + BUS_BW_LEVEL_5, BUS_BW_LEVEL_5}, + [QCA_WLAN_802_11_MODE_11N] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1, + BUS_BW_LEVEL_2, BUS_BW_LEVEL_3, + BUS_BW_LEVEL_4, BUS_BW_LEVEL_6, + BUS_BW_LEVEL_7, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11AC] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1, + BUS_BW_LEVEL_2, BUS_BW_LEVEL_3, + BUS_BW_LEVEL_4, BUS_BW_LEVEL_6, + BUS_BW_LEVEL_7, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11AX] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1, + BUS_BW_LEVEL_2, BUS_BW_LEVEL_3, + BUS_BW_LEVEL_4, BUS_BW_LEVEL_6, + BUS_BW_LEVEL_7, BUS_BW_LEVEL_8}, +}; + +/** + * bus_bw_table_low_latency - table which provides bus bandwidth level + * corresonding to a given connection mode and throughput level in low + * latency setting. + */ +static bus_bw_table_type bus_bw_table_low_latency = { + [QCA_WLAN_802_11_MODE_11B] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11G] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11A] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11N] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11AC] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8}, + [QCA_WLAN_802_11_MODE_11AX] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8, + BUS_BW_LEVEL_8, BUS_BW_LEVEL_8} +}; + +/** + * bbm_convert_to_pld_bus_lvl() - Convert from internal bus vote level to + * PLD bus vote level + * @vote_lvl: internal bus bw vote level + * + * Returns: PLD bus vote level + */ +static enum pld_bus_width_type +bbm_convert_to_pld_bus_lvl(enum bus_bw_level vote_lvl) +{ + switch (vote_lvl) { + case BUS_BW_LEVEL_1: + return PLD_BUS_WIDTH_IDLE; + case BUS_BW_LEVEL_2: + return PLD_BUS_WIDTH_LOW; + case BUS_BW_LEVEL_3: + return PLD_BUS_WIDTH_MEDIUM; + case BUS_BW_LEVEL_4: + return PLD_BUS_WIDTH_HIGH; + case BUS_BW_LEVEL_5: + return PLD_BUS_WIDTH_LOW_LATENCY; + case BUS_BW_LEVEL_6: + return PLD_BUS_WIDTH_VERY_HIGH; + case BUS_BW_LEVEL_7: + return PLD_BUS_WIDTH_ULTRA_HIGH; + case BUS_BW_LEVEL_8: + return PLD_BUS_WIDTH_MAX; + case BUS_BW_LEVEL_NONE: + default: + return PLD_BUS_WIDTH_NONE; + } +} + +/** + * bbm_get_bus_bw_level_vote() - Select bus bw vote level per interface based + * on connection mode and throughput level + * @dp_intf: DP Interface, caller assure that interface is valid. + * @tput_level: throughput level + * + * Returns: Bus bw level + */ +static enum bus_bw_level +bbm_get_bus_bw_level_vote(struct wlan_dp_intf *dp_intf, + enum tput_level tput_level) +{ + enum qca_wlan_802_11_mode i; + enum qca_wlan_802_11_mode dot11_mode; + enum bus_bw_level vote_lvl = BUS_BW_LEVEL_NONE; + struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; + struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx; + bus_bw_table_type *lkp_table = bbm_ctx->curr_bus_bw_lookup_table; + uint16_t client_count[QCA_WLAN_802_11_MODE_INVALID]; + struct wlan_dp_psoc_callbacks *cb_obj = &dp_ctx->dp_ops; + hdd_cb_handle ctx = cb_obj->callback_ctx; + + switch (dp_intf->device_mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + if (!cb_obj->wlan_dp_sta_get_dot11mode(ctx, + dp_intf->intf_id, + &dot11_mode)) + break; + + if (dot11_mode >= QCA_WLAN_802_11_MODE_INVALID) { + dp_err("invalid STA/P2P-CLI dot11 mode"); + break; + } + + return (*lkp_table)[dot11_mode][tput_level]; + case QDF_SAP_MODE: + case QDF_P2P_GO_MODE: + if (!cb_obj->wlan_dp_get_ap_client_count(ctx, + dp_intf->intf_id, + client_count)) + break; + + for (i = QCA_WLAN_802_11_MODE_11B; + i < QCA_WLAN_802_11_MODE_INVALID; i++) { + if (client_count[i] && + (*lkp_table)[i][tput_level] > vote_lvl) + vote_lvl = (*lkp_table)[i][tput_level]; + } + + return vote_lvl; + case QDF_NDI_MODE: + if (!cb_obj->wlan_dp_sta_ndi_connected(ctx, + dp_intf->intf_id)) + break; + + /* + * NDI dot11mode is currently hardcoded to 11AC in driver and + * since the bus bw levels in table do not differ between 11AC + * and 11AX, using max supported mode instead. Dot11mode of the + * peers are not saved in driver and legacy modes are not + * supported in NAN. + */ + return (*lkp_table)[QCA_WLAN_802_11_MODE_11AX][tput_level]; + default: + break; + } + + return vote_lvl; +} + +/** + * bbm_apply_tput_policy() - Apply tput BBM policy by considering + * throughput level and connection modes across adapters + * @dp_ctx: DP context + * @tput_level: throughput level + * + * Returns: None + */ +static void +bbm_apply_tput_policy(struct wlan_dp_psoc_context *dp_ctx, + enum tput_level tput_level) +{ + struct wlan_dp_intf *dp_intf; + struct wlan_dp_intf *dp_intf_next; + struct wlan_objmgr_psoc *psoc; + enum bus_bw_level next_vote = BUS_BW_LEVEL_NONE; + enum bus_bw_level tmp_vote; + struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx; + hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx; + + if (tput_level == TPUT_LEVEL_NONE) { + /* + * This is to handle the scenario where bus bw periodic work + * is force cancelled + */ + if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx)) + bbm_ctx->per_policy_vote[BBM_TPUT_POLICY] = next_vote; + return; + } + + psoc = dp_ctx->psoc; + if (!psoc) { + dp_err("psoc is NULL"); + return; + } + + dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { + if (!dp_intf) + continue; + tmp_vote = bbm_get_bus_bw_level_vote(dp_intf, tput_level); + if (tmp_vote > next_vote) + next_vote = tmp_vote; + } + + bbm_ctx->per_policy_vote[BBM_TPUT_POLICY] = next_vote; +} + +/** + * bbm_apply_driver_mode_policy() - Apply driver mode BBM policy + * @bbm_ctx: bus bw mgr context + * @driver_mode: global driver mode + * + * Returns: None + */ +static void +bbm_apply_driver_mode_policy(struct bbm_context *bbm_ctx, + enum QDF_GLOBAL_MODE driver_mode) +{ + switch (driver_mode) { + case QDF_GLOBAL_MONITOR_MODE: + case QDF_GLOBAL_FTM_MODE: + bbm_ctx->per_policy_vote[BBM_DRIVER_MODE_POLICY] = + BUS_BW_LEVEL_6; + return; + default: + bbm_ctx->per_policy_vote[BBM_DRIVER_MODE_POLICY] = + BUS_BW_LEVEL_NONE; + return; + } +} + +/** + * bbm_apply_non_persistent_policy() - Apply non persistent policy and set + * the bus bandwidth + * @dp_ctx: DP context + * @flag: flag + * + * Returns: None + */ +static void +bbm_apply_non_persistent_policy(struct wlan_dp_psoc_context *dp_ctx, + enum bbm_non_per_flag flag) +{ + hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx; + + switch (flag) { + case BBM_APPS_RESUME: + if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx)) { + dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_RESUME; + pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev, + bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_RESUME)); + } else { + dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_NONE; + pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev, + bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_NONE)); + } + return; + case BBM_APPS_SUSPEND: + dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_NONE; + pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev, + bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_NONE)); + return; + default: + dp_info("flag %d not handled in res/sus BBM policy", flag); + return; + } +} + +/** + * bbm_apply_wlm_policy() - Apply WLM based BBM policy by selecting + * lookup tables based on the latency level + * @bbm_ctx: Bus BW mgr context + * @wlm_level: WLM latency level + * + * Returns: None + */ +static void +bbm_apply_wlm_policy(struct bbm_context *bbm_ctx, enum wlm_ll_level wlm_level) +{ + switch (wlm_level) { + case WLM_LL_NORMAL: + bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_default; + break; + case WLM_LL_LOW: + bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_low_latency; + break; + default: + dp_info("wlm level %d not handled in BBM WLM policy", + wlm_level); + break; + } +} + +/** + * bbm_apply_user_policy() - Apply user specified bus voting + * level + * @bbm_ctx: Bus BW mgr context + * @set: set or reset flag + * @user_level: user bus vote level + * + * Returns: qdf status + */ +static QDF_STATUS +bbm_apply_user_policy(struct bbm_context *bbm_ctx, bool set, + enum bus_bw_level user_level) +{ + if (user_level >= BUS_BW_LEVEL_MAX) { + dp_err("Invalid user vote level %d", user_level); + return QDF_STATUS_E_FAILURE; + } + + if (set) + bbm_ctx->per_policy_vote[BBM_USER_POLICY] = user_level; + else + bbm_ctx->per_policy_vote[BBM_USER_POLICY] = BUS_BW_LEVEL_NONE; + + return QDF_STATUS_SUCCESS; +} + +/** + * bbm_request_bus_bandwidth() - Set bus bandwidth level + * @dp_ctx: DP context + * + * Returns: None + */ +static void +bbm_request_bus_bandwidth(struct wlan_dp_psoc_context *dp_ctx) +{ + enum bbm_policy i; + enum bus_bw_level next_vote = BUS_BW_LEVEL_NONE; + enum pld_bus_width_type pld_vote; + struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx; + + for (i = BBM_DRIVER_MODE_POLICY; i < BBM_MAX_POLICY; i++) { + if (bbm_ctx->per_policy_vote[i] > next_vote) + next_vote = bbm_ctx->per_policy_vote[i]; + } + + if (next_vote != bbm_ctx->curr_vote_level) { + pld_vote = bbm_convert_to_pld_bus_lvl(next_vote); + dp_info("Bus bandwidth vote level change from %d to %d pld_vote: %d", + bbm_ctx->curr_vote_level, next_vote, pld_vote); + bbm_ctx->curr_vote_level = next_vote; + pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev, pld_vote); + } +} + void dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc, struct bbm_params *params) { + struct wlan_dp_psoc_context *dp_ctx; + struct bbm_context *bbm_ctx; + QDF_STATUS status; + + dp_ctx = dp_psoc_get_priv(psoc); + if (!dp_ctx || !params) + return; + + bbm_ctx = dp_ctx->bbm_ctx; + + qdf_mutex_acquire(&bbm_ctx->bbm_lock); + + switch (params->policy) { + case BBM_TPUT_POLICY: + bbm_apply_tput_policy(dp_ctx, params->policy_info.tput_level); + break; + case BBM_NON_PERSISTENT_POLICY: + bbm_apply_non_persistent_policy(dp_ctx, + params->policy_info.flag); + goto done; + case BBM_DRIVER_MODE_POLICY: + bbm_apply_driver_mode_policy(bbm_ctx, + params->policy_info.driver_mode); + break; + case BBM_SELECT_TABLE_POLICY: + bbm_apply_wlm_policy(bbm_ctx, params->policy_info.wlm_level); + goto done; + case BBM_USER_POLICY: + /* + * This policy is not used currently. + */ + status = bbm_apply_user_policy(bbm_ctx, + params->policy_info.usr.set, + params->policy_info.usr.user_level); + if (QDF_IS_STATUS_ERROR(status)) + goto done; + break; + default: + dp_info("BBM policy %d not handled", params->policy); + goto done; + } + + bbm_request_bus_bandwidth(dp_ctx); + +done: + qdf_mutex_release(&bbm_ctx->bbm_lock); } int dp_bbm_context_init(struct wlan_objmgr_psoc *psoc) { + struct wlan_dp_psoc_context *dp_ctx; + struct bbm_context *bbm_ctx; + QDF_STATUS status; + + dp_ctx = dp_psoc_get_priv(psoc); + if (!dp_ctx) + return -EINVAL; + bbm_ctx = qdf_mem_malloc(sizeof(*bbm_ctx)); + if (!bbm_ctx) + return -ENOMEM; + + bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_default; + + status = qdf_mutex_create(&bbm_ctx->bbm_lock); + if (QDF_IS_STATUS_ERROR(status)) + goto free_ctx; + + dp_ctx->bbm_ctx = bbm_ctx; + return 0; + +free_ctx: + qdf_mem_free(bbm_ctx); + + return qdf_status_to_os_return(status); } void dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc) { -} + struct wlan_dp_psoc_context *dp_ctx; + struct bbm_context *bbm_ctx; + dp_ctx = dp_psoc_get_priv(psoc); + if (!dp_ctx) + return; + bbm_ctx = dp_ctx->bbm_ctx; + if (!bbm_ctx) + return; + + dp_ctx->bbm_ctx = NULL; + qdf_mutex_destroy(&bbm_ctx->bbm_lock); + + qdf_mem_free(bbm_ctx); +} +#endif /* FEATURE_BUS_BANDWIDTH_MGR */ diff --git a/components/dp/core/src/wlan_dp_bus_bandwidth.h b/components/dp/core/src/wlan_dp_bus_bandwidth.h index 5eb32e6240..e1265d0698 100644 --- a/components/dp/core/src/wlan_dp_bus_bandwidth.h +++ b/components/dp/core/src/wlan_dp_bus_bandwidth.h @@ -27,19 +27,30 @@ #include #include #include +#include "wlan_dp_public_struct.h" -#ifdef FEATURE_BUS_BANDWIDTH_MGR +typedef const enum bus_bw_level + bus_bw_table_type[QCA_WLAN_802_11_MODE_INVALID][TPUT_LEVEL_MAX]; /** - * struct bbm_params - BBM params + * struct bbm_context: Bus Bandwidth Manager context * + * @curr_bus_bw_lookup_table: current bus bw lookup table + * @curr_vote_level: current vote level + * @per_policy_vote: per BBM policy related vote + * @bbm_lock: BBM API lock */ -struct bbm_params { +struct bbm_context { + bus_bw_table_type *curr_bus_bw_lookup_table; + enum bus_bw_level curr_vote_level; + enum bus_bw_level per_policy_vote[BBM_MAX_POLICY]; + qdf_mutex_t bbm_lock; }; +#ifdef FEATURE_BUS_BANDWIDTH_MGR /** * dp_bbm_context_init() - Initialize BBM context - * @dp_ctx: DP context + * @psoc: psoc Handle * * Returns: error code */ @@ -47,7 +58,7 @@ int dp_bbm_context_init(struct wlan_objmgr_psoc *psoc); /** * dp_bbm_context_deinit() - De-initialize BBM context - * @dp_ctx: DP context + * @psoc: psoc Handle * * Returns: None */ @@ -56,7 +67,7 @@ void dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc); /** * dp_bbm_apply_independent_policy() - Function to apply independent policies * to set the bus bw level - * @dp_ctx: DP context + * @psoc: psoc Handle * @params: BBM policy related params * * The function applies BBM related policies and appropriately sets the bus diff --git a/components/dp/dispatcher/inc/wlan_dp_public_struct.h b/components/dp/dispatcher/inc/wlan_dp_public_struct.h index 42dd37cf5f..c9698e9d22 100644 --- a/components/dp/dispatcher/inc/wlan_dp_public_struct.h +++ b/components/dp/dispatcher/inc/wlan_dp_public_struct.h @@ -28,6 +28,156 @@ #include "wlan_objmgr_global_obj.h" #include "qdf_status.h" #include +#include + +/** + * typedef hdd_cb_handle - HDD Handle + * + * Handle to the HDD. The HDD handle is given to the DP component from the + * HDD during start modules. The HDD handle is an input to all HDD function + * calls and represents an opaque handle to the HDD instance that is + * tied to the DP context + * + * The HDD must be able to derive it's internal instance structure + * pointer through this handle. + */ +/* + * NOTE WELL: struct opaque_hdd_callback_handle is not defined anywhere. This + * reference is used to help ensure that a hdd_cb_handle is never used + * where a different handle type is expected + */ +struct opaque_hdd_callback_handle; +typedef struct opaque_hdd_callback_handle *hdd_cb_handle; + +/** + * enum bus_bw_level - bus bandwidth vote levels + * + * @BUS_BW_LEVEL_NONE: No vote for bus bandwidth + * @BUS_BW_LEVEL_1: vote for level-1 bus bandwidth + * @BUS_BW_LEVEL_2: vote for level-2 bus bandwidth + * @BUS_BW_LEVEL_3: vote for level-3 bus bandwidth + * @BUS_BW_LEVEL_4: vote for level-4 bus bandwidth + * @BUS_BW_LEVEL_5: vote for level-5 bus bandwidth + * @BUS_BW_LEVEL_6: vote for level-6 bus bandwidth + * @BUS_BW_LEVEL_7: vote for level-7 bus bandwidth + */ +enum bus_bw_level { + BUS_BW_LEVEL_NONE, + BUS_BW_LEVEL_1, + BUS_BW_LEVEL_2, + BUS_BW_LEVEL_3, + BUS_BW_LEVEL_4, + BUS_BW_LEVEL_5, + BUS_BW_LEVEL_6, + BUS_BW_LEVEL_7, + BUS_BW_LEVEL_8, + BUS_BW_LEVEL_MAX, +}; + +#define BUS_BW_LEVEL_RESUME BUS_BW_LEVEL_3 + +/** + * enum tput_level - throughput levels + * + * @TPUT_LEVEL_NONE: No throughput + * @TPUT_LEVEL_IDLE: idle throughtput level + * @TPUT_LEVEL_LOW: low throughput level + * @TPUT_LEVEL_MEDIUM: medium throughtput level + * @TPUT_LEVEL_HIGH: high throughput level + * @TPUT_LEVEL_VERY_HIGH: very high throughput level + * @TPUT_LEVEL_ULTRA_HIGH: ultra high throughput level + * @TPUT_LEVEL_SUPER_HIGH: super high throughput level + */ +enum tput_level { + TPUT_LEVEL_NONE, + TPUT_LEVEL_IDLE, + TPUT_LEVEL_LOW, + TPUT_LEVEL_MEDIUM, + TPUT_LEVEL_HIGH, + TPUT_LEVEL_VERY_HIGH, + TPUT_LEVEL_ULTRA_HIGH, + TPUT_LEVEL_SUPER_HIGH, + TPUT_LEVEL_MAX, +}; + +/** + * enum bbm_non_per_flag - Non persistent policy related flag + * + * @BBM_APPS_RESUME: system resume flag + * @BBM_APPS_SUSPEND: system suspend flag + */ +enum bbm_non_per_flag { + BBM_APPS_RESUME, + BBM_APPS_SUSPEND, + BBM_FLAG_MAX, +}; + +/** + * enum bbm_policy - BBM policy + * + * @BBM_DRIVER_MODE_POLICY: driver mode policy + * @BBM_TPUT_POLICY: throughput policy + * @BBM_USER_POLICY: user policy + * @BBM_NON_PERSISTENT_POLICY: non persistent policy. For example, bus resume + * sets the bus bw level to LEVEL_3 if any adapter is connected but + * this is only a one time setting and is not persistent. This bus bw level + * is set without taking other policy vote levels into consideration. + * @BBM_SELECT_TABLE_POLICY: policy where bus bw table is selected based on + * the latency level. + */ +enum bbm_policy { + BBM_DRIVER_MODE_POLICY, + BBM_TPUT_POLICY, + BBM_USER_POLICY, + BBM_NON_PERSISTENT_POLICY, + BBM_SELECT_TABLE_POLICY, + BBM_MAX_POLICY, +}; + +/** + * enum wlm_ll_level - WLM latency levels + * + * @WLM_LL_NORMAL: normal latency level + * @WLM_LL_LOW: low latency level + */ +enum wlm_ll_level { + WLM_LL_NORMAL, + WLM_LL_LOW, + WLM_LL_MAX, +}; + +/** + * union bbm_policy_info - BBM policy specific info. Only one of the value + * would be valid based on the BBM policy. + * + * @driver_mode: global driver mode. valid for BBM_DRIVER_MODE_POLICY. + * @flag: BBM non persistent flag. valid for BBM_NON_PERSISTENT_POLICY. + * @tput_level: throughput level. valid for BBM_TPUT_POLICY. + * @wlm_level: latency level. valid for BBM_WLM_POLICY. + * @user_level: user bus bandwidth vote. valid for BBM_USER_POLICY. + * @set: set or reset user level. valid for BBM_USER_POLICY. + */ +union bbm_policy_info { + enum QDF_GLOBAL_MODE driver_mode; + enum bbm_non_per_flag flag; + enum tput_level tput_level; + enum wlm_ll_level wlm_level; + struct { + enum bus_bw_level user_level; + bool set; + } usr; +}; + +/** + * struct bbm_params - BBM params + * + * @policy: BBM policy + * @policy_info: policy related info + */ +struct bbm_params { + enum bbm_policy policy; + union bbm_policy_info policy_info; +}; /** * wlan_tp_data : union of TCP msg for Tx and Rx Dir @@ -41,10 +191,32 @@ union wlan_tp_data { * struct wlan_dp_psoc_callbacks - struct containing callback * to non-converged driver * @os_if_dp_gro_rx: OS IF Callback to handle GRO packet to n/w stack + * @callback_ctx : Opaque callback context + * @wlan_dp_sta_get_dot11mode: Callback to get dot11 mode + * @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 + * @osif_dp_send_tcp_param_update_event: OS IF callback to send TCP param */ struct wlan_dp_psoc_callbacks { void (*os_if_dp_gro_rx)(struct sk_buff *skb, uint8_t napi_to_use, bool flush_gro); + hdd_cb_handle callback_ctx; + + bool + (*wlan_dp_sta_get_dot11mode)(hdd_cb_handle context, uint8_t vdev_id, + enum qca_wlan_802_11_mode *dot11_mode); + bool (*wlan_dp_get_ap_client_count)(hdd_cb_handle context, + uint8_t vdev_id, + uint16_t *client_count); + bool (*wlan_dp_sta_ndi_connected)(hdd_cb_handle context, + uint8_t vdev_id); + bool (*dp_any_adapter_connected)(hdd_cb_handle context); + + void + (*osif_dp_send_tcp_param_update_event)(struct wlan_objmgr_psoc *psoc, + union wlan_tp_data *data, + uint8_t dir); }; /** diff --git a/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h b/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h index 8289baffc6..5065764212 100644 --- a/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h +++ b/components/dp/dispatcher/inc/wlan_dp_ucfg_api.h @@ -129,4 +129,43 @@ ucfg_dp_update_config(struct wlan_objmgr_psoc *psoc, uint64_t ucfg_dp_get_rx_softirq_yield_duration(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_dp_bbm_context_init() - Initialize BBM context + * @psoc: psoc handle + * + * Returns: error code + */ +int ucfg_dp_bbm_context_init(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_dp_bbm_context_deinit() - De-initialize BBM context + * @psoc: psoc handle + * + * Returns: None + */ +void ucfg_dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_dp_bbm_apply_independent_policy() - Apply independent policies + * to set the bus bw level + * @psoc: psoc handle + * @params: BBM policy related params + * + * The function applies BBM related policies and appropriately sets the bus + * bandwidth level. + * + * Returns: None + */ +void ucfg_dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc, + struct bbm_params *params); + +/** + * ucfg_dp_register_hdd_callbacks() - Resiter HDD callbacks with DP component + * @psoc: psoc handle + * @cb_obj: Callback object + * + * Returns: None + */ +void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, + struct wlan_dp_psoc_callbacks *cb_obj); #endif diff --git a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c index 1126361207..60f9f5407f 100644 --- a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c +++ b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c @@ -26,6 +26,8 @@ #include "cdp_txrx_cmn.h" #include "cfg_ucfg_api.h" #include "wlan_pmo_obj_mgmt_api.h" +#include "wlan_dp_objmgr.h" +#include "wlan_dp_bus_bandwidth.h" void ucfg_dp_update_inf_mac(struct wlan_objmgr_psoc *psoc, struct qdf_mac_addr *cur_mac, @@ -465,3 +467,39 @@ ucfg_dp_get_rx_softirq_yield_duration(struct wlan_objmgr_psoc *psoc) return dp_ctx->dp_cfg.rx_softirq_max_yield_duration_ns; } + +int ucfg_dp_bbm_context_init(struct wlan_objmgr_psoc *psoc) +{ + return dp_bbm_context_init(psoc); +} + +void ucfg_dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc) +{ + dp_bbm_context_deinit(psoc); +} + +void ucfg_dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc, + struct bbm_params *params) +{ + dp_bbm_apply_independent_policy(psoc, params); +} + +void ucfg_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, + struct wlan_dp_psoc_callbacks *cb_obj) +{ + struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc); + + if (!dp_ctx) { + dp_err("DP ctx is NULL"); + return; + } + dp_ctx->dp_ops.callback_ctx = cb_obj->callback_ctx; + dp_ctx->dp_ops.wlan_dp_sta_get_dot11mode = + cb_obj->wlan_dp_sta_get_dot11mode; + dp_ctx->dp_ops.wlan_dp_get_ap_client_count = + cb_obj->wlan_dp_get_ap_client_count; + dp_ctx->dp_ops.wlan_dp_sta_ndi_connected = + cb_obj->wlan_dp_sta_ndi_connected; + dp_ctx->dp_ops.dp_any_adapter_connected = + cb_obj->dp_any_adapter_connected; +} diff --git a/os_if/dp/inc/os_if_dp.h b/os_if/dp/inc/os_if_dp.h index e7a277d81f..dcbf6912f6 100644 --- a/os_if/dp/inc/os_if_dp.h +++ b/os_if/dp/inc/os_if_dp.h @@ -33,23 +33,14 @@ */ void osif_dp_classify_pkt(struct sk_buff *skb); -#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH /** - * osif_dp_send_tcp_param_update_event() - Send vendor event to update - * TCP parameter through Wi-Fi HAL + * os_if_dp_register_hdd_callbacks() - Register callback handlers * @psoc: Pointer to psoc context - * @data: Parameters to update - * @dir: Direction(tx/rx) to update + * @cb_obj: Callback object pointer * * Return: None */ -void osif_dp_send_tcp_param_update_event(struct wlan_objmgr_psoc *psoc, - union wlan_tp_data *data, uint8_t dir); -#else -static inline -void osif_dp_send_tcp_param_update_event(struct wlan_objmgr_psoc *psoc, - union wlan_tp_data *data, uint8_t dir) -{ -} -#endif /* WLAN_FEATURE_DP_BUS_BANDWIDTH */ +void os_if_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, + struct wlan_dp_psoc_callbacks *cb_obj); + #endif /* __OSIF_DP_H__ */ diff --git a/os_if/dp/src/os_if_dp.c b/os_if/dp/src/os_if_dp.c index 08c43cdd64..54af33c24c 100644 --- a/os_if/dp/src/os_if_dp.c +++ b/os_if/dp/src/os_if_dp.c @@ -26,8 +26,19 @@ #include #include #include "qca_vendor.h" +#include "wlan_dp_ucfg_api.h" #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH +/** + * osif_dp_send_tcp_param_update_event() - Send vendor event to update + * TCP parameter through Wi-Fi HAL + * @psoc: Pointer to psoc context + * @data: Parameters to update + * @dir: Direction(tx/rx) to update + * + * Return: None + */ +static void osif_dp_send_tcp_param_update_event(struct wlan_objmgr_psoc *psoc, union wlan_tp_data *data, uint8_t dir) @@ -137,4 +148,20 @@ tcp_param_change_nla_failed: dp_err("nla_put api failed"); kfree_skb(vendor_event); } +#else +static +void osif_dp_send_tcp_param_update_event(struct wlan_objmgr_psoc *psoc, + union wlan_tp_data *data, + uint8_t dir) +{ +} #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ + +void os_if_dp_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc, + struct wlan_dp_psoc_callbacks *cb_obj) +{ + cb_obj->osif_dp_send_tcp_param_update_event = + osif_dp_send_tcp_param_update_event; + + ucfg_dp_register_hdd_callbacks(psoc, cb_obj); +}