qcacld-3.0: Implement ECSA Action Frame

qcacld-2.0 to qcacld-3.0 propagation

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
Этот коммит содержится в:
Abhishek Singh
2015-10-16 16:24:19 +05:30
коммит произвёл Satish Singh
родитель 07acefecec
Коммит 2a8a65d919
5 изменённых файлов: 144 добавлений и 4 удалений

Просмотреть файл

@@ -624,6 +624,27 @@ static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
#define PARAM_TDLS_FEATURE_SUPPORT \
QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED
/**
* hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
* @flags: Pointer to the flags to Add channel switch flag.
*
* This Function adds Channel Switch support flag, if channel switch is
* supported by kernel.
* Return: void.
*/
#ifdef CHANNEL_SWITCH_SUPPORTED
static inline void hdd_add_channel_switch_support(uint32_t *flags)
{
flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
return;
}
#else
static inline void hdd_add_channel_switch_support(uint32_t *flags)
{
return;
}
#endif
/**
* __wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilites.
* @wiphy: WIPHY structure pointer
@@ -4956,6 +4977,8 @@ int wlan_hdd_cfg80211_init(struct device *dev,
wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
#endif
hdd_add_channel_switch_support(&wiphy->flags);
EXIT();
return 0;
}
@@ -10551,6 +10574,72 @@ wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
}
#endif
#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;
uint8_t channel;
uint16_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 = cds_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;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
cds_ssr_unprotect(__func__);
return ret;
}
#endif
/**
* wlan_hdd_convert_nl_iftype_to_hdd_type() - provides the type
* translation from NL to policy manager type
@@ -10708,4 +10797,7 @@ 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
};

Просмотреть файл

@@ -101,6 +101,11 @@
#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS)
#define MAX_SCAN_SSID 10
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) \
|| defined(BACKPORTED_CHANNEL_SWITCH_PRESENT)
#define CHANNEL_SWITCH_SUPPORTED
#endif
/**
* typedef struct qcom_ie_age - age ie
*

Просмотреть файл

@@ -1693,6 +1693,16 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
if (!pHddCtx->config->force_sap_acs)
wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
return CDF_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 CDF_STATUS_E_FAILURE;
else
return CDF_STATUS_SUCCESS;
default:
hddLog(LOG1, "SAP message is not handled");
goto stopbss;
@@ -1883,7 +1893,6 @@ int hdd_softap_unpack_ie(tHalHandle halHandle,
*
* Return: 0 for success, non zero for failure
*/
static
int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
{
CDF_STATUS status;
@@ -1900,7 +1909,6 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
ret = wlan_hdd_validate_context(pHddCtx);
if (ret) {
hddLog(LOGE, FL("invalid HDD context"));
ret = -EBUSY;
return ret;
}
@@ -2251,9 +2259,10 @@ static __iw_softap_setparam(struct net_device *dev,
break;
case QCSAP_PARAM_SET_CHANNEL_CHANGE:
if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) ||
(WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
hddLog(LOG1,
"SET SAP Channel Change to new channel= %d",
"SET Channel Change to new channel= %d",
set_value);
ret = hdd_softap_set_channel_change(dev, set_value);
} else {

Просмотреть файл

@@ -57,6 +57,9 @@ CDF_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held);
eCsrAuthType
hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]);
int hdd_softap_set_channel_change(struct net_device *dev,
int target_channel);
eCsrEncryptionType
hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]);

Просмотреть файл

@@ -215,6 +215,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
#define WE_CLEAR_STATS 86
/* Private sub ioctl for starting/stopping the profiling */
#define WE_START_FW_PROFILE 87
#define WE_SET_CHANNEL 88
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -4938,6 +4939,7 @@ static int __iw_setint_getnone(struct net_device *dev,
int set_value = value[1];
int ret;
int enable_pbm, enable_mp;
CDF_STATUS status;
INIT_COMPLETION(pWextState->completion_var);
memset(&smeConfig, 0x00, sizeof(smeConfig));
@@ -6122,6 +6124,31 @@ static int __iw_setint_getnone(struct net_device *dev,
set_value, DBG_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(hHal,
set_value, pAdapter->sessionId);
if (status != CDF_STATUS_SUCCESS) {
hddLog(LOGE,
FL("Error in change channel status %d"),
status);
ret = -EINVAL;
}
} else {
hddLog(LOGE,
FL("change channel not supported for device mode %d"),
pAdapter->device_mode);
ret = -EINVAL;
}
break;
}
default:
{
hddLog(LOGE, "%s: Invalid sub command %d", __func__,
@@ -10065,6 +10092,10 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "startProfile"},
{WE_SET_CHANNEL,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "setChanChange" },
{WLAN_PRIV_SET_NONE_GET_INT,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,