mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 14:13:01 -04:00
qcacld-3.0: Validate STA channel switch notify
Add validation for STA CSA channel change notify event: 1. acquire the wdev->mtx lock before invoke kernel API - cfg80211_ch_switch_notify. Kernel will access wdev->current_bss in the API, it maybe changed in other thread. 2. if the bssid is not connected in vdev, don't invoke kernel API - cfg80211_ch_switch_notify since wdev->current_bss maybe unlinked from kernel bss list. cfg80211_ch_switch_notify make assumption current_bss existing on the bss list. Change-Id: I0dd415a5576d29e3a7729768c8482205677ca3e7 CRs-Fixed: 2855494
This commit is contained in:
parent
9b3c00d656
commit
0b3b7b36d5
3 changed files with 50 additions and 24 deletions
|
|
@ -3459,10 +3459,24 @@ int hdd_update_config(struct hdd_context *hdd_ctx);
|
|||
*/
|
||||
int hdd_update_components_config(struct hdd_context *hdd_ctx);
|
||||
|
||||
/**
|
||||
* hdd_chan_change_notify() - Function to notify hostapd about channel change
|
||||
* @hostapd_adapter: hostapd adapter
|
||||
* @dev: Net device structure
|
||||
* @chan_change: New channel change parameters
|
||||
* @legacy_phymode: is the phymode legacy
|
||||
* @lock_wdev: need wdev lock or not
|
||||
*
|
||||
* This function is used to notify hostapd about the channel change
|
||||
*
|
||||
* Return: Success on intimating userspace
|
||||
*
|
||||
*/
|
||||
QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter,
|
||||
struct net_device *dev,
|
||||
struct hdd_chan_change_params chan_change,
|
||||
bool legacy_phymode);
|
||||
bool legacy_phymode,
|
||||
bool lock_wdev);
|
||||
int wlan_hdd_set_channel(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
|
|
|
|||
|
|
@ -4400,6 +4400,8 @@ static void hdd_roam_channel_switch_handler(struct hdd_adapter *adapter,
|
|||
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
|
||||
struct hdd_station_ctx *sta_ctx;
|
||||
uint8_t connected_vdev;
|
||||
bool notify = true;
|
||||
|
||||
/* Enable Roaming on STA interface which was disabled before CSA */
|
||||
if (adapter->device_mode == QDF_STA_MODE)
|
||||
|
|
@ -4428,12 +4430,28 @@ static void hdd_roam_channel_switch_handler(struct hdd_adapter *adapter,
|
|||
hdd_err("%s: unable to create BSS entry", adapter->dev->name);
|
||||
else
|
||||
cfg80211_put_bss(wiphy, bss);
|
||||
|
||||
status = hdd_chan_change_notify(adapter, adapter->dev, chan_change,
|
||||
roam_info->mode == SIR_SME_PHY_MODE_LEGACY);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
hdd_err("channel change notification failed");
|
||||
|
||||
if ((adapter->device_mode == QDF_STA_MODE ||
|
||||
adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
|
||||
if (!wlan_get_connected_vdev_by_bssid(
|
||||
hdd_ctx->pdev, sta_ctx->conn_info.bssid.bytes,
|
||||
&connected_vdev))
|
||||
notify = false;
|
||||
else if (adapter->vdev_id != connected_vdev)
|
||||
notify = false;
|
||||
}
|
||||
if (notify) {
|
||||
status = hdd_chan_change_notify(adapter, adapter->dev,
|
||||
chan_change,
|
||||
roam_info->mode ==
|
||||
SIR_SME_PHY_MODE_LEGACY,
|
||||
true);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
hdd_err("channel change notification failed");
|
||||
} else {
|
||||
hdd_err("BSS "QDF_MAC_ADDR_FMT" no connected with vdev %d (%d)",
|
||||
QDF_MAC_ADDR_REF(sta_ctx->conn_info.bssid.bytes),
|
||||
adapter->vdev_id, connected_vdev);
|
||||
}
|
||||
status = policy_mgr_set_hw_mode_on_channel_switch(hdd_ctx->psoc,
|
||||
adapter->vdev_id);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
|
|
|
|||
|
|
@ -822,28 +822,18 @@ static int hdd_stop_bss_link(struct hdd_adapter *adapter)
|
|||
return errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_chan_change_notify() - Function to notify hostapd about channel change
|
||||
* @hostapd_adapter: hostapd adapter
|
||||
* @dev: Net device structure
|
||||
* @chan_change: New channel change parameters
|
||||
* @legacy_phymode: is the phymode legacy
|
||||
*
|
||||
* This function is used to notify hostapd about the channel change
|
||||
*
|
||||
* Return: Success on intimating userspace
|
||||
*
|
||||
*/
|
||||
QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter,
|
||||
struct net_device *dev,
|
||||
struct hdd_chan_change_params chan_change,
|
||||
bool legacy_phymode)
|
||||
bool legacy_phymode,
|
||||
bool lock_wdev)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
struct cfg80211_chan_def chandef;
|
||||
enum nl80211_channel_type channel_type;
|
||||
uint32_t freq;
|
||||
mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
|
||||
if (!mac_handle) {
|
||||
hdd_err("mac_handle is NULL");
|
||||
|
|
@ -912,11 +902,15 @@ QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter,
|
|||
chan_change.chan_params.mhz_freq_seg0;
|
||||
}
|
||||
|
||||
hdd_debug("notify: chan:%d width:%d freq1:%d freq2:%d",
|
||||
chandef.chan->center_freq, chandef.width, chandef.center_freq1,
|
||||
chandef.center_freq2);
|
||||
hdd_debug("notify: chan:%d width:%d freq1:%d freq2:%d locked %d",
|
||||
chandef.chan->center_freq, chandef.width,
|
||||
chandef.center_freq1, chandef.center_freq2, lock_wdev);
|
||||
if (lock_wdev)
|
||||
mutex_lock(&wdev->mtx);
|
||||
|
||||
cfg80211_ch_switch_notify(dev, &chandef);
|
||||
if (lock_wdev)
|
||||
mutex_unlock(&wdev->mtx);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1773,7 +1767,7 @@ static QDF_STATUS hdd_hostapd_chan_change(struct hdd_adapter *adapter,
|
|||
sap_chan_selected->vht_seg1_center_ch_freq;
|
||||
|
||||
return hdd_chan_change_notify(adapter, adapter->dev,
|
||||
chan_change, legacy_phymode);
|
||||
chan_change, legacy_phymode, false);
|
||||
}
|
||||
|
||||
QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
|
||||
|
|
|
|||
Loading…
Reference in a new issue