[WCNCR00174402] wifi, sync wifi

[Description]
Change wifi driver to MP2_20180427150009

Change-Id: I8ba20cfeedb1437a912bc9e632ce82d21f137ca3
Signed-off-by: Jiehang Zheng <jiehang.zheng@mediatek.com>
CR-Id: WCNCR00174402
Feature: wifi
Reviewed-on: http://gerrit.mediatek.inc:8080/1492307
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 4bd1e6a..c48009d 100644
--- a/common/wlan_lib.c
+++ b/common/wlan_lib.c
@@ -420,7 +420,10 @@
 		HAL_ENABLE_FWDL(prAdapter, TRUE);
 
 		/* 4 <7> Get ECO Version */
-		wlanSetChipEcoInfo(prAdapter);
+		u4Status = wlanSetChipEcoInfo(prAdapter);
+
+		if (u4Status != WLAN_STATUS_SUCCESS)
+			break;
 
 #if CFG_ENABLE_FW_DOWNLOAD
 		/* 4 <8> FW/patch download */
@@ -3726,19 +3729,22 @@
 */
 /*----------------------------------------------------------------------------*/
 
-VOID wlanSetChipEcoInfo(IN P_ADAPTER_T prAdapter)
+WLAN_STATUS wlanSetChipEcoInfo(IN P_ADAPTER_T prAdapter)
 {
 	UINT_32 hw_version, sw_version = 0;
 	struct mt66xx_chip_info *prChipInfo = prAdapter->chip_info;
 	UINT_32 chip_id = prChipInfo->chip_id;
 	/* WLAN_STATUS status; */
+	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
 
 	DEBUGFUNC("wlanSetChipEcoInfo.\n");
 
 	if (wlanAccessRegister(prAdapter, TOP_HVR, &hw_version, 0, 0) != WLAN_STATUS_SUCCESS) {
 		DBGLOG(INIT, ERROR, "wlanSetChipEcoInfo >> get TOP_HVR failed.\n");
+		u4Status = WLAN_STATUS_FAILURE;
 	} else if (wlanAccessRegister(prAdapter, TOP_FVR, &sw_version, 0, 0) != WLAN_STATUS_SUCCESS) {
 		DBGLOG(INIT, ERROR, "wlanSetChipEcoInfo >> get TOP_FVR failed.\n");
+		u4Status = WLAN_STATUS_FAILURE;
 	} else {
 		/* success */
 		nicSetChipHwVer((UINT_8)(GET_HW_VER(hw_version) & 0xFF));
@@ -3751,6 +3757,8 @@
 
 	DBGLOG(INIT, INFO, "Chip ID[%04X] Version[E%u] HW[0x%08x] SW[0x%08x]\n",
 		chip_id, prAdapter->chip_info->eco_ver, hw_version, sw_version);
+
+	return u4Status;
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/include/wlan_lib.h b/include/wlan_lib.h
index 9d4bf5f..dffac81 100644
--- a/include/wlan_lib.h
+++ b/include/wlan_lib.h
@@ -1352,7 +1352,7 @@
 WLAN_STATUS wlanAccessRegisterStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum,
 			IN UINT_8 ucSetQuery, IN PVOID prEvent, IN UINT_32 u4EventLen);
 
-VOID wlanSetChipEcoInfo(IN P_ADAPTER_T prAdapter);
+WLAN_STATUS wlanSetChipEcoInfo(IN P_ADAPTER_T prAdapter);
 
 VOID wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, struct net_device *prDev, BOOLEAN fgSuspend);
 
diff --git a/os/linux/gl_cfg80211.c b/os/linux/gl_cfg80211.c
index 6a2ada6..8636a9c 100644
--- a/os/linux/gl_cfg80211.c
+++ b/os/linux/gl_cfg80211.c
@@ -827,6 +827,11 @@
 	if (prGlueInfo->prScanRequest != NULL)
 		return -EBUSY;
 
+	if (prGlueInfo->u4ReadyFlag == 0) {
+		DBGLOG(REQ, WARN, "prGlueInfo->u4ReadyFlag == 0\n");
+		return -EFAULT;
+	}
+
 	if (request->n_ssids == 0) {
 		rScanRequest.u4SsidNum = 0;
 	} else if (request->n_ssids <= SCN_SSID_MAX_NUM) {
@@ -1412,6 +1417,11 @@
 	if (!prGlueInfo->prAdapter->prAisBssInfo)
 		return -EFAULT;
 
+	if (prGlueInfo->u4ReadyFlag == 0) {
+		DBGLOG(REQ, WARN, "prGlueInfo->u4ReadyFlag == 0\n");
+		return -EFAULT;
+	}
+
 	if (enabled) {
 		if (timeout == -1)
 			rPowerMode.ePowerMode = Param_PowerModeFast_PSP;
diff --git a/os/linux/gl_init.c b/os/linux/gl_init.c
index 478e032..e882606 100644
--- a/os/linux/gl_init.c
+++ b/os/linux/gl_init.c
@@ -1187,7 +1187,6 @@
 static int wlanStop(struct net_device *prDev)
 {
 	P_GLUE_INFO_T prGlueInfo = NULL;
-	struct cfg80211_scan_request *prScanRequest = NULL;
 
 	GLUE_SPIN_LOCK_DECLARATION();
 
@@ -1198,14 +1197,11 @@
 	/* CFG80211 down */
 	GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 	if (prGlueInfo->prScanRequest != NULL) {
-		prScanRequest = prGlueInfo->prScanRequest;
+		kalCfg80211ScanDone(prGlueInfo->prScanRequest, TRUE);
 		prGlueInfo->prScanRequest = NULL;
 	}
 	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 
-	if (prScanRequest)
-		kalCfg80211ScanDone(prScanRequest, TRUE);
-
 #if CFG_AUTO_CHANNEL_SEL_SUPPORT
 	/* zero clear old acs information */
 	kalMemZero(&(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo),
@@ -1216,7 +1212,6 @@
 
 	return 0;		/* success */
 }				/* end of wlanStop() */
-
 #if CFG_SUPPORT_SNIFFER
 static int wlanMonOpen(struct net_device *prDev)
 {
@@ -2360,6 +2355,9 @@
 		if (wlanAdapterStart(prAdapter, prRegInfo) != WLAN_STATUS_SUCCESS)
 			i4Status = -EIO;
 
+		if (i4Status < 0)
+			break;
+
 		if (HAL_IS_TX_DIRECT(prAdapter)) {
 			if (!prAdapter->fgTxDirectInited) {
 				skb_queue_head_init(&prAdapter->rTxDirectSkbQueue);
@@ -2378,9 +2376,6 @@
 
 		/* kfree(prRegInfo); */
 
-		if (i4Status < 0)
-			break;
-
 		INIT_WORK(&prGlueInfo->rTxMsduFreeWork, kalFreeTxMsduWorker);
 		INIT_DELAYED_WORK(&prGlueInfo->rRxPktDeAggWork, halDeAggRxPktWorker);
 
@@ -2432,30 +2427,19 @@
 		rlmDomainSendInfoToFirmware(prAdapter);
 
 		/* set MAC address */
-		{
-			WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
-			struct sockaddr MacAddr;
-			UINT_32 u4SetInfoLen = 0;
+		if (prAdapter && prAdapter->rWifiVar.aucMacAddress) {
+			kalMemCopy(prGlueInfo->prDevHandler->dev_addr,
+			prAdapter->rWifiVar.aucMacAddress, ETH_ALEN);
+			kalMemCopy(prGlueInfo->prDevHandler->perm_addr,
+			prGlueInfo->prDevHandler->dev_addr, ETH_ALEN);
 
-			rStatus = kalIoctl(prGlueInfo,
-					   wlanoidQueryCurrentAddr,
-					   &MacAddr.sa_data, PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, &u4SetInfoLen);
-
-			if (rStatus != WLAN_STATUS_SUCCESS) {
-				DBGLOG(INIT, WARN, "set MAC addr fail 0x%lx\n", rStatus);
-				prGlueInfo->u4ReadyFlag = 0;
-			} else {
-				kalMemCopy(prGlueInfo->prDevHandler->dev_addr, &MacAddr.sa_data, ETH_ALEN);
-				kalMemCopy(prGlueInfo->prDevHandler->perm_addr,
-					   prGlueInfo->prDevHandler->dev_addr, ETH_ALEN);
-
-				/* card is ready */
-				prGlueInfo->u4ReadyFlag = 1;
 #if CFG_SHOW_MACADDR_SOURCE
-				DBGLOG(INIT, INFO, "MAC address: " MACSTR, MAC2STR(&MacAddr.sa_data));
+			DBGLOG(INIT, ERROR, "MAC address: " MACSTR,
+			MAC2STR(prAdapter->rWifiVar.aucMacAddress));
 #endif
-			}
-		}
+
+		} else
+			prGlueInfo->u4ReadyFlag = 0;
 
 #if CFG_TCP_IP_CHKSUM_OFFLOAD
 		/* set HW checksum offload */
@@ -2613,15 +2597,8 @@
 			}
 		}
 #endif
-
-		DBGLOG(INIT, LOUD, "wlanProbe: probe success\n");
-	} else {
-		if (prGlueInfo == NULL)
-			return -1;
-
-		glBusFreeIrq(prGlueInfo->prDevHandler, prGlueInfo);
-		DBGLOG(INIT, LOUD, "wlanProbe: probe failed\n");
-	}
+		/* card is ready */
+		prGlueInfo->u4ReadyFlag = 1;
 
 #if CFG_SUPPORT_REPLAY_DETECTION
 	ucRpyDetectOffload = prAdapter->rWifiVar.ucRpyDetectOffload;
@@ -2636,6 +2613,14 @@
 			GTK_REKEY_CMD_MODE_RPY_OFFLOAD_OFF);
 	}
 #endif
+		DBGLOG(INIT, LOUD, "wlanProbe: probe success\n");
+	} else {
+		if (prGlueInfo == NULL)
+			return -1;
+
+		glBusFreeIrq(prGlueInfo->prDevHandler, prGlueInfo);
+		DBGLOG(INIT, LOUD, "wlanProbe: probe failed\n");
+	}
 
 	return i4Status;
 }				/* end of wlanProbe() */
@@ -2688,6 +2673,8 @@
 
 	prAdapter = prGlueInfo->prAdapter;
 
+	prGlueInfo->u4ReadyFlag = 0;
+
 #if CFG_ENABLE_BT_OVER_WIFI
 	if (prGlueInfo->rBowInfo.fgIsNetRegistered) {
 		bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter);
diff --git a/os/linux/gl_kal.c b/os/linux/gl_kal.c
index d71dc8a..9767852 100644
--- a/os/linux/gl_kal.c
+++ b/os/linux/gl_kal.c
@@ -957,7 +957,6 @@
 	P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus;
 	P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1);
 	PARAM_MAC_ADDRESS arBssid;
-	struct cfg80211_scan_request *prScanRequest = NULL;
 	PARAM_SSID_T ssid;
 	struct ieee80211_channel *prChannel = NULL;
 	struct cfg80211_bss *bss;
@@ -1143,15 +1142,12 @@
 		/* 1. reset first for newly incoming request */
 		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 		if (prGlueInfo->prScanRequest != NULL) {
-			prScanRequest = prGlueInfo->prScanRequest;
+			/* 2. then CFG80211 Indication */
+			kalCfg80211ScanDone(prGlueInfo->prScanRequest, FALSE);
 			prGlueInfo->prScanRequest = NULL;
 		}
 		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 
-		/* 2. then CFG80211 Indication */
-		if (prScanRequest)
-			kalCfg80211ScanDone(prScanRequest, FALSE);
-
 		break;
 
 #if 0
diff --git a/os/linux/gl_p2p.c b/os/linux/gl_p2p.c
index eea668b..674f4d9 100644
--- a/os/linux/gl_p2p.c
+++ b/os/linux/gl_p2p.c
@@ -1423,15 +1423,11 @@
 	if ((prP2pGlueDevInfo->prScanRequest != NULL) &&
 		(prP2pGlueDevInfo->prScanRequest->wdev == prTargetDev->ieee80211_ptr)) {
 		prScanRequest = prP2pGlueDevInfo->prScanRequest;
+		kalCfg80211ScanDone(prScanRequest, TRUE);
 		prP2pGlueDevInfo->prScanRequest = NULL;
 	}
 	GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 
-	if (prScanRequest) {
-		DBGLOG(INIT, INFO, "p2pStop and abort scan!!\n");
-		kalCfg80211ScanDone(prScanRequest, TRUE);
-	}
-
 	/* 1. stop TX queue */
 	netif_tx_stop_all_queues(prDev);
 #if 0
diff --git a/os/linux/gl_p2p_kal.c b/os/linux/gl_p2p_kal.c
index 457b109..4bd6b87 100644
--- a/os/linux/gl_p2p_kal.c
+++ b/os/linux/gl_p2p_kal.c
@@ -1080,21 +1080,33 @@
 		DBGLOG(INIT, INFO, "[p2p] scan complete %p\n", prP2pGlueDevInfo->prScanRequest);
 
 		KAL_ACQUIRE_MUTEX(prGlueInfo->prAdapter, MUTEX_DEL_INF);
-		GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 
-		if (prP2pGlueDevInfo->prScanRequest != NULL) {
+		/* The cfg80211_scan_done may be interruptd by the p2pStop.
+		 * And the following kernel process calls __cfg80211_scan_done,
+		 * that causes some issue. the temporary solution is putting
+		 * the scan_done inside the lock. ref: change 1022227.
+		 */
+		if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
+			GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 			prScanRequest = prP2pGlueDevInfo->prScanRequest;
-			prP2pGlueDevInfo->prScanRequest = NULL;
-		}
-		GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+			GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 
-		if ((prScanRequest != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) {
-
-			/* report all queued beacon/probe response frames  to upper layer */
-			scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL);
-
-			DBGLOG(INIT, INFO, "DBG:p2p_cfg_scan_done\n");
-			kalCfg80211ScanDone(prScanRequest, fgIsAbort);
+			if (prScanRequest != NULL) {
+				scanReportBss2Cfg80211(prGlueInfo->prAdapter,
+						BSS_TYPE_P2P_DEVICE, NULL);
+			}
+			/* scanReportBss2Cfg80211() do many works, so don't put
+			 * it inside the lock. And its main function puts bss
+			 * to cfg80211, that isn't related to scan_req.
+			 */
+			GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
+			prScanRequest = prP2pGlueDevInfo->prScanRequest;
+			if (prScanRequest != NULL) {
+				DBGLOG(INIT, INFO, "DBG:p2p_cfg_scan_done\n");
+				kalCfg80211ScanDone(prScanRequest, fgIsAbort);
+				prP2pGlueDevInfo->prScanRequest = NULL;
+			}
+			GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
 		}
 		KAL_RELEASE_MUTEX(prGlueInfo->prAdapter, MUTEX_DEL_INF);
 
diff --git a/os/linux/hif/usb/usb.c b/os/linux/hif/usb/usb.c
index 9c882d0..9cdf425 100644
--- a/os/linux/hif/usb/usb.c
+++ b/os/linux/hif/usb/usb.c
@@ -204,6 +204,12 @@
 	dev = interface_to_usbdev(intf);
 	dev = usb_get_dev(dev);
 
+	/* Prevent un-expected usb operation  */
+	if (g_fgDriverProbed) {
+		DBGLOG(HAL, ERROR, "wlan_probe(): Device already probed!!\n");
+		return -EBUSY;
+	}
+
 	DBGLOG(HAL, EVENT, "wlan_probe()\n");
 	if (pfWlanProbe((PVOID) intf, (PVOID) id->driver_info) != WLAN_STATUS_SUCCESS) {
 		/* printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); */