diff --git a/include/wifi_base.h b/include/wifi_base.h index cf61e79d2..f8431bc47 100644 --- a/include/wifi_base.h +++ b/include/wifi_base.h @@ -79,6 +79,22 @@ extern "C" { #define WIFI_CSA_BEACON_FRAME_RECEIVED "Device.WiFi.CSABeaconFrameRecieved" #define WIFI_STUCK_DETECT_FILE_NAME "/nvram/wifi_stuck_detect" +#ifdef CONFIG_IEEE80211BE + +#ifndef MAX_NUM_MLD_LINKS +#define MAX_NUM_MLD_LINKS 15 +#endif /*MAX_NUM_MLD_LINKS*/ + +#define UNDEFINED_MLD_ID 255 + +#ifdef CONFIG_NO_MLD_ONLY_PRIVATE +#define MLD_UNIT_COUNT 8 +#else +#define MLD_UNIT_COUNT 1 +#endif /* CONFIG_NO_MLD_ONLY_PRIVATE */ + +#endif /* CONFIG_IEEE80211BE */ + #define PLAN_ID_LENGTH 38 #define MAX_STEP_COUNT 32 /*Active Measurement Step Count */ #define MAC_ADDRESS_LENGTH 13 diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index 5d31d3978..2ce8a375d 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -760,6 +760,165 @@ bool is_force_apply_true(rdk_wifi_vap_info_t *rdk_vap_info) { return false; } + +#ifdef CONFIG_IEEE80211BE +wifi_vap_info_t *get_vap_info_from_webconfig(webconfig_subdoc_decoded_data_t *data, char *vap_name) +{ + unsigned int j, k; + + for (j = 0; j < getNumberRadios(); j++) { + for (k = 0; k < getNumberVAPsPerRadio(j); k++) { + if (strcmp(data->radios[j].vaps.vap_map.vap_array[k].vap_name, vap_name) == 0) { + return &data->radios[j].vaps.vap_map.vap_array[k]; + } + } + } + return NULL; +} + +wifi_vap_info_t *get_vap_info_from_radio(char *vap_name) +{ + unsigned int j; + int tgt_radio_idx, tgt_vap_index; + rdk_wifi_radio_t *radio; + wifi_vap_info_t *mgr_vap_info = NULL; + wifi_vap_info_map_t *mgr_vap_map = NULL; + wifi_mgr_t *mgr = get_wifimgr_obj(); + + if ((tgt_radio_idx = convert_vap_name_to_radio_array_index(&mgr->hal_cap.wifi_prop, vap_name)) == -1) { + wifi_util_error_print(WIFI_MGR, "%s:%d: Could not find radio index for vap name:%s\n", + __func__, __LINE__, vap_name); + return NULL; + } + + tgt_vap_index = convert_vap_name_to_index(&mgr->hal_cap.wifi_prop, vap_name); + if (tgt_vap_index == -1) { + wifi_util_error_print(WIFI_MGR, "%s:%d: Could not find vap index for vap name:%s\n", + __func__, __LINE__, vap_name); + return NULL; + } + + for (j = 0; j < getNumberRadios(); j++) { + radio = &mgr->radio_config[j]; + if (radio->vaps.radio_index == (unsigned int)tgt_radio_idx) { + mgr_vap_map = &radio->vaps.vap_map; + break; + } + } + + if (mgr_vap_map == NULL) { + wifi_util_error_print(WIFI_MGR, + "%s:%d: Could not find tgt_radio_idx:%d for vap name:%s\n", __func__, __LINE__, + tgt_radio_idx, vap_name); + return NULL; + } + + for (j = 0; j < mgr_vap_map->num_vaps; j++) { + if (mgr_vap_map->vap_array[j].vap_index == (unsigned int)tgt_vap_index) { + mgr_vap_info = &mgr_vap_map->vap_array[j]; + break; + } + } + + return mgr_vap_info; +} + +static void update_mld_group(webconfig_subdoc_decoded_data_t *data, char **vap_names, unsigned int size) +{ + unsigned int i; + wifi_vap_info_t *mgr_vap_info, *vap_info; + wifi_mld_common_info_t *mld_conf; + mac_address_t zero_mac = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + mac_address_t mlo_mac = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + mac_addr_str_t mac_str = { 0 }; + unsigned char *mld_addr_map[MAX_NUM_RADIOS] = { 0 }; + unsigned char mld_id = UNDEFINED_MLD_ID; + wifi_mld_common_info_t *mld_map[MAX_NUM_RADIOS] = { 0 }; + unsigned int mld_vap_count = 0; + bool disable_mld = false; + + if (size > MAX_NUM_RADIOS) { + wifi_util_error_print(WIFI_MGR, "%s:%d: size %d exceeds MAX_NUM_RADIOS %d\n", + __func__, __LINE__, size, MAX_NUM_RADIOS); + return; + } + for (i = 0; i < size; i++) { + + vap_info = get_vap_info_from_webconfig(data, vap_names[i]); + if (vap_info == NULL) { + wifi_util_error_print(WIFI_MGR, "%s:%d: Could not find vap_info vap name:%s\n", + __func__, __LINE__, vap_names[i]); + return; + } + + if (isVapSTAMesh(vap_info->vap_index)) + continue; + + mgr_vap_info = get_vap_info_from_radio(vap_names[i]); + if (mgr_vap_info == NULL) { + wifi_util_error_print(WIFI_MGR, "%s:%d: Could not find mgr_vap_info vap name:%s\n", + __func__, __LINE__, vap_names[i]); + return; + } + + mld_conf = &vap_info->u.bss_info.mld_info.common_info; + + /* Initialize mld_mac with VAP's BSSID */ + memcpy(mld_conf->mld_addr, mgr_vap_info->u.bss_info.bssid, sizeof(mac_address_t)); + + if (mld_conf->mld_id < MLD_UNIT_COUNT && mld_conf->mld_link_id < MAX_NUM_MLD_LINKS) { + if (mld_id == UNDEFINED_MLD_ID) + mld_id = mld_conf->mld_id; + if (mld_id != mld_conf->mld_id) { + wifi_util_error_print(WIFI_MGR, "%s:%d: vap name:%s is not part of mld unit %d. VAP's mld_id %d\n", + __func__, __LINE__, vap_names[i], mld_id, mld_conf->mld_id); + continue; + } + if (mld_conf->mld_enable) { + mld_vap_count++; + mld_addr_map[i] = mld_conf->mld_addr; + mld_map[i] = mld_conf; + if (mld_conf->mld_link_id == 0) { + memcpy(mlo_mac, mgr_vap_info->u.bss_info.bssid, sizeof(mac_address_t)); + } + } else { + if (mld_conf->mld_link_id == 0) { + wifi_util_info_print(WIFI_MGR, "%s:%d: Main link is disabled -> Disable whole MLO group\n",__func__, __LINE__); + disable_mld = true; + } + } + } + } + if (mld_vap_count > 0) { + if (disable_mld || mld_vap_count < 2) { + /* Disable MLD when main link is disabled or less than 2 VAPs are mld enabled */ + for (i = 0; i < size; i++) { + if (mld_map[i] != NULL) { + mld_map[i]->mld_enable = false; + wifi_util_info_print(WIFI_MGR, + "%s:%d: Disabling mld for vap name:%s - disable_mld %d mld_vap_count %d\n", + __func__, __LINE__, vap_names[i], disable_mld, mld_vap_count); + } + } + return; + } + } + + if (memcmp(mlo_mac, zero_mac, sizeof(mac_address_t)) == 0) { + return; /* VAPs group does not contain MLO enabled VAPs */ + } + + to_mac_str(mlo_mac, mac_str); + for (i = 0; i < size; i++) { + if (mld_addr_map[i] != NULL) { + memcpy(mld_addr_map[i], mlo_mac, sizeof(mac_address_t)); + wifi_util_info_print(WIFI_MGR, "%s:%d: Updating mld_addr %s for vap name:%s\n", + __func__, __LINE__, mac_str, vap_names[i]); + } + } +} +#endif // CONFIG_IEEE80211BE + int webconfig_hal_vap_apply_by_name(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t *data, char **vap_names, unsigned int size) { unsigned int i, j, k; @@ -776,6 +935,9 @@ int webconfig_hal_vap_apply_by_name(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_ rdk_wifi_vap_info_t tgt_rdk_vap_info; int ret = 0; +#ifdef CONFIG_IEEE80211BE + update_mld_group(data, vap_names, size); +#endif for (i = 0; i < size; i++) { if ((svc = get_svc_by_name(ctrl, vap_names[i])) == NULL) { diff --git a/source/db/wifi_db_apis.c b/source/db/wifi_db_apis.c index 3fdcad939..cc6e07e90 100644 --- a/source/db/wifi_db_apis.c +++ b/source/db/wifi_db_apis.c @@ -92,12 +92,6 @@ #define ONEWIFI_DB_VERSION_WPA3_T_DISABLE_FLAG 100042 #define ONEWIFI_DB_VERSION_UPDATE_MLD_FLAG 100043 -#ifdef CONFIG_NO_MLD_ONLY_PRIVATE -#define MLD_UNIT_COUNT 8 -#else -#define MLD_UNIT_COUNT 1 -#endif /* CONFIG_NO_MLD_ONLY_PRIVATE */ - ovsdb_table_t table_Wifi_Radio_Config; ovsdb_table_t table_Wifi_VAP_Config; ovsdb_table_t table_Wifi_Security_Config; @@ -7632,7 +7626,7 @@ void wifidb_init_default_value() wifi_util_info_print(WIFI_DB,"%s:%d Wifi db update completed\n",__func__, __LINE__); } - +#ifdef CONFIG_IEEE80211BE static int get_ap_mac_by_vap_index(wifi_vap_info_map_t *hal_vap_info_map, int vap_index, mac_address_t mac) { unsigned int j = 0; @@ -7726,6 +7720,7 @@ static int wifidb_vap_config_update_mld_mac() hal_vap_info_map = NULL; return RETURN_OK; } +#endif /* CONFIG_IEEE80211BE */ /************************************************************************************ ************************************************************************************ @@ -7925,7 +7920,9 @@ void init_wifidb_data() pthread_mutex_unlock(&g_wifidb->data_cache_lock); return; } + #ifdef CONFIG_IEEE80211BE wifidb_vap_config_update_mld_mac(); + #endif pthread_mutex_unlock(&g_wifidb->data_cache_lock); } diff --git a/source/utils/wifi_util.c b/source/utils/wifi_util.c index 609bc80df..b49b3318d 100644 --- a/source/utils/wifi_util.c +++ b/source/utils/wifi_util.c @@ -3808,6 +3808,34 @@ static bool is_vap_preassoc_cac_config_changed(char *vap_name, } } +#ifdef CONFIG_IEEE80211BE +static bool is_mld_addr_changed(wifi_vap_info_t *vap_info_old, wifi_vap_info_t *vap_info_new) +{ + if ((vap_info_old == NULL) || (vap_info_new == NULL)) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: input args are NULL vap_info_old : %p vap_info_new : %p\n", __func__, __LINE__, + vap_info_old, vap_info_new); + return false; + } + if (vap_info_old->u.bss_info.mld_info.common_info.mld_enable || + vap_info_new->u.bss_info.mld_info.common_info.mld_enable) { + if (IS_BIN_CHANGED(&vap_info_old->u.bss_info.mld_info.common_info.mld_addr, + &vap_info_new->u.bss_info.mld_info.common_info.mld_addr, + sizeof(vap_info_old->u.bss_info.mld_info.common_info.mld_addr))) { + mac_addr_str_t old_mld_mac_str = { 0 }; + mac_addr_str_t new_mld_mac_str = { 0 }; + + to_mac_str(vap_info_old->u.bss_info.mld_info.common_info.mld_addr, old_mld_mac_str); + to_mac_str(vap_info_new->u.bss_info.mld_info.common_info.mld_addr, new_mld_mac_str); + wifi_util_info_print(WIFI_WEBCONFIG, "%s:%d: MLD address changed old: %s ,new: %s\n", + __func__, __LINE__, old_mld_mac_str, new_mld_mac_str); + return true; + } + } + return false; +} +#endif /* CONFIG_IEEE80211BE */ + bool is_vap_param_config_changed(wifi_vap_info_t *vap_info_old, wifi_vap_info_t *vap_info_new, rdk_wifi_vap_info_t *rdk_old, rdk_wifi_vap_info_t *rdk_new, bool isSta) { @@ -3913,6 +3941,9 @@ bool is_vap_param_config_changed(wifi_vap_info_t *vap_info_old, wifi_vap_info_t vap_info_new->u.bss_info.mld_info.common_info.mld_link_id) || IS_CHANGED(vap_info_old->u.bss_info.mld_info.common_info.mld_apply, vap_info_new->u.bss_info.mld_info.common_info.mld_apply) || +#ifdef CONFIG_IEEE80211BE + is_mld_addr_changed(vap_info_old, vap_info_new) || +#endif /* CONFIG_IEEE80211BE */ IS_CHANGED(vap_info_old->u.bss_info.hostap_mgt_frame_ctrl, vap_info_new->u.bss_info.hostap_mgt_frame_ctrl) || IS_CHANGED(vap_info_old->u.bss_info.mbo_enabled,