diff --git a/core/hdd/src/wlan_hdd_green_ap.c b/core/hdd/src/wlan_hdd_green_ap.c index 9cc9117dac6b..cfdaf06a062b 100644 --- a/core/hdd/src/wlan_hdd_green_ap.c +++ b/core/hdd/src/wlan_hdd_green_ap.c @@ -80,6 +80,7 @@ enum hdd_green_ap_event { * @ps_state: Current state * @ps_event: Event to trigger when timer expires * @ps_timer: Event timer + * @egap_support: Enhanced Green AP support flag */ struct hdd_green_ap_ctx { uint8_t ps_enable; @@ -91,6 +92,8 @@ struct hdd_green_ap_ctx { enum hdd_green_ap_event ps_event; cdf_mc_timer_t ps_timer; + + bool egap_support; }; /** @@ -449,3 +452,18 @@ void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx) { hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_DEL_STA_EVENT); } + +/** + * hdd_wlan_set_egap_support() - helper function to set egap support flag + * @hdd_ctx: pointer to hdd context + * @param: pointer to target configuration + * + * Return: None + */ +void hdd_wlan_set_egap_support(hdd_context_t *hdd_ctx, void *param) +{ + struct wma_tgt_cfg *cfg = (struct wma_tgt_cfg *) param; + + if (hdd_ctx && cfg) + hdd_ctx->green_ap_ctx->egap_support = cfg->egap_support; +} diff --git a/core/hdd/src/wlan_hdd_green_ap.h b/core/hdd/src/wlan_hdd_green_ap.h index 8844d71d870b..a688ba0222b4 100644 --- a/core/hdd/src/wlan_hdd_green_ap.h +++ b/core/hdd/src/wlan_hdd_green_ap.h @@ -43,6 +43,7 @@ void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx); void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx); void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx); void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx); +void hdd_wlan_set_egap_support(struct hdd_context_s *hdd_ctx, void *param); #else static inline void hdd_wlan_green_ap_init(struct hdd_context_s *hdd_ctx) {} static inline void hdd_wlan_green_ap_deinit(struct hdd_context_s *hdd_ctx) {} @@ -50,5 +51,8 @@ static inline void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx) {} static inline void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx) {} static inline void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx) {} static inline void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx) {} +static inline void hdd_wlan_set_egap_support(struct hdd_context_s *hdd_ctx, + void *param) {} + #endif /* FEATURE_GREEN_AP */ #endif /* __WLAN_HDD_GREEN_AP_H */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 5d2bc52c46a6..2b3fccef9b94 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1213,6 +1213,8 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_ctx->lpss_support = cfg->lpss_support; #endif + hdd_wlan_set_egap_support(hdd_ctx, cfg); + hdd_ctx->ap_arpns_support = cfg->ap_arpns_support; hdd_update_tgt_services(hdd_ctx, &cfg->services); @@ -4880,6 +4882,8 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) cds_set_connection_in_progress(hdd_ctx, false); + hdd_wlan_green_ap_init(hdd_ctx); + status = cds_open(&p_cds_context, 0); if (!CDF_IS_STATUS_SUCCESS(status)) { hddLog(CDF_TRACE_LEVEL_FATAL, FL("cds_open failed")); @@ -5296,7 +5300,6 @@ ftm_processing: hddLog(LOGE, FL("Failed to init ACS Skip timer")); #endif - hdd_wlan_green_ap_init(hdd_ctx); wlan_hdd_nan_init(hdd_ctx); status = cds_init_policy_mgr(hdd_ctx); if (!CDF_IS_STATUS_SUCCESS(status)) { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 001844f6067e..d0c794834bf3 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5451,4 +5451,20 @@ struct sir_sme_ext_cng_chan_ind { uint8_t new_channel; }; +/** + * struct egap_params - the enhanced green ap params + * @vdev_id: vdev id + * @enable: enable or disable the enhance green ap in firmware + * @inactivity_time: inactivity timeout value + * @wait_time: wait timeout value + * @flags: feature flag in bitmask + * + */ +struct egap_conf_params { + uint32_t vdev_id; + bool enable; + uint32_t inactivity_time; + uint32_t wait_time; + uint32_t flags; +}; #endif /* __SIR_API_H */ diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 22aabae93a5b..64d4d624ecc1 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -605,6 +605,8 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_LRO_CONFIG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 335) +#define SIR_HAL_SET_EGAP_CONF_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 336) + #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* CFG message types */ diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index ba46b3a0e49a..9e8c40e1d845 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1064,4 +1064,18 @@ CDF_STATUS sme_gateway_param_update(tHalHandle hHal, struct gateway_param_update_req *request); #endif +#ifdef FEATURE_GREEN_AP +CDF_STATUS sme_send_egap_conf_params(uint32_t enable, + uint32_t inactivity_time, + uint32_t wait_time, + uint32_t flags); +#else +static inline CDF_STATUS sme_send_egap_conf_params(uint32_t enable, + uint32_t inactivity_time, + uint32_t wait_time, + uint32_t flags) +{ + return CDF_STATUS_E_NOSUPPORT; +} +#endif #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 527ad3ca8ec0..fa82c159f195 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14949,3 +14949,45 @@ void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset, } } #endif + +#ifdef FEATURE_GREEN_AP +/** + * sme_send_egap_conf_params() - set the enhanced green ap configuration params + * @enable: enable/disable the enhanced green ap feature + * @inactivity_time: inactivity timeout value + * @wait_time: wait timeout value + * @flag: feature flag in bitmasp + * + * Return: Return CDF_STATUS, otherwise appropriate failure code + */ +CDF_STATUS sme_send_egap_conf_params(uint32_t enable, uint32_t inactivity_time, + uint32_t wait_time, uint32_t flags) +{ + cds_msg_t message; + CDF_STATUS status; + struct egap_conf_params *egap_params; + + egap_params = cdf_mem_malloc(sizeof(*egap_params)); + if (NULL == egap_params) { + CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, + "%s: fail to alloc egap_params", __func__); + return CDF_STATUS_E_NOMEM; + } + + egap_params->enable = enable; + egap_params->inactivity_time = inactivity_time; + egap_params->wait_time = wait_time; + egap_params->flags = flags; + + message.type = WMA_SET_EGAP_CONF_PARAMS; + message.bodyptr = egap_params; + status = cds_mq_post_message(CDF_MODULE_ID_WMA, &message); + if (!CDF_IS_STATUS_SUCCESS(status)) { + CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, + "%s: Not able to post msg to WMA!", __func__); + + cdf_mem_free(egap_params); + } + return status; +} +#endif diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 95a1ad5b40e6..3906d6d74312 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1083,6 +1083,7 @@ struct wmi_init_cmd { * @final_abi_vers: The final ABI version to be used for communicating * @target_fw_version: Target f/w build version * @lpss_support: LPSS feature is supported in target or not + * @egap_support: Enhanced Green AP support flag * @wmi_ready: wmi status flag * @wlan_init_status: wlan init status * @cdf_dev: cdf device @@ -1211,6 +1212,9 @@ typedef struct { uint8_t lpss_support; #endif uint8_t ap_arpns_support; +#ifdef FEATURE_GREEN_AP + bool egap_support; +#endif bool wmi_ready; uint32_t wlan_init_status; cdf_device_t cdf_dev; diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index 0e9b5f5bc559..5990477e7ee9 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -219,4 +219,20 @@ struct wma_lro_config_cmd_t { int wma_lro_init(struct wma_lro_config_cmd_t *lro_config); #endif bool wma_is_scan_simultaneous_capable(void); + +#ifdef FEATURE_GREEN_AP +void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, WMA_HANDLE handle); +void wma_register_egap_event_handle(WMA_HANDLE handle); +CDF_STATUS wma_send_egap_conf_params(WMA_HANDLE handle, + struct egap_conf_params *egap_params); +#else +static inline void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, + WMA_HANDLE handle) {} +static inline void wma_register_egap_event_handle(WMA_HANDLE handle) {} +static inline CDF_STATUS wma_send_egap_conf_params(WMA_HANDLE handle, + struct egap_conf_params *egap_params) +{ + return CDF_STATUS_E_NOSUPPORT; +} +#endif #endif diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index 5efa9545d822..73a739be0ef9 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -147,6 +147,7 @@ struct wma_dfs_radar_ind { * @vht_cap: struct wma_tgt_vht_cap * @max_intf_count: max interface count * @lpss_support: lpass support + * @egap_support: enhanced green ap support */ struct wma_tgt_cfg { uint32_t target_fw_version; @@ -164,5 +165,8 @@ struct wma_tgt_cfg { uint8_t lpss_support; #endif uint8_t ap_arpns_support; +#ifdef FEATURE_GREEN_AP + bool egap_support; +#endif }; #endif /* WMA_TGT_CFG_H */ diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index 6676a08a1aef..0f244989b1c7 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -444,10 +444,11 @@ #define WMA_DCC_GET_STATS_CMD SIR_HAL_DCC_GET_STATS_CMD #define WMA_DCC_CLEAR_STATS_CMD SIR_HAL_DCC_CLEAR_STATS_CMD #define WMA_DCC_UPDATE_NDL_CMD SIR_HAL_DCC_UPDATE_NDL_CMD -#define WMA_SET_IE_INFO SIR_HAL_SET_IE_INFO +#define WMA_SET_IE_INFO SIR_HAL_SET_IE_INFO -#define WMA_LRO_CONFIG_CMD SIR_HAL_LRO_CONFIG_CMD +#define WMA_LRO_CONFIG_CMD SIR_HAL_LRO_CONFIG_CMD #define WMA_GW_PARAM_UPDATE_REQ SIR_HAL_GATEWAY_PARAM_UPDATE_REQ +#define WMA_SET_EGAP_CONF_PARAMS SIR_HAL_SET_EGAP_CONF_PARAMS /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 739cd6eae973..1163ccab0b88 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -979,6 +979,125 @@ CDF_STATUS wma_get_link_speed(WMA_HANDLE handle, tSirLinkSpeedInfo *pLinkSpeed) #ifdef FEATURE_GREEN_AP +/** + * wma_egap_info_status_event() - egap info status event + * @handle: pointer to wma handler + * @event: pointer to event + * @len: len of the event + * + * Return: 0 for success, otherwise appropriate error code + */ +static int wma_egap_info_status_event(void *handle, u_int8_t *event, + uint32_t len) +{ + WMI_TX_PAUSE_EVENTID_param_tlvs *param_buf; + wmi_ap_ps_egap_info_event_fixed_param *egap_info_event; + wmi_ap_ps_egap_info_chainmask_list *chainmask_event; + u_int8_t *buf_ptr; + + param_buf = (WMI_TX_PAUSE_EVENTID_param_tlvs *)event; + if (!param_buf) { + WMA_LOGE("Invalid EGAP Info status event buffer"); + return -EINVAL; + } + + egap_info_event = (wmi_ap_ps_egap_info_event_fixed_param *) + param_buf->fixed_param; + buf_ptr = (uint8_t *)egap_info_event; + buf_ptr += sizeof(wmi_ap_ps_egap_info_event_fixed_param); + chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *)buf_ptr; + + WMA_LOGI("mac_id: %d, status: %d, tx_mask: %x, rx_mask: %d", + chainmask_event->mac_id, + egap_info_event->status, + chainmask_event->tx_chainmask, + chainmask_event->rx_chainmask); + return 0; +} + +/** + * wma_send_egap_conf_params() - send wmi cmd of egap configuration params + * @wma_handle: wma handler + * @egap_params: pointer to egap_params + * + * Return: 0 for success, otherwise appropriate error code + */ +CDF_STATUS wma_send_egap_conf_params(WMA_HANDLE handle, + struct egap_conf_params *egap_params) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_ap_ps_egap_param_cmd_fixed_param *cmd; + wmi_buf_t buf; + int32_t err; + + buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd)); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send ap_ps_egap cmd"); + return CDF_STATUS_E_NOMEM; + } + cmd = (wmi_ap_ps_egap_param_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ap_ps_egap_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_ap_ps_egap_param_cmd_fixed_param)); + + cmd->enable = egap_params->enable; + cmd->inactivity_time = egap_params->inactivity_time; + cmd->wait_time = egap_params->wait_time; + cmd->flags = egap_params->flags; + err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + sizeof(*cmd), WMI_AP_PS_EGAP_PARAM_CMDID); + if (err) { + WMA_LOGE("Failed to send ap_ps_egap cmd"); + wmi_buf_free(buf); + return CDF_STATUS_E_FAILURE; + } + return CDF_STATUS_SUCCESS; +} + +/** + * wma_setup_egap_support() - setup the EGAP support flag + * @tgt_cfg: pointer to hdd target configuration + * @egap_support: EGAP support flag + * + * Return: None + */ +void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, WMA_HANDLE handle) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + + if (tgt_cfg && wma_handle) + tgt_cfg->egap_support = wma_handle->egap_support; +} + +/** + * wma_register_egap_event_handle() - register the EGAP event handle + * @wma_handle: wma handler + * + * Return: None + */ +void wma_register_egap_event_handle(WMA_HANDLE handle) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + int status; + + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_EGAP)) { + status = wmi_unified_register_event_handler( + wma_handle->wmi_handle, + WMI_AP_PS_EGAP_INFO_EVENTID, + wma_egap_info_status_event); + if (status) { + WMA_LOGE("Failed to register Enhance Green AP event"); + wma_handle->egap_support = false; + } else { + WMA_LOGI("Set the Enhance Green AP event handler"); + wma_handle->egap_support = true; + } + } else + wma_handle->egap_support = false; +} + /** * wmi_unified_pdev_green_ap_ps_enable_cmd() - enable green ap powersave command * @wmi_handle: wmi handle diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index b185e7e25070..59253b83a016 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3459,6 +3459,7 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle) tgt_cfg.lpss_support = wma_handle->lpss_support; #endif /* WLAN_FEATURE_LPSS */ tgt_cfg.ap_arpns_support = wma_handle->ap_arpns_support; + wma_setup_egap_support(&tgt_cfg, wma_handle); wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg); } @@ -3894,6 +3895,9 @@ void wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info) return; } + /* register the Enhanced Green AP event handler */ + wma_register_egap_event_handle(wma_handle); + /* Initialize the log supported event handler */ status = wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID, @@ -5283,6 +5287,10 @@ CDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) case WMA_GW_PARAM_UPDATE_REQ: wma_set_gateway_params(wma_handle, (struct gateway_param_update_req *)msg->bodyptr); + break; + case WMA_SET_EGAP_CONF_PARAMS: + wma_send_egap_conf_params(wma_handle, + (struct egap_conf_params *)msg->bodyptr); cdf_mem_free(msg->bodyptr); break; default: