Browse Source

qcacld-3.0: Add support for WDS repeater mode

Enable 4address frame format for the packets to the AP.
Enable MEC check for the sta dp vdev.

A new ini is added to enable WDS feature specifying the
desired WDS mode.

CRs-Fixed: 2889438
Change-Id: I99ccb91adf283a1ed863902ec4b31f1c3e821d32
Subrat Dash 4 years ago
parent
commit
d7794ba3b5

+ 21 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -362,6 +362,26 @@ mlme_init_lpass_support_cfg(struct wlan_objmgr_psoc *psoc,
 }
 #endif
 
+#ifdef FEATURE_WDS
+/**
+ * mlme_init_wds_config_cfg() - initialize wds_mode flag
+ * @psoc: Pointer to PSOC
+ * @gen: pointer to generic CFG items
+ *
+ * Return: None
+ */
+static void mlme_init_wds_config_cfg(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_mlme_generic *gen)
+{
+	gen->wds_mode = cfg_get(psoc, CFG_WDS_MODE);
+}
+#else
+static void mlme_init_wds_config_cfg(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_mlme_generic *gen)
+{
+}
+#endif
+
 static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
 				  struct wlan_mlme_generic *gen)
 {
@@ -425,6 +445,7 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
 		cfg_get(psoc, CFG_SAE_CONNECION_RETRIES);
 	gen->monitor_mode_concurrency =
 		cfg_get(psoc, CFG_MONITOR_MODE_CONCURRENCY);
+	mlme_init_wds_config_cfg(psoc, gen);
 }
 
 static void mlme_init_edca_ani_cfg(struct wlan_mlme_edca_params *edca_params)

+ 52 - 1
components/mlme/dispatcher/inc/cfg_mlme_generic.h

@@ -37,6 +37,22 @@ enum monitor_mode_concurrency {
 	MONITOR_MODE_CONC_AFTER_LAST,
 	MONITOR_MODE_CONC_MAX = MONITOR_MODE_CONC_AFTER_LAST - 1,
 };
+
+/**
+ * enum wds_mode_type: wds mode
+ * @WLAN_WDS_MODE_DISABLED: WDS is disabled
+ * @WLAN_WDS_MODE_REPEATER: WDS repeater mode
+ *
+ * This is used for 'type' values in wds_mode
+ */
+enum wlan_wds_mode {
+	WLAN_WDS_MODE_DISABLED  =  0,
+	WLAN_WDS_MODE_REPEATER  =  1,
+	/* keep this last */
+	WLAN_WDS_MODE_LAST,
+	WLAN_WDS_MODE_MAX = WLAN_WDS_MODE_LAST - 1,
+};
+
 /*
  * pmfSaQueryMaxRetries - Control PMF SA query retries for SAP
  * @Min: 0
@@ -822,6 +838,40 @@ enum monitor_mode_concurrency {
 	CFG_VALUE_OR_DEFAULT, \
 	"Monitor mode concurrency supported")
 
+#ifdef FEATURE_WDS
+/*
+ * <ini>
+ *
+ * wds_mode - wds mode supported
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Related: None
+ *
+ * wds mode supported
+ * 0 - wds mode disabled
+ * 1 - wds repeater mode
+ *
+ * Supported Feature: General
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_WDS_MODE CFG_INI_UINT( \
+	"wds_mode", \
+	WLAN_WDS_MODE_DISABLED, \
+	WLAN_WDS_MODE_MAX, \
+	WLAN_WDS_MODE_DISABLED, \
+	CFG_VALUE_OR_DEFAULT, \
+	"wds mode supported")
+
+#define CFG_WDS_MODE_ALL CFG(CFG_WDS_MODE)
+#else
+#define CFG_WDS_MODE_ALL
+#endif
+
 #define CFG_GENERIC_ALL \
 	CFG(CFG_ENABLE_DEBUG_PACKET_LOG) \
 	CFG(CFG_PMF_SA_QUERY_MAX_RETRIES) \
@@ -855,5 +905,6 @@ enum monitor_mode_concurrency {
 	CFG(CFG_DFS_CHAN_AGEOUT_TIME) \
 	CFG(CFG_SAE_CONNECION_RETRIES) \
 	CFG(CFG_WLS_6GHZ_CAPABLE) \
-	CFG(CFG_MONITOR_MODE_CONCURRENCY)
+	CFG(CFG_MONITOR_MODE_CONCURRENCY) \
+	CFG_WDS_MODE_ALL
 #endif /* __CFG_MLME_GENERIC_H */

+ 17 - 0
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -3050,6 +3050,23 @@ QDF_STATUS mlme_set_ext_opr_rate(struct wlan_objmgr_vdev *vdev, uint8_t *src,
  */
 bool wlan_mlme_is_sta_mon_conc_supported(struct wlan_objmgr_psoc *psoc);
 
+#ifdef FEATURE_WDS
+/**
+ * wlan_mlme_get_wds_mode() - Check wds mode supported
+ * @psoc: pointer to psoc object
+ *
+ * Return: supprted wds mode
+ */
+enum wlan_wds_mode
+wlan_mlme_get_wds_mode(struct wlan_objmgr_psoc *psoc);
+#else
+static inline enum wlan_wds_mode
+wlan_mlme_get_wds_mode(struct wlan_objmgr_psoc *psoc)
+{
+	return WLAN_WDS_MODE_DISABLED;
+}
+#endif
+
 #ifdef WLAN_SUPPORT_TWT
 /**
  * mlme_is_twt_enabled() - Get if TWT is enabled via ini.

+ 2 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -1306,6 +1306,7 @@ struct wlan_mlme_ratemask {
  * @wls_6ghz_capable: wifi location service(WLS) is 6ghz capable
  * @monitor_mode_concurrency: Monitor mode concurrency supported
  * @ocv_support: FW supports OCV or not
+ * @wds_mode: wds mode supported
  */
 struct wlan_mlme_generic {
 	uint32_t band_capability;
@@ -1349,6 +1350,7 @@ struct wlan_mlme_generic {
 	bool wls_6ghz_capable;
 	enum monitor_mode_concurrency monitor_mode_concurrency;
 	bool ocv_support;
+	enum wlan_wds_mode wds_mode;
 };
 
 /*

+ 14 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -4676,6 +4676,20 @@ wlan_mlme_get_monitor_mode_concurrency(struct wlan_objmgr_psoc *psoc)
 	return mlme_obj->cfg.gen.monitor_mode_concurrency;
 }
 
+#ifdef FEATURE_WDS
+enum wlan_wds_mode
+wlan_mlme_get_wds_mode(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj)
+		return cfg_default(CFG_WDS_MODE);
+
+	return mlme_obj->cfg.gen.wds_mode;
+}
+#endif
+
 bool wlan_mlme_is_sta_mon_conc_supported(struct wlan_objmgr_psoc *psoc)
 {
 	if (wlan_mlme_get_monitor_mode_concurrency(psoc) ==

+ 40 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -1943,6 +1943,41 @@ void hdd_set_unpause_queue(void *soc, struct hdd_adapter *adapter)
 { }
 #endif
 
+#ifdef FEATURE_WDS
+/**
+ * hdd_config_wds_repeater_mode() - configures vdev for wds repeater mode
+ * @adapter: pointer to adapter
+ * @peer_addr: peer mac address
+ *
+ * Configure dp vdev to detect and drop multicast echo packets and enable
+ * 4 address frame format in fw.
+ *
+ * Return: None
+ */
+static void
+hdd_config_wds_repeater_mode(struct hdd_adapter *adapter, uint8_t *peer_addr)
+{
+	cdp_config_param_type vdev_param;
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	vdev_param.cdp_vdev_param_mec = true;
+	if (cdp_txrx_set_vdev_param(soc, adapter->vdev_id, CDP_ENABLE_MEC,
+				    vdev_param))
+		hdd_debug("Failed to set MEC param on DP vdev");
+
+	hdd_nofl_info("Turn on 4 address for peer: " QDF_MAC_ADDR_FMT,
+		      QDF_MAC_ADDR_REF(peer_addr));
+	if (sme_set_peer_param(peer_addr, WMI_HOST_PEER_USE_4ADDR, true,
+			       adapter->vdev_id))
+		hdd_err("Failed to enable WDS on vdev");
+}
+#else
+static inline void
+hdd_config_wds_repeater_mode(struct hdd_adapter *adapter, uint8_t *peer_addr)
+{
+}
+#endif
+
 QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
 				 uint8_t *peer_mac,
 				 enum ol_txrx_peer_state sta_state)
@@ -1982,6 +2017,11 @@ QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
 		    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
 			hdd_set_unpause_queue(soc, adapter);
 		}
+
+		if (adapter->device_mode == QDF_STA_MODE &&
+		    (wlan_mlme_get_wds_mode(hdd_ctx->psoc) ==
+		    WLAN_WDS_MODE_REPEATER))
+			hdd_config_wds_repeater_mode(adapter, peer_mac);
 	}
 	return QDF_STATUS_SUCCESS;
 }