[WCNCR00172942] wifi: sync driver to mp2

[Description]
Change wifi driver to MP2

Change-Id: I11c7d2fe5faf7c47ac34d1f8e795edabfd9a7798
Signed-off-by: Jiehang Zheng <jiehang.zheng@mediatek.com>
CR-Id: WCNCR00172942
Feature: wifi
Reviewed-on: http://gerrit.mediatek.inc:8080/1420263
CheckPatch: Check Patch <srv_checkpatch@mediatek.com>
Reviewed-by: Shengxi xu <shengxi.xu@mediatek.com>
Tested-by: Shengxi xu <shengxi.xu@mediatek.com>
diff --git a/common/wlan_lib.c b/common/wlan_lib.c
index 8e83f76..002aa0a 100644
--- a/common/wlan_lib.c
+++ b/common/wlan_lib.c
@@ -4867,6 +4867,13 @@
 		prAdapter->rWifiVar.ucP2p5gBandwidth = MAX_BW_40MHZ;
 		prAdapter->rWifiVar.ucApBandwidth = MAX_BW_40MHZ;
 		prAdapter->rWifiVar.ucAp5gBandwidth = MAX_BW_40MHZ;
+#if CFG_SUPPORT_MTK_SYNERGY
+		/* Disable the 2.4G 256QAM feature bit if N only chip*/
+		prAdapter->rWifiVar.aucMtkFeature[0] &=
+			~(MTK_SYNERGY_CAP_SUPPORT_24G_MCS89);
+		DBGLOG(INIT, WARN,
+			"Disable 2.4G 256QAM support if N only chip\n");
+#endif
 	}
 
 	prAdapter->u4FwCompileFlag0 = prEventNicCapability->u4CompileFlag0;
@@ -6685,7 +6692,8 @@
 	prWifiVar->ucDynBwRts = (UINT_8) wlanCfgGetUint32(prAdapter, "DynBwRts", FEATURE_DISABLED);
 	prWifiVar->ucTxopPsTx = (UINT_8) wlanCfgGetUint32(prAdapter, "TxopPsTx", FEATURE_DISABLED);
 
-	prWifiVar->ucStaHtBfee = (UINT_8) wlanCfgGetUint32(prAdapter, "StaHTBfee", FEATURE_ENABLED);
+	prWifiVar->ucStaHtBfee = (UINT_8) wlanCfgGetUint32(prAdapter,
+					"StaHTBfee", FEATURE_DISABLED);
 	prWifiVar->ucStaVhtBfee = (UINT_8) wlanCfgGetUint32(prAdapter, "StaVHTBfee", FEATURE_ENABLED);
 	prWifiVar->ucStaVhtMuBfee = (UINT_8)wlanCfgGetUint32(prAdapter, "StaVHTMuBfee", FEATURE_ENABLED);
 	prWifiVar->ucStaHtBfer = (UINT_8) wlanCfgGetUint32(prAdapter, "StaHTBfer", FEATURE_DISABLED);
diff --git a/common/wlan_oid.c b/common/wlan_oid.c
index ab65ac6..6fb45f4 100644
--- a/common/wlan_oid.c
+++ b/common/wlan_oid.c
@@ -2718,6 +2718,11 @@
 				if (u4KeyIndex != 0)
 					ASSERT(prBssInfo->ucBMCWlanIndexS[u4KeyIndex] < WTBL_SIZE);
 				ucRemoveBCKeyAtIdx = prBssInfo->ucBMCWlanIndexS[u4KeyIndex];
+
+				prBssInfo->ucBMCWlanIndexSUsed[u4KeyIndex]
+					= FALSE;
+				prBssInfo->ucBMCWlanIndexS[u4KeyIndex]
+					= WTBL_RESERVED_ENTRY;
 			}
 		}
 
@@ -5835,10 +5840,6 @@
 			}
 		}
 
-		if (prMcrWrInfo->u4McrData & 0x00000000) {
-			prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
-			prBssInfo->eBssSCO = CHNL_EXT_SCN;
-		}
 		rlmBssInitForAPandIbss(prAdapter, prBssInfo);
 	}
 	/* 0xFFFFFFFB for HT Capability */
diff --git a/include/config.h b/include/config.h
index 097920b..1a3cc14 100644
--- a/include/config.h
+++ b/include/config.h
@@ -278,7 +278,9 @@
 /* 1: Enable SDIO RX Tasklet De-Aggregation
  * 0(default): Disable
  */
-#define CFG_SDIO_RX_AGG_TASKLET			     0
+#ifndef CFG_SDIO_RX_AGG_TASKLET
+#define CFG_SDIO_RX_AGG_TASKLET			0
+#endif
 
 #if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0)
 #error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1"
@@ -875,11 +877,11 @@
 
 /*------------------------------------------------------------------------------
  * Flags for E1 IC workaround (SPI clock divided by 2)
+ * Disabled for MT7668 since external PMIC is NOT used.
+ * TBD: Let chip info structs decide.
  *------------------------------------------------------------------------------
  */
-#define CFG_SUPPORT_PMIC_SPI_CLOCK_SWITCH       1
-
-
+#define CFG_SUPPORT_PMIC_SPI_CLOCK_SWITCH       0
 
 /*------------------------------------------------------------------------------
  * Flags of driver EEPROM pages for QA tool
diff --git a/mgmt/ais_fsm.c b/mgmt/ais_fsm.c
index 81b71b1..1a475e0 100644
--- a/mgmt/ais_fsm.c
+++ b/mgmt/ais_fsm.c
@@ -1011,6 +1011,7 @@
 					    prBssDesc->u4RsnSelectedPairwiseCipher;
 					prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
 #if (CFG_HW_WMM_BY_BSS == 1)
+					prAisBssInfo->eBand = prBssDesc->eBand;
 					if (prAisBssInfo->fgIsWmmInited == FALSE)
 						prAisBssInfo->ucWmmQueSet =
 							cnmWmmIndexDecision(prAdapter, prAisBssInfo);
diff --git a/mgmt/cnm.c b/mgmt/cnm.c
index 5a17792..c1d9492 100644
--- a/mgmt/cnm.c
+++ b/mgmt/cnm.c
@@ -990,7 +990,7 @@
 P_BSS_INFO_T cnmGetBssInfoAndInit(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_T eNetworkType, BOOLEAN fgIsP2pDevice)
 {
 	P_BSS_INFO_T prBssInfo;
-	UINT_8 ucBssIndex, ucOwnMacIdx;
+	UINT_8 i, ucBssIndex, ucOwnMacIdx;
 
 	ASSERT(prAdapter);
 
@@ -1006,6 +1006,15 @@
 		prBssInfo->fgIsPNOEnable = FALSE;
 		prBssInfo->fgIsNetRequestInActive = FALSE;
 #endif
+
+		/* initialize wlan id and status for keys */
+		prBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY;
+		prBssInfo->wepkeyWlanIdx = WTBL_RESERVED_ENTRY;
+		for (i = 0; i < MAX_KEY_NUM; i++) {
+			prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE;
+			prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY;
+			prBssInfo->wepkeyUsed[i] = FALSE;
+		}
 		return prBssInfo;
 	}
 
@@ -1071,12 +1080,21 @@
 
 	if (ucOwnMacIdx >= HW_BSSID_NUM || ucBssIndex >= BSS_INFO_NUM)
 		prBssInfo = NULL;
-#if CFG_SUPPORT_PNO
 	if (prBssInfo) {
+#if CFG_SUPPORT_PNO
 		prBssInfo->fgIsPNOEnable = FALSE;
 		prBssInfo->fgIsNetRequestInActive = FALSE;
-	}
 #endif
+
+		/* initialize wlan id and status for keys */
+		prBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY;
+		prBssInfo->wepkeyWlanIdx = WTBL_RESERVED_ENTRY;
+		for (i = 0; i < MAX_KEY_NUM; i++) {
+			prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE;
+			prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY;
+			prBssInfo->wepkeyUsed[i] = FALSE;
+		}
+	}
 	return prBssInfo;
 }
 
@@ -1317,7 +1335,8 @@
 	P_BSS_INFO_T	prBssInfo;
 	UINT_8			ucBssIndex;
 
-	if (prAdapter->rWifiVar.ucDbdcMode != DBDC_MODE_DYNAMIC)
+	if ((prAdapter->rWifiVar.ucDbdcMode != DBDC_MODE_DYNAMIC) &&
+		(prAdapter->rWifiVar.ucDbdcMode != DBDC_MODE_STATIC))
 		return;
 
 	if (prAdapter->rWifiVar.fgDbDcModeEn) {
@@ -1330,6 +1349,8 @@
 								&prAdapter->rWifiVar.rDBDCSwitchGuardTimer,
 								DBDC_SWITCH_GUARD_TIME);
 		}
+		/* The DBDC is already ON, so renew WMM band information only */
+		cnmUpdateDbdcSetting(prAdapter, TRUE);
 		return;
 	}
 
diff --git a/mgmt/cnm_mem.c b/mgmt/cnm_mem.c
index 3f77937..1a0e459 100644
--- a/mgmt/cnm_mem.c
+++ b/mgmt/cnm_mem.c
@@ -1259,6 +1259,12 @@
 	prCmd = (CMD_PEER_ADD_T *) pvSetBuffer;
 
 	prAisBssInfo = prAdapter->prAisBssInfo;	/* for AIS only test */
+
+	if (prAisBssInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "[%s]prAisBssInfo is NULL!", __func__);
+		return TDLS_STATUS_FAIL;
+	}
+
 	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeerMac);
 
 	if (prStaRec == NULL) {
@@ -1339,6 +1345,11 @@
 
 	prAisBssInfo = prAdapter->prAisBssInfo;
 
+	if (prAisBssInfo == NULL) {
+		DBGLOG(TDLS, ERROR, "[%s]prAisBssInfo is NULL!", __func__);
+		return TDLS_STATUS_FAIL;
+	}
+
 	prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeerMac);
 
 	if ((!prStaRec) || !(prStaRec->fgIsInUse))
diff --git a/mgmt/p2p_func.c b/mgmt/p2p_func.c
index ef0d9b1..6fde0ea 100644
--- a/mgmt/p2p_func.c
+++ b/mgmt/p2p_func.c
@@ -4191,26 +4191,23 @@
 
 UINT_32 wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBssIndex, IN P_STA_RECORD_T prStaRec)
 {
-
 #if CFG_SUPPORT_WFD_COMPOSE_IE
 	UINT_16 u2EstimatedExtraIELen = 0;
-	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
 	P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL;
 
 	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);
-
 	if (prBssInfo->eNetworkType != NETWORK_TYPE_P2P)
 		return 0;
 
-	prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings);
+	if (!IS_STA_P2P_TYPE(prStaRec))
+		return 0;
 
-	if (IS_STA_P2P_TYPE(prStaRec) && (prWfdCfgSettings->ucWfdEnable > 0)) {
+	u2EstimatedExtraIELen = prAdapter->prGlueInfo->prP2PInfo[0]->u2WFDIELen;
 
-		u2EstimatedExtraIELen = prAdapter->prGlueInfo->prP2PInfo[0]->u2WFDIELen;
-		ASSERT(u2EstimatedExtraIELen < 128);
-	}
-	return u2EstimatedExtraIELen;
-
+	if (u2EstimatedExtraIELen < VENDOR_SPECIFIC_IE_LENGTH)
+		return u2EstimatedExtraIELen;
+	else
+		return 0;
 #else
 	return 0;
 #endif
@@ -4218,50 +4215,44 @@
 
 VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
 {
-
 #if CFG_SUPPORT_WFD_COMPOSE_IE
-	P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL;
 	P_STA_RECORD_T prStaRec;
 	UINT_16 u2EstimatedExtraIELen;
 	P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
+	P_GLUE_INFO_T prGlueInfo;
+	P_GL_P2P_INFO_T prP2PInfo;
+
+	if (!prAdapter)
+		return;
+
+	if (!prMsduInfo)
+		return;
+
+	prGlueInfo = prAdapter->prGlueInfo;
+	if (!prGlueInfo)
+		return;
+
+	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+	if (!prStaRec)
+		return;
+
+	if (!IS_STA_P2P_TYPE(prStaRec))
+		return;
 
 	prP2pBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
+	prP2PInfo = prGlueInfo->prP2PInfo[prP2pBssInfo->u4PrivateData];
+	if (!prP2PInfo)
+		return;
 
-	prWfdCfgSettings = &(prAdapter->rWifiVar.rWfdConfigureSettings);
-
-	do {
-		ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL));
-
-		prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
-
-		if (prStaRec) {
-			if (IS_STA_P2P_TYPE(prStaRec)) {
-
-				if (prWfdCfgSettings->ucWfdEnable > 0) {
-					u2EstimatedExtraIELen = prAdapter->prGlueInfo->prP2PInfo[prP2pBssInfo
-						->u4PrivateData]->u2WFDIELen;
-					if (u2EstimatedExtraIELen > 0) {
-						ASSERT(u2EstimatedExtraIELen < 128);
-						ASSERT(sizeof
-						       (prAdapter->prGlueInfo->prP2PInfo[prP2pBssInfo->u4PrivateData]
-						       ->aucWFDIE) >= prAdapter->prGlueInfo->prP2PInfo[prP2pBssInfo
-						       ->u4PrivateData]->u2WFDIELen);
-						kalMemCopy((prMsduInfo->prPacket +
-							    prMsduInfo->u2FrameLength),
-							   prAdapter->prGlueInfo
-							   ->prP2PInfo[prP2pBssInfo->u4PrivateData]->aucWFDIE,
-							   u2EstimatedExtraIELen);
-						prMsduInfo->u2FrameLength += u2EstimatedExtraIELen;
-					}
-				}
-			}	/* IS_STA_P2P_TYPE */
-		} else {
-		}
-	} while (FALSE);
-
+	u2EstimatedExtraIELen = prP2PInfo->u2WFDIELen;
+	if (u2EstimatedExtraIELen > 0
+		&& u2EstimatedExtraIELen < VENDOR_SPECIFIC_IE_LENGTH) {
+		kalMemCopy((prMsduInfo->prPacket + prMsduInfo->u2FrameLength),
+			prP2PInfo->aucWFDIE, u2EstimatedExtraIELen);
+		prMsduInfo->u2FrameLength += u2EstimatedExtraIELen;
+	}
 	return;
 #else
-
 	return;
 #endif
 }				/* wfdFuncGenerateWfdIEForAssocRsp */
diff --git a/mgmt/p2p_role_fsm.c b/mgmt/p2p_role_fsm.c
index f9a3d9e..32b22b3 100644
--- a/mgmt/p2p_role_fsm.c
+++ b/mgmt/p2p_role_fsm.c
@@ -958,6 +958,7 @@
 #if (CFG_HW_WMM_BY_BSS == 1)
 	if (prP2pBssInfo->fgIsWmmInited == FALSE)
 		prP2pBssInfo->ucWmmQueSet = cnmWmmIndexDecision(prAdapter, prP2pBssInfo);
+	prP2pBssInfo->eBand = prP2pConnReqInfo->rChannelInfo.eBand;
 #endif
 #if CFG_SUPPORT_DBDC
 	cnmDbdcEnableDecision(prAdapter, prP2pBssInfo->ucBssIndex, prP2pConnReqInfo->rChannelInfo.eBand);
@@ -1216,6 +1217,7 @@
 #if (CFG_HW_WMM_BY_BSS == 1)
 	if (prP2pBssInfo->fgIsWmmInited == FALSE)
 		prP2pBssInfo->ucWmmQueSet = cnmWmmIndexDecision(prAdapter, prP2pBssInfo);
+	prP2pBssInfo->eBand = prP2pConnReqInfo->rChannelInfo.eBand;
 #endif
 #if CFG_SUPPORT_DBDC
 	cnmDbdcEnableDecision(prAdapter, prP2pBssInfo->ucBssIndex, prP2pConnReqInfo->rChannelInfo.eBand);
@@ -1476,6 +1478,7 @@
 #if (CFG_HW_WMM_BY_BSS == 1)
 		if (prP2pBssInfo->fgIsWmmInited == FALSE)
 			prP2pBssInfo->ucWmmQueSet = cnmWmmIndexDecision(prAdapter, prP2pBssInfo);
+		prP2pBssInfo->eBand = prChnlReqInfo->eBand;
 #endif
 #if CFG_SUPPORT_DBDC
 		cnmDbdcEnableDecision(prAdapter, prP2pBssInfo->ucBssIndex, prChnlReqInfo->eBand);
@@ -1978,6 +1981,7 @@
 #if (CFG_HW_WMM_BY_BSS == 1)
 				if (prP2pBssInfo->fgIsWmmInited == FALSE)
 					prP2pBssInfo->ucWmmQueSet = cnmWmmIndexDecision(prAdapter, prP2pBssInfo);
+				prP2pBssInfo->eBand = prChnlReqInfo->eBand;
 #endif
 #if CFG_SUPPORT_DBDC
 				cnmDbdcEnableDecision(prAdapter,
diff --git a/mgmt/privacy.c b/mgmt/privacy.c
index 96a0672..81dab8d 100644
--- a/mgmt/privacy.c
+++ b/mgmt/privacy.c
@@ -840,21 +840,35 @@
 			for (i = 0; i < MAX_KEY_NUM; i++) {
 				if (prBssInfo->ucBMCWlanIndexSUsed[i])
 					secPrivacyFreeForEntry(prAdapter, prBssInfo->ucBMCWlanIndexS[i]);
+
+#if 0
+				/* move to cfg delete cb function for sync. */
 				prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE;
 				prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY;
+#endif
 			}
+
 			prBssInfo->fgBcDefaultKeyExist = FALSE;
 			prBssInfo->ucBcDefaultKeyIdx = 0xff;
 		}
 	} else {
+		/* According to wh.su's comment, it's ok to change to
+		 * reserved_entry here so that the entry is _NOT_ freed at all.
+		 * In this way, the same BSS(ucBssIndex) could reuse the same
+		 * entry next time in secPrivacySeekForBcEntry(), and we could
+		 * see the following log: "[Wlan index]: Reuse entry ...".
+		 */
 		prBssInfo->ucBMCWlanIndex = WTBL_RESERVED_ENTRY;
 		secPrivacyFreeForEntry(prAdapter, prBssInfo->ucBMCWlanIndex);
 
 		for (i = 0; i < MAX_KEY_NUM; i++) {
 			if (prBssInfo->ucBMCWlanIndexSUsed[i])
 				secPrivacyFreeForEntry(prAdapter, prBssInfo->ucBMCWlanIndexS[i]);
+#if 0
+			/* move to cfg delete cb function for sync. */
 			prBssInfo->ucBMCWlanIndexSUsed[i] = FALSE;
 			prBssInfo->ucBMCWlanIndexS[i] = WTBL_RESERVED_ENTRY;
+#endif
 		}
 		for (i = 0; i < MAX_KEY_NUM; i++) {
 			if (prBssInfo->wepkeyUsed[i])
diff --git a/nic/nic.c b/nic/nic.c
index 4fe165c..807fe4e 100644
--- a/nic/nic.c
+++ b/nic/nic.c
@@ -1292,9 +1292,6 @@
 	prBssInfo->ucBMCWlanIndex =
 	    secPrivacySeekForBcEntry(prAdapter, prBssInfo->ucBssIndex,
 				     prBssInfo->aucOwnMacAddr, STA_REC_INDEX_NOT_FOUND, CIPHER_SUITE_NONE, 0xFF);
-
-	prBssInfo->ucBMCWlanIndexSUsed[0] = TRUE;
-
 	rCmdActivateCtrl.ucBMCWlanIndex = prBssInfo->ucBMCWlanIndex;
 
 	kalMemZero(&rCmdActivateCtrl.ucReserved, sizeof(rCmdActivateCtrl.ucReserved));
diff --git a/nic/nic_tx.c b/nic/nic_tx.c
index a4eb754..2490fd0 100644
--- a/nic/nic_tx.c
+++ b/nic/nic_tx.c
@@ -3490,7 +3490,7 @@
 		if (prAdapter->u4BssAbsentBitmap)
 			DBGLOG(TX, INFO, "fgIsNetAbsent END!\n");
 		QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo);
-		if (QUEUE_IS_NOT_EMPTY(&prAdapter->rBssAbsentQueue[prMsduInfo->ucStaRecIndex]))
+		if (QUEUE_IS_NOT_EMPTY(&prAdapter->rBssAbsentQueue[ucBssIndex]))
 			QUEUE_CONCATENATE_QUEUES(prQue, &prAdapter->rBssAbsentQueue[ucBssIndex]);
 	}
 	prAdapter->u4BssAbsentBitmap &= ~BIT(ucBssIndex);
diff --git a/nic/que_mgt.c b/nic/que_mgt.c
index 8d522c5..ab643fe 100644
--- a/nic/que_mgt.c
+++ b/nic/que_mgt.c
@@ -211,6 +211,26 @@
 } while (0)
 #endif
 
+#define RX_DIRECT_REORDER_LOCK(pad, dbg) \
+do { \
+	P_GLUE_INFO_T _glue = pad->prGlueInfo; \
+	if (!HAL_IS_RX_DIRECT(pad) || !_glue) \
+		break; \
+	if (dbg) \
+		DBGLOG(QM, EVENT, "RX_DIRECT_REORDER_LOCK %d\n", __LINE__); \
+	spin_lock_bh(&_glue->rSpinLock[SPIN_LOCK_RX_DIRECT_REORDER]);\
+} while (0)
+
+#define RX_DIRECT_REORDER_UNLOCK(pad, dbg) \
+do { \
+	P_GLUE_INFO_T _glue = pad->prGlueInfo; \
+	if (!HAL_IS_RX_DIRECT(pad) || !_glue) \
+		break; \
+	if (dbg) \
+		DBGLOG(QM, EVENT, "RX_DIRECT_REORDER_UNLOCK %u\n", __LINE__); \
+	spin_unlock_bh(&_glue->rSpinLock[SPIN_LOCK_RX_DIRECT_REORDER]); \
+} while (0)
+
 /*******************************************************************************
 *                   F U N C T I O N   D E C L A R A T I O N S
 ********************************************************************************
@@ -713,6 +733,7 @@
 
 	DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n");
 
+	RX_DIRECT_REORDER_LOCK(prAdapter, 0);
 	for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) {
 		if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) {
 			if (!prSwRfbListHead) {
@@ -732,11 +753,16 @@
 			}
 
 			QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue));
-
+			if (QM_RX_GET_NEXT_SW_RFB(prSwRfbListTail)) {
+				DBGLOG(QM, ERROR,
+					"QM: non-null tail->next at arRxBaTable[%u]\n",
+					i);
+			}
 		} else {
 			continue;
 		}
 	}
+	RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
 
 	if (prSwRfbListTail) {
 		/* Terminate the MSDU_INFO list with a NULL pointer */
@@ -782,7 +808,7 @@
 
 	/* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */
 	if (prReorderQueParm) {
-
+		RX_DIRECT_REORDER_LOCK(prAdapter, 0);
 		if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) {
 
 			prSwRfbListHead = (P_SW_RFB_T)
@@ -791,11 +817,17 @@
 			    QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue));
 
 			QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue));
-
 		}
+		RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
 	}
 
 	if (prSwRfbListTail) {
+		if (QM_RX_GET_NEXT_SW_RFB(prSwRfbListTail)) {
+			DBGLOG(QM, ERROR,
+				"QM: non-empty tail->next at STA %u TID %u\n",
+				u4StaRecIdx, u4Tid);
+		}
+
 		/* Terminate the MSDU_INFO list with a NULL pointer */
 		QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL);
 	}
@@ -2645,9 +2677,10 @@
 	prReorderQueParm->u4SeqNo = u4SeqNo;
 #endif
 
+	RX_DIRECT_REORDER_LOCK(prAdapter, 0);
 	/* Insert reorder packet */
 	qmInsertReorderPkt(prAdapter, prSwRfb, prReorderQueParm, prReturnedQue);
-
+	RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
 }
 
 VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue)
@@ -2661,8 +2694,6 @@
 	UINT_32 u4SSN;
 	UINT_32 u4WinStart;
 	UINT_32 u4WinEnd;
-	P_QUE_T prReorderQue;
-	/* P_SW_RFB_T prReorderedSwRfb; */
 
 	ASSERT(prSwRfb);
 	ASSERT(prReturnedQue);
@@ -2706,7 +2737,7 @@
 #endif
 
 	/* Check whether the BA agreement exists */
-	prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]);
+	prReorderQueParm = prStaRec->aprRxReorderParamRefTbl[prSwRfb->ucTid];
 	if (!prReorderQueParm) {
 		/* TODO: (Tehuang) Handle the Host-FW sync issue. */
 		DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n");
@@ -2714,8 +2745,9 @@
 		return;
 	}
 
+	RX_DIRECT_REORDER_LOCK(prAdapter, 0);
+
 	u4SSN = (UINT_32) (prSwRfb->u2SSN);
-	prReorderQue = &(prReorderQueParm->rReOrderQue);
 	u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart);
 	u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd);
 
@@ -2727,32 +2759,32 @@
 		/* RX reorder for one MSDU in AMSDU issue */
 		prReorderQueParm->u8LastAmsduSubIdx = RX_PAYLOAD_FORMAT_MSDU;
 #endif
-		DBGLOG(QM, TRACE,
-		       "QM:(BAR)[%d](%ld){%d,%d}\n", prSwRfb->ucTid, u4SSN,
-		       prReorderQueParm->u2WinStart, prReorderQueParm->u2WinEnd);
+		DBGLOG(QM, TRACE, "QM:(BAR)[%u](%u){%u,%u}\n", prSwRfb->ucTid,
+			u4SSN, prReorderQueParm->u2WinStart,
+			prReorderQueParm->u2WinEnd);
 		qmPopOutDueToFallAhead(prAdapter, prReorderQueParm, prReturnedQue);
 	} else {
-		DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd);
+		DBGLOG(QM, TRACE, "QM:(BAR)(%u)(%u){%u,%u}\n", prSwRfb->ucTid,
+			u4SSN, u4WinStart, u4WinEnd);
 	}
+	RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
 }
 
 VOID qmInsertReorderPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb,
 	IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue)
 {
-	P_QUE_T prReorderQue;
-
 	UINT_32 u4SeqNo;
 	UINT_32 u4WinStart;
 	UINT_32 u4WinEnd;
 
 	/* Start to reorder packets */
 	u4SeqNo = (UINT_32) (prSwRfb->u2SSN);
-	prReorderQue = &(prReorderQueParm->rReOrderQue);
 	u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart);
 	u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd);
 
 	/* Debug */
-	DBGLOG(QM, LOUD, "QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
+	DBGLOG(QM, LOUD, "QM:(R)[%u](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo,
+		u4WinStart, u4WinEnd);
 
 	/* Case 1: Fall within */
 	if			/* 0 - start - sn - end - 4095 */
@@ -2767,7 +2799,8 @@
 #if QM_RX_WIN_SSN_AUTO_ADVANCING
 		if (prReorderQueParm->fgIsWaitingForPktWithSsn) {
 			/* Let the first received packet pass the reorder check */
-			DBGLOG(QM, LOUD, "QM:(A)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
+			DBGLOG(QM, LOUD, "QM:(A)[%u](%u){%u,%u}\n",
+				prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
 
 			prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo;
 			prReorderQueParm->u2WinEnd =
@@ -2812,8 +2845,8 @@
 		/* Advance the window after inserting a new tail */
 		prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo;
 		prReorderQueParm->u2WinStart =
-		    (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1)
-		     % MAX_SEQ_NO_COUNT);
+			(prReorderQueParm->u2WinEnd + MAX_SEQ_NO_COUNT -
+			 prReorderQueParm->u2WinSize + 1) % MAX_SEQ_NO_COUNT;
 #if CFG_SUPPORT_RX_AMSDU
 		/* RX reorder for one MSDU in AMSDU issue */
 		prReorderQueParm->u8LastAmsduSubIdx = RX_PAYLOAD_FORMAT_MSDU;
@@ -2834,19 +2867,22 @@
 	else {
 #if QM_RX_WIN_SSN_AUTO_ADVANCING && QM_RX_INIT_FALL_BEHIND_PASS
 		if (prReorderQueParm->fgIsWaitingForPktWithSsn) {
-			DBGLOG(QM, LOUD, "QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
-			qmPopOutReorderPkt(prAdapter, prSwRfb, prReturnedQue, RX_DATA_REORDER_BEHIND_COUNT);
+			DBGLOG(QM, LOUD, "QM:(P)[%u](%u){%u,%u}\n",
+				prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
+			qmPopOutReorderPkt(prAdapter, prSwRfb, prReturnedQue,
+				RX_DATA_REORDER_BEHIND_COUNT);
 			return;
 		}
 #endif
 
 		/* An erroneous packet */
-		DBGLOG(QM, LOUD, "QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd);
+		DBGLOG(QM, LOUD, "QM:(D)[%u](%u){%u,%u}\n", prSwRfb->ucTid,
+			u4SeqNo, u4WinStart, u4WinEnd);
 		prSwRfb->eDst = RX_PKT_DESTINATION_NULL;
-		qmPopOutReorderPkt(prAdapter, prSwRfb, prReturnedQue, RX_DATA_REORDER_BEHIND_COUNT);
+		qmPopOutReorderPkt(prAdapter, prSwRfb, prReturnedQue,
+			RX_DATA_REORDER_BEHIND_COUNT);
 		return;
 	}
-
 }
 
 VOID qmInsertFallWithinReorderPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb,
@@ -2918,6 +2954,7 @@
 #if CFG_SUPPORT_RX_AMSDU
 		prReorderQueParm->fgIsAmsduDuplicated = FALSE;
 #endif
+
 		/* Update the Reorder Queue Parameters according to the found insert position */
 		if (prExaminedQueuedSwRfb == NULL) {
 			/* The received packet shall be placed at the tail */
@@ -2938,7 +2975,6 @@
 		}
 
 		prReorderQue->u4NumElem++;
-
 	}
 
 }
@@ -2956,7 +2992,6 @@
 	prReorderQueParm->fgIsAmsduDuplicated = FALSE;
 #endif
 	prReorderQue = &(prReorderQueParm->rReOrderQue);
-
 	/* There are no packets queued in the Reorder Queue */
 	if (QUEUE_IS_EMPTY(prReorderQue)) {
 		((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL;
@@ -2969,7 +3004,6 @@
 	}
 	prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb;
 	prReorderQue->u4NumElem++;
-
 }
 
 VOID qmPopOutReorderPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue,
@@ -3064,16 +3098,21 @@
 				prReorderQueParm->fgHasBubble = TRUE;
 				prReorderQueParm->u2FirstBubbleSn = prReorderQueParm->u2WinStart;
 
-				DBGLOG(QM, TRACE, "QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n",
-					prReorderQueParm->ucStaRecIdx, prReorderedSwRfb->ucTid,
-					prReorderQueParm->u2FirstBubbleSn, prReorderQueParm->u2WinStart,
+				DBGLOG(QM, TRACE,
+					"QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%u, %u}\n",
+					prReorderQueParm->ucStaRecIdx,
+					prReorderedSwRfb->ucTid,
+					prReorderQueParm->u2FirstBubbleSn,
+					prReorderQueParm->u2WinStart,
 					prReorderQueParm->u2WinEnd);
 			}
 
 			if (fgMissing && CHECK_FOR_TIMEOUT(rCurrentTime, *prMissTimeout,
 				MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) {
 
-				DBGLOG(QM, TRACE, "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid,
+				DBGLOG(QM, TRACE,
+					"QM:RX BA Timout Next Tid %u SSN %u\n",
+					prReorderQueParm->ucTid,
 					prReorderedSwRfb->u2SSN);
 				fgDequeuHead = TRUE;
 				prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT);
@@ -3096,7 +3135,9 @@
 				(((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL;
 			}
 			prReorderQue->u4NumElem--;
-			DBGLOG(QM, LOUD, "QM: [%d] %d (%d)\n", prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen,
+			DBGLOG(QM, LOUD, "QM: [%u] %u (%u)\n",
+				prReorderQueParm->ucTid,
+				prReorderedSwRfb->u2PacketLen,
 				prReorderedSwRfb->u2SSN);
 			qmPopOutReorderPkt(prAdapter, prReorderedSwRfb, prReturnedQue, RX_DATA_REORDER_WITHIN_COUNT);
 		}
@@ -3178,9 +3219,12 @@
 				prReorderQueParm->fgHasBubble = TRUE;
 				prReorderQueParm->u2FirstBubbleSn = prReorderQueParm->u2WinStart;
 
-				DBGLOG(QM, TRACE, "QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n",
-					prReorderQueParm->ucStaRecIdx, prReorderedSwRfb->ucTid,
-					prReorderQueParm->u2FirstBubbleSn, prReorderQueParm->u2WinStart,
+				DBGLOG(QM, TRACE,
+					"QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%u,%u}\n",
+					prReorderQueParm->ucStaRecIdx,
+					prReorderedSwRfb->ucTid,
+					prReorderQueParm->u2FirstBubbleSn,
+					prReorderQueParm->u2WinStart,
 					prReorderQueParm->u2WinEnd);
 			}
 			break;
@@ -3196,8 +3240,10 @@
 				(((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL;
 			}
 			prReorderQue->u4NumElem--;
-			DBGLOG(QM, TRACE, "QM: [%d] %d (%d)\n", prReorderQueParm->ucTid,
-				prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN);
+			DBGLOG(QM, TRACE, "QM: [%u] %u (%u)\n",
+				prReorderQueParm->ucTid,
+				prReorderedSwRfb->u2PacketLen,
+				prReorderedSwRfb->u2SSN);
 
 			qmPopOutReorderPkt(prAdapter, prReorderedSwRfb, prReturnedQue, RX_DATA_REORDER_AHEAD_COUNT);
 		}
@@ -3271,10 +3317,12 @@
 
 		cnmTimerStartTimer(prAdapter, &(prReorderQueParm->rReorderBubbleTimer), QM_RX_BA_ENTRY_MISS_TIMEOUT_MS);
 
-		DBGLOG(QM, TRACE, "QM:(Bub Timer Restart) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n",
-		       prReorderQueParm->ucStaRecIdx,
-		       prReorderQueParm->ucTid,
-		       prReorderQueParm->u2FirstBubbleSn, prReorderQueParm->u2WinStart, prReorderQueParm->u2WinEnd);
+		DBGLOG(QM, TRACE,
+			"QM:(Bub Timer Restart) STA[%u] TID[%u] BubSN[%u] Win{%u,%u}\n",
+		       prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid,
+		       prReorderQueParm->u2FirstBubbleSn,
+		       prReorderQueParm->u2WinStart,
+		       prReorderQueParm->u2WinEnd);
 	}
 
 }
@@ -3318,13 +3366,15 @@
 
 	prReorderQue = &(prReorderQueParm->rReOrderQue);
 
+	RX_DIRECT_REORDER_LOCK(prAdapter, 0);
+
 	if (QUEUE_IS_EMPTY(prReorderQue)) {
 		prReorderQueParm->fgHasBubble = FALSE;
 
 		DBGLOG(QM, TRACE,
 		       "QM:(Bub Check Cancel) STA[%u] TID[%u], Bubble has been filled\n",
 		       prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid);
-
+		RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
 		return;
 	}
 
@@ -3333,10 +3383,12 @@
 
 	/* Expected bubble timeout => pop out packets before win_end */
 	if (prReorderQueParm->u2FirstBubbleSn == prReorderQueParm->u2WinStart) {
-
-		prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_TAIL(prReorderQue);
+		prReorderedSwRfb = (P_SW_RFB_T)QUEUE_GET_TAIL(prReorderQue);
 
 		prReorderQueParm->u2WinStart = prReorderedSwRfb->u2SSN + 1;
+		if (prReorderQueParm->u2WinStart >= MAX_SEQ_NO_COUNT)
+			prReorderQueParm->u2WinStart %= MAX_SEQ_NO_COUNT;
+
 		prReorderQueParm->u2WinEnd =
 		    ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT;
 #if CFG_SUPPORT_RX_AMSDU
@@ -3344,13 +3396,21 @@
 #endif
 		qmPopOutDueToFallAhead(prAdapter, prReorderQueParm, prReturnedQue);
 
-		DBGLOG(QM, TRACE, "QM:(Bub Flush) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n",
-		       prReorderQueParm->ucStaRecIdx,
-		       prReorderQueParm->ucTid,
-		       prReorderQueParm->u2FirstBubbleSn, prReorderQueParm->u2WinStart, prReorderQueParm->u2WinEnd);
+		DBGLOG(QM, TRACE,
+			"QM:(Bub Flush) STA[%u] TID[%u] BubSN[%u] Win{%u,%u}\n",
+			prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid,
+			prReorderQueParm->u2FirstBubbleSn,
+			prReorderQueParm->u2WinStart,
+			prReorderQueParm->u2WinEnd);
 
+		prReorderQueParm->fgHasBubble = FALSE;
+		RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
+
+		/* process prReturnedQue after unlock prReturnedQue */
 		if (QUEUE_IS_NOT_EMPTY(prReturnedQue)) {
-			QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(prReturnedQue), NULL);
+			P_QUE_ENTRY_T prTail = QUEUE_GET_TAIL(prReturnedQue);
+
+			QM_RX_SET_NEXT_SW_RFB((P_SW_RFB_T)prTail, NULL);
 
 			prSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReturnedQue);
 			while (prSwRfb) {
@@ -3366,18 +3426,21 @@
 			DBGLOG(QM, TRACE, "QM:(Bub Flush) STA[%u] TID[%u] Pop Out 0 packet\n",
 			       prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid);
 		}
-
-		prReorderQueParm->fgHasBubble = FALSE;
 	}
 	/* First bubble has been filled but others exist */
 	else {
 		prReorderQueParm->u2FirstBubbleSn = prReorderQueParm->u2WinStart;
-		cnmTimerStartTimer(prAdapter, &(prReorderQueParm->rReorderBubbleTimer), QM_RX_BA_ENTRY_MISS_TIMEOUT_MS);
+		DBGLOG(QM, TRACE,
+			"QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%u,%u}\n",
+			prReorderQueParm->ucStaRecIdx, prReorderQueParm->ucTid,
+			prReorderQueParm->u2FirstBubbleSn,
+			prReorderQueParm->u2WinStart,
+			prReorderQueParm->u2WinEnd);
+		RX_DIRECT_REORDER_UNLOCK(prAdapter, 0);
 
-		DBGLOG(QM, TRACE, "QM:(Bub Timer) STA[%u] TID[%u] BubSN[%u] Win{%d, %d}\n",
-		       prReorderQueParm->ucStaRecIdx,
-		       prReorderQueParm->ucTid,
-		       prReorderQueParm->u2FirstBubbleSn, prReorderQueParm->u2WinStart, prReorderQueParm->u2WinEnd);
+		cnmTimerStartTimer(prAdapter,
+			&(prReorderQueParm->rReorderBubbleTimer),
+			QM_RX_BA_ENTRY_MISS_TIMEOUT_MS);
 	}
 
 	prMissTimeout = &g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid];
@@ -3593,9 +3656,9 @@
 			g_arMissTimeout[ucStaRecIdx][ucTid] = 0;
 
 			DBGLOG(QM, INFO,
-			       "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n",
-			       ucStaRecIdx, ucTid, prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd,
-			       prRxBaEntry->u2WinSize);
+			       "QM: +RxBA(STA=%u TID=%u WinStart=%u WinEnd=%u WinSize=%u)\n",
+			       ucStaRecIdx, ucTid, prRxBaEntry->u2WinStart,
+			       prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize);
 
 			/* Update the BA entry reference table for per-packet lookup */
 			prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry;
@@ -4206,10 +4269,9 @@
 
 					prStaRec->fgIsWmmSupported = TRUE;
 					prStaRec->fgIsUapsdSupported =
-						(((((P_IE_WMM_PARAM_T) pucIE)
-						->ucQosInfo) &
-						WMM_QOS_INFO_UAPSD) ?
-						TRUE : FALSE);
+				(((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo)
+				& WMM_QOS_INFO_UAPSD) ?
+				TRUE : FALSE);
 					break;
 
 				case VENDOR_OUI_SUBTYPE_WMM_INFO:
@@ -4218,10 +4280,9 @@
 
 					prStaRec->fgIsWmmSupported = TRUE;
 					prStaRec->fgIsUapsdSupported =
-						(((((P_IE_WMM_INFO_T) pucIE)
-						->ucQosInfo) &
-						WMM_QOS_INFO_UAPSD) ?
-						TRUE : FALSE);
+					(((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo)
+						& WMM_QOS_INFO_UAPSD) ?
+						     TRUE : FALSE);
 					break;
 
 				default:
diff --git a/os/linux/gl_cfg80211.c b/os/linux/gl_cfg80211.c
index 32d12ce..6a2ada6 100644
--- a/os/linux/gl_cfg80211.c
+++ b/os/linux/gl_cfg80211.c
@@ -2017,11 +2017,11 @@
 	if (data && len)
 		prParams = (struct wpa_driver_hs20_data_s *)data;
 
-	DBGLOG(INIT, INFO, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType);
-
 	if (prParams) {
 		int i;
 
+		DBGLOG(INIT, INFO, "[%s] Cmd Type (%d)\n",
+		__func__, prParams->CmdType);
 		switch (prParams->CmdType) {
 		case HS20_CMD_ID_SET_BSSID_POOL:
 			DBGLOG(INIT, INFO,
@@ -2078,11 +2078,13 @@
 	DBGLOG(INIT, INFO, "--> %s()\n", __func__);
 #endif
 
-	if (data && len)
-		prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data;
+	if (data == NULL || len == 0) {
+		DBGLOG(INIT, TRACE, "%s data or len is invalid\n", __func__);
+		return -EINVAL;
+	}
 
-	if (prParams)
-		prIWEncExt = (struct iw_encode_exts *)&prParams->ext;
+	prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data;
+	prIWEncExt = (struct iw_encode_exts *)&prParams->ext;
 
 	if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
 		/* KeyID */
diff --git a/os/linux/gl_init.c b/os/linux/gl_init.c
index a561c6f..4fa7c64 100644
--- a/os/linux/gl_init.c
+++ b/os/linux/gl_init.c
@@ -1550,7 +1550,7 @@
 
 static void wlanDestroyWirelessDevice(void)
 {
-	set_wiphy_dev(gprWdev->wiphy, NULL);
+	/* Move set_wiphy_dev(wiphy, NULL) in wlanNetDestroy */
 	wiphy_unregister(gprWdev->wiphy);
 	wiphy_free(gprWdev->wiphy);
 	kfree(gprWdev);
@@ -1798,6 +1798,18 @@
 	/* prGlueInfo is allocated with net_device */
 	prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
 	ASSERT(prGlueInfo);
+	/* prWdev: base AIS dev
+	 * Becase the interface dev (ex: usb_device) would be free
+	 * after un-plug event. Should set the wiphy->dev->parent which
+	 * pointer to the interface dev to NULL. Otherwise, the corresponding
+	 * system operation (poweroff, suspend) might reference it.
+	 * set_wiphy_dev(wiphy, NULL): set the wiphy->dev->parent = NULL
+	 * The trunk-ce1 does this, but the trunk seems not.
+	 * ce1 do set_wiphy_dev(prWdev->wiphy, prDev) in wlanNetCreate.
+	 * But that is after wiphy_register, and will cause exception in
+	 * wiphy_unregister(), if do not set_wiphy_dev(wiphy, NULL).
+	 */
+	set_wiphy_dev(prWdev->wiphy, NULL);
 
 	/* destroy kal OS timer */
 	kalCancelTimer(prGlueInfo);
diff --git a/os/linux/gl_p2p.c b/os/linux/gl_p2p.c
index 0682363..eea668b 100644
--- a/os/linux/gl_p2p.c
+++ b/os/linux/gl_p2p.c
@@ -1171,7 +1171,7 @@
 #else
 	int i = 0;
 
-	set_wiphy_dev(gprP2pWdev->wiphy, NULL);
+	/* Move set_wiphy_dev(wiphy, NULL) in wlanNetDestroy */
 
 	wiphy_unregister(gprP2pWdev->wiphy);
 	wiphy_free(gprP2pWdev->wiphy);
diff --git a/os/linux/gl_p2p_init.c b/os/linux/gl_p2p_init.c
index ee6854d..15db164 100644
--- a/os/linux/gl_p2p_init.c
+++ b/os/linux/gl_p2p_init.c
@@ -212,6 +212,7 @@
 /*----------------------------------------------------------------------------*/
 BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo)
 {
+	int idx = 0;
 	if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
 		DBGLOG(P2P, INFO, "p2p is not registered\n");
 		return FALSE;
@@ -221,6 +222,27 @@
 	prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
 	prGlueInfo->prAdapter->p2p_scan_report_all_bss = FALSE;
 	glUnregisterP2P(prGlueInfo);
+
+	/* gprP2pWdev/gprP2pRoleWdev[0]: base P2P dev
+	 * gprP2pRoleWdev[1]: AP dev
+	 * Becase the interface dev (ex: usb_device) would be free
+	 * after un-plug event. Should set the wiphy->dev->parent which
+	 * pointer to the interface dev to NULL. Otherwise, the corresponding
+	 * system operation (poweroff, suspend) might reference it.
+	 * set_wiphy_dev(wiphy, NULL): set the wiphy->dev->parent = NULL
+	 * The trunk-ce1 does this, but the trunk seems not.
+	 * ce1 do set_wiphy_dev(prWdev->wiphy, prDev) in wlanNetCreate.
+	 * But that is after wiphy_register, and will cause exception in
+	 * wiphy_unregister(), if do not set_wiphy_dev(wiphy, NULL).
+	 */
+	for (idx = 0 ; idx < KAL_P2P_NUM; idx++) {
+		if (gprP2pRoleWdev[idx] == NULL)
+			continue;
+
+		DBGLOG(INIT, INFO, "Clean parent dev of P2P[%d] wiphy\n", idx);
+		set_wiphy_dev(gprP2pRoleWdev[idx]->wiphy, NULL);
+	}
+
 	return TRUE;
 }
 
diff --git a/os/linux/gl_vendor.c b/os/linux/gl_vendor.c
index 1a484df..13abe5d 100644
--- a/os/linux/gl_vendor.c
+++ b/os/linux/gl_vendor.c
@@ -839,8 +839,8 @@
 	if (attr->nla_type != WIFI_ATTRIBUTE_COUNTRY_CODE)
 		return -EINVAL;
 
-	country[0] = *((PUINT_8)nla_data(attr));
-	country[1] = *((PUINT_8)nla_data(attr) + 1);
+		country[0] = *((PUINT_8)nla_data(attr));
+		country[1] = *((PUINT_8)nla_data(attr) + 1);
 
 	DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]);
 
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index 0e8eed0..0457cc5 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -943,7 +943,7 @@
 	UINT_32 u4BufLen = 0;
 	int status = 0;
 	P_NDIS_TRANSPORT_STRUCT prNdisReq;
-	INT_32 ch[50];
+	INT_32 ch[MAX_CHN_NUM];
 
 	ASSERT(prNetDev);
 	ASSERT(prIwReqInfo);
@@ -1077,14 +1077,14 @@
 	case PRIV_CMD_GET_CH_LIST:
 		{
 			UINT_16 i, j = 0;
-			UINT_8 NumOfChannel = 50;
-			UINT_8 ucMaxChannelNum = 50;
-			RF_CHANNEL_INFO_T aucChannelList[50];
+			UINT_8 NumOfChannel = MAX_CHN_NUM;
+			UINT_8 ucMaxChannelNum = MAX_CHN_NUM;
+			RF_CHANNEL_INFO_T aucChannelList[MAX_CHN_NUM];
 
 			DBGLOG(RLM, INFO, "Domain: Query Channel List.\n");
 			kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList);
-			if (NumOfChannel > 50)
-				NumOfChannel = 50;
+			if (NumOfChannel > MAX_CHN_NUM)
+				NumOfChannel = MAX_CHN_NUM;
 
 			if (kalIsAPmode(prGlueInfo)) {
 				for (i = 0; i < NumOfChannel; i++) {
@@ -1243,7 +1243,7 @@
 	UINT_32 u4SubCmd;
 	P_GLUE_INFO_T prGlueInfo;
 	int status = 0;
-	INT_32 ch[50];
+	INT_32 ch[MAX_CHN_NUM];
 
 	ASSERT(prNetDev);
 	ASSERT(prIwReqInfo);
@@ -1259,13 +1259,13 @@
 	case PRIV_CMD_GET_CH_LIST:
 		{
 			UINT_16 i;
-			UINT_8 NumOfChannel = 50;
-			UINT_8 ucMaxChannelNum = 50;
-			RF_CHANNEL_INFO_T aucChannelList[50];
+			UINT_8 NumOfChannel = MAX_CHN_NUM;
+			UINT_8 ucMaxChannelNum = MAX_CHN_NUM;
+			RF_CHANNEL_INFO_T aucChannelList[MAX_CHN_NUM];
 
 			kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList);
-			if (NumOfChannel > 50)
-				NumOfChannel = 50;
+			if (NumOfChannel > MAX_CHN_NUM)
+				NumOfChannel = MAX_CHN_NUM;
 
 			for (i = 0; i < NumOfChannel; i++)
 				ch[i] = (INT_32) aucChannelList[i].ucChannelNum;
@@ -11197,6 +11197,16 @@
 
 	bytes_written = priv_driver_cmds(prNetDev, command, priv_cmd.total_len);
 
+	if (bytes_written == -EOPNOTSUPP) {
+		/* Report positive status */
+		INT_32 i4BytesWritten = 0;
+
+		i4BytesWritten += kalSnprintf(command + i4BytesWritten,
+					priv_cmd.total_len - i4BytesWritten,
+					"%s", "NotSupport");
+		bytes_written = i4BytesWritten;
+	}
+
 	if (bytes_written >= 0) {
 		/* priv_cmd in but no response */
 		if ((bytes_written == 0) && (priv_cmd.total_len > 0))
diff --git a/os/linux/include/gl_kal.h b/os/linux/include/gl_kal.h
index 46b28ac..bed8470 100644
--- a/os/linux/include/gl_kal.h
+++ b/os/linux/include/gl_kal.h
@@ -207,6 +207,7 @@
 	/* TX/RX Direct : BEGIN */
 	SPIN_LOCK_TX_DIRECT,
 	SPIN_LOCK_RX_DIRECT,
+	SPIN_LOCK_RX_DIRECT_REORDER,
 	/* TX/RX Direct : END */
 	SPIN_LOCK_IO_REQ,
 	SPIN_LOCK_INT,