diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 7cb473e94f..51b70ba861 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/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) diff --git a/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/components/mlme/dispatcher/inc/cfg_mlme_generic.h index 4ed0d93904..6d8a660c4c 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_generic.h +++ b/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 +/* + * + * + * 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 + * + * + */ +#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 */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 2f68b51b91..6e4f8a24a3 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/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. diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index b1cb32edeb..753c12b6ee 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/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; }; /* diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index cdbcb6667b..7238b140c1 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/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) == diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index db312f5bb6..f3aa6b84b1 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/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; }