[WCNCR00151635] misc: Add iwpriv command to get Tx rate from rate table
[Description]
Add iwpriv command 'driver get_curr_ar_rate', which will return current
Tx rate being used in the AR rate table.
Command example:
iwpriv wlan0 driver get_curr_ar_rate
Output example:
VHT-2SS-BW80-SGI-MCS11
Feature: misc
Change-Id: I1937aa0e036b75219f2720d2647f71d20f395da7
Signed-off-by: Sarick Jiang <sarick.jiang@mediatek.com>
CR-Id: WCNCR00151635
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index 6f64742..b4eed66 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -2299,6 +2299,7 @@
#define CMD_DEL_ACL_ENTRY "DEL_ACL_ENTRY"
#define CMD_SHOW_ACL_ENTRY "SHOW_ACL_ENTRY"
#define CMD_CLEAR_ACL_ENTRY "CLEAR_ACL_ENTRY"
+#define CMD_GET_CURR_AR_RATE "GET_CURR_AR_RATE"
#if CFG_WOW_SUPPORT
#define CMD_WOW_START "WOW_START"
@@ -2847,8 +2848,25 @@
static char *HW_TX_RATE_CCK_STR[] = {"1M", "2M", "5.5M", "11M", "N/A"};
static char *HW_TX_RATE_OFDM_STR[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M", "N/A"};
static char *HW_TX_RATE_BW[] = {"BW20", "BW40", "BW80", "BW160/BW8080", "N/A"};
+enum {
+ RATE_TBL_B = 0,
+ RATE_TBL_G,
+ RATE_TBL_N,
+ RATE_TBL_N_2SS,
+ RATE_TBL_AC,
+ RATE_TBL_AC_2SS,
+ RATE_TBL_MAX
+};
-static char *RATE_TBLE[] = {"B", "G", "N", "N_2SS", "AC", "AC_2SS", "N/A"};
+static char *RATE_TBLE[] = {
+ [RATE_TBL_B] = "B",
+ [RATE_TBL_G] = "G",
+ [RATE_TBL_N] = "N",
+ [RATE_TBL_N_2SS] = "N_2SS",
+ [RATE_TBL_AC] = "AC",
+ [RATE_TBL_AC_2SS] = "AC_2SS",
+ [RATE_TBL_MAX] = "N/A"
+};
#if 0
static char *AR_STATE[] = {"NULL", "STEADY", "PROBE", "N/A"};
static char *AR_ACTION[] = {"NULL", "INDEX", "RATE_UP", "RATE_DOWN", "RATE_GRP", "RATE_BACK",
@@ -4240,8 +4258,8 @@
if (!prQueryStaStatistics->ucSkipAr) {
i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
- "%-20s%s%s\n", "RateTable", " = ", prQueryStaStatistics->ucArTableIdx < 6 ?
- RATE_TBLE[prQueryStaStatistics->ucArTableIdx] : RATE_TBLE[6]);
+ "%-20s%s%s\n", "RateTable", " = ", prQueryStaStatistics->ucArTableIdx < RATE_TBL_MAX ?
+ RATE_TBLE[prQueryStaStatistics->ucArTableIdx] : RATE_TBLE[RATE_TBL_MAX]);
if (wlanGetStaIdxByWlanIdx(prAdapter, (UINT_8)(prHwWlanInfo->u4Index), &ucStaIdx) ==
WLAN_STATUS_SUCCESS){
@@ -5182,6 +5200,168 @@
}
/*----------------------------------------------------------------------------*/
+/*!
+* \brief Handle command to get current Tx rate from rate table and respond
+* string buffer. Example: VHT-2SS-BW80-SGI-MCS7
+*
+* \param[in] net_device Pointer to the Adapter structure.
+* \param[out] pcCommand Pointer to the command buffer to respond.
+* \param[in] i4TotalLen The length of buffer.
+*
+* \retval Length of response buffer
+*/
+/*----------------------------------------------------------------------------*/
+static int priv_driver_get_sta_curr_ar_rate(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+ P_GLUE_INFO_T prGlueInfo = NULL;
+ P_ADAPTER_T prAdapter = NULL;
+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+ UINT_32 u4BufLen = 0;
+ INT_32 i4BytesWritten = 0;
+ UINT_8 ucWlanIndex = 0;
+ PUINT_8 pucMacAddr = NULL;
+ UINT_8 idx, txmode, rate;
+ P_PARAM_GET_STA_STATISTICS prQueryStaStatistics = NULL;
+ P_PARAM_HW_WLAN_INFO_T prHwWlanInfo = NULL;
+
+ ASSERT(prNetDev);
+ if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE)
+ return -EINVAL;
+
+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+ prAdapter = prGlueInfo->prAdapter;
+
+ /* Get AIS AP address for no argument */
+ if (prAdapter->prAisBssInfo->prStaRecOfAP)
+ ucWlanIndex = prAdapter->prAisBssInfo->prStaRecOfAP->ucWlanIndex;
+ else if (!wlanGetWlanIdxByAddress(prAdapter, NULL, &ucWlanIndex))
+ return i4BytesWritten;
+ pucMacAddr = wlanGetStaAddrByWlanIdx(prAdapter, ucWlanIndex);
+ if (!pucMacAddr) {
+ DBGLOG(REQ, WARN, "%s: MAC address is invalid!\n", __func__);
+ return -EFAULT;
+ }
+ /* Get WTBL info */
+ prHwWlanInfo = (P_PARAM_HW_WLAN_INFO_T)kalMemAlloc(sizeof(PARAM_HW_WLAN_INFO_T), VIR_MEM_TYPE);
+ if (!prHwWlanInfo)
+ return -ENOMEM;
+ prHwWlanInfo->u4Index = ucWlanIndex;
+ rStatus = kalIoctl(prGlueInfo,
+ wlanoidQueryWlanInfo,
+ prHwWlanInfo, sizeof(PARAM_HW_WLAN_INFO_T), TRUE, TRUE, TRUE, &u4BufLen);
+ if (rStatus != WLAN_STATUS_SUCCESS) {
+ i4BytesWritten = -EFAULT;
+ goto out_get_curr_ar_rate;
+ }
+
+ prQueryStaStatistics =
+ (P_PARAM_GET_STA_STATISTICS)kalMemAlloc(sizeof(PARAM_GET_STA_STA_STATISTICS), VIR_MEM_TYPE);
+ if (!prQueryStaStatistics) {
+ i4BytesWritten = -ENOMEM;
+ goto out_get_curr_ar_rate;
+ }
+
+ /* Get Statistics info */
+ COPY_MAC_ADDR(prQueryStaStatistics->aucMacAddr, pucMacAddr);
+ rStatus = kalIoctl(prGlueInfo,
+ wlanoidQueryStaStatistics,
+ prQueryStaStatistics,
+ sizeof(PARAM_GET_STA_STA_STATISTICS), TRUE, TRUE, TRUE, &u4BufLen);
+
+ if (rStatus != WLAN_STATUS_SUCCESS) {
+ i4BytesWritten = -EFAULT;
+ goto out_get_curr_ar_rate;
+ }
+
+ idx = prHwWlanInfo->rWtblRateInfo.ucRateIdx;
+ if (idx >= AUTO_RATE_NUM) {
+ DBGLOG(REQ, WARN, "%s: Rate index is incorrect (%d)\n", __func__, idx);
+ i4BytesWritten = -EFAULT;
+ goto out_get_curr_ar_rate;
+ }
+ txmode = HW_TX_RATE_TO_MODE(prHwWlanInfo->rWtblRateInfo.au2RateCode[idx]);
+ if (txmode >= MAX_TX_MODE)
+ txmode = MAX_TX_MODE;
+ rate = HW_TX_RATE_TO_MCS(prHwWlanInfo->rWtblRateInfo.au2RateCode[idx], txmode);
+
+ /* Mode: [CCK | OFDM | HT | VHT] */
+ if (txmode == TX_RATE_MODE_CCK)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "CCK-");
+ else if (txmode == TX_RATE_MODE_OFDM)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "OFDM-");
+ else if (txmode == TX_RATE_MODE_HTGF || txmode == TX_RATE_MODE_HTMIX)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "HT-");
+ else
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "VHT-");
+ /* Spatial Streams: [1SS | 2SS | N/A] */
+ if (prQueryStaStatistics->ucArTableIdx == RATE_TBL_N_2SS ||
+ prQueryStaStatistics->ucArTableIdx == RATE_TBL_AC_2SS)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "2SS-");
+ else if (prQueryStaStatistics->ucArTableIdx == RATE_TBL_N ||
+ prQueryStaStatistics->ucArTableIdx == RATE_TBL_AC)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "1SS-");
+ else
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "N/A-");
+
+ /* BW mode: [BW20 | BW40 | BW80 | BW160/BW8080] */
+ if ((txmode == TX_RATE_MODE_CCK) || (txmode == TX_RATE_MODE_OFDM))
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s-", HW_TX_RATE_BW[0]);
+ else
+ if (idx > prHwWlanInfo->rWtblPeerCap.ucChangeBWAfterRateN)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten,
+ i4TotalLen - i4BytesWritten, "%s-",
+ prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability < 4 ?
+ (prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability > BW_20 ?
+ HW_TX_RATE_BW[prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability - 1] :
+ HW_TX_RATE_BW[prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability]) :
+ HW_TX_RATE_BW[4]);
+ else
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten,
+ i4TotalLen - i4BytesWritten, "%s-",
+ prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability < 4 ?
+ HW_TX_RATE_BW[prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability] :
+ HW_TX_RATE_BW[4]);
+ /* GI mode: [LGI | SGI | X] */
+ if (txmode == TX_RATE_MODE_CCK || txmode == TX_RATE_MODE_OFDM)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "N/A-");
+ else
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s-", priv_driver_get_sgi_info(&prHwWlanInfo->rWtblPeerCap) == 0 ?
+ "LGI" : "SGI");
+ /* Rate index: [1M | 2M | 5.5M | 11M |
+ * 6M | 9M | 12M | 18M | 24M | 36M | 48M | 54M |
+ * MCS# ]
+ */
+ if (txmode == TX_RATE_MODE_CCK)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s", rate < 4 ? HW_TX_RATE_CCK_STR[rate] : HW_TX_RATE_CCK_STR[4]);
+ else if (txmode == TX_RATE_MODE_OFDM)
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s", hw_rate_ofdm_str(rate));
+ else
+ i4BytesWritten += kalSnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "MCS%d", rate);
+
+out_get_curr_ar_rate:
+ if (prHwWlanInfo)
+ kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, sizeof(PARAM_HW_WLAN_INFO_T));
+ if (prQueryStaStatistics)
+ kalMemFree(prQueryStaStatistics, VIR_MEM_TYPE, sizeof(PARAM_GET_STA_STA_STATISTICS));
+
+ return i4BytesWritten;
+
+}
+
+/*----------------------------------------------------------------------------*/
/*
* @ The function will set policy of ACL.
* 0: disable ACL
@@ -8603,6 +8783,8 @@
i4BytesWritten = priv_driver_get_sta_stat2(prNetDev, pcCommand, i4TotalLen);
} else if (strnicmp(pcCommand, CMD_GET_STA_STAT, strlen(CMD_GET_STA_STAT)) == 0) {
i4BytesWritten = priv_driver_get_sta_stat(prNetDev, pcCommand, i4TotalLen);
+ } else if (strnicmp(pcCommand, CMD_GET_CURR_AR_RATE, strlen(CMD_GET_CURR_AR_RATE)) == 0) {
+ i4BytesWritten = priv_driver_get_sta_curr_ar_rate(prNetDev, pcCommand, i4TotalLen);
} else if (strnicmp(pcCommand, CMD_GET_STA_RX_STAT, strlen(CMD_GET_STA_RX_STAT)) == 0) {
i4BytesWritten = priv_driver_show_rx_stat(prNetDev, pcCommand, i4TotalLen);
} else if (strnicmp(pcCommand, CMD_SET_ACL_POLICY, strlen(CMD_SET_ACL_POLICY)) == 0) {