qcacld-3.0: Record Monitor Mode Frequency from Pdev

Extend WAR mechanism to record monitor mode capture frequency from
pdev if RX PPDU TLV is empty.

Change freq type to qdf_freq_t.

iw dev wlan0 set freq <freq> [HT20|HT40+|HT40-]

Change-Id: Ic66f516f1f0f2ac97563e27b1d7c86032e8690ec
CRs-Fixed: 2568971
This commit is contained in:
Saket Jha 2019-11-18 16:53:47 -08:00 • committed by nshrivas
commit d5c0e02813
4 changed files with 49 additions and 44 deletions

View file

@ -1978,7 +1978,7 @@ struct hdd_channel_info {
* Return: 0 for success, non-zero for failure
*/
int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
uint32_t chan_freq,
qdf_freq_t chan_freq,
enum phy_ch_width chan_bw);
/**
@ -3807,16 +3807,16 @@ void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool disconnecting);
/**
* wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
* @adapter: Handle to adapter
* @chan: Monitor mode channel
* @freq: Monitor mode frequency (MHz)
* @bandwidth: Capture channel bandwidth
*
* Return: 0 on success else error code.
*/
int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq,
uint32_t bandwidth);
#else
static inline
int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq,
uint32_t bandwidth)
{
return 0;

View file

@ -17433,12 +17433,12 @@ void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
/**
* hdd_select_cbmode() - select channel bonding mode
* @adapter: Pointer to adapter
* @operatingChannel: Operating channel
* @oper_freq: Operating frequency (MHz)
* @ch_params: channel info struct to populate
*
* Return: none
*/
void hdd_select_cbmode(struct hdd_adapter *adapter, uint32_t oper_freq,
void hdd_select_cbmode(struct hdd_adapter *adapter, qdf_freq_t oper_freq,
struct ch_params *ch_params)
{
uint32_t sec_ch_freq = 0;
@ -22526,8 +22526,8 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
mac_handle_t mac_handle;
struct qdf_mac_addr bssid;
struct csr_roam_profile roam_profile;
struct ch_params ch_params;
int ret;
uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq);
enum channel_state chan_freq_state;
uint8_t max_fw_bw;
enum phy_ch_width ch_width;
@ -22544,8 +22544,8 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
if (!adapter)
return -EIO;
hdd_debug("%s: set monitor mode Channel %d and freq %d",
adapter->dev->name, chan_num, chandef->chan->center_freq);
hdd_debug("%s: set monitor mode freq %d",
adapter->dev->name, chandef->chan->center_freq);
/* Verify channel state before accepting this request */
chan_freq_state =
@ -22588,8 +22588,14 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
QDF_MAC_ADDR_SIZE);
if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan_num,
POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
ch_params.ch_width = ch_width;
wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev,
chandef->chan->center_freq,
0, &ch_params);
if (wlan_hdd_change_hw_mode_for_given_chnl(adapter,
chandef->chan->center_freq,
POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
hdd_err("Failed to change hw mode");
return -EINVAL;
}

View file

@ -820,7 +820,7 @@ uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBU
#endif
int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
uint32_t chan_freq,
qdf_freq_t chan_freq,
enum phy_ch_width chan_bw)
{
mac_handle_t mac_handle;
@ -855,6 +855,14 @@ int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
}
}
if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) {
if ((chan_bw != CH_WIDTH_20MHZ) && (chan_freq == 5825) &&
(chan_bw != CH_WIDTH_MAX)) {
hdd_err("Only BW20 possible on channel freq 5825");
return -EINVAL;
}
}
return 0;
}
@ -6920,8 +6928,8 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid,
#endif
#ifdef FEATURE_MONITOR_MODE_SUPPORT
int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
uint32_t bandwidth)
int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq,
uint32_t bandwidth)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
@ -6929,20 +6937,16 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
QDF_STATUS status;
struct qdf_mac_addr bssid;
struct csr_roam_profile roam_profile;
struct ch_params ch_params;
enum phy_ch_width max_fw_bw;
enum phy_ch_width ch_width;
int ret;
if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) {
hdd_err("Not supported, device is not in monitor mode");
return -EINVAL;
}
/* Validate Channel */
if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
hdd_err("Channel %d Not supported", chan);
return -EINVAL;
}
/* Verify the BW before accepting this request */
ch_width = bandwidth;
@ -6964,40 +6968,34 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
return -EINVAL;
}
if (WLAN_REG_IS_24GHZ_CH(chan)) {
if (bandwidth == CH_WIDTH_80MHZ) {
hdd_err("BW80 not possible in 2.4GHz band");
return -EINVAL;
}
if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
(bandwidth != CH_WIDTH_MAX)) {
hdd_err("Only BW20 possible on channel 14");
return -EINVAL;
}
ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth);
if (ret) {
hdd_err("Invalid CH and BW combo");
return ret;
}
if (WLAN_REG_IS_5GHZ_CH(chan)) {
if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
(bandwidth != CH_WIDTH_MAX)) {
hdd_err("Only BW20 possible on channel 165");
return -EINVAL;
}
}
hdd_debug("Set monitor mode Channel %d", chan);
hdd_debug("Set monitor mode frequency %d", freq);
qdf_mem_zero(&roam_profile, sizeof(roam_profile));
roam_profile.ChannelInfo.freq_list = &ch_info->freq;
roam_profile.ChannelInfo.numOfChannels = 1;
roam_profile.phyMode = ch_info->phy_mode;
roam_profile.ch_params.ch_width = bandwidth;
hdd_select_cbmode(adapter, wlan_chan_to_freq(chan),
hdd_select_cbmode(adapter, freq,
&roam_profile.ch_params);
qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
QDF_MAC_ADDR_SIZE);
if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
ch_params.ch_width = bandwidth;
wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, freq, 0,
&ch_params);
if (ch_params.ch_width == CH_WIDTH_INVALID) {
hdd_err("Invalid capture channel or bandwidth for a country");
return -EINVAL;
}
if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq,
POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
hdd_err("Failed to change hw mode");
return -EINVAL;
}
@ -7010,7 +7008,7 @@ int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
status);
}
adapter->mon_chan_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, chan);
adapter->mon_chan_freq = freq;
adapter->mon_bandwidth = bandwidth;
return qdf_status_to_os_return(status);
}
@ -7163,7 +7161,7 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
adapter->mon_chan_freq);
hdd_start_station_adapter(adapter);
hdd_set_mon_rx_cb(adapter->dev);
wlan_hdd_set_mon_chan(adapter, chan,
wlan_hdd_set_mon_chan(adapter, adapter->mon_chan_freq,
adapter->mon_bandwidth);
break;
default:

View file

@ -4289,6 +4289,7 @@ QDF_STATUS wma_post_chan_switch_setup(uint8_t vdev_id)
if (intr->type == WMI_VDEV_TYPE_MONITOR) {
des_chan = intr->vdev->vdev_mlme.des_chan;
cdp_record_monitor_chan_num(soc, pdev, des_chan->ch_ieee);
cdp_record_monitor_chan_freq(soc, pdev, des_chan->ch_freq);
}
return QDF_STATUS_SUCCESS;
}