diff --git a/Kbuild b/Kbuild index 96be0fe023..ccf38685a0 100644 --- a/Kbuild +++ b/Kbuild @@ -1042,6 +1042,7 @@ P2P_INC := -I$(WLAN_ROOT)/$(P2P_DISPATCHER_INC_DIR) \ P2P_OBJS := $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_ucfg_api.o \ $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_tgt_api.o \ $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_cfg.o \ + $(P2P_DISPATCHER_OBJ_DIR)/wlan_p2p_api.o \ $(P2P_CORE_OBJ_DIR)/wlan_p2p_main.o \ $(P2P_CORE_OBJ_DIR)/wlan_p2p_roc.o \ $(P2P_CORE_OBJ_DIR)/wlan_p2p_off_chan_tx.o \ diff --git a/components/p2p/core/src/wlan_p2p_main.c b/components/p2p/core/src/wlan_p2p_main.c index 8ccfe130ab..733b4d675b 100644 --- a/components/p2p/core/src/wlan_p2p_main.c +++ b/components/p2p/core/src/wlan_p2p_main.c @@ -1101,6 +1101,89 @@ QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } +bool p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len) +{ + const uint8_t *vendor_ie, *p2p_ie, *pos; + uint8_t rem_len, attr; + uint16_t attr_len; + + vendor_ie = (uint8_t *)p2p_get_p2pie_ptr(assoc_ie, assoc_ie_len); + if (!vendor_ie) { + p2p_debug("P2P IE not found"); + return false; + } + + rem_len = vendor_ie[1]; + if (rem_len < (2 + OUI_SIZE_P2P) || rem_len > WLAN_MAX_IE_LEN) { + p2p_err("Invalid IE len %d", rem_len); + return false; + } + + p2p_ie = vendor_ie + HEADER_LEN_P2P_IE; + rem_len -= OUI_SIZE_P2P; + + while (rem_len) { + attr = p2p_ie[0]; + attr_len = LE_READ_2(&p2p_ie[1]); + if (attr_len > rem_len) { + p2p_err("Invalid len %d for elem:%d", attr_len, attr); + return false; + } + + switch (attr) { + case P2P_ATTR_CAPABILITY: + case P2P_ATTR_DEVICE_ID: + case P2P_ATTR_GROUP_OWNER_INTENT: + case P2P_ATTR_STATUS: + case P2P_ATTR_LISTEN_CHANNEL: + case P2P_ATTR_OPERATING_CHANNEL: + case P2P_ATTR_GROUP_INFO: + case P2P_ATTR_MANAGEABILITY: + case P2P_ATTR_CHANNEL_LIST: + break; + + case P2P_ATTR_DEVICE_INFO: + if (attr_len < (QDF_MAC_ADDR_SIZE + + MAX_CONFIG_METHODS_LEN + 8 + + DEVICE_CATEGORY_MAX_LEN)) { + p2p_err("Invalid Device info attr len %d", + attr_len); + return false; + } + + /* move by attr id and 2 bytes of attr len */ + pos = p2p_ie + 3; + + /* + * the P2P Device info is of format: + * attr_id - 1 byte + * attr_len - 2 bytes + * device mac addr - 6 bytes + * config methods - 2 bytes + * primary device type - 8bytes + * -primary device type category - 1 byte + * -primary device type oui - 4bytes + * number of secondary device type - 2 bytes + */ + pos += ETH_ALEN + MAX_CONFIG_METHODS_LEN + + DEVICE_CATEGORY_MAX_LEN; + + if (!qdf_mem_cmp(pos, P2P_1X1_WAR_OUI, + P2P_1X1_OUI_LEN)) + return true; + + break; + default: + p2p_err("Invalid P2P attribute"); + break; + } + p2p_ie += (3 + attr_len); + rem_len -= (3 + attr_len); + } + + return false; +} + #ifdef FEATURE_P2P_LISTEN_OFFLOAD QDF_STATUS p2p_process_lo_stop( struct p2p_lo_stop_event *lo_stop_event) @@ -1442,4 +1525,5 @@ QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_SUCCESS; } + #endif /* WLAN_FEATURE_P2P_DEBUG */ diff --git a/components/p2p/core/src/wlan_p2p_main.h b/components/p2p/core/src/wlan_p2p_main.h index fe9801c7fd..67b292c724 100644 --- a/components/p2p/core/src/wlan_p2p_main.h +++ b/components/p2p/core/src/wlan_p2p_main.h @@ -466,6 +466,16 @@ QDF_STATUS p2p_msg_flush_callback(struct scheduler_msg *msg); */ QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg); +/** + * p2p_check_oui_and_force_1x1() - Function to get P2P client device + * attributes from assoc request frame IE passed in. + * @assoc_ie: Pointer to the IEs in the association req frame + * @assoc_ie_len: Total length of the IE in association req frame + * + * Return: true if the OUI is present else false + */ +bool p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len); + #ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * p2p_process_lo_stop() - Process lo stop event diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c index aa2cb76b8d..1a9c5e7c1c 100644 --- a/components/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -220,7 +220,7 @@ static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx) * * Return: pointer to p2p ie */ -static const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len) +const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len) { return wlan_get_vendor_ie_ptr_from_oui(P2P_OUI, P2P_OUI_SIZE, ie, ie_len); diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.h b/components/p2p/core/src/wlan_p2p_off_chan_tx.h index 5b18b36f27..1a6309f804 100644 --- a/components/p2p/core/src/wlan_p2p_off_chan_tx.h +++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.h @@ -435,4 +435,15 @@ void p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj); */ void p2p_deinit_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj); +/** + * p2p_get_p2pie_ptr() - get the pointer to p2p ie + * @ie: source ie + * @ie_len: source ie length + * + * This function finds out p2p ie by p2p oui and return the pointer. + * + * Return: pointer to p2p ie + */ +const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len); + #endif /* _WLAN_P2P_OFF_CHAN_TX_H_ */ diff --git a/components/p2p/dispatcher/inc/wlan_p2p_api.h b/components/p2p/dispatcher/inc/wlan_p2p_api.h new file mode 100644 index 0000000000..d9d0757d7b --- /dev/null +++ b/components/p2p/dispatcher/inc/wlan_p2p_api.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 The Linux Foundation. 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Contains p2p public data structure definitions + */ + +#ifndef _WLAN_P2P_API_H_ +#define _WLAN_P2P_API_H_ + +#include + +/** + * wlan_p2p_check_oui_and_force_1x1() - Function to get P2P client device + * attributes from assoc request frames + * @assoc_ie: pointer to assoc request frame IEs + * @ie_len: length of the assoc request frame IE + * + * When assoc request is received from P2P STA device, this function checks + * for specific OUI present in the P2P device info attribute. The caller should + * take care of checking if this is called only in P2P GO mode. + * + * Return: True if OUI is present, else false. + */ +bool wlan_p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t ie_len); +#endif diff --git a/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h b/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h index d1c597ff35..0172ff34fb 100644 --- a/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h +++ b/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. 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 @@ -27,6 +27,15 @@ #define P2P_MAX_NOA_DESC 4 +#define HEADER_LEN_P2P_IE 6 +#define OUI_SIZE_P2P 4 + +#define P2P_1X1_WAR_OUI "\x00\x50\xf2\x04" +#define P2P_1X1_OUI_LEN 4 + +#define MAX_CONFIG_METHODS_LEN 2 +#define DEVICE_CATEGORY_MAX_LEN 1 + /** * struct p2p_ps_params - P2P powersave related params * @opp_ps: opportunistic power save @@ -269,4 +278,67 @@ struct p2p_protocol_callbacks { bool (*is_mgmt_protected)(uint32_t vdev_id, const uint8_t *peer_addr); }; +/** + * enum p2p_attr_id - enum for P2P attributes ID in P2P IE + * @P2P_ATTR_STATUS - Attribute Status none + * @P2P_ATTR_MINOR_REASON_CODE: Minor reason code attribute + * @P2P_ATTR_CAPABILITY: Capability attribute + * @P2P_ATTR_DEVICE_ID: device ID attribute + * @P2P_ATTR_GROUP_OWNER_INTENT: Group owner intent attribute + * @P2P_ATTR_CONFIGURATION_TIMEOUT: Config timeout attribute + * @P2P_ATTR_LISTEN_CHANNEL: listen channel attribute + * @P2P_ATTR_GROUP_BSSID: Group BSSID attribute + * @P2P_ATTR_EXT_LISTEN_TIMING: Listen timing attribute + * @P2P_ATTR_INTENDED_INTERFACE_ADDR: Intended interface address attribute + * @P2P_ATTR_MANAGEABILITY: Manageability attribute + * @P2P_ATTR_CHANNEL_LIST: Channel list attribute + * @P2P_ATTR_NOTICE_OF_ABSENCE: Notice of Absence attribute + * @P2P_ATTR_DEVICE_INFO: Device Info attribute + * @P2P_ATTR_GROUP_INFO: Group Info attribute + * @P2P_ATTR_GROUP_ID: Group ID attribute + * @P2P_ATTR_INTERFACE: Interface attribute + * @P2P_ATTR_OPERATING_CHANNEL: Operating channel attribute + * @P2P_ATTR_INVITATION_FLAGS: Invitation flags attribute + * @P2P_ATTR_OOB_GO_NEG_CHANNEL: GO neg channel attribute + * @P2P_ATTR_SERVICE_HASH: Service HASH attribute + * @P2P_ATTR_SESSION_INFORMATION_DATA: Session Info data attribute + * @P2P_ATTR_CONNECTION_CAPABILITY = Connection capability attribute + * @P2P_ATTR_ADVERTISEMENT_ID = Advertisement ID attribute + * @P2P_ATTR_ADVERTISED_SERVICE = Advertised Service attribute + * @P2P_ATTR_SESSION_ID = Session ID attribute + * @P2P_ATTR_FEATURE_CAPABILITY = Feature capability attribute + * @P2P_ATTR_PERSISTENT_GROUP -Persistent group attribute + * @P2P_ATTR_VENDOR_SPECIFIC - Vendor specific attribute + */ +enum p2p_attr_id { + P2P_ATTR_STATUS = 0, + P2P_ATTR_MINOR_REASON_CODE = 1, + P2P_ATTR_CAPABILITY = 2, + P2P_ATTR_DEVICE_ID = 3, + P2P_ATTR_GROUP_OWNER_INTENT = 4, + P2P_ATTR_CONFIGURATION_TIMEOUT = 5, + P2P_ATTR_LISTEN_CHANNEL = 6, + P2P_ATTR_GROUP_BSSID = 7, + P2P_ATTR_EXT_LISTEN_TIMING = 8, + P2P_ATTR_INTENDED_INTERFACE_ADDR = 9, + P2P_ATTR_MANAGEABILITY = 10, + P2P_ATTR_CHANNEL_LIST = 11, + P2P_ATTR_NOTICE_OF_ABSENCE = 12, + P2P_ATTR_DEVICE_INFO = 13, + P2P_ATTR_GROUP_INFO = 14, + P2P_ATTR_GROUP_ID = 15, + P2P_ATTR_INTERFACE = 16, + P2P_ATTR_OPERATING_CHANNEL = 17, + P2P_ATTR_INVITATION_FLAGS = 18, + P2P_ATTR_OOB_GO_NEG_CHANNEL = 19, + P2P_ATTR_SERVICE_HASH = 21, + P2P_ATTR_SESSION_INFORMATION_DATA = 22, + P2P_ATTR_CONNECTION_CAPABILITY = 23, + P2P_ATTR_ADVERTISEMENT_ID = 24, + P2P_ATTR_ADVERTISED_SERVICE = 25, + P2P_ATTR_SESSION_ID = 26, + P2P_ATTR_FEATURE_CAPABILITY = 27, + P2P_ATTR_PERSISTENT_GROUP = 28, + P2P_ATTR_VENDOR_SPECIFIC = 221 +}; #endif /* _WLAN_P2P_PUBLIC_STRUCT_H_ */ diff --git a/components/p2p/dispatcher/src/wlan_p2p_api.c b/components/p2p/dispatcher/src/wlan_p2p_api.c new file mode 100644 index 0000000000..63f04cdd27 --- /dev/null +++ b/components/p2p/dispatcher/src/wlan_p2p_api.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 The Linux Foundation. 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: This file contains P2P public API's exposed. + */ + +#include "wlan_p2p_api.h" +#include +#include "wlan_p2p_public_struct.h" +#include "../../core/src/wlan_p2p_main.h" + +bool wlan_p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len) +{ + if (!assoc_ie || !assoc_ie_len) + return false; + + return p2p_check_oui_and_force_1x1(assoc_ie, assoc_ie_len); +} diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h index 2f569ff37a..693b31dda2 100644 --- a/core/mac/src/pe/include/lim_global.h +++ b/core/mac/src/pe/include/lim_global.h @@ -247,6 +247,7 @@ typedef struct sLimMlmStaContext { #ifdef WLAN_FEATURE_11AX bool he_capable; #endif + bool force_1x1; uint8_t *owe_ie; uint32_t owe_ie_len; } tLimMlmStaContext, *tpLimMlmStaContext; diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index d6d37c06ba..7939bd497a 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -38,6 +38,7 @@ #include "cds_packet.h" #include "lim_session_utils.h" #include "utils_parser.h" +#include "wlan_p2p_api.h" #include "qdf_types.h" #include "cds_utils.h" @@ -1424,6 +1425,8 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, * @peer_idx: peer index * @qos_mode: qos mode * @pmf_connection: flag indicating pmf connection + * @force_1x1: Flag to check if the HT capable STA needs to be downgraded to 1x1 + * nss. * * Updates ds dph entry * @@ -1436,7 +1439,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, tAniAuthType auth_type, enum ani_akm_type akm_type, bool *assoc_req_copied, uint16_t peer_idx, - tHalBitVal qos_mode, bool pmf_connection) + tHalBitVal qos_mode, bool pmf_connection, + bool force_1x1) { tHalBitVal wme_mode, wsm_mode; uint8_t *ht_cap_ie = NULL; @@ -1498,6 +1502,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->mlmStaContext.authType = auth_type; sta_ds->mlmStaContext.akm_type = akm_type; sta_ds->staType = STA_ENTRY_PEER; + sta_ds->mlmStaContext.force_1x1 = force_1x1; pe_debug("auth_type = %d, akm_type = %d", auth_type, akm_type); @@ -1964,13 +1969,11 @@ static void lim_defer_sme_indication(struct mac_context *mac_ctx, bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, struct pe_session *session, - uint8_t sub_type, - tpSirMacMgmtHdr hdr, + uint8_t sub_type, tpSirMacMgmtHdr hdr, tpSirAssocReq assoc_req, enum ani_akm_type akm_type, - bool pmf_connection, - bool *assoc_req_copied, - bool dup_entry) + bool pmf_connection, bool *assoc_req_copied, + bool dup_entry, bool force_1x1) { uint16_t peer_idx; struct tLimPreAuthNode *sta_pre_auth_ctx; @@ -2055,7 +2058,7 @@ send_ind_to_sme: if (!lim_update_sta_ds(mac_ctx, hdr, session, assoc_req, sub_type, sta_ds, auth_type, akm_type, assoc_req_copied, peer_idx, qos_mode, - pmf_connection)) + pmf_connection, force_1x1)) return false; /* BTAMP: Storing the parsed assoc request in the session array */ @@ -2112,7 +2115,7 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in tSirMacCapabilityInfo local_cap; tpDphHashNode sta_ds = NULL; tpSirAssocReq assoc_req; - bool dup_entry = false; + bool dup_entry = false, force_1x1 = false; QDF_STATUS status; lim_get_phy_mode(mac_ctx, &phy_mode, session); @@ -2354,10 +2357,28 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in return; } + if (session->opmode == QDF_P2P_GO_MODE) { + /* + * WAR: In P2P GO mode, if the P2P client device + * is only HT capable and not VHT capable, but the P2P + * GO device is VHT capable and advertises 2x2 NSS with + * HT capablity client device, which results in IOT + * issues. + * When GO is operating in DBS mode, GO beacons + * advertise 2x2 capability but include OMN IE to + * indicate current operating mode of 1x1. But here + * peer device is only HT capable and will not + * understand OMN IE. + */ + force_1x1 = wlan_p2p_check_oui_and_force_1x1( + frm_body + LIM_ASSOC_REQ_IE_OFFSET, + frame_len - LIM_ASSOC_REQ_IE_OFFSET); + } + /* Send assoc indication to SME */ if (!lim_send_assoc_ind_to_sme(mac_ctx, session, sub_type, hdr, assoc_req, akm_type, pmf_connection, - &assoc_req_copied, dup_entry)) + &assoc_req_copied, dup_entry, force_1x1)) goto error; return; diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 1890448b60..23d00a0130 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -118,6 +118,7 @@ static void lim_process_sae_msg_ap(struct mac_context *mac, { struct tLimPreAuthNode *sta_pre_auth_ctx; struct lim_assoc_data *assoc_req; + bool assoc_ind_sent; /* Extract pre-auth context for the STA and move limMlmState * of preauth node to eLIM_MLM_AUTHENTICATED_STATE @@ -161,14 +162,16 @@ static void lim_process_sae_msg_ap(struct mac_context *mac, assoc_req->present = false; pe_debug("Assoc req cached; handle it"); - if (lim_send_assoc_ind_to_sme(mac, session, - assoc_req->sub_type, - &assoc_req->hdr, - assoc_req->assoc_req, - ANI_AKM_TYPE_SAE, - assoc_req->pmf_connection, - &assoc_req_copied, - assoc_req->dup_entry) == false) + assoc_ind_sent = + lim_send_assoc_ind_to_sme(mac, session, + assoc_req->sub_type, + &assoc_req->hdr, + assoc_req->assoc_req, + ANI_AKM_TYPE_SAE, + assoc_req->pmf_connection, + &assoc_req_copied, + assoc_req->dup_entry, false); + if (!assoc_ind_sent) lim_process_assoc_cleanup(mac, session, assoc_req->assoc_req, assoc_req->sta_ds, diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 688549c9b2..5dce49382a 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -1135,7 +1135,7 @@ lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx, frm.HTCaps.shortGI40MHz = 0; populate_dot11f_ht_info(mac_ctx, &frm.HTInfo, - pe_session); + pe_session); } pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x", frm.HTCaps.supportedChannelWidthSet, @@ -1153,6 +1153,22 @@ lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx, populate_dot11f_vht_operation(mac_ctx, pe_session, &frm.VHTOperation); is_vht = true; + } else if (sta->mlmStaContext.force_1x1 && + frm.HTCaps.present) { + /* + * WAR: In P2P GO mode, if the P2P client device + * is only HT capable and not VHT capable, but the P2P + * GO device is VHT capable and advertises 2x2 NSS with + * HT capablity client device, which results in IOT + * issues. + * When GO is operating in DBS mode, GO beacons + * advertise 2x2 capability but include OMN IE to + * indicate current operating mode of 1x1. But here + * peer device is only HT capable and will not + * understand OMN IE. + */ + frm.HTInfo.basicMCSSet[1] = 0; + frm.HTCaps.supportedMCSSet[1] = 0; } if (pe_session->vhtCapability && diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 7f8e48e0a0..d0896ce6b2 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -1178,6 +1178,7 @@ void lim_process_assoc_cleanup(struct mac_context *mac_ctx, * @pmf_connection: flag indicating pmf connection * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above * @dup_entry: flag indicating if duplicate entry found + * @force_1x1: flag to indicate if the STA nss needs to be downgraded to 1x1 * * Return: void */ @@ -1189,5 +1190,5 @@ bool lim_send_assoc_ind_to_sme(struct mac_context *mac_ctx, enum ani_akm_type akm_type, bool pmf_connection, bool *assoc_req_copied, - bool dup_entry); + bool dup_entry, bool force_1x1); #endif /* __LIM_TYPES_H */ diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 9e11daecce..7c81539b20 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1553,7 +1553,9 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, wma_populate_peer_he_cap(cmd, params); - intr->nss = cmd->peer_nss; + if (!wma_is_vdev_in_ap_mode(wma, params->smesessionId)) + intr->nss = cmd->peer_nss; + cmd->peer_phymode = phymode; WMA_LOGD("%s: vdev_id %d associd %d rate_caps %x peer_caps %x", __func__, cmd->vdev_id, cmd->peer_associd,