summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/mac/inc/sir_mac_prot_def.h72
-rw-r--r--core/mac/src/pe/include/lim_global.h3
-rw-r--r--core/mac/src/pe/lim/lim_p2p.c89
-rw-r--r--core/mac/src/pe/lim/lim_process_assoc_req_frame.c31
-rw-r--r--core/mac/src/pe/lim/lim_send_management_frames.c20
-rw-r--r--core/mac/src/pe/lim/lim_types.h14
-rw-r--r--core/mac/src/pe/lim/lim_utils.h5
-rw-r--r--core/wma/src/wma_mgmt.c4
8 files changed, 227 insertions, 11 deletions
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 2ff3a26e87f8..07042919d9cd 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -455,6 +455,13 @@
#define SIR_MAX_NOA_ATTR_LEN 31
#define SIR_MAX_NOA_DESCR 2
#define SIR_P2P_IE_HEADER_LEN 6
+#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
#define SIR_MAC_CISCO_OUI "\x00\x40\x96"
#define SIR_MAC_CISCO_OUI_SIZE 3
@@ -2261,4 +2268,67 @@ typedef struct sSirMacRadioMeasureReport {
#define SIR_MAC_TXSTBC 1
#define SIR_MAC_RXSTBC 1
+/**
+ * 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 /* __MAC_PROT_DEFS_H */
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
index 4bd7bdde5f5d..f455308936d4 100644
--- a/core/mac/src/pe/include/lim_global.h
+++ b/core/mac/src/pe/include/lim_global.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -340,6 +340,7 @@ typedef struct sLimMlmStaContext {
/* 802.11n HT Capability in Station: Enabled 1 or DIsabled 0 */
uint8_t htCapability:1;
uint8_t vhtCapability:1;
+ bool force_1x1;
} tLimMlmStaContext, *tpLimMlmStaContext;
/* Structure definition to hold deferred messages queue parameters */
diff --git a/core/mac/src/pe/lim/lim_p2p.c b/core/mac/src/pe/lim/lim_p2p.c
index 59a18feac556..1cb32030d462 100644
--- a/core/mac/src/pe/lim/lim_p2p.c
+++ b/core/mac/src/pe/lim/lim_p2p.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -774,3 +774,90 @@ tSirRetStatus __lim_process_sme_no_a_update(tpAniSirGlobal pMac, uint32_t *pMsgB
return eSIR_SUCCESS;
} /*** end __limProcessSmeGoNegReq() ***/
+bool lim_p2p_check_oui_and_force_1x1(tpAniSirGlobal mac_ctx,
+ 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;
+
+ if (!assoc_ie || !assoc_ie_len)
+ return false;
+
+ vendor_ie = (uint8_t *)limGetP2pIEPtr(mac_ctx, assoc_ie, assoc_ie_len);
+ if (!vendor_ie) {
+ pe_debug("P2P IE not found");
+ return false;
+ }
+
+ rem_len = vendor_ie[1];
+ if (rem_len < (2 + SIR_MAC_P2P_OUI_SIZE) ||
+ rem_len > SIR_MAC_MAX_IE_LENGTH) {
+ pe_err("Invalid IE len %d", rem_len);
+ return false;
+ }
+
+ p2p_ie = vendor_ie + HEADER_LEN_P2P_IE;
+ rem_len -= SIR_MAC_P2P_OUI_SIZE;
+
+ while (rem_len) {
+ attr = p2p_ie[0];
+ attr_len = LE_READ_2(&p2p_ie[1]);
+ if (attr_len > rem_len) {
+ pe_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)) {
+ pe_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:
+ pe_err("Invalid P2P attribute");
+ break;
+ }
+ p2p_ie += (3 + attr_len);
+ rem_len -= (3 + attr_len);
+ }
+
+ return false;
+}
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 003fd59983be..75952720f3b9 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -1209,6 +1209,8 @@ static bool lim_chk_wmm(tpAniSirGlobal 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
*
@@ -1219,7 +1221,8 @@ static bool lim_update_sta_ds(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
uint8_t sub_type, tpDphHashNode sta_ds,
tAniAuthType auth_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;
@@ -1283,6 +1286,7 @@ static bool lim_update_sta_ds(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
sta_ds->valid = 0;
sta_ds->mlmStaContext.authType = auth_type;
sta_ds->staType = STA_ENTRY_PEER;
+ sta_ds->mlmStaContext.force_1x1 = force_1x1;
/*
* TODO: If listen interval is more than certain limit, reject the
@@ -1754,7 +1758,7 @@ void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
tSirMacCapabilityInfo local_cap;
tpDphHashNode sta_ds = NULL;
tpSirAssocReq assoc_req;
- bool dup_entry = false;
+ bool dup_entry = false, force_1x1 = false;
lim_get_phy_mode(mac_ctx, &phy_mode, session);
@@ -1984,6 +1988,25 @@ void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
MAC_ADDR_ARRAY(hdr->sa));
+ if (session->pePersona == 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 = lim_p2p_check_oui_and_force_1x1(
+ mac_ctx,
+ frm_body + LIM_ASSOC_REQ_IE_OFFSET,
+ frame_len - LIM_ASSOC_REQ_IE_OFFSET);
+ }
+
/*
* AID for this association will be same as the peer Index used in DPH
* table. Assign unused/least recently used peer Index from perStaDs.
@@ -2027,7 +2050,7 @@ sendIndToSme:
if (false == lim_update_sta_ds(mac_ctx, hdr, session, assoc_req,
sub_type, sta_ds, auth_type,
&assoc_req_copied, peer_idx, qos_mode,
- pmf_connection))
+ pmf_connection, force_1x1))
goto error;
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 392dc1d9dddf..2ff0358a1866 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -1204,7 +1204,7 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal 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,
@@ -1222,6 +1222,22 @@ lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal 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 688a10d5613f..8caf092c4af5 100644
--- a/core/mac/src/pe/lim/lim_types.h
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -1028,4 +1028,16 @@ void lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx,
void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx,
uint32_t *msg_buf);
+/**
+ * lim_p2p_check_oui_and_force_1x1() - Function to get P2P client device
+ * attributes from assoc request frame IE passed in.
+ * @mac_ctx: Pointer to mac_context
+ * @assoc_ie: Pointer to IE in association request
+ * @assoc_ie_len: Total association IE length
+ *
+ * Return: True if OUI is found. Else return false
+ *
+ */
+bool lim_p2p_check_oui_and_force_1x1(tpAniSirGlobal mac_ctx,
+ uint8_t *assoc_ie, uint32_t assoc_ie_len);
#endif /* __LIM_TYPES_H */
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 46894381acd7..de9f49959c74 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -460,6 +460,11 @@ void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal pMac);
cfg_get_vendor_ie_ptr_from_oui(pMac, SIR_MAC_P2P_OUI, \
SIR_MAC_P2P_OUI_SIZE, ie, ie_len)
+#define LE_READ_2(p) \
+ ((uint16_t)\
+ ((((const uint8_t *)(p))[0]) |\
+ (((const uint8_t *)(p))[1] << 8)))
+
uint8_t lim_get_noa_attr_stream_in_mult_p2p_ies(tpAniSirGlobal pMac,
uint8_t *noaStream, uint8_t noaLen,
uint8_t overFlowLen);
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index b66a27a3e03a..3ad0282ca1e7 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1328,7 +1328,9 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
if (cmd->peer_nss > WMA_MAX_NSS)
cmd->peer_nss = WMA_MAX_NSS;
- 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_LOGI("%s: vdev_id %d associd %d peer_flags %x nss %d phymode %d ht_caps %x",
__func__, cmd->vdev_id, cmd->peer_associd, cmd->peer_flags,