[WCNCR00147259] regd: fix crash problem if setting country multiple times

[Description]
Fix crash problem of regd and refine regd messages
1. Fix crash/assert problem when user sets country code for multiple times
2. Fix crash problem of issuing command 'iwpriv wlan0 driver get_channels'
3. Refine/shorten log messages when updating regd channels
4. Refine display messages of "get_channels" result
5. Modify Makefile.x86 to allow changing ko chip name

Feature: regd
Change-Id: I584b92fa29fef250ae48655b4efe77861a885889
Signed-off-by: Sarick Jiang <sarick.jiang@mediatek.com>
CR-Id: WCNCR00147259
diff --git a/Makefile b/Makefile
index 78d805d..c741963 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,9 @@
 ccflags-y += $(WLAN_CHIP_LIST)
 
 #WLAN_CHIP_ID=$(MTK_COMBO_CHIP)
-WLAN_CHIP_ID=MT6632
+ifeq ($(WLAN_CHIP_ID),)
+    WLAN_CHIP_ID := MT6632
+endif
 
 ccflags-y += -DCFG_SUPPORT_DEBUG_FS=0
 ccflags-y += -DWLAN_INCLUDE_PROC
diff --git a/Makefile.x86 b/Makefile.x86
index 9a57aaf..b30db1e 100644
--- a/Makefile.x86
+++ b/Makefile.x86
@@ -1,7 +1,14 @@
+# Makefile.x86: Makefile for Linux PC
+# You can build specific .ko name by assiging the WLAN_CHIP_ID parameter
+# Default=wlan_mt6632_usb.ko:
+# 	make -f Makefile.x86
+# wlan_mt7668_usb.ko:
+# 	make -f Makefile.x86 WLAN_CHIP_ID=mt7668
+
 LINUX_SRC=/lib/modules/$(shell uname -r)/build
+WLAN_CHIP_ID := MT6632
 
 export CONFIG_MTK_COMBO_PLATFORM=x86
-export MTK_COMBO_CHIP=MT6632
 
 PWD=$(shell pwd)
 DRIVER_DIR=$(PWD)
@@ -19,7 +26,7 @@
     hif=usb
 endif
 
-MODULES_NAME := wlan_$(shell echo $(MTK_COMBO_CHIP) | tr A-Z a-z)
+MODULES_NAME := wlan_$(shell echo $(WLAN_CHIP_ID) | tr A-Z a-z)
 
 export CONFIG_MTK_COMBO_WIFI_HIF=$(hif)
 
@@ -46,12 +53,12 @@
 all: driver
 
 driver:
-	+cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) PLATFORM_FLAGS="$(PLATFORM_FLAGS)" modules
+	+cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) PLATFORM_FLAGS="$(PLATFORM_FLAGS)" WLAN_CHIP_ID=$(WLAN_CHIP_ID) modules
 	@cd $(DRIVER_DIR) && cp $(MODULES_NAME)_$(hif).ko $(MODULES_NAME).ko
 
 clean: driver_clean
 
 driver_clean:
-	cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) clean
+	cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) WLAN_CHIP_ID=$(WLAN_CHIP_ID) clean
 
 .PHONY: all clean driver driver_clean
diff --git a/include/debug.h b/include/debug.h
index 3b82fe3..4a8f94d 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -310,12 +310,12 @@
 /* LOG function for print to buffer */
 /* If buffer pointer is NULL, redirect to normal DBGLOG */
 #define LOGBUF(_pucBuf, _maxLen, _curLen, _Fmt, ...) \
-	{ \
+	do { \
 		if (_pucBuf) \
 			(_curLen) += kalSnprintf((_pucBuf) + (_curLen), (_maxLen) - (_curLen), _Fmt, ##__VA_ARGS__); \
 		else \
 			DBGLOG(SW4, INFO, _Fmt, ##__VA_ARGS__); \
-	}
+	} while (0)
 /* The following macro is used for debugging packed structures. */
 #ifndef DATA_STRUCT_INSPECTING_ASSERT
 #define DATA_STRUCT_INSPECTING_ASSERT(expr) \
diff --git a/mgmt/rlm_domain.c b/mgmt/rlm_domain.c
index 9ab4e9b..4220363 100644
--- a/mgmt/rlm_domain.c
+++ b/mgmt/rlm_domain.c
@@ -2303,12 +2303,12 @@
 		break;
 
 	case REGD_STATE_SET_COUNTRY_USER:
-		if ((old_state == REGD_STATE_SET_WW_CORE) || (old_state == REGD_STATE_INIT))
+		/* Allow user to set multiple times */
+		if ((old_state == REGD_STATE_SET_WW_CORE) || (old_state == REGD_STATE_INIT)
+		    || old_state == REGD_STATE_SET_COUNTRY_USER)
 			next_state = request_state;
-		else if ((old_state == request_state)
-				 && (rlmDomainIsSameCountryCode(pRequest->alpha2, sizeof(pRequest->alpha2))))
-			next_state = old_state;
-
+		else
+			DBGLOG(RLM, ERROR, "Invalid old state = %d\n", old_state);
 		break;
 	case REGD_STATE_SET_COUNTRY_DRIVER:
 		/*check if country is the same as previous one*/
@@ -2393,6 +2393,38 @@
 	return g_mtk_regd_control.pRefWiphy;
 }
 
+/**
+ * rlmDomainChannelFlagString - Transform channel flags to readable string
+ *
+ * @ flags: the ieee80211_channel->flags for a channel
+ * @ buf: string buffer to put the transformed string
+ * @ buf_size: size of the buf
+ **/
+void rlmDomainChannelFlagString(u32 flags, char *buf, size_t buf_size)
+{
+	INT_32 buf_written = 0;
+
+	if (!flags || !buf || !buf_size)
+		return;
+
+	if (flags & IEEE80211_CHAN_DISABLED) {
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, "DISABLED ");
+		/* If DISABLED, don't need to check other flags */
+		return;
+	}
+	if (flags & IEEE80211_CHAN_PASSIVE_FLAG)
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, IEEE80211_CHAN_PASSIVE_STR " ");
+	if (flags & IEEE80211_CHAN_RADAR)
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, "RADAR ");
+	if (flags & IEEE80211_CHAN_NO_HT40PLUS)
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, "NO_HT40PLUS ");
+	if (flags & IEEE80211_CHAN_NO_HT40MINUS)
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, "NO_HT40MINUS ");
+	if (flags & IEEE80211_CHAN_NO_80MHZ)
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, "NO_80MHZ ");
+	if (flags & IEEE80211_CHAN_NO_160MHZ)
+		LOGBUF(buf, ((INT_32)buf_size), buf_written, "NO_160MHZ ");
+}
 
 void rlmDomainParsingChannel(IN struct wiphy *pWiphy)
 {
@@ -2401,6 +2433,7 @@
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_channel *chan;
 	struct channel *pCh;
+	char chan_flag_string[64] = {0};
 
 
 	if (!pWiphy) {
@@ -2436,11 +2469,13 @@
 		for (ch_idx = 0; ch_idx < sband->n_channels; ch_idx++) {
 			chan = &sband->channels[ch_idx];
 			pCh = (rlmDomainGetActiveChannels() + ch_count);
+			/* Parse flags and get readable string */
+			rlmDomainChannelFlagString(chan->flags, chan_flag_string, sizeof(chan_flag_string));
 
 			if (chan->flags & IEEE80211_CHAN_DISABLED) {
-				DBGLOG(RLM, INFO, "[DISABLE] channel[%d][%d]: freq = %d, ch_num = %d\n",
-					band_idx, ch_idx, chan->center_freq, chan->hw_value);
-
+				DBGLOG(RLM, INFO, "channels[%d][%d]: ch%d (freq = %d) flags=0x%x [ %s]\n",
+				    band_idx, ch_idx, chan->hw_value, chan->center_freq, chan->flags,
+				    chan_flag_string);
 				continue;
 			}
 
@@ -2452,13 +2487,9 @@
 
 			rlmDomainAddActiveChannel(band_idx);
 
-			DBGLOG(RLM, INFO, "[EN-ABLE] channel[%d][%d]: freq = %d, ch_num = %d ",
-					band_idx, ch_idx, chan->center_freq, chan->hw_value);
-
-			DBGLOG(RLM, INFO, "flags = %x (radar = %d, no ht40 PLUS = %d, no ht40 minus = %d)\n",
-					chan->flags, (chan->flags & IEEE80211_CHAN_RADAR)?1:0,
-								(chan->flags & IEEE80211_CHAN_NO_HT40PLUS)?1:0,
-								(chan->flags & IEEE80211_CHAN_NO_HT40MINUS)?1:0);
+			DBGLOG(RLM, INFO, "channels[%d][%d]: ch%d (freq = %d) flgs=0x%x [ %s]\n",
+				band_idx, ch_idx, chan->hw_value, chan->center_freq, chan->flags,
+				chan_flag_string);
 
 			pCh->chNum = chan->hw_value;
 			pCh->flags = chan->flags;
diff --git a/os/linux/gl_cfg80211.c b/os/linux/gl_cfg80211.c
index d9e4c32..1856079 100644
--- a/os/linux/gl_cfg80211.c
+++ b/os/linux/gl_cfg80211.c
@@ -3233,7 +3233,6 @@
 		return;
 	}
 
-
 	/*
 	 * Magic flow for driver to send inband command after kernel's calling reg_notifier callback
 	 */
@@ -3281,14 +3280,20 @@
 	/*
 	 * State machine transition
 	 */
-	DBGLOG(RLM, INFO, "request->alpha2 = %s, initiator = %x\n", pRequest->alpha2, pRequest->initiator);
+	DBGLOG(RLM, INFO, "request->alpha2=%s, initiator=%x, intersect=%d\n",
+			pRequest->alpha2, pRequest->initiator, pRequest->intersect);
 
 	old_state = rlmDomainGetCtrlState();
 	regd_state_machine(pRequest);
 
-	if (rlmDomainGetCtrlState() == old_state)
-		return; /*the same state. no need to go further process*/
-	else if (rlmDomainIsCtrlStateEqualTo(REGD_STATE_INVALID)) {
+	if (rlmDomainGetCtrlState() == old_state) {
+		if (old_state == REGD_STATE_SET_COUNTRY_USER &&
+		    !(rlmDomainIsSameCountryCode(pRequest->alpha2, sizeof(pRequest->alpha2))))
+			DBGLOG(RLM, INFO, "Set by user to NEW country code\n");
+		else
+			/* Change to same state or same country, ignore */
+			return;
+	} else if (rlmDomainIsCtrlStateEqualTo(REGD_STATE_INVALID)) {
 		DBGLOG(RLM, ERROR, "\n%s():\n---> ERROR. Transit to invalid state.\n", __func__);
 		DBGLOG(RLM, ERROR, "---> ERROR. Ignore country code updateing.\n");
 		DBGLOG(RLM, ERROR, "---> ERROR.\n ");
@@ -3296,7 +3301,6 @@
 		return; /*error state*/
 	}
 
-
 	/*
 	 * Set country code
 	 */
@@ -3317,11 +3321,9 @@
 	}
 
 
-
 DOMAIN_SEND_CMD:
 	DBGLOG(RLM, INFO, "g_mtk_regd_control.alpha2 = 0x%x\n", rlmDomainGetCountryCode());
 
-
 	/*
 	 * Check if using customized regulatory rule
 	 */
@@ -3352,7 +3354,6 @@
 	}
 
 
-
 	/*
 	 * Parsing channels
 	 */
@@ -3371,7 +3372,6 @@
 
 	prGlueInfo = rlmDomainGetGlueInfo();
 
-
 	/*
 	 * Prepare to send channel information to firmware
 	 */
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index f23f802..eaa35f4 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -5751,7 +5751,7 @@
 	UINT_32 ch_idx, start_idx, end_idx;
 	struct channel *pCh;
 	UINT_32 ch_num = 0;
-	UINT_8	old_format = 0;
+	UINT_8 maxbw = 160;
 #endif
 
 	ASSERT(prNetDev);
@@ -5763,33 +5763,28 @@
 	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
 
 	if (!regd_is_single_sku_en()) {
-		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Not Supported.")
+		LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Not Supported.");
 		return i4BytesWritten;
 	}
 
 #if (CFG_SUPPORT_SINGLE_SKU == 1)
-	if ((apcArgv[1][0] == '2') && (apcArgv[1][1] == 'g')) {
+	/**
+	 * Usage: iwpriv wlan0 driver "get_channels [2g |5g |ch_num]"
+	 **/
+	if (i4Argc >= 2 && (apcArgv[1][0] == '2') && (apcArgv[1][1] == 'g')) {
 		start_idx = 0;
 		end_idx = rlmDomainGetActiveChannelCount(IEEE80211_BAND_2GHZ);
-	} else if ((apcArgv[1][0] == '5') && (apcArgv[1][1] == 'g')) {
+	} else if (i4Argc >= 2 && (apcArgv[1][0] == '5') && (apcArgv[1][1] == 'g')) {
 		start_idx = rlmDomainGetActiveChannelCount(IEEE80211_BAND_2GHZ);
 		end_idx = rlmDomainGetActiveChannelCount(IEEE80211_BAND_2GHZ)
-					+ rlmDomainGetActiveChannelCount(IEEE80211_BAND_5GHZ);
+				+ rlmDomainGetActiveChannelCount(IEEE80211_BAND_5GHZ);
 	} else {
 		start_idx = 0;
 		end_idx = rlmDomainGetActiveChannelCount(IEEE80211_BAND_2GHZ)
-					+ rlmDomainGetActiveChannelCount(IEEE80211_BAND_5GHZ);
-	}
-
-	if (i4Argc == 3) {
-		/*specific channel detail information*/
-		u4Ret = kalkStrtou32(apcArgv[2], 0, &ch_num);
-	} else if (i4Argc == 2) {
-		/*show active channels only*/
-		old_format = 0;
-	} else {
-		/* old format: 7662*/
-		old_format = 1;
+				+ rlmDomainGetActiveChannelCount(IEEE80211_BAND_5GHZ);
+		if (i4Argc >= 2)
+			/* Dump only specified channel */
+			u4Ret = kalkStrtou32(apcArgv[1], 0, &ch_num);
 	}
 
 	if (regd_is_single_sku_en()) {
@@ -5799,90 +5794,27 @@
 
 			pCh = (rlmDomainGetActiveChannels() + ch_idx);
 
-			if ((ch_num != pCh->chNum) && (ch_num != 0))
+			if (ch_num && (ch_num != pCh->chNum))
 				continue; /*show specific channel information*/
 
-			LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "CH-%d: ",
+			/* Channel number */
+			LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "CH-%d:",
 					pCh->chNum);
-
-			if ((ch_num == 0) && (!old_format))
-				continue; /*show all active channels*/
-
-
-			if (old_format) {
-				UINT_8 passive_scan = 0;
-				UINT_8 bw = 160;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
-				passive_scan = ((pCh->flags & IEEE80211_CHAN_PASSIVE_SCAN)?1:0);
-#else
-				passive_scan = ((pCh->flags & IEEE80211_CHAN_NO_IR)?1:0);
-#endif
-				if (passive_scan) {
-					/*passive*/
-					LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Status = Passive, ");
-				} else {
-					/*active*/
-					LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "Status = Active, ");
-				}
-
-				/*max bandwidth detection*/
-				if ((pCh->flags & IEEE80211_CHAN_NO_160MHZ) == IEEE80211_CHAN_NO_160MHZ)
-					bw = 80;
-
-				if ((pCh->flags & IEEE80211_CHAN_NO_80MHZ) == IEEE80211_CHAN_NO_80MHZ)
-					bw = 40;
-
-				if ((pCh->flags & IEEE80211_CHAN_NO_HT40) == IEEE80211_CHAN_NO_HT40)
-					bw = 20;
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "MaxBw = %d\n", bw);
-			} else {
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_IR/PASSIVE SCAN = %d\n",
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
-						(pCh->flags & IEEE80211_CHAN_PASSIVE_SCAN)?1:0);
-#else
-						(pCh->flags & IEEE80211_CHAN_NO_IR)?1:0);
-#endif
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tRADAR_DETECT = %d\n",
-						(pCh->flags & IEEE80211_CHAN_RADAR)?1:0);
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_HT40 = %d\n",
-#if 1
-						((pCh->flags & IEEE80211_CHAN_NO_HT40) == IEEE80211_CHAN_NO_HT40)?1:0);
-#else
-						((pCh->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
-						(pCh->flags & IEEE80211_CHAN_NO_HT40MINUS))?1:0);
-#endif
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_OFDM = %d\n",
-						(pCh->flags & IEEE80211_CHAN_NO_OFDM)?1:0);
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_80MHZ = %d\n",
-						(pCh->flags & IEEE80211_CHAN_NO_80MHZ)?1:0);
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_160MHZ = %d\n",
-						(pCh->flags & IEEE80211_CHAN_NO_160MHZ)?1:0);
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 15, 0)
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tINDOOR_ONLY = %d\n",
-						(pCh->flags & IEEE80211_CHAN_INDOOR_ONLY)?1:0);
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 1, 0)
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tIR_CONCURRENT = %d\n",
-						(pCh->flags & IEEE80211_CHAN_IR_CONCURRENT)?1:0);
-#else
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tIR_CONCURRENT = %d\n",
-						(pCh->flags & IEEE80211_CHAN_GO_CONCURRENT)?1:0);
-#endif
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_20MHZ = %d\n",
-						(pCh->flags & IEEE80211_CHAN_NO_20MHZ)?1:0);
-
-				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\tNO_10MHz = %d\n",
-						(pCh->flags & IEEE80211_CHAN_NO_10MHZ)?1:0);
-#endif
-			}
+			/* Active/Passive */
+			if (pCh->flags & IEEE80211_CHAN_PASSIVE_FLAG)
+				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, " " IEEE80211_CHAN_PASSIVE_STR);
+			else
+				LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, " ACTIVE");
+			/* Max BW */
+			if ((pCh->flags & IEEE80211_CHAN_NO_160MHZ) == IEEE80211_CHAN_NO_160MHZ)
+				maxbw = 80;
+			if ((pCh->flags & IEEE80211_CHAN_NO_80MHZ) == IEEE80211_CHAN_NO_80MHZ)
+				maxbw = 40;
+			if ((pCh->flags & IEEE80211_CHAN_NO_HT40) == IEEE80211_CHAN_NO_HT40)
+				maxbw = 20;
+			LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, " BW_%dMHz", maxbw);
+			/* Channel flags */
+			LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "  (flags=0x%x)\n", pCh->flags);
 		}
 	}
 #endif
diff --git a/os/linux/include/gl_kal.h b/os/linux/include/gl_kal.h
index beee4b8..f292775 100644
--- a/os/linux/include/gl_kal.h
+++ b/os/linux/include/gl_kal.h
@@ -427,6 +427,17 @@
 #define KAL_GET_PKT_ARRIVAL_TIME(_p)            GLUE_GET_PKT_ARRIVAL_TIME(_p)
 
 /*----------------------------------------------------------------------------*/
+/* Macros for kernel related defines                      */
+/*----------------------------------------------------------------------------*/
+#if KERNEL_VERSION(3, 14, 0) > LINUX_VERSION_CODE
+#define IEEE80211_CHAN_PASSIVE_FLAG	IEEE80211_CHAN_PASSIVE_SCAN
+#define IEEE80211_CHAN_PASSIVE_STR		"PASSIVE"
+#else
+#define IEEE80211_CHAN_PASSIVE_FLAG	IEEE80211_CHAN_NO_IR
+#define IEEE80211_CHAN_PASSIVE_STR		"NO_IR"
+#endif
+
+/*----------------------------------------------------------------------------*/
 /* Macros of wake_lock operations for using in Driver Layer                   */
 /*----------------------------------------------------------------------------*/
 #if defined(CONFIG_ANDROID) && (CFG_ENABLE_WAKE_LOCK)