[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)