diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 0de818425292..b62dea1d3592 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1120,6 +1120,8 @@ struct hdd_adapter { struct hdd_ap_ctx ap; } session; + qdf_atomic_t dfs_radar_found; + #ifdef WLAN_FEATURE_TSF /* tsf value received from firmware */ uint64_t cur_target_time; @@ -1545,7 +1547,6 @@ struct hdd_context { /* defining the firmware version */ uint32_t target_fw_version; uint32_t target_fw_vers_ext; - qdf_atomic_t dfs_radar_found; /* defining the chip/rom version */ uint32_t target_hw_version; @@ -2164,13 +2165,15 @@ int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason); * hdd_switch_sap_channel() - Move SAP to the given channel * @adapter: AP adapter * @channel: Channel + * @forced: Force to switch channel, ignore SCC/MCC check * * Moves the SAP interface by invoking the function which * executes the callback to perform channel switch using (E)CSA. * * Return: None */ -void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel); +void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel, + bool forced); void hdd_update_macaddr(struct hdd_config *config, struct qdf_mac_addr hw_macaddr); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 81ebf3fdc014..87f4ecd339ef 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -11185,7 +11185,8 @@ static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason, sap_config->acs_cfg.ch_width = channel_list->chan_width; hdd_ap_ctx->sap_config.ch_width_orig = channel_list->chan_width; - hdd_switch_sap_channel(adapter, sap_config->acs_cfg.pri_ch); + hdd_switch_sap_channel(adapter, sap_config->acs_cfg.pri_ch, + true); break; default: @@ -20931,7 +20932,7 @@ static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy, ch_width = hdd_map_nl_chan_width(csa_params->chandef.width); - ret = hdd_softap_set_channel_change(dev, channel, ch_width); + ret = hdd_softap_set_channel_change(dev, channel, ch_width, false); return ret; } diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index dcbbf168aa1f..dc645f8c89c1 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -214,8 +214,6 @@ int hdd_sap_context_init(struct hdd_context *hdd_ctx) qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); qdf_spinlock_create(&hdd_ctx->sap_update_info_lock); - qdf_atomic_init(&hdd_ctx->dfs_radar_found); - return 0; } @@ -1176,7 +1174,7 @@ static void wlan_hdd_sap_pre_cac_success(void *data) wlan_hdd_set_pre_cac_complete_status(ap_adapter, true); i = hdd_softap_set_channel_change(ap_adapter->dev, ap_adapter->pre_cac_chan, - CH_WIDTH_MAX); + CH_WIDTH_MAX, false); if (0 != i) { hdd_err("failed to change channel"); wlan_hdd_set_pre_cac_complete_status(ap_adapter, false); @@ -1691,7 +1689,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, hostapd_state->qdf_status = pSapEvent->sapevt.sapStartBssCompleteEvent.status; - qdf_atomic_set(&hdd_ctx->dfs_radar_found, 0); + qdf_atomic_set(&adapter->dfs_radar_found, 0); wlansap_get_dfs_ignore_cac(hdd_ctx->hHal, &ignoreCAC); /* DFS requirement: DO NOT transmit during CAC. */ @@ -1944,7 +1942,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, hdd_debug("Sent CAC start to user space"); } - qdf_atomic_set(&hdd_ctx->dfs_radar_found, 0); + qdf_atomic_set(&adapter->dfs_radar_found, 0); break; case eSAP_DFS_CAC_INTERRUPTED: /* @@ -2586,7 +2584,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, pSapEvent->sapevt.sap_chan_cng_ind.new_chan); if (hdd_softap_set_channel_change(dev, pSapEvent->sapevt.sap_chan_cng_ind.new_chan, - CH_WIDTH_MAX)) + CH_WIDTH_MAX, false)) return QDF_STATUS_E_FAILURE; else return QDF_STATUS_SUCCESS; @@ -2801,11 +2799,12 @@ int hdd_softap_unpack_ie(tHalHandle halHandle, * @target_channel: target channel number. * @target_bw: Target bandwidth to move. * If no bandwidth is specified, the value is CH_WIDTH_MAX + * @forced: Force to switch channel, ignore SCC/MCC check * * Return: 0 for success, non zero for failure */ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, - enum phy_ch_width target_bw) + enum phy_ch_width target_bw, bool forced) { QDF_STATUS status; int ret = 0; @@ -2850,7 +2849,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, * once the channel change is completed and SAP will * post eSAP_START_BSS_EVENT success event to HDD. */ - if (qdf_atomic_inc_return(&hdd_ctx->dfs_radar_found) > 1) { + if (qdf_atomic_inc_return(&adapter->dfs_radar_found) > 1) { hdd_err("Channel switch in progress!!"); return -EBUSY; } @@ -2861,7 +2860,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, status = wlansap_set_channel_change_with_csa( WLAN_HDD_GET_SAP_CTX_PTR(adapter), (uint32_t)target_channel, - target_bw, true); + target_bw, forced); if (QDF_STATUS_SUCCESS != status) { hdd_err("SAP set channel failed for channel: %d, bw: %d", @@ -2871,7 +2870,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, * radar found flag and also restart the netif * queues. */ - qdf_atomic_set(&hdd_ctx->dfs_radar_found, 0); + qdf_atomic_set(&adapter->dfs_radar_found, 0); ret = -EINVAL; } @@ -2885,6 +2884,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, * @ap_adapter: HDD adapter * @target_channel: Channel to which switch must happen * @target_bw: Bandwidth of the target channel + * @forced: Force to switch channel, ignore SCC/MCC check * * Invokes the necessary API to perform channel switch for the SAP or GO * @@ -2892,7 +2892,8 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, */ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, uint32_t target_channel, - uint32_t target_bw) + uint32_t target_bw, + bool forced) { struct net_device *dev = ap_adapter->dev; int ret; @@ -2904,7 +2905,8 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, return; } - ret = hdd_softap_set_channel_change(dev, target_channel, target_bw); + ret = hdd_softap_set_channel_change(dev, target_channel, + target_bw, forced); if (ret) { hdd_err("channel switch failed"); return; @@ -2913,7 +2915,8 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter, void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t channel, - uint32_t channel_bw) + uint32_t channel_bw, + bool forced) { struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(psoc, vdev_id); @@ -2923,7 +2926,7 @@ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, return; } hdd_sap_restart_with_channel_switch(ap_adapter, channel, - channel_bw); + channel_bw, forced); } QDF_STATUS wlan_hdd_get_channel_for_sap_restart( @@ -3020,7 +3023,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( hdd_info("SAP channel change with CSA/ECSA"); hdd_sap_restart_chan_switch_cb(psoc, vdev_id, hdd_ap_ctx->sap_config.channel, - hdd_ap_ctx->sap_config.ch_params.ch_width); + hdd_ap_ctx->sap_config.ch_params.ch_width, false); return QDF_STATUS_SUCCESS; } @@ -3382,7 +3385,8 @@ static __iw_softap_setparam(struct net_device *dev, hdd_debug("SET Channel Change to new channel= %d", set_value); ret = hdd_softap_set_channel_change(dev, set_value, - CH_WIDTH_MAX); + CH_WIDTH_MAX, + false); } else { hdd_err("Channel Change Failed, Device in test mode"); ret = -EINVAL; @@ -6488,6 +6492,8 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx, spin_lock_init(&adapter->pause_map_lock); adapter->start_time = adapter->last_time = qdf_system_ticks(); + qdf_atomic_init(&adapter->dfs_radar_found); + return adapter; } diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h index 769354576589..2c529b5c8b37 100644 --- a/core/hdd/src/wlan_hdd_hostapd.h +++ b/core/hdd/src/wlan_hdd_hostapd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -59,18 +59,21 @@ 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, - enum phy_ch_width target_bw); + enum phy_ch_width target_bw, + bool forced); #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH void hdd_sap_restart_with_channel_switch(struct hdd_adapter *adapter, uint32_t target_channel, - uint32_t target_bw); + uint32_t target_bw, + bool forced); /** * hdd_sap_restart_chan_switch_cb() - Function to restart SAP with * a different channel * @psoc: PSOC object information * @vdev_id: vdev id * @channel: channel to switch + * @forced: Force to switch channel, ignore SCC/MCC check * * This function restarts SAP with a different channel * @@ -79,7 +82,8 @@ void hdd_sap_restart_with_channel_switch(struct hdd_adapter *adapter, */ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t channel, - uint32_t channel_bw); + uint32_t channel_bw, + bool forced); /** * wlan_hdd_get_channel_for_sap_restart() - Function to get * suitable channel and restart SAP diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 968b46c2a23c..0e5162ed9cf2 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -6722,7 +6722,7 @@ static int drv_cmd_set_channel_switch(struct hdd_adapter *adapter, hdd_debug("CH:%d BW:%d", chan_number, chan_bw); - status = hdd_softap_set_channel_change(dev, chan_number, width); + status = hdd_softap_set_channel_change(dev, chan_number, width, false); if (status) { hdd_err("Set channel change fail"); return status; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 422afd10808f..d1ffa7b19224 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -7571,13 +7571,15 @@ static uint8_t hdd_get_safe_channel_from_pcl_and_acs_range( * hdd_switch_sap_channel() - Move SAP to the given channel * @adapter: AP adapter * @channel: Channel + * @forced: Force to switch channel, ignore SCC/MCC check * * Moves the SAP interface by invoking the function which * executes the callback to perform channel switch using (E)CSA. * * Return: None */ -void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel) +void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel, + bool forced) { struct hdd_ap_ctx *hdd_ap_ctx; tHalHandle *hal_handle; @@ -7612,7 +7614,7 @@ void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel) policy_mgr_change_sap_channel_with_csa(hdd_ctx->hdd_psoc, adapter->session_id, channel, - hdd_ap_ctx->sap_config.ch_width_orig); + hdd_ap_ctx->sap_config.ch_width_orig, forced); } int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason) @@ -7717,7 +7719,8 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) hdd_debug("driver to start sap: %d", hdd_ctxt->config->sap_internal_restart); if (hdd_ctxt->config->sap_internal_restart) - hdd_switch_sap_channel(adapter, restart_chan); + hdd_switch_sap_channel(adapter, restart_chan, + true); else return; } @@ -7782,7 +7785,7 @@ static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, WLAN_SVC_LTE_COEX_IND, NULL, 0); - hdd_switch_sap_channel(adapter, restart_chan); + hdd_switch_sap_channel(adapter, restart_chan, true); } int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx, diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 28bbf42bf18a..42ab5d34ff58 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1253,8 +1253,9 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, * @sapContext: Pointer to SAP context * @targetChannel: Target channel * @target_bw: Target bandwidth - * @strict: if true switch to the requested channel always, fail - * otherwise + * @strict: if true switch to the requested channel always, + * SCC/MCC check will be ignored, + * fail otherwise * * This api function does a channel change to the target channel specified. * CSA IE is included in the beacons before doing a channel change. @@ -1315,13 +1316,16 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext, * validate target channel switch w.r.t various concurrency * rules set. */ - valid = wlan_sap_validate_channel_switch(hHal, targetChannel, - sapContext); - if (!valid) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Channel switch to %u is not allowed due to concurrent channel interference"), - targetChannel); - return QDF_STATUS_E_FAULT; + if (!strict) { + valid = wlan_sap_validate_channel_switch(hHal, + targetChannel, sapContext); + if (!valid) { + QDF_TRACE(QDF_MODULE_ID_SAP, + QDF_TRACE_LEVEL_ERROR, + FL("Channel switch to %u is not allowed due to concurrent channel interference"), + targetChannel); + return QDF_STATUS_E_FAULT; + } } /* * Post a CSA IE request to SAP state machine with