Sfoglia il codice sorgente

qcacld-3.0: Control chan avoidance indication through vendor command

qcacld-2.0 to qcacld-3.0 propagation

Provide mechanism to user to enable or disable channel avoidance
indication through vendor command and also control this mechanism
using "gOptimizeCAevent" ini parameter.

By default "gOPtimizeCAevent" ini parameter is disabled. Ini param
controls the CA events based on the mode. If ini is enabled(1) then
firmware will send CA events only in SAP/GO mode and it will not send
any CA events in STA mode. If ini is disabled CA events are sent to
host in all the modes.
a. gOptimizeCAevent = 1
  - When host sends ioctl(enable), FW will send "ONE" CA indication
    to host(though it is duplicate).
  - When host sends ioctl(disable), FW doesnot perform any action.
  - Whenever any change in CA and WLAN is SAP/P2P-GO mode, FW will
    send CA ind to host regardless of the ioctl status.
b. gOptimizeCAevent = 0
  - FW will ignore ioctl request if received.
  - CxM behavior will be as per the current implementation.

Change-Id: I9bd81b03b97a60bb81e550068742b2fc0b776ebb
CRs-Fixed: 903249
Selvaraj, Sridhar 8 anni fa
parent
commit
ebda0f2713

+ 6 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -3482,6 +3482,11 @@ enum dot11p_mode {
 #define CFG_SIFS_BURST_DURATION_MAX      (12)
 #define CFG_SIFS_BURST_DURATION_DEFAULT  (8)
 
+/* Optimize channel avoidance indication comming from firmware */
+#define CFG_OPTIMIZE_CA_EVENT_NAME       "goptimize_chan_avoid_event"
+#define CFG_OPTIMIZE_CA_EVENT_DISABLE    (0)
+#define CFG_OPTIMIZE_CA_EVENT_ENABLE     (1)
+#define CFG_OPTIMIZE_CA_EVENT_DEFAULT    (0)
 
 /*---------------------------------------------------------------------------
    Type declarations
@@ -4140,6 +4145,7 @@ struct hdd_config {
 	bool multicast_replay_filter;
 	/* parameter for indicating sifs burst duration to fw */
 	uint8_t sifs_burst_duration;
+	bool goptimize_chan_avoid_event;
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

+ 2 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1866,4 +1866,6 @@ enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode);
 
 void hdd_ch_avoid_cb(void *hdd_context, void *indi_param);
 void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctx);
+int hdd_enable_disable_ca_event(hdd_context_t *hddctx,
+				uint8_t set_value);
 #endif /* end #if !defined(WLAN_HDD_MAIN_H) */

+ 7 - 0
core/hdd/src/wlan_hdd_cfg.c

@@ -3970,6 +3970,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_SIFS_BURST_DURATION_DEFAULT,
 		     CFG_SIFS_BURST_DURATION_MIN,
 		     CFG_SIFS_BURST_DURATION_MAX),
+	REG_VARIABLE(CFG_OPTIMIZE_CA_EVENT_NAME, WLAN_PARAM_Integer,
+			struct hdd_config, goptimize_chan_avoid_event,
+			VAR_FLAGS_OPTIONAL |
+			VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+			CFG_OPTIMIZE_CA_EVENT_DEFAULT,
+			CFG_OPTIMIZE_CA_EVENT_DISABLE,
+			CFG_OPTIMIZE_CA_EVENT_ENABLE),
 };
 
 /**

+ 9 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -3868,6 +3868,7 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM] = {.type = NLA_U32 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR] = {.type = NLA_U16 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND] = {.type = NLA_U8 },
 };
 
 
@@ -3898,6 +3899,7 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
 	u32 modulated_dtim;
 	u16 stats_avg_factor;
 	u32 guard_time;
+	uint8_t set_value;
 	u32 ftm_capab;
 	QDF_STATUS status;
 	int attr_len;
@@ -4023,6 +4025,13 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
 		}
 	}
 
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND]) {
+		set_value = nla_get_u8(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND]);
+		hdd_info("set_value: %d", set_value);
+		ret_val = hdd_enable_disable_ca_event(hdd_ctx, set_value);
+	}
+
 	return ret_val;
 }
 

+ 2 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -2341,6 +2341,8 @@ enum qca_wlan_vendor_config {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT,
+	QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS,
+	QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND,
 	/* Attribute used to set scan default IEs to the driver.
 	*
 	* These IEs can be used by scan operations that will be initiated by

+ 39 - 0
core/hdd/src/wlan_hdd_main.c

@@ -7765,6 +7765,13 @@ int hdd_wlan_startup(struct device *dev)
 
 	qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
 			   hdd_ctx->config->iface_change_wait_time * 5000);
+
+	if (hdd_ctx->config->goptimize_chan_avoid_event) {
+		status = sme_enable_disable_chanavoidind_event(
+							hdd_ctx->hHal, 0);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			hdd_err("Failed to disable Chan Avoidance Indication");
+	}
 	goto success;
 
 err_debugfs_exit:
@@ -9291,6 +9298,38 @@ enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
 	}
 }
 
+/**
+ * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
+ * @hddctx: pointer to hdd context
+ * @set_value: enable/disable
+ *
+ * When Host sends vendor command enable, FW will send *ONE* CA ind to
+ * Host(even though it is duplicate). When Host send vendor command
+ * disable,FW doesn't perform any action. Whenever any change in
+ * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
+ *
+ * return - 0 on success, appropriate error values on failure.
+ */
+int hdd_enable_disable_ca_event(hdd_context_t *hddctx, uint8_t set_value)
+{
+	QDF_STATUS status;
+
+	if (0 != wlan_hdd_validate_context(hddctx)) {
+		return -EAGAIN;
+	}
+
+	if (!hddctx->config->goptimize_chan_avoid_event) {
+		hdd_warn("goptimize_chan_avoid_event ini param disabled");
+		return -EINVAL;
+	}
+
+	status = sme_enable_disable_chanavoidind_event(hddctx->hHal, set_value);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to send chan avoid command to SME");
+		return -EINVAL;
+	}
+	return 0;
+}
 
 /* Register the module init/exit functions */
 module_init(hdd_module_init);

+ 1 - 0
core/mac/src/include/sir_params.h

@@ -630,6 +630,7 @@ typedef struct sSirMbMsgP2p {
 #define SIR_HAL_NDP_END_IND                 (SIR_HAL_ITC_MSG_TYPES_BEGIN + 357)
 #define SIR_HAL_UPDATE_WEP_DEFAULT_KEY      (SIR_HAL_ITC_MSG_TYPES_BEGIN + 358)
 
+#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 360)
 #define SIR_HAL_POWER_DBG_CMD               (SIR_HAL_ITC_MSG_TYPES_BEGIN + 362)
 #define SIR_HAL_SET_DTIM_PERIOD             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 363)
 

+ 2 - 0
core/sme/inc/sme_api.h

@@ -1259,4 +1259,6 @@ QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal,
 		enum sta_roam_policy_dfs_mode dfs_mode,
 		bool skip_unsafe_channels,
 		uint8_t session_id);
+QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal,
+					uint8_t set_value);
 #endif /* #if !defined( __SME_API_H ) */

+ 29 - 0
core/sme/src/common/sme_api.c

@@ -16541,6 +16541,35 @@ QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal_handle,
 		csr_roam_offload_scan(mac_ctx, session_id,
 				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
 				REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED);
+	return status;
+}
+
+/**
+ * sme_enable_disable_chanavoidind_event - configure ca event ind
+ * @hal: handler to hal
+ * @set_value: enable/disable
+ *
+ * function to enable/disable chan avoidance indication
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal,
+		uint8_t set_value)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	cds_msg_t msg;
+
+	sms_log(mac_ctx, LOG1, FL("set_value: %d"), set_value);
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		qdf_mem_zero(&msg, sizeof(cds_msg_t));
+		msg.type = WMA_SEND_FREQ_RANGE_CONTROL_IND;
+		msg.bodyval = set_value;
+		status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
+		sme_release_global_lock(&mac_ctx->sme);
+		return status;
+	}
 
 	return status;
 }

+ 3 - 0
core/wma/inc/wma.h

@@ -2213,3 +2213,6 @@ WLAN_PHY_MODE wma_chan_phy_mode(u8 chan, enum phy_ch_width chan_width,
 QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle,
 				  struct oem_data_req *oem_req);
 #endif
+
+QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma_handle,
+				uint8_t val);

+ 2 - 0
core/wma/inc/wma_types.h

@@ -473,6 +473,8 @@
 
 #define WMA_SET_PDEV_IE_REQ                  SIR_HAL_SET_PDEV_IE_REQ
 #define WMA_UPDATE_WEP_DEFAULT_KEY           SIR_HAL_UPDATE_WEP_DEFAULT_KEY
+#define WMA_SEND_FREQ_RANGE_CONTROL_IND      SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND
+
 /* Bit 6 will be used to control BD rate for Management frames */
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
 

+ 43 - 0
core/wma/src/wma_features.c

@@ -8175,3 +8175,46 @@ void wma_process_fw_test_cmd(WMA_HANDLE handle,
 		return;
 	}
 }
+
+/**
+ * wma_enable_disable_caevent_ind() - Issue WMI command to enable or
+ * disable ca event indication
+ * @wma: wma handler
+ * @val: boolean value true or false
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val)
+{
+	WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *cmd;
+	wmi_buf_t wmi_buf;
+	uint8_t *buf_ptr;
+	uint32_t len;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE(FL("WMA is closed, can not issue set/clear CA"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	len = sizeof(*cmd);
+	wmi_buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!wmi_buf) {
+		WMA_LOGE(FL("wmi_buf_alloc failed"));
+		return QDF_STATUS_E_NOMEM;
+	}
+	buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
+	cmd = (WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param *) buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+				WMI_CHAN_AVOID_RPT_ALLOW_CMD_fixed_param));
+	cmd->rpt_allow = val;
+	if (wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
+				WMI_CHAN_AVOID_RPT_ALLOW_CMDID)) {
+		WMA_LOGE(FL("Failed to send enable/disable CA event command"));
+		wmi_buf_free(wmi_buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}

+ 3 - 0
core/wma/src/wma_main.c

@@ -6294,6 +6294,9 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
 			(struct wep_update_default_key_idx *)msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
 		break;
+	case WMA_SEND_FREQ_RANGE_CONTROL_IND:
+		wma_enable_disable_caevent_ind(wma_handle, msg->bodyval);
+		break;
 	default:
 		WMA_LOGD("unknow msg type %x", msg->type);
 		/* Do Nothing? MSG Body should be freed at here */