Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions include/webconfig_external_proto_easymesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ typedef void (*ext_proto_update_ap_mld_info_t)(void *data_model, em_ap_mld_info_
typedef void (*ext_proto_update_bsta_mld_info_t)(void *data_model, em_bsta_mld_info_t *bsta_mld_info);
typedef void (*ext_proto_update_assoc_sta_mld_info_t)(void *data_model, em_assoc_sta_mld_info_t *assoc_sta_mld_info);
typedef em_ap_mld_info_t * (*ext_proto_get_ap_mld_frm_bssid_t)(void *data_model, mac_address_t bss_id);
typedef void * (*ext_proto_get_radio_cap_t)(void *data_model, mac_address_t ruid);

typedef struct {
void *data_model; /* agent data model dm_easy_mesh_t */
Expand Down Expand Up @@ -75,7 +76,8 @@ typedef struct {
ext_proto_update_ap_mld_info_t update_ap_mld_info;
ext_proto_update_bsta_mld_info_t update_bsta_mld_info;
ext_proto_update_assoc_sta_mld_info_t update_assoc_sta_mld_info;
ext_proto_get_ap_mld_frm_bssid_t get_ap_mld_frm_bssid;
ext_proto_get_ap_mld_frm_bssid_t get_ap_mld_frm_bssid;
ext_proto_get_radio_cap_t get_radio_cap;
} webconfig_external_easymesh_t;

void webconfig_proto_easymesh_init(webconfig_external_easymesh_t *proto, void *data_model, void *m2ctrl_vapconfig, void *policy_config,
Expand All @@ -89,7 +91,7 @@ void webconfig_proto_easymesh_init(webconfig_external_easymesh_t *proto, void *d
ext_proto_get_sta_info_t get_sta, ext_proto_put_sta_info_t put_sta, ext_proto_em_get_bss_info_with_mac_t get_bss_info_with_mac,
ext_proto_put_scan_results_t put_scan_results, ext_proto_update_ap_mld_info_t update_ap_mld_info,
ext_proto_update_bsta_mld_info_t update_bsta_mld_info, ext_proto_update_assoc_sta_mld_info_t update_assoc_sta_mld_info,
ext_proto_get_ap_mld_frm_bssid_t get_ap_mld_frm_bssid);
ext_proto_get_ap_mld_frm_bssid_t get_ap_mld_frm_bssid, ext_proto_get_radio_cap_t get_radio_cap);

#ifdef __cplusplus
}
Expand Down
26 changes: 26 additions & 0 deletions include/wifi_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -842,12 +842,38 @@ typedef struct {
int ap_reason_counts[9];
} interop_data_t;

typedef struct {
/* WiFi6 (HE) capabilities */
BOOL wifi6_supported; /**< Whether WiFi6 (HE) is supported */
UCHAR phy_cap[11]; /**< HE PHY capabilities (HE_MAX_PHY_CAPAB_SIZE = 11) */
UCHAR mac_cap[4]; /**< HE MAC capabilities (HE_MAX_MAC_CAPAB_SIZE = 4) */
UCHAR mcs_nss_set[6]; /**< HE MCS NSS set (HE_MAX_MCS_CAPAB_SIZE = 6) */
UCHAR ppet[7]; /**< HE PPE thresholds (HE_MAX_PPET_CAPAB_SIZE = 7) */
//USHORT 6ghz_capa; /**< HE 6GHz capabilities */
} he_radio_capability_t;

typedef struct {
/* WiFi7 (EHT) capabilities */
BOOL wifi7_supported; /**< Whether WiFi7 (EHT) is supported */
UCHAR mac_cap[4]; /**< EHT MAC capabilities */
UCHAR phy_cap[9]; /**< EHT PHY capabilities (EHT_PHY_CAPAB_LEN = 9) */
UCHAR mcs[3]; /**< EHT MCS set */
UCHAR ppet[16]; /**< EHT PPE thresholds */
} eht_radio_capability_t;

/* This structure is populated from HAL and translated to easymesh */
typedef struct {
he_radio_capability_t he_cap;
eht_radio_capability_t eht_cap;
} __attribute__((packed)) rdk_wifi_radio_capability_t;

typedef struct {
char name[16];
wifi_radio_operationParam_t oper;
rdk_wifi_vap_map_t vaps;
wifi_radio_feature_param_t feature;
radarInfo_t radarInfo;
rdk_wifi_radio_capability_t radio_capability; /**< WiFi6/WiFi7 capabilities for AP mode */
// schema_wifi_radio_state_t radio_state;
} rdk_wifi_radio_t;

Expand Down
70 changes: 70 additions & 0 deletions source/core/wifi_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,47 @@ int init_wifi_hal()
wifi_util_error_print(WIFI_CTRL,"RDK_LOG_ERROR, %s wifi_getHalCapability returned with error %d\n", __FUNCTION__, ret);
return RETURN_ERR;
}

wifi_util_info_print(WIFI_CTRL,"%s:%d: Calling wifi_hal_print_all_he_eht_capabilities\n", __func__, __LINE__);
//wifi_hal_print_all_he_eht_capabilities();
wifi_util_info_print(WIFI_CTRL,"%s:%d: after wifi_hal_print_all_he_eht_capabilities\n", __func__, __LINE__);

return RETURN_OK;
}

void dump_hw_caps(rdk_wifi_radio_t *radios_cfg)
{
wifi_util_info_print(WIFI_CTRL,"%s:%d:Inside\n", __func__, __LINE__);
if (radios_cfg->radio_capability.he_cap.wifi6_supported) {
wifi_util_info_print(WIFI_CTRL,"%s:%d: HE Supported: YES\n", __func__, __LINE__);
wifi_util_info_print(WIFI_CTRL,"%s:%d: HE PHY Cap: ", __func__, __LINE__);
wifi_util_info_print(WIFI_CTRL,"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
radios_cfg->radio_capability.he_cap.phy_cap[0], radios_cfg->radio_capability.he_cap.phy_cap[1],
radios_cfg->radio_capability.he_cap.phy_cap[2], radios_cfg->radio_capability.he_cap.phy_cap[3],
radios_cfg->radio_capability.he_cap.phy_cap[4], radios_cfg->radio_capability.he_cap.phy_cap[5],
radios_cfg->radio_capability.he_cap.phy_cap[6], radios_cfg->radio_capability.he_cap.phy_cap[7],
radios_cfg->radio_capability.he_cap.phy_cap[8], radios_cfg->radio_capability.he_cap.phy_cap[9],
radios_cfg->radio_capability.he_cap.phy_cap[10]);
wifi_util_info_print(WIFI_CTRL,"\n");
//wifi_util_info_print(WIFI_CTRL,"%s:%d: HE MAC Cap: ", __func__, __LINE__);
//wifi_util_info_print(WIFI_CTRL,"%02x:%02x:%02x:%02x",
// radios_cfg->radio_capability.he_cap.mac_cap[0], radios_cfg->radio_capability.he_cap.mac_cap[1],
// radios_cfg->radio_capability.he_cap.mac_cap[2], radios_cfg->radio_capability.he_cap.mac_cap[3]);
//wifi_util_info_print(WIFI_CTRL,"\n");
//wifi_util_info_print(WIFI_CTRL,"%s:%d: HE MCS: ", __func__, __LINE__);
//wifi_util_info_print(WIFI_CTRL,"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x: \
// %02x:%02x:", radios_cfg->radio_capability.he_cap.mcs[0], radios_cfg->radio_capability.he_cap.mcs[1],
// radios_cfg->radio_capability.he_cap.mcs[2], radios_cfg->radio_capability.he_cap.mcs[3],
// radios_cfg->radio_capability.he_cap.mcs[4], radios_cfg->radio_capability.he_cap.mcs[5],
// radios_cfg->radio_capability.he_cap.mcs[6], radios_cfg->radio_capability.he_cap.mcs[7],
// radios_cfg->radio_capability.he_cap.mcs[8], radios_cfg->radio_capability.he_cap.mcs[9],
// radios_cfg->radio_capability.he_cap.mcs[10], radios_cfg->radio_capability.he_cap.mcs[11]);
//wifi_util_info_print(WIFI_CTRL,"\n");
} else {
wifi_util_info_print(WIFI_CTRL,"%s:%d: HE Supported: NO\n", __func__, __LINE__);
}
}

int init_global_radio_config(rdk_wifi_radio_t *radios_cfg, UINT radio_index)
{
UINT vap_array_index = 0;
Expand Down Expand Up @@ -174,6 +212,38 @@ int init_global_radio_config(rdk_wifi_radio_t *radios_cfg, UINT radio_index)
radios_cfg->vaps.radio_index = radio_index;
radios_cfg->vaps.num_vaps = vap_array_index;
radios_cfg->vaps.vap_map.num_vaps = vap_array_index;

/* Populate radio capabilities from HAL */
wifi_freq_bands_t band;
if (convert_radio_index_to_freq_band(&wifi_hal_cap_obj->wifi_prop, radio_index, &band) == RETURN_OK) {
wifi_radio_capability_data_t *hal_cap_data = (wifi_radio_capability_data_t *)malloc(sizeof(wifi_radio_capability_data_t));
memset(&hal_cap_data, 0, sizeof(hal_cap_data));

if (wifi_getRadioCapabilityData(radio_index, band, hal_cap_data) == RETURN_OK) {
/* Copy from HAL structure to OneWifi structure */
radios_cfg->radio_capability.he_cap.wifi6_supported = hal_cap_data->wifi6_supported;
memcpy(radios_cfg->radio_capability.he_cap.phy_cap, hal_cap_data->he_phy_cap, sizeof(hal_cap_data->he_phy_cap));
memcpy(radios_cfg->radio_capability.he_cap.mac_cap, hal_cap_data->he_mac_cap, sizeof(hal_cap_data->he_mac_cap));
memcpy(radios_cfg->radio_capability.he_cap.mcs_nss_set, hal_cap_data->he_mcs_nss_set, sizeof(hal_cap_data->he_mcs_nss_set));
memcpy(radios_cfg->radio_capability.he_cap.ppet, hal_cap_data->he_ppet, sizeof(hal_cap_data->he_ppet));

radios_cfg->radio_capability.eht_cap.wifi7_supported = hal_cap_data->wifi7_supported;
memcpy(radios_cfg->radio_capability.eht_cap.mac_cap, hal_cap_data->eht_mac_cap, sizeof(hal_cap_data->eht_mac_cap));
memcpy(radios_cfg->radio_capability.eht_cap.phy_cap, hal_cap_data->eht_phy_cap, sizeof(hal_cap_data->eht_phy_cap));
memcpy(radios_cfg->radio_capability.eht_cap.mcs, hal_cap_data->eht_mcs, sizeof(hal_cap_data->eht_mcs));
memcpy(radios_cfg->radio_capability.eht_cap.ppet, hal_cap_data->eht_ppet, sizeof(hal_cap_data->eht_ppet));
} else {
wifi_util_dbg_print(WIFI_CTRL, "%s:%d: Failed to get radio capability data for radio %d\n",
__func__, __LINE__, radio_index);
}
} else {
wifi_util_dbg_print(WIFI_CTRL, "%s:%d: Failed to convert radio index %d to band\n",
__func__, __LINE__, radio_index);
}

wifi_util_dbg_print(WIFI_CTRL, "%s:%d:Calling dump_hw_caps\n", __func__, __LINE__);
dump_hw_caps(radios_cfg);

return RETURN_OK;
}

Expand Down
164 changes: 164 additions & 0 deletions source/webconfig/wifi_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -2904,6 +2904,160 @@ webconfig_error_t decode_radio_curr_operating_classes(const cJSON *obj_radio_set
return webconfig_error_none;
}

/* Decode radio capabilities (WiFi6/WiFi7) from JSON */
webconfig_error_t decode_radio_capability(const cJSON *cap_obj, rdk_wifi_radio_capability_t *radio_cap)
{
#if 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this #if 0? How have you tested this functionality?

const cJSON *param;
cJSON *array_item;
int i, array_size;

if (cap_obj == NULL || radio_cap == NULL) {
wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d NULL pointer\n", __func__, __LINE__);
return webconfig_error_decode;
}

memset(radio_cap, 0, sizeof(rdk_wifi_radio_capability_t));

/* WiFi6 (HE) capabilities */
#ifdef CONFIG_IEEE80211AX
decode_param_bool(cap_obj, "WiFi6Supported", param);
if (param != NULL) {
radio_cap->wifi6_supported = (param->type & cJSON_True) ? true : false;
}

param = cJSON_GetObjectItem(cap_obj, "HEPHYCap");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->he_phy_cap)) {
array_size = sizeof(radio_cap->he_phy_cap);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->he_phy_cap[i] = (UCHAR)array_item->valuedouble;
}
}
}

param = cJSON_GetObjectItem(cap_obj, "HEMACCap");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->he_mac_cap)) {
array_size = sizeof(radio_cap->he_mac_cap);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->he_mac_cap[i] = (UCHAR)array_item->valuedouble;
}
}
}

param = cJSON_GetObjectItem(cap_obj, "HEMCSNSSSet");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->he_mcs_nss_set)) {
array_size = sizeof(radio_cap->he_mcs_nss_set);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->he_mcs_nss_set[i] = (UCHAR)array_item->valuedouble;
}
}
}

param = cJSON_GetObjectItem(cap_obj, "HEPPET");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->he_ppet)) {
array_size = sizeof(radio_cap->he_ppet);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->he_ppet[i] = (UCHAR)array_item->valuedouble;
}
}
}

decode_param_integer(cap_obj, "HE6GHzCapa", param);
if (param != NULL && cJSON_IsNumber(param)) {
radio_cap->he_6ghz_capa = (USHORT)param->valuedouble;
}
#endif /* CONFIG_IEEE80211AX */

/* WiFi7 (EHT) capabilities */
#ifdef CONFIG_IEEE80211BE
#if HOSTAPD_VERSION >= 211
decode_param_bool(cap_obj, "WiFi7Supported", param);
if (param != NULL) {
radio_cap->wifi7_supported = (param->type & cJSON_True) ? true : false;
}

param = cJSON_GetObjectItem(cap_obj, "EHTMACCap");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->eht_mac_cap)) {
array_size = sizeof(radio_cap->eht_mac_cap);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->eht_mac_cap[i] = (UCHAR)array_item->valuedouble;
}
}
}

param = cJSON_GetObjectItem(cap_obj, "EHTPHYCap");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->eht_phy_cap)) {
array_size = sizeof(radio_cap->eht_phy_cap);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->eht_phy_cap[i] = (UCHAR)array_item->valuedouble;
}
}
}

param = cJSON_GetObjectItem(cap_obj, "EHTMCS");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->eht_mcs)) {
array_size = sizeof(radio_cap->eht_mcs);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->eht_mcs[i] = (UCHAR)array_item->valuedouble;
}
}
}

param = cJSON_GetObjectItem(cap_obj, "EHTPPET");
if (param != NULL && cJSON_IsArray(param)) {
array_size = cJSON_GetArraySize(param);
if (array_size > sizeof(radio_cap->eht_ppet)) {
array_size = sizeof(radio_cap->eht_ppet);
}
for (i = 0; i < array_size; i++) {
array_item = cJSON_GetArrayItem(param, i);
if (cJSON_IsNumber(array_item)) {
radio_cap->eht_ppet[i] = (UCHAR)array_item->valuedouble;
}
}
}
#endif /* HOSTAPD_VERSION >= 211 */
#endif /* CONFIG_IEEE80211BE */
#endif

return webconfig_error_none;
}

webconfig_error_t decode_radio_object(const cJSON *obj_radio, rdk_wifi_radio_t *radio)
{
const cJSON *param;
Expand Down Expand Up @@ -3249,6 +3403,16 @@ webconfig_error_t decode_radio_object(const cJSON *obj_radio, rdk_wifi_radio_t *
wifi_util_error_print(WIFI_WEBCONFIG,
"%s:%d Radio current operation class decoding failed\n", __func__, __LINE__);
}

// Radio Capabilities (WiFi6/WiFi7)
decode_param_object(obj_radio, "RadioCapability", param);
if (param != NULL) {
if (decode_radio_capability(param, &radio->radio_capability) != webconfig_error_none) {
wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d Radio capability decode failed\n", __func__, __LINE__);
return webconfig_error_decode;
}
}

return webconfig_error_none;
}

Expand Down
Loading
Loading