[WCNCR00155320] misc: Add last second Tx PER and T/Rx MCS distribution support
[Description]
Add driver command "GET_MCS_INFO" for outputing following result:
1. Last Second Tx MCS PER
2. Last Second Tx MCS distribution
3. Last Second Rx MCS distribution
Change-Id: I027e1743dac1efdc8ad761dc137598a8da8569ea
Signed-off-by: Glenn Tung <glenn.tung@mediatek.com>
Feature: misc
CR-Id: WCNCR00166815
diff --git a/common/wlan_oid.c b/common/wlan_oid.c
index a12eddd..1aa4094 100644
--- a/common/wlan_oid.c
+++ b/common/wlan_oid.c
@@ -11941,6 +11941,48 @@
} /* wlanoidQueryMibInfo */
#endif
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+WLAN_STATUS
+wlanoidTxMcsInfo(IN P_ADAPTER_T prAdapter,
+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen)
+{
+ struct PARAM_TX_MCS_INFO *prMcsInfo;
+
+ DEBUGFUNC("wlanoidQueryWlanInfo");
+ DBGLOG(REQ, LOUD, "\n");
+
+ ASSERT(prAdapter);
+ if (u4QueryBufferLen)
+ ASSERT(pvQueryBuffer);
+ ASSERT(pu4QueryInfoLen);
+
+ *pu4QueryInfoLen = sizeof(struct PARAM_TX_MCS_INFO);
+
+ if (prAdapter->rAcpiState == ACPI_STATE_D3) {
+ DBGLOG(REQ, WARN,
+ "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n",
+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff);
+ *pu4QueryInfoLen = sizeof(UINT_32);
+ return WLAN_STATUS_ADAPTER_NOT_READY;
+ } else if (u4QueryBufferLen < sizeof(struct PARAM_TX_MCS_INFO)) {
+ DBGLOG(REQ, WARN, "Too short length %ld\n", u4QueryBufferLen);
+ return WLAN_STATUS_INVALID_LENGTH;
+ }
+
+ prMcsInfo = (struct PARAM_TX_MCS_INFO *)pvQueryBuffer;
+
+ return wlanSendSetQueryCmd(prAdapter,
+ CMD_ID_TX_MCS_INFO,
+ FALSE,
+ TRUE,
+ TRUE,
+ nicCmdEventTxMcsInfo,
+ nicOidCmdTimeoutCommon,
+ sizeof(struct PARAM_TX_MCS_INFO), (PUINT_8)prMcsInfo,
+ pvQueryBuffer, u4QueryBufferLen);
+
+}
+#endif
/*----------------------------------------------------------------------------*/
/*!
diff --git a/include/config.h b/include/config.h
index 0695220..7edcf6e 100644
--- a/include/config.h
+++ b/include/config.h
@@ -847,6 +847,15 @@
*/
#define CFG_SUPPORT_REPLAY_DETECTION 1
+/*------------------------------------------------------------------------------
+ * Flags of Last Second MCS Tx/Rx Info
+ *------------------------------------------------------------------------------
+ */
+#define CFG_SUPPORT_LAST_SEC_MCS_INFO 1
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+#define MCS_INFO_SAMPLE_CNT 10
+#endif
+
/*------------------------------------------------------------------------------
* Flags of driver fw customization
diff --git a/include/mgmt/ais_fsm.h b/include/mgmt/ais_fsm.h
index 99eadcb..7968855 100644
--- a/include/mgmt/ais_fsm.h
+++ b/include/mgmt/ais_fsm.h
@@ -380,6 +380,10 @@
VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParamPtr);
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+VOID aisRxMcsCollectionTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParamPtr);
+#endif
+
/*----------------------------------------------------------------------------*/
/* OID/IOCTL Handling */
/*----------------------------------------------------------------------------*/
diff --git a/include/mgmt/cnm_mem.h b/include/mgmt/cnm_mem.h
index ed3df96..4b3a132 100644
--- a/include/mgmt/cnm_mem.h
+++ b/include/mgmt/cnm_mem.h
@@ -543,6 +543,10 @@
UINT_32 u4RxVector3;
UINT_32 u4RxVector4;
#endif
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+ UINT_32 au4RxVect0Que[MCS_INFO_SAMPLE_CNT];
+ UINT_32 au4RxVect1Que[MCS_INFO_SAMPLE_CNT];
+#endif
UINT_8 ucSmDialogToken; /* Spectrum Mngt Dialog Token */
UINT_8 ucSmMsmtRequestMode; /* Measurement Request Mode */
UINT_8 ucSmMsmtToken; /* Measurement Request Token */
diff --git a/include/nic/adapter.h b/include/nic/adapter.h
index ec504d4..a184640 100644
--- a/include/nic/adapter.h
+++ b/include/nic/adapter.h
@@ -1117,6 +1117,11 @@
EVENT_WLAN_INFO rEventWlanInfo;
#endif
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+ TIMER_T rRxMcsInfoTimer;
+ BOOLEAN fgIsMcsInfoValid;
+#endif
+
EVENT_LINK_QUALITY rLinkQuality;
OS_SYSTIME rLinkQualityUpdateTime;
BOOLEAN fgIsLinkQualityValid;
diff --git a/include/nic_cmd_event.h b/include/nic_cmd_event.h
index 509a359..d187fb1 100644
--- a/include/nic_cmd_event.h
+++ b/include/nic_cmd_event.h
@@ -537,6 +537,10 @@
CMD_ID_WLAN_INFO = 0xCD, /* 0xcd (Query) */
CMD_ID_MIB_INFO = 0xCE, /* 0xce (Query) */
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+ CMD_ID_TX_MCS_INFO = 0xCF, /* 0xcf (Query) */
+#endif
+
CMD_ID_SET_RDD_CH = 0xE1,
#if CFG_SUPPORT_QA_TOOL
@@ -648,6 +652,10 @@
EVENT_ID_WLAN_INFO = 0xCD,
EVENT_ID_MIB_INFO = 0xCE,
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+ EVENT_ID_TX_MCS_INFO = 0xCF,
+#endif
+
EVENT_ID_NIC_CAPABILITY_V2 = 0xEC, /* 0xEC (Query - CMD_ID_GET_NIC_CAPABILITY_V2) */
/*#if (CFG_EFUSE_BUFFER_MODE_DELAY_CAL == 1)*/
EVENT_ID_LAYER_0_EXT_MAGIC_NUM = 0xED, /* magic number for Extending MT6630 original EVENT header */
@@ -3042,6 +3050,14 @@
} EVENT_MIB_INFO, *P_EVENT_MIB_INFO;
#endif
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+struct EVENT_TX_MCS_INFO {
+ UINT_16 au2TxRateCode[MCS_INFO_SAMPLE_CNT];
+ UINT_8 aucTxRatePer[MCS_INFO_SAMPLE_CNT];
+ UINT_8 aucReserved[2];
+};
+#endif
+
/*#if (CFG_EEPROM_PAGE_ACCESS == 1)*/
typedef struct _EVENT_ACCESS_EFUSE {
@@ -3245,6 +3261,10 @@
VOID nicCmdEventQueryMibInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+VOID nicCmdEventTxMcsInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf);
+#endif
+
VOID nicCmdEventQueryNicCapabilityV2(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEventBuf);
WLAN_STATUS nicCmdEventQueryNicTxResource(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEventBuf);
@@ -3269,6 +3289,9 @@
VOID nicEventStatistics(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
VOID nicEventWlanInfo(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
VOID nicEventMibInfo(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+VOID nicEventTxMcsInfo(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+#endif
VOID nicEventBeaconTimeout(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
VOID nicEventUpdateNoaParams(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
VOID nicEventStaAgingTimeout(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
diff --git a/include/wlan_oid.h b/include/wlan_oid.h
index da9444a..51a832b 100644
--- a/include/wlan_oid.h
+++ b/include/wlan_oid.h
@@ -1820,6 +1820,13 @@
} PARAM_HW_MIB_INFO_T, *P_PARAM_HW_MIB_INFO_T;
#endif
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+struct PARAM_TX_MCS_INFO {
+ UINT_8 ucStaIndex;
+ UINT_16 au2TxRateCode[MCS_INFO_SAMPLE_CNT];
+ UINT_8 aucTxRatePer[MCS_INFO_SAMPLE_CNT];
+};
+#endif
/*--------------------------------------------------------------*/
/*! \brief For Fixed Rate Configuration (Registry) */
@@ -2645,6 +2652,11 @@
WLAN_STATUS
wlanoidQueryMibInfo(IN P_ADAPTER_T prAdapter,
OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+WLAN_STATUS
+wlanoidTxMcsInfo(IN P_ADAPTER_T prAdapter,
+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen);
+#endif
WLAN_STATUS
wlanoidSetFwLog2Host(
diff --git a/mgmt/ais_fsm.c b/mgmt/ais_fsm.c
index 08ff61b..fce992f 100644
--- a/mgmt/ais_fsm.c
+++ b/mgmt/ais_fsm.c
@@ -3133,6 +3133,22 @@
aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT);
}
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+VOID aisRxMcsCollectionTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParamPtr)
+{
+ static UINT_8 ucSmapleCnt;
+ UINT_8 ucStaIdx = prAdapter->prAisBssInfo->prStaRecOfAP->ucIndex;
+
+ if (prAdapter->arStaRec[ucStaIdx].fgIsValid && prAdapter->arStaRec[ucStaIdx].fgIsInUse) {
+ prAdapter->arStaRec[ucStaIdx].au4RxVect0Que[ucSmapleCnt] = prAdapter->arStaRec[ucStaIdx].u4RxVector0;
+ prAdapter->arStaRec[ucStaIdx].au4RxVect1Que[ucSmapleCnt] = prAdapter->arStaRec[ucStaIdx].u4RxVector1;
+ ucSmapleCnt = (ucSmapleCnt + 1) % MCS_INFO_SAMPLE_CNT;
+ }
+
+ cnmTimerStartTimer(prAdapter, &prAdapter->rRxMcsInfoTimer, 100);
+}
+#endif
+
#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0)
/*----------------------------------------------------------------------------*/
/*!
diff --git a/nic/nic_cmd_event.c b/nic/nic_cmd_event.c
index 929d15e..d2a9a93 100644
--- a/nic/nic_cmd_event.c
+++ b/nic/nic_cmd_event.c
@@ -2489,6 +2489,36 @@
}
#endif
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+VOID nicCmdEventTxMcsInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
+{
+ UINT_32 u4QueryInfoLen;
+ P_GLUE_INFO_T prGlueInfo;
+ struct EVENT_TX_MCS_INFO *prTxMcsEvent;
+ struct PARAM_TX_MCS_INFO *prTxMcsInfo;
+
+ ASSERT(prAdapter);
+ ASSERT(prCmdInfo);
+ ASSERT(pucEventBuf);
+ ASSERT(prCmdInfo->pvInformationBuffer);
+
+ if (prCmdInfo->fgIsOid) {
+ prGlueInfo = prAdapter->prGlueInfo;
+ prTxMcsEvent = (struct EVENT_TX_MCS_INFO *) pucEventBuf;
+ prTxMcsInfo = (struct PARAM_TX_MCS_INFO *) prCmdInfo->pvInformationBuffer;
+
+ u4QueryInfoLen = sizeof(struct EVENT_TX_MCS_INFO);
+
+ kalMemCopy(prTxMcsInfo->au2TxRateCode, prTxMcsEvent->au2TxRateCode,
+ sizeof(prTxMcsEvent->au2TxRateCode));
+ kalMemCopy(prTxMcsInfo->aucTxRatePer, prTxMcsEvent->aucTxRatePer,
+ sizeof(prTxMcsEvent->aucTxRatePer));
+
+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS);
+ }
+}
+#endif
+
#if CFG_TCP_IP_CHKSUM_OFFLOAD
WLAN_STATUS nicCmdEventQueryNicCsumOffload(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEventBuf)
{
@@ -2926,6 +2956,27 @@
}
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+VOID nicEventTxMcsInfo(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+ P_CMD_INFO_T prCmdInfo;
+
+ DBGLOG(RSN, INFO, "EVENT_ID_TX_MCS_INFO");
+ /* command response handling */
+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
+
+ if (prCmdInfo != NULL) {
+ if (prCmdInfo->pfCmdDoneHandler)
+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
+ else if (prCmdInfo->fgIsOid)
+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
+ /* return prCmdInfo */
+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
+ }
+
+}
+#endif
+
VOID nicEventBeaconTimeout(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
{
DBGLOG(NIC, INFO, "EVENT_ID_BSS_BEACON_TIMEOUT\n");
diff --git a/nic/nic_rx.c b/nic/nic_rx.c
index cf4491e..1dca538 100644
--- a/nic/nic_rx.c
+++ b/nic/nic_rx.c
@@ -148,6 +148,9 @@
{EVENT_ID_STATISTICS, nicEventStatistics},
{EVENT_ID_WLAN_INFO, nicEventWlanInfo},
{EVENT_ID_MIB_INFO, nicEventMibInfo},
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+ {EVENT_ID_TX_MCS_INFO, nicEventTxMcsInfo},
+#endif
{EVENT_ID_CH_PRIVILEGE, cnmChMngrHandleChEvent},
{EVENT_ID_BSS_ABSENCE_PRESENCE, qmHandleEventBssAbsencePresence},
{EVENT_ID_STA_CHANGE_PS_MODE, qmHandleEventStaChangePsMode},
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index 5d99d2e..f48a537 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -2223,6 +2223,9 @@
#define CMD_GET_STA_STATISTICS "GET_STA_STATISTICS"
#define CMD_GET_WTBL_INFO "GET_WTBL"
#define CMD_GET_MIB_INFO "GET_MIB"
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+#define CMD_GET_MCS_INFO "GET_MCS_INFO"
+#endif
#define CMD_GET_STA_INFO "GET_STA"
#define CMD_SET_FW_LOG "SET_FWLOG"
#define CMD_GET_QUE_INFO "GET_QUE"
@@ -3992,6 +3995,185 @@
} /* priv_driver_get_test_result */
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+INT_32 priv_driver_last_sec_mcs_info(IN P_ADAPTER_T prAdapter, IN char *pcCommand, IN int i4TotalLen,
+ P_PARAM_HW_WLAN_INFO_T prHwWlanInfo, struct PARAM_TX_MCS_INFO *prTxMcsInfo)
+{
+ UINT_8 i, j, txmode, rate, stbc;
+ UINT_8 nsts;
+ INT_32 i4BytesWritten = 0;
+ UINT_32 au4RxVect0Que[MCS_INFO_SAMPLE_CNT], au4RxVect1Que[MCS_INFO_SAMPLE_CNT];
+ UINT_8 ucStaIdx = prAdapter->prAisBssInfo->prStaRecOfAP->ucIndex;
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, "\nTx MCS:\n");
+
+ for (i = 0; i < MCS_INFO_SAMPLE_CNT; i++) {
+ UINT_8 tmpPerSum = 0, cnt = 0;
+ UINT_16 tmpRateCode = 0xFFFF;
+
+ if (prTxMcsInfo->au2TxRateCode[i] == 0xFFFF)
+ continue;
+
+ if (tmpRateCode == 0xFFFF)
+ tmpRateCode = prTxMcsInfo->au2TxRateCode[i];
+
+ txmode = HW_TX_RATE_TO_MODE(prTxMcsInfo->au2TxRateCode[i]);
+ if (txmode >= MAX_TX_MODE)
+ txmode = MAX_TX_MODE;
+ rate = HW_TX_RATE_TO_MCS(prTxMcsInfo->au2TxRateCode[i], txmode);
+ nsts = HW_TX_RATE_TO_NSS(prTxMcsInfo->au2TxRateCode[i]) + 1;
+ stbc = HW_TX_RATE_TO_STBC(prTxMcsInfo->au2TxRateCode[i]);
+
+ for (j = 0; j < MCS_INFO_SAMPLE_CNT; j++) {
+ if (tmpRateCode == prTxMcsInfo->au2TxRateCode[j]) {
+ tmpPerSum += prTxMcsInfo->aucTxRatePer[j];
+ cnt++;
+ prTxMcsInfo->au2TxRateCode[j] = 0xFFFF;
+ }
+ }
+
+ if (txmode == TX_RATE_MODE_CCK)
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " %s, ", HW_TX_RATE_CCK_STR[rate & 0x3]);
+ else if (txmode == TX_RATE_MODE_OFDM)
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " %s, ", hw_rate_ofdm_str(rate));
+ else if ((txmode == TX_RATE_MODE_HTMIX) || (txmode == TX_RATE_MODE_HTGF))
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " MCS%d, ", rate);
+ else
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " NSS%d_MCS%d, ", nsts, rate);
+
+ if ((txmode == TX_RATE_MODE_CCK) || (txmode == TX_RATE_MODE_OFDM))
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, ", HW_TX_RATE_BW[0]);
+ else
+ if (i > prHwWlanInfo->rWtblPeerCap.ucChangeBWAfterRateN)
+ i4BytesWritten += kalScnprintf(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 += kalScnprintf(pcCommand + i4BytesWritten,
+ i4TotalLen - i4BytesWritten, "%s, ",
+ prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability < 4 ?
+ HW_TX_RATE_BW[prHwWlanInfo->rWtblPeerCap.ucFrequencyCapability] :
+ HW_TX_RATE_BW[4]);
+
+ if (txmode == TX_RATE_MODE_CCK)
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, ", rate < 4 ? "LP" : "SP");
+ else if (txmode == TX_RATE_MODE_OFDM)
+ ;
+ else
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, ", priv_driver_get_sgi_info(&prHwWlanInfo->rWtblPeerCap) == 0 ? "LGI" : "SGI");
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s%s%s [PER: %02d%]\t", txmode < 5 ? HW_TX_MODE_STR[txmode] : HW_TX_MODE_STR[5],
+ stbc ? ", STBC, " : ", ",
+ ((priv_driver_get_ldpc_info(&prHwWlanInfo->rWtblTxConfig) == 0) ||
+ (txmode == TX_RATE_MODE_CCK) || (txmode == TX_RATE_MODE_OFDM)) ? "BCC" : "LDPC",
+ tmpPerSum/cnt);
+
+ for (j = 0; j < cnt; j++)
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, "*");
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, "\n");
+ }
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, "\nRx MCS:\n");
+
+ kalMemCopy(au4RxVect0Que, prAdapter->arStaRec[ucStaIdx].au4RxVect0Que, sizeof(au4RxVect0Que));
+ kalMemCopy(au4RxVect1Que, prAdapter->arStaRec[ucStaIdx].au4RxVect1Que, sizeof(au4RxVect1Que));
+
+ for (i = 0; i < MCS_INFO_SAMPLE_CNT; i++) {
+ UINT_8 cnt = 0;
+ UINT_32 u4RxVector0 = 0xFFFFFFFF;
+ UINT_32 txmode, rate, frmode, sgi, nsts, ldpc, stbc, groupid, mu;
+ #define RX_MCS_INFO_MASK BITS(0, 17)
+
+ if (au4RxVect0Que[i] == 0xFFFFFFFF)
+ continue;
+
+ if (u4RxVector0 == 0xFFFFFFFF)
+ u4RxVector0 = au4RxVect0Que[i];
+
+ txmode = (au4RxVect0Que[i] & RX_VT_RX_MODE_MASK) >> RX_VT_RX_MODE_OFFSET;
+ rate = (au4RxVect0Que[i] & RX_VT_RX_RATE_MASK) >> RX_VT_RX_RATE_OFFSET;
+ frmode = (au4RxVect0Que[i] & RX_VT_FR_MODE_MASK) >> RX_VT_FR_MODE_OFFSET;
+ nsts = ((au4RxVect1Que[i] & RX_VT_NSTS_MASK) >> RX_VT_NSTS_OFFSET);
+ stbc = (au4RxVect0Que[i] & RX_VT_STBC_MASK) >> RX_VT_STBC_OFFSET;
+ sgi = au4RxVect0Que[i] & RX_VT_SHORT_GI;
+ ldpc = au4RxVect0Que[i] & RX_VT_LDPC;
+ groupid = (au4RxVect1Que[i] & RX_VT_GROUP_ID_MASK) >> RX_VT_GROUP_ID_OFFSET;
+
+ for (j = 0; j < MCS_INFO_SAMPLE_CNT; j++) {
+ if ((u4RxVector0 & RX_MCS_INFO_MASK) == (au4RxVect0Que[j] & RX_MCS_INFO_MASK)) {
+ au4RxVect0Que[j] = 0xFFFFFFFF;
+ cnt++;
+ }
+ }
+
+ if (groupid && groupid != 63) {
+ mu = 1;
+ } else {
+ mu = 0;
+ nsts += 1;
+ }
+
+ if (txmode == TX_RATE_MODE_CCK)
+ i4BytesWritten += kalScnprintf(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 += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " %s, ", hw_rate_ofdm_str(rate));
+ else if ((txmode == TX_RATE_MODE_HTMIX) || (txmode == TX_RATE_MODE_HTGF))
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " MCS%d, ", rate);
+ else
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ " NSS%d_MCS%d, ", nsts, rate);
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, ", frmode < 4 ? HW_TX_RATE_BW[frmode] : HW_TX_RATE_BW[4]);
+
+ if (txmode == TX_RATE_MODE_CCK)
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, ", rate < 4 ? "LP" : "SP");
+ else if (txmode == TX_RATE_MODE_OFDM)
+ ;
+ else
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s,", sgi == 0 ? "LGI" : "SGI");
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s", stbc == 0 ? " " : " STBC, ");
+
+ if (mu) {
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, %s, %s (%d)\t", txmode < 5 ? HW_TX_MODE_STR[txmode] : HW_TX_MODE_STR[5],
+ ldpc == 0 ? "BCC" : "LDPC", "MU", groupid);
+ } else {
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten,
+ "%s, %s\t", txmode < 5 ? HW_TX_MODE_STR[txmode] : HW_TX_MODE_STR[5],
+ ldpc == 0 ? "BCC" : "LDPC");
+ }
+
+ for (j = 0; j < cnt; j++)
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, "*");
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten, i4TotalLen - i4BytesWritten, "\n");
+ }
+
+ return i4BytesWritten;
+}
+#endif
+
INT_32 priv_driver_tx_rate_info(IN char *pcCommand, IN int i4TotalLen, BOOLEAN fgDumpAll,
P_PARAM_HW_WLAN_INFO_T prHwWlanInfo, P_PARAM_GET_STA_STATISTICS prQueryStaStatistics)
{
@@ -8568,6 +8750,102 @@
return i4BytesWritten;
}
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+static int priv_driver_get_mcs_info(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+ P_GLUE_INFO_T prGlueInfo = NULL;
+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
+ UINT_32 u4BufLen = 0;
+ INT_32 i4BytesWritten = 0, i4Argc = 0;
+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
+ P_PARAM_HW_WLAN_INFO_T prHwWlanInfo = NULL;
+ struct PARAM_TX_MCS_INFO *prTxMcsInfo = NULL;
+
+ ASSERT(prNetDev);
+ if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE)
+ return -1;
+
+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+ DBGLOG(REQ, LOUD, "command is %s\n", pcCommand);
+ wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+ if (prGlueInfo->prAdapter->rRxMcsInfoTimer.pfMgmtTimeOutFunc == NULL) {
+ cnmTimerInitTimer(prGlueInfo->prAdapter,
+ &prGlueInfo->prAdapter->rRxMcsInfoTimer,
+ (PFN_MGMT_TIMEOUT_FUNC) aisRxMcsCollectionTimeout, (ULONG) NULL);
+ }
+
+ if (i4Argc >= 2) {
+ if (strnicmp(apcArgv[1], "START", strlen("START")) == 0) {
+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rRxMcsInfoTimer, 100);
+ prGlueInfo->prAdapter->fgIsMcsInfoValid = TRUE;
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten,
+ i4TotalLen - i4BytesWritten,
+ "\nStart the MCS Info Function\n");
+ return i4BytesWritten;
+ } else if (strnicmp(apcArgv[1], "STOP", strlen("STOP")) == 0) {
+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rRxMcsInfoTimer);
+ prGlueInfo->prAdapter->fgIsMcsInfoValid = FALSE;
+
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten,
+ i4TotalLen - i4BytesWritten,
+ "\nStop the MCS Info Function\n");
+ return i4BytesWritten;
+ }
+ }
+
+ if (prGlueInfo->prAdapter->fgIsMcsInfoValid != TRUE) {
+ i4BytesWritten += kalScnprintf(pcCommand + i4BytesWritten,
+ i4TotalLen - i4BytesWritten,
+ "\nUse GET_MCS_INFO [START/STOP] to control the MCS Info Function\n");
+ return i4BytesWritten;
+ }
+
+ if (prGlueInfo->prAdapter->prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)
+ return -1;
+
+ prHwWlanInfo = (P_PARAM_HW_WLAN_INFO_T)kalMemAlloc(sizeof(PARAM_HW_WLAN_INFO_T), VIR_MEM_TYPE);
+ if (!prHwWlanInfo)
+ return -1;
+
+ rStatus = kalIoctl(prGlueInfo,
+ wlanoidQueryWlanInfo,
+ prHwWlanInfo, sizeof(PARAM_HW_WLAN_INFO_T), TRUE, TRUE, TRUE, &u4BufLen);
+
+ DBGLOG(REQ, INFO, "rStatus %u u4BufLen = %d\n", rStatus, u4BufLen);
+ if (rStatus != WLAN_STATUS_SUCCESS)
+ goto out;
+
+ prTxMcsInfo = (struct PARAM_TX_MCS_INFO *)kalMemAlloc(sizeof(struct PARAM_TX_MCS_INFO), VIR_MEM_TYPE);
+ if (!prTxMcsInfo)
+ goto out;
+
+ prTxMcsInfo->ucStaIndex = prGlueInfo->prAdapter->prAisBssInfo->prStaRecOfAP->ucIndex;
+ rStatus = kalIoctl(prGlueInfo,
+ wlanoidTxMcsInfo,
+ prTxMcsInfo, sizeof(struct PARAM_TX_MCS_INFO), TRUE, TRUE, TRUE, &u4BufLen);
+
+ DBGLOG(REQ, INFO, "rStatus %u u4BufLen = %d\n", rStatus, u4BufLen);
+ if (rStatus != WLAN_STATUS_SUCCESS)
+ goto out;
+
+ i4BytesWritten = priv_driver_last_sec_mcs_info(prGlueInfo->prAdapter,
+ pcCommand, i4TotalLen, prHwWlanInfo, prTxMcsInfo);
+
+ DBGLOG(REQ, INFO, "%s: command result is %s\n", __func__, pcCommand);
+
+out:
+ if (prHwWlanInfo)
+ kalMemFree(prHwWlanInfo, VIR_MEM_TYPE, sizeof(PARAM_HW_WLAN_INFO_T));
+ if (prTxMcsInfo)
+ kalMemFree(prTxMcsInfo, VIR_MEM_TYPE, sizeof(struct PARAM_TX_MCS_INFO));
+
+ return i4BytesWritten;
+}
+#endif
+
static int priv_driver_get_deep_sleep_cnt(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
{
P_GLUE_INFO_T prGlueInfo = NULL;
@@ -10304,6 +10582,10 @@
i4BytesWritten = priv_driver_get_wtbl_info(prNetDev, pcCommand, i4TotalLen);
else if (strnicmp(pcCommand, CMD_GET_MIB_INFO, strlen(CMD_GET_MIB_INFO)) == 0)
i4BytesWritten = priv_driver_get_mib_info(prNetDev, pcCommand, i4TotalLen);
+#if CFG_SUPPORT_LAST_SEC_MCS_INFO
+ else if (strnicmp(pcCommand, CMD_GET_MCS_INFO, strlen(CMD_GET_MCS_INFO)) == 0)
+ i4BytesWritten = priv_driver_get_mcs_info(prNetDev, pcCommand, i4TotalLen);
+#endif
else if (strnicmp(pcCommand, CMD_SET_FW_LOG, strlen(CMD_SET_FW_LOG)) == 0)
i4BytesWritten = priv_driver_set_fw_log(prNetDev, pcCommand, i4TotalLen);
#endif