summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmar Singhal <asinghal@qca.qualcomm.com>2015-06-09 13:19:38 -0700
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2015-06-15 17:33:59 +0530
commitdad9bba046e0b85ba922cfd1945abc9ad6dfdca6 (patch)
tree96f7ea96ed83e09d0f8b5ebb24b7a93b5b999f2f
parente244cedfaccac6362afb6010ec89fbd74a7f0d28 (diff)
qcacld-2.0: Add new DRIVER command SET_FCC_CHANNEL
Due to airplane mode and subsequent change of country, there may be a time gap till a new country code gets programmed into the WLAN sub-system. In order to avoid FCC violation during this period, provide command to enable/disable channels 12/13. Change-Id: I81ddd2688badd3a1a3c6954095692f6fc44765dd CRs-Fixed: 852045
-rwxr-xr-xCORE/HDD/src/wlan_hdd_main.c47
-rw-r--r--CORE/SME/inc/csrInternal.h5
-rw-r--r--CORE/SME/inc/sme_Api.h3
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c6
-rw-r--r--CORE/SME/src/csr/csrApiScan.c5
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c29
6 files changed, 91 insertions, 4 deletions
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 554a1dda0828..183a82630521 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -3860,6 +3860,40 @@ hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen)
#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+/**
+ * drv_cmd_set_fcc_channel() - handle fcc constraint request
+ * @hdd_ctx: HDD context
+ * @cmd: command ptr
+ * @cmd_len: command len
+ *
+ * Return: status
+ */
+static int drv_cmd_set_fcc_channel(hdd_context_t *hdd_ctx, uint8_t *cmd,
+ uint8_t cmd_len)
+{
+ uint8_t *value;
+ uint8_t fcc_constraint;
+ eHalStatus status;
+ int ret = 0;
+
+ value = cmd + cmd_len + 1;
+
+ ret = kstrtou8(value, 10, &fcc_constraint);
+ if ((ret < 0) || (fcc_constraint > 1)) {
+ /*
+ * If the input value is greater than max value of datatype,
+ * then also it is a failure
+ */
+ hddLog(LOGE, FL("value out of range"));
+ return -EINVAL;
+ }
+
+ status = sme_disable_non_fcc_channel(hdd_ctx->hHal, !fcc_constraint);
+ if (status != eHAL_STATUS_SUCCESS)
+ ret = -EPERM;
+
+ return ret;
+}
static int hdd_driver_command(hdd_adapter_t *pAdapter,
hdd_priv_data_t *ppriv_data)
@@ -5999,6 +6033,19 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter,
ret = -EFAULT;
goto exit;
}
+ } else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0) {
+ /*
+ * this command wld be called by user-space when it detects WLAN
+ * ON after airplane mode is set. When APM is set, WLAN turns off.
+ * But it can be turned back on. Otherwise; when APM is turned back
+ * off, WLAN wld turn back on. So at that point the command is
+ * expected to come down. 0 means disable, 1 means enable. The
+ * constraint is removed when parameter 1 is set or different
+ * country code is set
+ */
+
+ ret = drv_cmd_set_fcc_channel(pHddCtx, command, 15);
+
} else {
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 6d86b9218ae2..5b5bb98be88c 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -812,12 +812,9 @@ typedef struct tagCsrScanStruct
tANI_S8 inScanResultBestAPRssi;
eCsrBand scanBandPreference; //This defines the band perference for scan
csrScanCompleteCallback callback11dScanDone;
+ bool fcc_constraint;
}tCsrScanStruct;
-
-
-
-
//Save the connected information. This structure + connectedProfile
//should contain all information about the connection
typedef struct tagRoamCsrConnectedInfo
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 5a50ae6d2768..74deacfb5ded 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -4288,4 +4288,7 @@ typedef void ( *tSmeSetThermalLevelCallback)(void *pContext, u_int8_t level);
void sme_add_set_thermal_level_callback(tHalHandle hHal,
tSmeSetThermalLevelCallback callback);
+eHalStatus sme_disable_non_fcc_channel(tHalHandle hHal,
+ bool fcc_constraint);
+
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index a91da205dae1..8323f88437cd 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -484,6 +484,12 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
for (i = 0; i < pScan->base20MHzChannels.numChannels; i++)
{
+ if (pScan->fcc_constraint) {
+ if (pScan->base20MHzChannels.channelList[i] == 12)
+ continue;
+ if (pScan->base20MHzChannels.channelList[i] == 13)
+ continue;
+ }
channel_state =
vos_nv_getChannelEnabledState(
pScan->base20MHzChannels.channelList[i]);
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index c228be9984c5..982d0e580dac 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -7859,6 +7859,11 @@ void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"Scan offload is enabled, update default chan list");
+ /*
+ * disable fcc constraint since new country code
+ * is being set
+ */
+ pMac->scan.fcc_constraint = false;
status = csrUpdateChannelList(pMac);
if (eHAL_STATUS_SUCCESS != status)
{
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 833387ba030d..8bfcc7066fed 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -16506,3 +16506,32 @@ eHalStatus vos_send_flush_logs_cmd_to_fw(tpAniSirGlobal mac)
sme_ReleaseGlobalLock(&mac->sme);
return status;
}
+
+/**
+ * sme_disable_non_fcc_channel() - non-fcc channel disable request
+ * @hal: HAL pointer
+ * @fcc_constraint: true: disable, false; enable
+ *
+ * Return: eHalStatus.
+ */
+eHalStatus sme_disable_non_fcc_channel(tHalHandle hal, bool fcc_constraint)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal);
+
+ status = sme_AcquireGlobalLock(&mac_ptr->sme);
+
+ if (eHAL_STATUS_SUCCESS == status) {
+
+ if (fcc_constraint != mac_ptr->scan.fcc_constraint) {
+ mac_ptr->scan.fcc_constraint = fcc_constraint;
+
+ /* update the channel list to the firmware */
+ status = csrUpdateChannelList(mac_ptr);
+ }
+
+ sme_ReleaseGlobalLock(&mac_ptr->sme);
+ }
+
+ return status;
+}