Browse Source

qcacld-3.0: Add Enhanced Green AP interfaces and event handler

qcacld-2.0 to qcacld-3.0 propagation

The firmware reports the Enhanced Green AP (EGAP) service
(EGAP_SERVICE) feature flag to indicate the support of EGAP
feature.

The EGAP is to offload the legacy Green AP feature to firmware
in order to aggressively enable the Green AP other than wait
for host control latency.

Add the knob to hold the EGAP infomation when firmware support
it, also populate the information up to hdd target config.

And then add a SME interface to allow hdd layer to configure
the EGAP configuration.

Change-Id: I9be927369e7cf07731f8e9ba49d65224e05c340b
CRs-fixed: 929063
Ryan Hsu 9 years ago
parent
commit
3c8f79f22c

+ 18 - 0
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;
+}

+ 4 - 0
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 */

+ 4 - 1
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)) {

+ 16 - 0
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 */

+ 2 - 0
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 */

+ 14 - 0
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 ) */

+ 42 - 0
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

+ 4 - 0
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;

+ 16 - 0
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

+ 4 - 0
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 */

+ 3 - 2
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

+ 119 - 0
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

+ 8 - 0
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: