瀏覽代碼

qcacld-3.0: Pass sta_inactivity_timeout to FW

qcacld-2.0 to qcacld-3.0 propagation

If a station does not send anything in sta_inactivity_timeout, an
empty data frame is sent to it in order to verify whether it is
still in range. If this frame is not ACKed, the station will be
disassociated and then deauthenticated.

Change-Id: Ib86c9aacdb52141890b224262d55abbe58b1604d
CRs-Fixed: 1020078
Agrawal, Ashish 8 年之前
父節點
當前提交
4e5fa1c5a1

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

@@ -3470,6 +3470,21 @@ enum dot11p_mode {
 #define CFG_TGT_GTX_USR_CFG_MAX     (32)
 #define CFG_TGT_GTX_USR_CFG_DEFAULT (32)
 
+/*
+ * This parameter will avoid updating ap_sta_inactivity from hostapd.conf
+ * file. If a station does not send anything in ap_max_inactivity seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated. This feature is used to
+ * clear station table of old entries when the STAs move out of the
+ * range.
+ * Default : Disable
+ */
+#define CFG_SAP_MAX_INACTIVITY_OVERRIDE_NAME     "gSapMaxInactivityOverride"
+#define CFG_SAP_MAX_INACTIVITY_OVERRIDE_MIN      (0)
+#define CFG_SAP_MAX_INACTIVITY_OVERRIDE_MAX      (1)
+#define CFG_SAP_MAX_INACTIVITY_OVERRIDE_DEFAULT  (0)
+
 /*
  * This parameter determines that which defered method will be use in rx path
  * If no bits are set then rx path processing will happen in tasklet context.
@@ -4245,6 +4260,7 @@ struct hdd_config {
 	uint32_t tx_aggregation_size;
 	uint32_t rx_aggregation_size;
 	bool sta_prefer_80MHz_over_160MHz;
+	uint8_t sap_max_inactivity_override;
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

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

@@ -4036,6 +4036,12 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		CFG_RX_AGGREGATION_SIZE_DEFAULT,
 		CFG_RX_AGGREGATION_SIZE_MIN,
 		CFG_RX_AGGREGATION_SIZE_MAX),
+	REG_VARIABLE(CFG_SAP_MAX_INACTIVITY_OVERRIDE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, sap_max_inactivity_override,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_SAP_MAX_INACTIVITY_OVERRIDE_DEFAULT,
+		CFG_SAP_MAX_INACTIVITY_OVERRIDE_MIN,
+		CFG_SAP_MAX_INACTIVITY_OVERRIDE_MAX)
 };
 
 /**
@@ -5701,6 +5707,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	hdd_info("Name = [%s] Value = [%u]",
 		 CFG_TGT_GTX_USR_CFG_NAME,
 		 pHddCtx->config->tgt_gtx_usr_cfg);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_SAP_MAX_INACTIVITY_OVERRIDE_NAME,
+		pHddCtx->config->sap_max_inactivity_override);
 	hdd_ndp_print_ini_config(pHddCtx);
 	hdd_info("Name = [%s] Value = [%s]",
 		CFG_RM_CAPABILITY_NAME,

+ 1 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -8900,7 +8900,7 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 #ifdef QCA_HT_2040_COEX
 	wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
 #endif
-
+	wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
 	hdd_add_channel_switch_support(&wiphy->flags);
 
 	EXIT();

+ 15 - 0
core/hdd/src/wlan_hdd_hostapd.c

@@ -7825,6 +7825,7 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 	hdd_context_t *pHddCtx;
 	enum hw_mode_bandwidth channel_width;
 	int status;
+	struct sme_sta_inactivity_timeout  *sta_inactivity_timer;
 	uint8_t channel;
 
 	ENTER();
@@ -7988,6 +7989,20 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 				&params->beacon,
 				params->ssid, params->ssid_len,
 				params->hidden_ssid, true);
+
+		if (pHddCtx->config->sap_max_inactivity_override) {
+			sta_inactivity_timer = qdf_mem_malloc(
+					sizeof(*sta_inactivity_timer));
+			if (!sta_inactivity_timer) {
+				hdd_err("Failed to allocate Memory");
+				return QDF_STATUS_E_FAILURE;
+			}
+			sta_inactivity_timer->session_id = pAdapter->sessionId;
+			sta_inactivity_timer->sta_inactivity_timeout =
+				params->inactivity_timeout;
+			sme_update_sta_inactivity_timeout(WLAN_HDD_GET_HAL_CTX
+					(pAdapter), sta_inactivity_timer);
+		}
 	}
 
 	EXIT();

+ 11 - 0
core/mac/inc/sir_api.h

@@ -6617,4 +6617,15 @@ struct sme_long_retry_limit {
 	uint8_t session_id;
 	uint32_t long_retry_limit;
 };
+
+/**
+ * struct sme_sta_inactivity_timeout - set sta_inactivity_timeout
+ * @session_id: session Id.
+ * @sta_inactivity_timeout: Timeout to disconnect STA after there
+ * is no activity.
+ */
+struct sme_sta_inactivity_timeout {
+	uint8_t session_id;
+	uint32_t sta_inactivity_timeout;
+};
 #endif /* __SIR_API_H */

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

@@ -637,7 +637,6 @@ typedef struct sSirMbMsgP2p {
 #define SIR_HAL_ENCRYPT_DECRYPT_MSG         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 364)
 #define SIR_HAL_SHORT_RETRY_LIMIT_CNT       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 365)
 #define SIR_HAL_LONG_RETRY_LIMIT_CNT        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 366)
-
 #define SIR_HAL_UPDATE_TX_FAIL_CNT_TH       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 367)
 #define SIR_HAL_MSG_TYPES_END                (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 

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

@@ -1333,4 +1333,20 @@ QDF_STATUS sme_update_short_retry_limit_threshold(tHalHandle hal_handle,
 		struct sme_short_retry_limit *short_retry_limit_th);
 QDF_STATUS sme_update_long_retry_limit_threshold(tHalHandle hal_handle,
 		struct sme_long_retry_limit  *long_retry_limit_th);
+
+/**
+ * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW
+ * @hal: Handle returned by mac_open
+ * @sta_inactivity_timer:  struct for sta inactivity timer
+ *
+ * If a station does not send anything in sta_inactivity_timeout seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated.
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+*/
+QDF_STATUS sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
+		struct sme_sta_inactivity_timeout  *sta_inactivity_timer);
+
 #endif /* #if !defined( __SME_API_H ) */

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

@@ -12355,6 +12355,45 @@ QDF_STATUS sme_update_long_retry_limit_threshold(tHalHandle hal_handle,
 	return status;
 }
 
+/**
+ * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW
+ * @hal: Handle returned by mac_open
+ * @session_id: Session ID on which sta_inactivity_timeout needs
+ * to be updated to FW
+ * @sta_inactivity_timeout: sta inactivity timeout.
+ *
+ * If a station does not send anything in sta_inactivity_timeout seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated.
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure.
+*/
+QDF_STATUS sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
+		 struct sme_sta_inactivity_timeout  *sta_inactivity_timer)
+{
+	struct sme_sta_inactivity_timeout *inactivity_time;
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	inactivity_time = qdf_mem_malloc(sizeof(*inactivity_time));
+	if (NULL == inactivity_time) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: fail to alloc inactivity_time", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
+			FL("sta_inactivity_timeout: %d"),
+			sta_inactivity_timer->sta_inactivity_timeout);
+	inactivity_time->session_id = sta_inactivity_timer->session_id;
+	inactivity_time->sta_inactivity_timeout =
+		sta_inactivity_timer->sta_inactivity_timeout;
+
+	wma_update_sta_inactivity_timeout(wma_handle,
+				inactivity_time);
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * sme_get_reg_info() - To get registration info
  * @hHal: HAL context

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

@@ -183,7 +183,6 @@
 #define WMA_IPV6_PROTO_GET_MIN_LEN        21
 #define WMA_IPV6_PKT_INFO_GET_MIN_LEN     62
 #define WMA_ICMPV6_SUBTYPE_GET_MIN_LEN    55
-
 /**
  * ds_mode: distribution system mode
  * @IEEE80211_NO_DS: NO DS at either side
@@ -388,6 +387,7 @@ enum ds_mode {
 #define WMA_NEXT_20MHZ_START_CH_DIFF 4
 
 #define WMA_DEFAULT_HW_MODE_INDEX 0xFFFF
+#define TWO_THIRD (2/3)
 
 /**
  * WMA hardware mode list bit-mask definitions.
@@ -2335,3 +2335,5 @@ void wma_register_packetdump_callback(
 		tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb,
 		tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb);
 void wma_deregister_packetdump_callback(void);
+void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
+		struct sme_sta_inactivity_timeout  *sta_inactivity_timer);

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

@@ -475,7 +475,6 @@
 #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
 #define WMA_ENCRYPT_DECRYPT_MSG              SIR_HAL_ENCRYPT_DECRYPT_MSG
-
 /* Bit 6 will be used to control BD rate for Management frames */
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
 

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

@@ -6029,6 +6029,56 @@ static QDF_STATUS wma_update_long_retry_limit(tp_wma_handle wma,
 	return QDF_STATUS_SUCCESS;
 }
 
+/*
+ * wma_update_sta_inactivity_timeout() - Set sta_inactivity_timeout to fw
+ * @wma_handle: WMA handle
+ * @sta_inactivity_timer: sme_sta_inactivity_timeout
+ *
+ * This function is used to set sta_inactivity_timeout.
+ * If a station does not send anything in sta_inactivity_timeout seconds, an
+ * empty data frame is sent to it in order to verify whether it is
+ * still in range. If this frame is not ACKed, the station will be
+ * disassociated and then deauthenticated.
+ *
+ * Return: None
+ */
+void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
+		struct sme_sta_inactivity_timeout  *sta_inactivity_timer)
+{
+	uint8_t vdev_id;
+	uint32_t max_unresponsive_time;
+	uint32_t min_inactive_time, max_inactive_time;
+
+	if (!wma || !wma->wmi_handle) {
+		WMA_LOGE("WMA is closed, can not issue sta_inactivity_timeout");
+		return;
+	}
+	vdev_id = sta_inactivity_timer->session_id;
+	max_unresponsive_time = sta_inactivity_timer->sta_inactivity_timeout;
+	max_inactive_time = max_unresponsive_time * TWO_THIRD;
+	min_inactive_time = max_unresponsive_time - max_inactive_time;
+
+	if (wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+			min_inactive_time))
+		WMA_LOGE("Failed to Set AP MIN IDLE INACTIVE TIME");
+
+	if (wma_vdev_set_param(wma->wmi_handle, vdev_id,
+			WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+			max_inactive_time))
+		WMA_LOGE("Failed to Set AP MAX IDLE INACTIVE TIME");
+
+	if (wma_vdev_set_param(wma->wmi_handle, vdev_id,
+		WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+		max_unresponsive_time))
+		WMA_LOGE("Failed to Set MAX UNRESPONSIVE TIME");
+
+	WMA_LOGI("%s:vdev_id:%d min_inactive_time: %u max_inactive_time: %u max_unresponsive_time: %u",
+			__func__, vdev_id,
+			min_inactive_time, max_inactive_time,
+			max_unresponsive_time);
+}
+
 /**
  * wma_mc_process_msg() - process wma messages and call appropriate function.
  * @cds_context: cds context