Merge 20037a19b2 on remote branch

Change-Id: If16508894b1c04bbbaf4663b3616e1e1fc07bf42
This commit is contained in:
Linux Build Service Account 2023-03-13 01:58:28 -07:00
commit ed283d572b
17 changed files with 632 additions and 55 deletions

2
Kbuild
View file

@ -3649,7 +3649,7 @@ ccflags-y += -DWLAN_PDEV_MAX_VDEVS=$(CONFIG_WLAN_PDEV_MAX_VDEVS)
CONFIG_WLAN_PSOC_MAX_VDEVS ?= $(CONFIG_WLAN_MAX_VDEVS)
ccflags-y += -DWLAN_PSOC_MAX_VDEVS=$(CONFIG_WLAN_PSOC_MAX_VDEVS)
CONFIG_MAX_SCAN_CACHE_SIZE ?= 300
CONFIG_MAX_SCAN_CACHE_SIZE ?= 500
ccflags-y += -DMAX_SCAN_CACHE_SIZE=$(CONFIG_MAX_SCAN_CACHE_SIZE)
CONFIG_SCAN_MAX_REST_TIME ?= 0
ccflags-y += -DSCAN_MAX_REST_TIME=$(CONFIG_SCAN_MAX_REST_TIME)

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -125,8 +125,8 @@ static void pkt_capture_wdi_event_unsubscribe(struct wlan_objmgr_psoc *psoc)
WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA);
/* unsubscribe for rx data no peer packets */
cdp_wdi_event_sub(soc, pdev_id, &PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER,
WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER);
cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_RX_NO_PEER_SUBSCRIBER,
WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER);
/* unsubscribing for rx data packets */
cdp_wdi_event_unsub(soc, pdev_id, &PKT_CAPTURE_RX_SUBSCRIBER,

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -7237,6 +7237,8 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE] = {
.type = NLA_U8 },
};
static const struct nla_policy
@ -9017,6 +9019,38 @@ static int hdd_set_nss(struct hdd_adapter *adapter,
return ret;
}
/**
* hdd_set_wfc_state() - Set wfc state
* @adapter: hdd adapter
* @attr: pointer to nla attr
*
* Return: 0 on success, negative on failure
*/
static int hdd_set_wfc_state(struct hdd_adapter *adapter,
const struct nlattr *attr)
{
uint8_t cfg_val;
enum pld_wfc_mode set_val;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
int errno;
errno = wlan_hdd_validate_context(hdd_ctx);
if (errno)
return errno;
cfg_val = nla_get_u8(attr);
hdd_debug_rl("set wfc state %d", cfg_val);
if (cfg_val == 0)
set_val = PLD_WFC_MODE_OFF;
else if (cfg_val == 1)
set_val = PLD_WFC_MODE_ON;
else
return -EINVAL;
return pld_set_wfc_mode(hdd_ctx->parent_dev, set_val);
}
/**
* typedef independent_setter_fn - independent attribute handler
* @adapter: The adapter being configured
@ -9129,6 +9163,8 @@ static const struct independent_setters independent_setters[] = {
hdd_config_udp_qos_upgrade_threshold},
{QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
hdd_set_ft_over_ds},
{QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE,
hdd_set_wfc_state},
};
#ifdef WLAN_FEATURE_ELNA
@ -19714,7 +19750,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter,
const u8 *ssid, size_t ssid_len,
const u8 *bssid, const u8 *bssid_hint,
uint32_t oper_freq,
enum nl80211_chan_width ch_width)
enum nl80211_chan_width ch_width,
uint32_t ch_freq_hint)
{
int status = 0;
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
@ -19907,6 +19944,8 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter,
roam_profile->ChannelInfo.numOfChannels = 0;
}
roam_profile->freq_hint = ch_freq_hint;
if (wlan_hdd_cfg80211_check_pmf_valid(roam_profile)) {
status = -EINVAL;
goto conn_failure;
@ -21723,6 +21762,7 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
#endif
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
struct hdd_context *hdd_ctx;
uint32_t ch_freq_hint = 0;
hdd_enter();
@ -21838,11 +21878,15 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
else
ch_freq = 0;
if (req->channel_hint)
ch_freq_hint = req->channel_hint->center_freq;
wlan_hdd_check_ht20_ht40_ind(hdd_ctx, adapter, req);
status = wlan_hdd_cfg80211_connect_start(adapter, req->ssid,
req->ssid_len, req->bssid,
bssid_hint, ch_freq, 0);
bssid_hint, ch_freq, 0,
ch_freq_hint);
if (status) {
wlan_hdd_cfg80211_clear_privacy(adapter);
hdd_err("connect failed");

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -6507,12 +6507,15 @@ static int drv_cmd_set_channel_switch(struct hdd_adapter *adapter,
return status;
}
if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80)) {
if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80) &&
(chan_bw != 160)) {
hdd_err("BW %d is not allowed for CHANNEL_SWITCH", chan_bw);
return -EINVAL;
}
if (chan_bw == 80)
if (chan_bw == 160)
width = CH_WIDTH_160MHZ;
else if (chan_bw == 80)
width = CH_WIDTH_80MHZ;
else if (chan_bw == 40)
width = CH_WIDTH_40MHZ;

View file

@ -32,9 +32,9 @@
#define QWLAN_VERSION_MAJOR 2
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 8
#define QWLAN_VERSION_EXTRA "B"
#define QWLAN_VERSION_EXTRA "L"
#define QWLAN_VERSION_BUILD 32
#define QWLAN_VERSIONSTR "2.0.8.32B"
#define QWLAN_VERSIONSTR "2.0.8.32L"
#endif /* QWLAN_VERSION_H */

View file

@ -347,9 +347,11 @@
#define SIR_MAC_BAD_HTC_HE_VENDOR_OUI2 "\x00\x50\xF2\x12"
#define SIR_MAC_BAD_HTC_HE_VENDOR_OUI_LEN 4
/* Maximum allowable size of a beacon and probe rsp frame */
#define SIR_MAX_BEACON_SIZE 512
/* Maximum allowable size of a beacon,probe rsp and fils discovery frame */
#define SIR_MAX_BEACON_SIZE 512
#define SIR_MAX_PROBE_RESP_SIZE 512
#define SIR_MAX_FD_TMPL_SIZE 512
/* / Frame control field format (2 bytes) */
typedef struct sSirMacFrameCtl {

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -2138,7 +2138,9 @@ void lim_calculate_tpc(struct mac_context *mac,
if (mlme_obj->reg_tpc_obj.ap_constraint_power) {
local_constraint =
mlme_obj->reg_tpc_obj.ap_constraint_power;
reg_max = mlme_obj->reg_tpc_obj.reg_max[i];
pe_debug("local constraint: %d"
"power constraint absolute: %d",
local_constraint, is_pwr_constraint_absolute);
if (is_pwr_constraint_absolute)
max_tx_power = QDF_MIN(reg_max,
local_constraint);

View file

@ -47,6 +47,398 @@
#include "wma_types.h"
#include <target_if_vdev_mgr_tx_ops.h>
#include <wlan_cmn_ieee80211.h>
#include <wlan_mgmt_txrx_utils_api.h>
/* Fils Dicovery Frame */
/**
* struct fd_action_header - FILS Discovery Action frame header
* @action_header: WLAN Action frame header
* @fd_frame_cntl: FILS Disovery Frame Control
* @timestamp: Time stamp
* @bcn_interval: Beacon Interval
* @elem: variable len sub element fields
*/
struct fd_action_header {
struct action_frm_hdr action_header;
uint16_t fd_frame_cntl;
uint8_t timestamp[WLAN_TIMESTAMP_LEN];
uint16_t bcn_interval;
uint8_t elem[];
} qdf_packed;
/**
* struct tpe_ie - Transmit Power Enevolpe IE
* @tpe_header: WLAN IE Header
* @max_tx_pwr_count: Maximum Transmit Power Count
* @max_tx_pwr_interpret: Maximum Transmit Power Interpretation
* @max_tx_pwr_category: Maximum Transmit Power category
* @tx_pwr_info: Transmit power Information
* @elem: variable len sub element fields
*/
struct tpe_ie {
struct ie_header tpe_header;
union {
struct {
uint8_t max_tx_pwr_count:3;
uint8_t max_tx_pwr_interpret:3;
uint8_t max_tx_pwr_category:2;
};
uint8_t tx_pwr_info;
};
uint8_t elem[];
} qdf_packed;
/**
* lim_populate_fd_capability() - populate the capability field in the
* fils discovery template
* @pe_session: pointer to pe session
* @cur_phymode: current phymode
* @fd_cap: pointer to fils discovery capability array
*
* Return: void
*/
static void lim_populate_fd_capability(struct pe_session *pe_session,
enum wlan_phymode cur_phymode,
uint8_t *fd_cap)
{
/* Setting ESS and Privacy bits */
fd_cap[0] |= ((!WLAN_FD_CAP_ESS_ENABLE << WLAN_FD_CAP_ESS_S) |
((pe_session->privacy) << WLAN_FD_CAP_PRIVACY_S));
/* Channel Width Selection */
switch (pe_session->ch_width) {
case CH_WIDTH_20MHZ:
fd_cap[0] |= (WLAN_FD_CHWIDTH_20 << WLAN_FD_CAP_BSS_CHWIDTH_S);
break;
case CH_WIDTH_40MHZ:
fd_cap[0] |= (WLAN_FD_CHWIDTH_40 << WLAN_FD_CAP_BSS_CHWIDTH_S);
break;
case CH_WIDTH_80MHZ:
fd_cap[0] |= (WLAN_FD_CHWIDTH_80 << WLAN_FD_CAP_BSS_CHWIDTH_S);
break;
case CH_WIDTH_160MHZ:
case CH_WIDTH_80P80MHZ:
fd_cap[0] |= (WLAN_FD_CHWIDTH_160_80_80 <<
WLAN_FD_CAP_BSS_CHWIDTH_S);
break;
default:
pe_err("channel width : %d is not supported", pe_session->ch_width);
break;
}
/* Max Num of Spatial Steam */
switch (pe_session->nss) {
case WLAN_FD_CAP_NSS_MODE_1:
case WLAN_FD_CAP_NSS_MODE_2:
fd_cap[0] |= ((pe_session->nss - 1) << WLAN_FD_CAP_NSS_S);
break;
case WLAN_FD_CAP_NSS_MODE_3:
case WLAN_FD_CAP_NSS_MODE_4:
case WLAN_FD_CAP_NSS_MODE_5:
case WLAN_FD_CAP_NSS_MODE_6:
case WLAN_FD_CAP_NSS_MODE_7:
case WLAN_FD_CAP_NSS_MODE_8:
fd_cap[0] |= (WLAN_FD_CAP_NSS_GTE_5 << WLAN_FD_CAP_NSS_S);
break;
default:
pe_err("NSS value: %d is not supported", pe_session->nss);
break;
}
/* Set PHY index */
switch (cur_phymode) {
case WLAN_PHYMODE_11AXA_HE20:
case WLAN_PHYMODE_11AXG_HE20:
case WLAN_PHYMODE_11AXA_HE40:
case WLAN_PHYMODE_11AXG_HE40:
case WLAN_PHYMODE_11AXG_HE40PLUS:
case WLAN_PHYMODE_11AXG_HE40MINUS:
case WLAN_PHYMODE_11AXA_HE80:
case WLAN_PHYMODE_11AXA_HE160:
case WLAN_PHYMODE_11AXA_HE80_80:
fd_cap[1] |= (WLAN_FD_CAP_PHY_INDEX_HE <<
WLAN_FD_CAP_PHY_INDEX_S);
break;
case WLAN_PHYMODE_11AC_VHT20:
case WLAN_PHYMODE_11AC_VHT40:
case WLAN_PHYMODE_11AC_VHT80:
case WLAN_PHYMODE_11AC_VHT160:
case WLAN_PHYMODE_11AC_VHT80_80:
fd_cap[1] |= (WLAN_FD_CAP_PHY_INDEX_VHT <<
WLAN_FD_CAP_PHY_INDEX_S);
break;
case WLAN_PHYMODE_11NA_HT20:
case WLAN_PHYMODE_11NG_HT20:
case WLAN_PHYMODE_11NG_HT40PLUS:
case WLAN_PHYMODE_11NG_HT40MINUS:
case WLAN_PHYMODE_11NG_HT40:
case WLAN_PHYMODE_11NA_HT40:
fd_cap[1] |= (WLAN_FD_CAP_PHY_INDEX_HT <<
WLAN_FD_CAP_PHY_INDEX_S);
break;
default:
pe_err("Phymode : %d is not supported", cur_phymode);
break;
}
/* FILS Min Rate */
fd_cap[1] |= (WLAN_FD_CAP_MIN_RATE << WLAN_FD_CAP_MIN_RATE_S);
}
/**
* lim_populate_fd_tmpl_frame() - populate the fils discovery frame
* @mac: pointer to mac structure
* @frm: pointer to fils discovery frame
* @pe_session:pointer to pe session
* @frame_size: pointer to fils discovery frame size
*
* return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
*/
static QDF_STATUS lim_populate_fd_tmpl_frame(struct mac_context *mac,
struct pe_session *pe_session,
uint8_t *frm, uint32_t *frame_size)
{
uint16_t fd_cntl_subfield = 0;
struct fd_action_header *fd_header;
struct wlan_objmgr_vdev *vdev;
uint8_t fd_cap[WLAN_FD_CAP_LEN] = {0};
uint8_t length = 0;
uint8_t ssid_len = 0, ssid[WLAN_SSID_MAX_LEN + 1] = {0};
uint32_t shortssid;
uint16_t chwidth = pe_session->ch_width;
qdf_freq_t cur_chan_freq = pe_session->curr_op_freq;
struct wlan_channel *des_chan;
enum wlan_phymode cur_phymode;
uint16_t tpe_num = 0;
tDot11fIEtransmit_power_env tpe[WLAN_MAX_NUM_TPE_IE];
struct tpe_ie *tpe_ie;
uint8_t i, idx;
tSirMacMgmtHdr *mac_hdr;
struct qdf_mac_addr broadcast_mac_addr = QDF_MAC_ADDR_BCAST_INIT;
pe_debug("FD TMPL freq: %d chWidth: %d", cur_chan_freq, chwidth);
vdev = pe_session->vdev;
if (!vdev) {
pe_err("VDEV is NULL");
return QDF_STATUS_E_FAILURE;
}
des_chan = wlan_vdev_mlme_get_des_chan(vdev);
if (!des_chan) {
pe_err("des_chan is NULL");
return QDF_STATUS_E_FAILURE;
}
cur_phymode = des_chan->ch_phymode;
lim_populate_mac_header(mac, frm, SIR_MAC_MGMT_FRAME,
SIR_MAC_MGMT_ACTION, broadcast_mac_addr.bytes,
pe_session->self_mac_addr);
mac_hdr = (tpSirMacMgmtHdr)frm;
sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
frm += sizeof(*mac_hdr);
*frame_size = sizeof(*mac_hdr);
/* filling fd header */
fd_header = (struct fd_action_header *)frm;
fd_header->action_header.action_category = ACTION_CATEGORY_PUBLIC;
fd_header->action_header.action_code = WLAN_ACTION_FILS_DISCOVERY;
/*
* FILS DIscovery Frame Control Subfield - 2 byte
* Enable Short SSID
* When the Short SSID Indicator subfield is equal to 1,
* the SSID Length subfield is equal to 3
*/
fd_cntl_subfield = WLAN_FD_SSID_LEN_PRES(WLAN_FD_FRAMECNTL_SHORTSSID_LEN);
fd_cntl_subfield |= WLAN_FD_FRAMECNTL_SHORTSSID;
if (wlan_reg_is_6ghz_chan_freq(cur_chan_freq)) {
fd_cntl_subfield |= WLAN_FD_FRAMECNTL_CAP;
pe_debug("FD Capability Present");
length = WLAN_FD_CAP_LEN;
}
/* For 80+80 set Channel center freq segment 1 */
if (IS_WLAN_PHYMODE_160MHZ(cur_phymode)) {
fd_cntl_subfield |= WLAN_FD_FRAMECNTL_CH_CENTERFREQ;
pe_debug("Center frequenceny Present");
length += 1;
}
/* Update the length field */
/*Indicates length from FD cap to Mobility Domain */
if (length)
fd_cntl_subfield |= WLAN_FD_FRAMECNTL_LEN_PRES;
/* FD Control - 2 bytes */
fd_header->fd_frame_cntl = qdf_cpu_to_le16(fd_cntl_subfield);
/* Timestamp - 8 bytes */
qdf_mem_zero(fd_header->timestamp, sizeof(fd_header->timestamp));
/* Beacon Interval - 2 bytes */
fd_header->bcn_interval =
qdf_cpu_to_le16(pe_session->beaconParams.beaconInterval);
*frame_size += sizeof(*fd_header);
/* Variable length data */
frm = &fd_header->elem[0];
/* Short SSID - 4 bytes */
wlan_vdev_mlme_get_ssid(vdev, ssid, &ssid_len);
shortssid = wlan_construct_shortssid(ssid, ssid_len);
*(uint32_t *)frm = qdf_cpu_to_le32(shortssid);
frm += 4;
*frame_size += 4;
pe_debug("Category:%02x Action:%02x fd_cntl:%02x bcn_intvl:%02x short ssid:%02x frame_size:%02x",
fd_header->action_header.action_category,
fd_header->action_header.action_code, fd_cntl_subfield,
fd_header->bcn_interval, shortssid, *frame_size);
/* Length - 1 byte */
if (length) {
*frm = length;
pe_debug("length: %d", length);
frm++;
*frame_size += length + 1;
}
/* FD Capabilities - 2 bytes */
if (WLAN_FD_IS_CAP_PRESENT(fd_cntl_subfield)) {
lim_populate_fd_capability(pe_session, cur_phymode, &fd_cap[0]);
qdf_mem_copy(frm, fd_cap, WLAN_FD_CAP_LEN);
frm += WLAN_FD_CAP_LEN;
pe_debug("fd_cap: %02x %02x", fd_cap[0], fd_cap[1]);
}
/* Channel Center Freq Segment 1 - 1 byte */
if (WLAN_FD_IS_FRAMECNTL_CH_CENTERFREQ(fd_cntl_subfield)) {
/* spec has seg0 and seg1 naming while we use seg1 and seg2 */
*frm = des_chan->ch_freq_seg1;
frm++;
pe_debug("ch_center_freq: %02x", des_chan->ch_freq_seg1);
}
/* Add TPE IE */
if ((wlan_reg_is_6ghz_chan_freq(cur_chan_freq)) ||
(pe_session->vhtCapability)) {
populate_dot11f_tx_power_env(mac, &tpe[0], chwidth,
cur_chan_freq, &tpe_num, false);
pe_debug("tpe_num: %02x", tpe_num);
if (tpe_num > WLAN_MAX_NUM_TPE_IE) {
pe_err("tpe_num %d greater than max size", tpe_num);
return QDF_STATUS_E_FAILURE;
}
for (idx = 0; idx < tpe_num; idx++) {
/* filling tpe_header header */
tpe_ie = (struct tpe_ie *)frm;
tpe_ie->tpe_header.ie_id = WLAN_ELEMID_VHT_TX_PWR_ENVLP;
if (tpe[idx].num_tx_power > WLAN_MAX_NUM_TPE_IE) {
pe_err("num_tx_power %d greater than max num",
tpe[idx].num_tx_power);
return QDF_STATUS_E_FAILURE;
}
/* +1 for including tx power info */
tpe_ie->tpe_header.ie_len = tpe[idx].num_tx_power + 1;
if (tpe_ie->tpe_header.ie_len < WLAN_TPE_IE_MIN_LEN ||
tpe_ie->tpe_header.ie_len > WLAN_TPE_IE_MAX_LEN) {
pe_err("tpe length %d less than min len or greater than max len",
tpe_ie->tpe_header.ie_len);
return QDF_STATUS_E_FAILURE;
}
tpe_ie->max_tx_pwr_count = tpe[idx].max_tx_pwr_count;
tpe_ie->max_tx_pwr_interpret =
tpe[idx].max_tx_pwr_interpret;
tpe_ie->max_tx_pwr_category =
tpe[idx].max_tx_pwr_category;
pe_debug("tx_pwr_info: %02x", tpe_ie->tx_pwr_info);
frm = &tpe_ie->elem[0];
for (i = 0; i < tpe[idx].num_tx_power; i++) {
*frm = tpe[idx].tx_power[i];
pe_debug("tx_pwr[%d]: %02x", i, *frm);
frm++;
}
/* +2 for including element id and length */
*frame_size += tpe_ie->tpe_header.ie_len + 2;
}
}
return QDF_STATUS_SUCCESS;
}
/**
* lim_send_fils_discovery_template() - send fils discovery template to
* target_if
* @mac: pointer to mac structure
* @pe_session:pe session
*
* return: status
*/
static QDF_STATUS lim_send_fils_discovery_template(struct mac_context *mac,
struct pe_session *pe_session)
{
struct fils_discovery_tmpl_params *fd_params;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
uint32_t n_bytes = sizeof(*fd_params);
fd_params = qdf_mem_malloc(n_bytes);
if (!fd_params)
return QDF_STATUS_E_NOMEM;
fd_params->vdev_id = pe_session->vdev_id;
fd_params->frm = qdf_mem_malloc(SIR_MAX_FD_TMPL_SIZE);
if (!(fd_params->frm)) {
qdf_mem_free(fd_params);
return QDF_STATUS_E_NOMEM;
}
status = lim_populate_fd_tmpl_frame(mac, pe_session, fd_params->frm,
&n_bytes);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("FAIL bytes %d retcode[%X]", n_bytes, status);
goto memfree;
}
pe_debug("Fils Discovery template created successfully %d", n_bytes);
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
fd_params->frm, n_bytes);
fd_params->tmpl_len = n_bytes;
fd_params->tmpl_len_aligned = roundup(fd_params->tmpl_len,
sizeof(uint32_t));
/* Sending data to wmi layer via target_if */
status = target_if_vdev_mgr_send_fd_tmpl(pe_session->vdev,
fd_params);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("FAIL bytes %d retcode[%X]", n_bytes, status);
} else {
pe_debug("Fils Discovery tmpl msg posted to HAL of bytes %d",
n_bytes);
}
memfree:
qdf_mem_free(fd_params->frm);
qdf_mem_free(fd_params);
return status;
}
QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
uint16_t size, struct pe_session *pe_session,
enum sir_bcn_update_reason reason)
@ -66,6 +458,11 @@ QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
if (QDF_STATUS_SUCCESS != retCode)
pe_err("FAILED to send probe response template with retCode %d",
retCode);
/*Fils Discovery Template */
retCode = lim_send_fils_discovery_template(mac, pe_session);
if (QDF_STATUS_SUCCESS != retCode)
pe_err("FAILED to send fils discovery template retCode %d",
retCode);
}
beaconParams = qdf_mem_malloc(sizeof(tSendbeaconParams));

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -133,6 +133,16 @@ enum pld_platform_cap_flag {
PLD_HAS_DRV_SUPPORT = 0x04,
};
/**
* enum pld_wfc_mode - WFC Mode
* @PLD_WFC_MODE_OFF: WFC Inactive
* @PLD_WFC_MODE_ON: WFC Active
*/
enum pld_wfc_mode {
PLD_WFC_MODE_OFF,
PLD_WFC_MODE_ON,
};
/**
* struct pld_platform_cap - platform capabilities
* @cap_flag: capabilities flag
@ -946,6 +956,15 @@ int pld_thermal_register(struct device *dev, unsigned long state, int mon_id);
*/
void pld_thermal_unregister(struct device *dev, int mon_id);
/**
* pld_set_wfc_mode() - Sent WFC mode to FW via platform driver
* @dev: The device structure
* @wfc_mode: WFC Modes (0 => Inactive, 1 => Active)
*
* Return: Error code on error
*/
int pld_set_wfc_mode(struct device *dev, enum pld_wfc_mode wfc_mode);
/**
* pld_bus_width_type_to_str() - Helper function to convert PLD bandwidth level
* to string

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -3154,6 +3154,32 @@ void pld_thermal_unregister(struct device *dev, int mon_id)
}
}
int pld_set_wfc_mode(struct device *dev, enum pld_wfc_mode wfc_mode)
{
int errno = -ENOTSUPP;
enum pld_bus_type type;
type = pld_get_bus_type(dev);
switch (type) {
case PLD_BUS_TYPE_SDIO:
case PLD_BUS_TYPE_USB:
case PLD_BUS_TYPE_SNOC:
case PLD_BUS_TYPE_IPCI_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
case PLD_BUS_TYPE_PCIE_FW_SIM:
break;
case PLD_BUS_TYPE_PCIE:
errno = pld_pcie_set_wfc_mode(dev, wfc_mode);
break;
default:
pr_err("Invalid device type %d\n", type);
break;
}
return errno;
}
const char *pld_bus_width_type_to_str(enum pld_bus_width_type level)
{
switch (level) {

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -940,5 +941,30 @@ void pld_pcie_device_self_recovery(struct device *dev,
}
cnss_self_recovery(dev, cnss_reason);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
int pld_pcie_set_wfc_mode(struct device *dev,
enum pld_wfc_mode wfc_mode)
{
struct cnss_wfc_cfg cfg;
int ret;
switch (wfc_mode) {
case PLD_WFC_MODE_OFF:
cfg.mode = CNSS_WFC_MODE_OFF;
break;
case PLD_WFC_MODE_ON:
cfg.mode = CNSS_WFC_MODE_ON;
break;
default:
ret = -EINVAL;
goto out;
}
ret = cnss_set_wfc_mode(dev, cfg);
out:
return ret;
}
#endif
#endif
#endif

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -404,7 +405,24 @@ static inline bool pld_pcie_platform_driver_support(void)
{
return false;
}
static inline int pld_pcie_set_wfc_mode(struct device *dev,
enum pld_wfc_mode wfc_mode)
{
return 0;
}
#else
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
int pld_pcie_set_wfc_mode(struct device *dev,
enum pld_wfc_mode wfc_mode);
#else
static inline int pld_pcie_set_wfc_mode(struct device *dev,
enum pld_wfc_mode wfc_mode)
{
return 0;
}
#endif
int pld_pcie_get_fw_files_for_target(struct device *dev,
struct pld_fw_files *pfw_files,
u32 target_type, u32 target_version);

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -662,6 +663,7 @@ struct csr_roam_profile {
tCsrKeys Keys;
tCsrChannelInfo ChannelInfo;
uint32_t op_freq;
uint32_t freq_hint;
struct ch_params ch_params;
/* If this is 0, SME will fill in for caller. */
uint16_t beaconInterval;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -8711,35 +8711,60 @@ bool is_disconnect_pending(struct mac_context *pmac, uint8_t vdev_id)
return disconnect_cmd_exist;
}
bool is_disconnect_pending_on_other_vdev(struct mac_context *pmac,
uint8_t vdev_id)
bool is_any_other_vdev_connecting_disconnecting(struct mac_context *pmac,
uint8_t vdev_id)
{
tListElem *entry = NULL;
tListElem *next_entry = NULL;
tSmeCmd *command = NULL;
bool disconnect_cmd_exist = false;
bool is_pending_cmd = false;
enum QDF_OPMODE opmode;
entry = csr_nonscan_pending_ll_peek_head(pmac, LL_ACCESS_NOLOCK);
while (entry) {
next_entry = csr_nonscan_pending_ll_next(pmac, entry,
LL_ACCESS_NOLOCK);
command = GET_BASE_ADDR(entry, tSmeCmd, Link);
/*
* check if any other vdev NB disconnect or SB disconnect
* (eSmeCommandWmStatusChange) is pending
*/
if (command && (CSR_IS_DISCONNECT_COMMAND(command) ||
command->command == eSmeCommandWmStatusChange) &&
command->vdev_id != vdev_id) {
sme_debug("disconnect is pending on vdev:%d, cmd:%d",
command->vdev_id, command->command);
disconnect_cmd_exist = true;
break;
if (!command) {
entry = next_entry;
continue;
}
opmode = wlan_get_opmode_from_vdev_id(pmac->pdev,
command->vdev_id);
if (opmode == QDF_STA_MODE || opmode == QDF_P2P_CLIENT_MODE) {
/*
* check if any other vdev NB disconnect or SB
* disconnect (eSmeCommandWmStatusChange) is pending
*/
if ((CSR_IS_DISCONNECT_COMMAND(command) ||
command->command == eSmeCommandWmStatusChange) &&
command->vdev_id != vdev_id) {
sme_debug("disconnect is pending on vdev:%d, cmd:%d",
command->vdev_id, command->command);
is_pending_cmd = true;
break;
}
}
if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
/* Check if START/STOP AP OP is in progress */
if ((command->command == eSmeCommandRoam &&
(command->u.roamCmd.roamReason == eCsrStopBss ||
command->u.roamCmd.roamReason == eCsrHddIssued))) {
sme_debug("vdev ops pending on vdev_id:%d, cmd:%d, reason:%d",
command->vdev_id, command->command,
command->u.roamCmd.roamReason);
is_pending_cmd = true;
break;
}
}
entry = next_entry;
}
return disconnect_cmd_exist;
return is_pending_cmd;
}
#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
@ -8861,7 +8886,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
struct csr_roam_connectedinfo *prev_connect_info;
struct wlan_crypto_pmksa *pmksa;
uint32_t len = 0, roamId = 0, reason_code = 0;
bool is_dis_pending, is_dis_pending_on_other_vdev;
bool is_dis_pending, is_vdev_ops_pending_on_other_vdev;
bool use_same_bss = false;
uint8_t max_retry_count = 1;
bool retry_same_bss = false;
@ -8965,8 +8990,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
reason_code);
is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId);
is_dis_pending_on_other_vdev =
is_disconnect_pending_on_other_vdev(mac,
is_vdev_ops_pending_on_other_vdev =
is_any_other_vdev_connecting_disconnecting(mac,
session_ptr->sessionId);
is_time_allowed =
csr_is_time_allowed_for_connect_attempt(pCommand,
@ -8976,7 +9001,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
* if userspace has issued disconnection or we have reached mac tries or
* max time, driver should not continue for next connection.
*/
if (is_dis_pending || is_dis_pending_on_other_vdev || !is_time_allowed ||
if (is_dis_pending || is_vdev_ops_pending_on_other_vdev || !is_time_allowed ||
session_ptr->join_bssid_count >= CSR_MAX_BSSID_COUNT)
attempt_next_bss = false;
@ -9092,8 +9117,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
if (is_dis_pending)
sme_err("disconnect is pending, complete roam");
if (is_dis_pending_on_other_vdev)
sme_err("disconnect is pending on other vdev, complete roam");
if (is_vdev_ops_pending_on_other_vdev)
sme_err("vdev ops is pending on other vdev, complete roam");
if (!is_time_allowed)
sme_err("time can exceed the active timeout for connection attempt");

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -1395,6 +1395,15 @@ QDF_STATUS csr_scan_for_ssid(struct mac_context *mac_ctx, uint32_t session_id,
req->scan_req.chan_list.num_chan = num_chan;
}
/* Add freq hint for scan for ssid */
if (!num_chan && profile->freq_hint &&
csr_roam_is_valid_channel(mac_ctx, profile->freq_hint)) {
sme_debug("add freq hint %d", profile->freq_hint);
req->scan_req.chan_list.chan[0].freq =
profile->freq_hint;
req->scan_req.chan_list.num_chan = 1;
}
/* Extend it for multiple SSID */
if (profile->SSIDs.numOfSSIDs) {
if (profile->SSIDs.SSIDList[0].SSID.length > WLAN_SSID_MAX_LEN) {

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -984,15 +985,15 @@ bool is_disconnect_pending(struct mac_context *mac_ctx,
uint8_t sessionid);
/**
* is_disconnect_pending_on_other_vdev() - To check whether a disconnect req
* is pending on any other vdev or not
* is_any_other_vdev_connecting_disconnecting() - To check whether any other
* vdev is in waiting for vdev operations (connect/disconnect or start/stop AP)
* @mac_tx: mac context
* @sessionid: session id
*
* Return true if disconnect is pending on any other vdev
*/
bool is_disconnect_pending_on_other_vdev(struct mac_context *mac_ctx,
uint8_t sessionid);
bool is_any_other_vdev_connecting_disconnecting(struct mac_context *mac_ctx,
uint8_t sessionid);
QDF_STATUS
csr_roam_prepare_bss_config_from_profile(struct mac_context *mac_ctx,

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -3730,6 +3730,7 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info,
struct extscan_cached_scan_results *t_cached_result;
struct extscan_cached_scan_result *t_scan_id_grp;
int i, j;
uint32_t total_scan_num_results = 0;
tSirWifiScanResult *ap;
param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
@ -3740,16 +3741,19 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info,
t_cached_result = cached_result;
t_scan_id_grp = &t_cached_result->result[0];
if ((t_cached_result->num_scan_ids *
QDF_MIN(t_scan_id_grp->num_results,
param_buf->num_bssid_list)) > param_buf->num_bssid_list) {
wma_err("num_scan_ids %d, num_results %d num_bssid_list %d",
t_cached_result->num_scan_ids,
t_scan_id_grp->num_results,
param_buf->num_bssid_list);
for (i = 0; i < t_cached_result->num_scan_ids; i++) {
total_scan_num_results += t_scan_id_grp->num_results;
t_scan_id_grp++;
}
if (total_scan_num_results > param_buf->num_bssid_list) {
wma_err("total_scan_num_results %d, num_bssid_list %d",
total_scan_num_results,
param_buf->num_bssid_list);
return -EINVAL;
}
t_scan_id_grp = &t_cached_result->result[0];
wma_debug("num_scan_ids:%d",
t_cached_result->num_scan_ids);
for (i = 0; i < t_cached_result->num_scan_ids; i++) {
@ -3760,8 +3764,7 @@ static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info,
return -ENOMEM;
ap = &t_scan_id_grp->ap[0];
for (j = 0; j < QDF_MIN(t_scan_id_grp->num_results,
param_buf->num_bssid_list); j++) {
for (j = 0; j < t_scan_id_grp->num_results; j++) {
ap->channel = src_hotlist->channel;
ap->ts = WMA_MSEC_TO_USEC(src_rssi->tstamp);
ap->rtt = src_hotlist->rtt;