summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Singh <absingh@qti.qualcomm.com>2015-08-25 10:41:02 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2015-09-01 14:22:08 +0530
commitcf286234d5c08359a8888ebfc95cf5bd6fbaf02f (patch)
treeefa414636ba93ddf7ba8c919df0341bbbd68ab79
parent3c02341e0fd083b67101ffedcdcacd413dedc4ee (diff)
qcacld-2.0: Implement ECSA Action Frame
Implement: 1. Send & receive logic of ECSA action frame from P2P-CLI/GO 2. Trigger channel change on P2P GO side once ECSA action frame is received by, i) Adding CSA & ESCA IE in beacon template and updating FW to send it out . ii) Notifying supplicant of channel change for P2P GO. This change include HDD changes CRs-fixed: 895240 Change-Id: Iea66ddbbb8946443d5e701e3c14b2f33c6bb6bf8
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h6
-rw-r--r--CORE/HDD/inc/wlan_hdd_hostapd.h1
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c76
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c35
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c25
5 files changed, 127 insertions, 16 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 3300368b9ee5..8eec1200b343 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -103,6 +103,12 @@
#endif
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) \
+ || defined(BACKPORTED_CHANNEL_SWITCH_PRESENT)
+#define CHANNEL_SWITCH_SUPPORTED
+#endif
+
+
#define MAX_CHANNEL (MAX_2_4GHZ_CHANNEL + NUM_5GHZ_CHANNELS)
typedef struct {
diff --git a/CORE/HDD/inc/wlan_hdd_hostapd.h b/CORE/HDD/inc/wlan_hdd_hostapd.h
index 11d74a1b0d74..8a35162a5930 100644
--- a/CORE/HDD/inc/wlan_hdd_hostapd.h
+++ b/CORE/HDD/inc/wlan_hdd_hostapd.h
@@ -111,6 +111,7 @@ hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, bool enabled)
{
}
#endif /* SAP_AUTH_OFFLOAD */
+int hdd_softap_set_channel_change(struct net_device *dev, int target_channel);
/**
* hdd_is_sta_connection_pending() - This function will check if sta connection
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 4e96b7ff42a2..2a932dcd351c 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -124,7 +124,6 @@
#define INVALID_MCS_IDX 255
#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
-
/*
* Android CTS verifier needs atleast this much wait time (in msec)
*/
@@ -10422,6 +10421,11 @@ int wlan_hdd_cfg80211_init(struct device *dev,
#ifdef QCA_HT_2040_COEX
wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
#endif
+
+#ifdef CHANNEL_SWITCH_SUPPORTED
+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+#endif
+
EXIT();
return 0;
}
@@ -21011,6 +21015,72 @@ static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
return ret;
}
+#ifdef CHANNEL_SWITCH_SUPPORTED
+/**
+ * __wlan_hdd_cfg80211_channel_switch()- function to switch
+ * channel in SAP/GO
+ * @wiphy: wiphy pointer
+ * @dev: dev pointer.
+ * @csa_params: Change channel params
+ *
+ * This function is called to switch channel in SAP/GO
+ *
+ * Return: 0 if success else return non zero
+ */
+static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_csa_settings *csa_params)
+{
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx;
+ v_U8_t channel;
+ v_U16_t freq;
+ int ret;
+
+ hddLog(LOG1, FL(" Set Freq %d"), csa_params->chandef.chan->center_freq);
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ ret = wlan_hdd_validate_context(hdd_ctx);
+
+ if (0 != ret) {
+ return ret;
+ }
+
+ if ((WLAN_HDD_P2P_GO != adapter->device_mode) &&
+ (WLAN_HDD_SOFTAP != adapter->device_mode))
+ return -ENOTSUPP;
+
+ freq = csa_params->chandef.chan->center_freq;
+ channel = vos_freq_to_chan(freq);
+
+ ret = hdd_softap_set_channel_change(dev, channel);
+ return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_channel_switch()- function to switch
+ * channel in SAP/GO
+ * @wiphy: wiphy pointer
+ * @dev: dev pointer.
+ * @csa_params: Change channel params
+ *
+ * This function is called to switch channel in SAP/GO
+ *
+ * Return: 0 if success else return non zero
+ */
+static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_csa_settings *csa_params)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
+ vos_ssr_unprotect(__func__);
+ return ret;
+}
+#endif
+
/*
* FUNCTION: __wlan_hdd_cfg80211_resume_wlan
* this is called when cfg80211 driver resume
@@ -22819,4 +22889,8 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops =
.set_ap_chanwidth = wlan_hdd_cfg80211_set_ap_channel_width,
#endif
.dump_survey = wlan_hdd_cfg80211_dump_survey,
+#ifdef CHANNEL_SWITCH_SUPPORTED
+ .channel_switch = wlan_hdd_cfg80211_channel_switch,
+#endif
+
};
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 79552dbba60f..f6d736220ec4 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -2009,6 +2009,15 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
/* send vendor event to hostapd */
wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
return VOS_STATUS_SUCCESS;
+ case eSAP_ECSA_CHANGE_CHAN_IND:
+ hddLog(LOG1,
+ FL("Channel change indication from peer for channel %d"),
+ pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
+ if (hdd_softap_set_channel_change(dev,
+ pSapEvent->sapevt.sap_chan_cng_ind.new_chan))
+ return VOS_STATUS_E_FAILURE;
+ else
+ return VOS_STATUS_SUCCESS;
default:
hddLog(LOG1,"SAP message is not handled");
goto stopbss;
@@ -2191,7 +2200,6 @@ int hdd_softap_unpackIE(
--------------------------------------------------------------------------*/
-static
int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
{
VOS_STATUS status;
@@ -2210,7 +2218,6 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
if (ret)
{
hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid HDD context", __func__);
- ret = -EBUSY;
return ret;
}
@@ -2665,19 +2672,17 @@ static __iw_softap_setparam(struct net_device *dev,
break;
case QCSAP_PARAM_SET_CHANNEL_CHANGE:
- if ( WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode )
- {
- hddLog(LOG1, "SET SAP Channel Change to new channel= %d",
- set_value);
- ret = hdd_softap_set_channel_change(dev, set_value);
- }
- else
- {
- hddLog(LOGE, FL("%s:Channel Change Failed, Device in test mode"),
- __func__);
- ret = -EINVAL;
- }
- break;
+ if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)||
+ (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
+ hddLog(LOG1, "SET Channel Change to new channel= %d",
+ set_value);
+ ret = hdd_softap_set_channel_change(dev, set_value);
+ } else {
+ hddLog(LOGE,
+ FL("Channel Change Failed, Device in test mode"));
+ ret = -EINVAL;
+ }
+ break;
case QCSAP_PARAM_MAX_ASSOC:
if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value)
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index c5a8a98220ca..f606af7410b5 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -245,6 +245,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_SET_CTS_CBW 84
#define WE_DUMP_STATS 85
#define WE_CLEAR_STATS 86
+#define WE_SET_CHANNEL 87
+
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -5845,6 +5847,7 @@ static int __iw_setint_getnone(struct net_device *dev,
int set_value = value[1];
int ret = 0; /* success */
int enable_pbm, enable_mp;
+ eHalStatus status;
#ifdef CONFIG_HAS_EARLYSUSPEND
v_U8_t nEnableSuspendOld;
@@ -7048,6 +7051,24 @@ static int __iw_setint_getnone(struct net_device *dev,
set_value, VDEV_CMD);
break;
}
+ case WE_SET_CHANNEL:
+ {
+ hddLog(LOG1, "Set Channel %d Session ID %d mode = %d", set_value,
+ pAdapter->sessionId, pAdapter->device_mode);
+
+ if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
+ (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
+
+ status = sme_ext_change_channel(pHddCtx->hHal,
+ set_value, pAdapter->sessionId);
+
+ if (status != eHAL_STATUS_SUCCESS)
+ ret = -EINVAL;
+ } else {
+ ret = -EINVAL;
+ }
+ break;
+ }
default:
{
hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
@@ -11484,6 +11505,10 @@ static const struct iw_priv_args we_private_args[] = {
0,
"clearStats" },
+ { WE_SET_CHANNEL,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "setChanChange" },
+
/* handlers for sub-ioctl */
{ WE_GET_11D_STATE,
0,