[rdk-b][mt7986][wifi-hal][Refactor getRadioMaxBitRate]

[Description]
Refactor getRadioMaxBitRate by get radio mode and TX chain mask.
For max bit rate, we should always choose the best MCS.

[Release-log]
N/A

Change-Id: I3d4facc54393a9513e7d913a1f304e0694401799
diff --git a/src/wifi/wifi_hal.c b/src/wifi/wifi_hal.c
index f004f80..dda881b 100644
--- a/src/wifi/wifi_hal.c
+++ b/src/wifi/wifi_hal.c
@@ -1089,34 +1089,115 @@
 //The output_string is a max length 64 octet string that is allocated by the RDKB code.  Implementations must ensure that strings are not longer than this.
 INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
 {
-    char cmd[1024] =  {0};
-    char buf[1024] = {0};
-    char HConf_file[MAX_BUF_SIZE] = {'\0'};
-    char interface_name[50] = {0};
+    // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
+    // For max bit rate, we should always choose the best MCS
+    char mode[64] = {0};
+    char channel_bandwidth_str[16] = {0};
+    char *tmp = NULL;
+    UINT mode_map = 0;
+    UINT num_subcarrier = 0;
+    UINT code_bits = 0;
+    float code_rate = 0;    // use max code rate
+    int NSS = 0;
+    UINT Symbol_duration = 0;
+    UINT GI_duration = 0; 
+    wifi_band band = band_invalid;
+    wifi_guard_interval_t gi = wifi_guard_interval_auto;
+    BOOL enable = FALSE;
+    float bit_rate = 0;
 
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
     if (NULL == output_string)
         return RETURN_ERR;
 
-    sprintf(HConf_file,"%s%d%s","/nvram/hostapd",radioIndex,".conf");
-    GetInterfaceName(interface_name,HConf_file);
+    wifi_getRadioEnable(radioIndex, &enable);
+    if (enable == FALSE) {
+        snprintf(output_string, 64, "0 Mb/s");
+        return RETURN_OK;
+    }
+
+    if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
+        fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
+        return RETURN_ERR;
+    }
+
+    if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
+        fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
+        return RETURN_ERR;
+    }
+
+    if (gi == wifi_guard_interval_3200)
+        GI_duration = 32;
+    else if (gi == wifi_guard_interval_1600)
+        GI_duration = 16;
+    else if (gi == wifi_guard_interval_800)
+        GI_duration = 8;
+    else    // auto, 400
+        GI_duration = 4;
 
-    sprintf(cmd, "iwconfig %s | grep 'Bit Rate' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1,2", interface_name);
-    _syscmd(cmd, buf, sizeof(buf));
+    if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
+        fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
+        return RETURN_ERR;
+    }
+
+    if (strstr(channel_bandwidth_str, "80+80") != NULL)
+        strcpy(channel_bandwidth_str, "160");
+
+    if (mode_map & WIFI_MODE_AX) {
+        if (strstr(channel_bandwidth_str, "160") != NULL)
+            num_subcarrier = 1960;
+        else if (strstr(channel_bandwidth_str, "80") != NULL)
+            num_subcarrier = 980;
+        else if (strstr(channel_bandwidth_str, "40") != NULL)
+            num_subcarrier = 468;
+        else if (strstr(channel_bandwidth_str, "20") != NULL)
+            num_subcarrier = 234;
+        code_bits = 10;
+        code_rate = (float)5/6;
+        Symbol_duration = 128;
+    } else if (mode_map & WIFI_MODE_AC) {
+        if (strstr(channel_bandwidth_str, "160") != NULL)
+            num_subcarrier = 468;
+        else if (strstr(channel_bandwidth_str, "80") != NULL)
+            num_subcarrier = 234;
+        else if (strstr(channel_bandwidth_str, "40") != NULL)
+            num_subcarrier = 108;
+        else if (strstr(channel_bandwidth_str, "20") != NULL)
+            num_subcarrier = 52;
+        code_bits = 8;
+        code_rate = (float)5/6;
+        Symbol_duration = 32;
+    } else if (mode_map & WIFI_MODE_N) {
+        if (strstr(channel_bandwidth_str, "160") != NULL)
+            num_subcarrier = 468;
+        else if (strstr(channel_bandwidth_str, "80") != NULL)
+            num_subcarrier = 234;
+        else if (strstr(channel_bandwidth_str, "40") != NULL)
+            num_subcarrier = 108;
+        else if (strstr(channel_bandwidth_str, "20") != NULL)
+            num_subcarrier = 52;
+        code_bits = 6;
+        code_rate = (float)3/4;
+        Symbol_duration = 32;
+    } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
+        // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
+        snprintf(output_string, 64, "65 Mb/s");
+        return RETURN_OK;
+    } else {
+        snprintf(output_string, 64, "0 Mb/s");
+        return RETURN_OK;
+    }
 
-    if(strlen(buf) > 0)
-        snprintf(output_string, 64, "%s", buf);
-    else
-    {
-        wifi_getRadioOperatingChannelBandwidth(radioIndex,buf);
-        if((strcmp(buf,"20MHz") == 0) && (radioIndex == 0))
-            strcpy(output_string,"144 Mb/s");
-        else if((strcmp(buf,"20MHz") == 0) && (radioIndex == 1))
-            strcpy(output_string,"54 Mb/s");
-        else if((strcmp(buf,"40MHz") == 0) && (radioIndex == 1))
-            strcpy(output_string,"300 Mb/s");
-        //TODO: CHECK VALID VALUE
+    // Spatial streams
+    if (wifi_getRadioTxChainMask(radioIndex, &NSS) != RETURN_OK) {
+        fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
+        return RETURN_ERR;
     }
+
+    // multiple 10 is to align duration unit (0.1 us)
+    bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
+    snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
+
     WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
 
     return RETURN_OK;