blob: ef96bbdc9e3c2962c6b34a71c4b2da0724d6be7f [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Zhu Jianmin5d8e3fe2018-01-04 16:16:20 +08002 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/*===========================================================================
20 * lim_process_tdls.c
21 * OVERVIEW:
22 *
23 * DEPENDENCIES:
24 *
25 * Are listed for each API below.
26 * ===========================================================================*/
27
28/*===========================================================================
29
30 * EDIT HISTORY FOR FILE
31
32 * This section contains comments describing changes made to the module.
33 * Notice that changes are listed in reverse chronological order.
34
35 * $Header$$DateTime$$Author$
36
37 * when who what, where, why
38 * ---------- --- ------------------------------------------------------
39 * 05/05/2010 Ashwani Initial Creation, added TDLS action frame
40 * functionality,TDLS message exchange with SME..etc..
41
42 ===========================================================================*/
43
44/**
45 * \file lim_process_tdls.c
46 *
47 * \brief Code for preparing,processing and sending 802.11z action frames
48 *
49 */
50
51#ifdef FEATURE_WLAN_TDLS
52
53#include "sir_api.h"
54#include "ani_global.h"
55#include "sir_mac_prot_def.h"
56#include "cfg_api.h"
57#include "utils_api.h"
58#include "lim_types.h"
59#include "lim_utils.h"
60#include "lim_security_utils.h"
61#include "dot11f.h"
62#include "lim_sta_hash_api.h"
63#include "sch_api.h"
64#include "lim_send_messages.h"
65#include "utils_parser.h"
66#include "lim_assoc_utils.h"
Jeff Johnson1396a3c2016-11-04 07:54:41 -070067#include "lim_prop_exts_utils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068#include "dph_hash_table.h"
69#include "wma_types.h"
Naveen Rawat3b6068c2016-04-14 19:01:06 -070070#include "cds_regdomain.h"
Archana Ramachandran63f64dd2016-04-28 15:13:35 -070071#include "cds_utils.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070072#include "wlan_reg_services_api.h"
Frank Liud4b2fa02017-03-29 11:46:48 +080073#include "wlan_tdls_tgt_api.h"
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053074#include "wlan_mlme_public_struct.h"
Frank Liud4b2fa02017-03-29 11:46:48 +080075
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630
77 There was IOT issue with cisco 1252 open mode, where it pads
78 discovery req/teardown frame with some junk value up to min size.
79 To avoid this issue, we pad QCOM_VENDOR_IE.
80 If there is other IOT issue because of this bandage, define NO_PAD...
81 */
82#ifndef NO_PAD_TDLS_MIN_8023_SIZE
83#define MIN_IEEE_8023_SIZE 46
84#define MIN_VENDOR_SPECIFIC_IE_SIZE 5
85#endif
86
Jeff Johnson0301ecb2018-06-29 09:36:23 -070087static QDF_STATUS lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088 tSirTdlsAddStaReq * pAddStaReq, tpPESession psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089
90/*
91 * TDLS data frames will go out/come in as non-qos data.
92 * so, eth_890d_header will be aligned access..
93 */
94static const uint8_t eth_890d_header[] = {
95 0xaa, 0xaa, 0x03, 0x00,
96 0x00, 0x00, 0x89, 0x0d,
97};
98
99/*
100 * type of links used in TDLS
101 */
102enum tdlsLinks {
103 TDLS_LINK_AP,
104 TDLS_LINK_DIRECT
105} e_tdls_link;
106
107/*
108 * node status in node searching
109 */
110enum tdlsLinkNodeStatus {
111 TDLS_NODE_NOT_FOUND,
112 TDLS_NODE_FOUND
113} e_tdls_link_node_status;
114
115enum tdlsReqType {
116 TDLS_INITIATOR,
117 TDLS_RESPONDER
118} e_tdls_req_type;
119
120typedef enum tdlsLinkSetupStatus {
121 TDLS_SETUP_STATUS_SUCCESS = 0,
122 TDLS_SETUP_STATUS_FAILURE = 37
123} etdlsLinkSetupStatus;
124
125/* These maps to Kernel TDLS peer capability
126 * flags and should get changed as and when necessary
127 */
128enum tdls_peer_capability {
129 TDLS_PEER_HT_CAP = 0,
130 TDLS_PEER_VHT_CAP = 1,
131 TDLS_PEER_WMM_CAP = 2
132} e_tdls_peer_capability;
133
134/* some local defines */
135#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
136#define PTI_LINK_IDEN_OFFSET (5)
137#define PTI_BUF_STATUS_OFFSET (25)
138
139/* TODO, Move this parameters to configuration */
140#define PEER_PSM_SUPPORT (0)
141#define TDLS_SUPPORT (1)
142#define TDLS_PROHIBITED (0)
143#define TDLS_CH_SWITCH_PROHIBITED (1)
144/** @brief Set bit manipulation macro */
145#define SET_BIT(value, mask) ((value) |= (1 << (mask)))
146/** @brief Clear bit manipulation macro */
147#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask)))
148/** @brief Check bit manipulation macro */
149#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
150
151#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
152 do { \
153 if ((aid) < (sizeof(uint32_t) << 3)) \
154 SET_BIT(peer_bitmap[0], (aid)); \
155 else if ((aid) < (sizeof(uint32_t) << 4)) \
156 SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
157 } while (0);
158
159#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \
160 do { \
161 if ((aid) < (sizeof(uint32_t) << 3)) \
162 CLEAR_BIT(peer_bitmap[0], (aid)); \
163 else if ((aid) < (sizeof(uint32_t) << 4)) \
164 CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
165 } while (0);
166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800167#ifdef FEATURE_WLAN_TDLS
168#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800)
169#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200)
170#endif
171
172#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \
173 SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) || \
174 (((psessionEntry)->limWmeEnabled) && \
175 LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps)))
176
177#define TID_AC_VI 4
178#define TID_AC_BK 1
179
Jeff Johnson43fee1c2016-11-23 13:12:03 -0800180static const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800181{
182 switch (tdlsActionCode) {
183 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
184 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
185 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
186 CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
187 CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
188 CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
189 CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
190 CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
191 CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
192 CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
193 }
194 return (const uint8_t *)"UNKNOWN";
195}
Srinivas Girigowda15460572017-03-16 00:01:21 -0700196
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197/*
198 * initialize TDLS setup list and related data structures.
199 */
200void lim_init_tdls_data(tpAniSirGlobal pMac, tpPESession pSessionEntry)
201{
202 lim_init_peer_idxpool(pMac, pSessionEntry);
203
204 return;
205}
206
Jeff Johnsona38de672016-11-04 06:53:58 -0700207static void populate_dot11f_tdls_offchannel_params(
208 tpAniSirGlobal pMac,
209 tpPESession psessionEntry,
210 tDot11fIESuppChannels *suppChannels,
211 tDot11fIESuppOperatingClasses *suppOperClasses)
212{
213 uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
214 uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
215 uint8_t i;
216 uint8_t valid_count = 0;
217 uint8_t chanOffset;
218 uint8_t op_class;
219 uint8_t numClasses;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700220 uint8_t classes[REG_MAX_SUPP_OPER_CLASSES];
Jeff Johnsona38de672016-11-04 06:53:58 -0700221 uint32_t band;
222 uint8_t nss_2g;
223 uint8_t nss_5g;
224
225 if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700226 validChan, &numChans) != QDF_STATUS_SUCCESS) {
Jeff Johnsona38de672016-11-04 06:53:58 -0700227 /**
228 * Could not get Valid channel list from CFG.
229 * Log error.
230 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530231 pe_err("could not retrieve Valid channel list");
Jeff Johnsona38de672016-11-04 06:53:58 -0700232 return;
233 }
234
235 if (IS_5G_CH(psessionEntry->currentOperChannel))
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -0800236 band = BAND_5G;
Jeff Johnsona38de672016-11-04 06:53:58 -0700237 else
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -0800238 band = BAND_2G;
Jeff Johnsona38de672016-11-04 06:53:58 -0700239
240 nss_5g = QDF_MIN(pMac->vdev_type_nss_5g.tdls,
241 pMac->user_configured_nss);
242 nss_2g = QDF_MIN(pMac->vdev_type_nss_2g.tdls,
243 pMac->user_configured_nss);
244
245 /* validating the channel list for DFS and 2G channels */
246 for (i = 0U; i < numChans; i++) {
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -0800247 if ((band == BAND_5G) &&
Jeff Johnsona38de672016-11-04 06:53:58 -0700248 (NSS_2x2_MODE == nss_5g) &&
249 (NSS_1x1_MODE == nss_2g) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700250 (wlan_reg_is_dfs_ch(pMac->pdev, validChan[i]))) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530251 pe_debug("skipping channel: %d, nss_5g: %d, nss_2g: %d",
Jeff Johnsona38de672016-11-04 06:53:58 -0700252 validChan[i], nss_5g, nss_2g);
253 continue;
254 } else {
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700255 if (wlan_reg_is_dsrc_chan(pMac->pdev, validChan[i])) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530256 pe_debug("skipping channel: %d from the valid channel list",
Jeff Johnsona38de672016-11-04 06:53:58 -0700257 validChan[i]);
258 continue;
259 }
260 }
261
262 if (valid_count >= ARRAY_SIZE(suppChannels->bands))
263 break;
264 suppChannels->bands[valid_count][0] = validChan[i];
265 suppChannels->bands[valid_count][1] = 1;
266 valid_count++;
267 }
268
269 suppChannels->num_bands = valid_count;
270 suppChannels->present = 1;
271
272 /* find channel offset and get op class for current operating channel */
273 switch (psessionEntry->htSecondaryChannelOffset) {
274 case PHY_SINGLE_CHANNEL_CENTERED:
275 chanOffset = BW20;
276 break;
277
278 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
279 chanOffset = BW40_LOW_PRIMARY;
280 break;
281
282 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
283 chanOffset = BW40_HIGH_PRIMARY;
284 break;
285
286 default:
287 chanOffset = BWALL;
288 break;
Jeff Johnsona38de672016-11-04 06:53:58 -0700289 }
290
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700291 op_class = wlan_reg_dmn_get_opclass_from_channel(
Jeff Johnsona38de672016-11-04 06:53:58 -0700292 pMac->scan.countryCodeCurrent,
293 psessionEntry->currentOperChannel,
294 chanOffset);
295
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530296 pe_debug("countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d op class: %d",
Jeff Johnsona38de672016-11-04 06:53:58 -0700297 pMac->scan.countryCodeCurrent,
298 psessionEntry->currentOperChannel,
299 psessionEntry->htSecondaryChannelOffset,
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530300 chanOffset, op_class);
Jeff Johnsona38de672016-11-04 06:53:58 -0700301 suppOperClasses->present = 1;
302 suppOperClasses->classes[0] = op_class;
303
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700304 wlan_reg_dmn_get_curr_opclasses(&numClasses, &classes[0]);
Jeff Johnsona38de672016-11-04 06:53:58 -0700305
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700306 for (i = 0; i < numClasses; i++)
Jeff Johnsona38de672016-11-04 06:53:58 -0700307 suppOperClasses->classes[i + 1] = classes[i];
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700308
Jeff Johnsona38de672016-11-04 06:53:58 -0700309 /* add one for present operating class, added in the beginning */
310 suppOperClasses->num_classes = numClasses + 1;
311
312 return;
313}
314
315/*
316 * FUNCTION: Populate Link Identifier element IE
317 *
318 */
319
320static void populate_dot11f_link_iden(tpAniSirGlobal pMac,
321 tpPESession psessionEntry,
322 tDot11fIELinkIdentifier *linkIden,
323 struct qdf_mac_addr peer_mac,
324 uint8_t reqType)
325{
326 uint8_t *initStaAddr = NULL;
327 uint8_t *respStaAddr = NULL;
328
329 (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
330 (respStaAddr = linkIden->RespStaAddr))
331 : ((respStaAddr = linkIden->InitStaAddr),
332 (initStaAddr = linkIden->RespStaAddr));
333 qdf_mem_copy((uint8_t *) linkIden->bssid,
334 (uint8_t *) psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
335
336 qdf_mem_copy((uint8_t *) initStaAddr,
337 psessionEntry->selfMacAddr, QDF_MAC_ADDR_SIZE);
338
339 qdf_mem_copy((uint8_t *) respStaAddr, (uint8_t *) peer_mac.bytes,
340 QDF_MAC_ADDR_SIZE);
341
342 linkIden->present = 1;
343 return;
344
345}
346
347static void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
348 tpPESession psessionEntry,
349 tDot11fIEExtCap *extCapability)
350{
351 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes;
352
353 p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT;
354 p_ext_cap->tdls_peer_uapsd_buffer_sta = pMac->lim.gLimTDLSBufStaEnabled;
355
356 /*
357 * Set TDLS channel switching bits only if offchannel is enabled
358 * and TDLS Channel Switching is not prohibited by AP in ExtCap
359 * IE in assoc/re-assoc response.
360 */
361 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
362 (!psessionEntry->tdls_chan_swit_prohibited)) {
363 p_ext_cap->tdls_channel_switching = 1;
364 p_ext_cap->tdls_chan_swit_prohibited = 0;
365 } else {
366 p_ext_cap->tdls_channel_switching = 0;
367 p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED;
368 }
369 p_ext_cap->tdls_support = TDLS_SUPPORT;
370 p_ext_cap->tdls_prohibited = TDLS_PROHIBITED;
371
372 extCapability->present = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800373 extCapability->num_bytes = lim_compute_ext_cap_ie_length(extCapability);
Jeff Johnsona38de672016-11-04 06:53:58 -0700374
375 return;
376}
377
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800378/*
379 * prepare TDLS frame header, it includes
380 * | | | |
381 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
382 * | | | |
383 */
384static uint32_t lim_prepare_tdls_frame_header(tpAniSirGlobal pMac, uint8_t *pFrame,
385 tDot11fIELinkIdentifier *link_iden,
386 uint8_t tdlsLinkType, uint8_t reqType,
387 uint8_t tid,
388 tpPESession psessionEntry)
389{
390 tpSirMacDataHdr3a pMacHdr;
391 uint32_t header_offset = 0;
392 uint8_t *addr1 = NULL;
393 uint8_t *addr3 = NULL;
394 uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP)
395 ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS;
396 uint8_t *peerMac = (reqType == TDLS_INITIATOR)
397 ? link_iden->RespStaAddr : link_iden->InitStaAddr;
398 uint8_t *staMac = (reqType == TDLS_INITIATOR)
399 ? link_iden->InitStaAddr : link_iden->RespStaAddr;
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530400 tpDphHashNode sta_ds;
401 uint16_t aid = 0;
402 uint8_t qos_mode = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403
404 pMacHdr = (tpSirMacDataHdr3a) (pFrame);
405
406 /*
407 * if TDLS frame goes through the AP link, it follows normal address
408 * pattern, if TDLS frame goes thorugh the direct link, then
409 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
410 */
411 (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
412 (addr3 = (peerMac)))
413 : ((addr1 = (peerMac)), (addr3 = (link_iden->bssid)));
414 /*
415 * prepare 802.11 header
416 */
417 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
418 pMacHdr->fc.type = SIR_MAC_DATA_FRAME;
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530419
420 sta_ds = dph_lookup_hash_entry(pMac, peerMac, &aid,
421 &psessionEntry->dph.dphHashTable);
422 if (sta_ds)
423 qos_mode = sta_ds->qosMode;
424
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800425 pMacHdr->fc.subType =
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530426 ((IS_QOS_ENABLED(psessionEntry) &&
427 (tdlsLinkType == TDLS_LINK_AP)) ||
428 ((tdlsLinkType == TDLS_LINK_DIRECT) && qos_mode))
429 ? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800430
431 /*
432 * TL is not setting up below fields, so we are doing it here
433 */
434 pMacHdr->fc.toDS = toDs;
435 pMacHdr->fc.powerMgmt = 0;
436 pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE) ? 0 : 1;
437
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530438 qdf_mem_copy((uint8_t *) pMacHdr->addr1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439 (uint8_t *) addr1, sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530440 qdf_mem_copy((uint8_t *) pMacHdr->addr2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441 (uint8_t *) staMac, sizeof(tSirMacAddr));
442
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530443 qdf_mem_copy((uint8_t *) pMacHdr->addr3,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 (uint8_t *) (addr3), sizeof(tSirMacAddr));
445
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530446 pe_debug("Preparing TDLS frame header to %s A1:"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530448 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT",
450 MAC_ADDR_ARRAY(pMacHdr->addr1),
451 MAC_ADDR_ARRAY(pMacHdr->addr2),
452 MAC_ADDR_ARRAY(pMacHdr->addr3));
453
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530454 if (pMacHdr->fc.subType == SIR_MAC_DATA_QOS_DATA) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 pMacHdr->qosControl.tid = tid;
456 header_offset += sizeof(tSirMacDataHdr3a);
457 } else
458 header_offset += sizeof(tSirMacMgmtHdr);
459
460 /*
461 * Now form RFC1042 header
462 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530463 qdf_mem_copy((uint8_t *) (pFrame + header_offset),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 (uint8_t *) eth_890d_header, sizeof(eth_890d_header));
465
466 header_offset += sizeof(eth_890d_header);
467
468 /* add payload type as TDLS */
469 *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
470 header_offset += PAYLOAD_TYPE_TDLS_SIZE;
471 return header_offset;
472}
473
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530474/**
475 * lim_mgmt_tdls_tx_complete - callback to indicate Tx completion
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530476 * @context: pointer to mac structure
477 * @buf: buffer
Jeff Johnson5ead5ab2018-05-06 00:11:08 -0700478 * @tx_complete: indicates tx success/failure
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530479 * @params: tx completion params
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530480 *
481 * function will be invoked on receiving tx completion indication
482 *
483 * return: success: eHAL_STATUS_SUCCESS failure: eHAL_STATUS_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530485static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context,
486 qdf_nbuf_t buf,
487 uint32_t tx_complete,
488 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530490 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800491
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530492 pe_debug("tdls_frm_session_id: %x tx_complete: %x",
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530493 mac_ctx->lim.tdls_frm_session_id, tx_complete);
494
495 if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) {
Ganesh Kondabattiniac570072016-12-21 12:45:48 +0530496 lim_send_sme_mgmt_tx_completion(mac_ctx,
497 mac_ctx->lim.tdls_frm_session_id,
498 tx_complete);
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530499 mac_ctx->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +0530501
502 if (buf)
503 qdf_nbuf_free(buf);
504
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530505 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506}
507
508/*
509 * This function can be used for bacst or unicast discovery request
510 * We are not differentiating it here, it will all depnds on peer MAC address,
511 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700512static QDF_STATUS lim_send_tdls_dis_req_frame(tpAniSirGlobal pMac,
Jeff Johnson43fee1c2016-11-23 13:12:03 -0800513 struct qdf_mac_addr peer_mac,
514 uint8_t dialog,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +0530515 tpPESession psessionEntry,
516 enum wifi_traffic_ac ac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517{
518 tDot11fTDLSDisReq tdlsDisReq;
519 uint32_t status = 0;
520 uint32_t nPayload = 0;
521 uint32_t size = 0;
522 uint32_t nBytes = 0;
523 uint32_t header_offset = 0;
524 uint8_t *pFrame;
525 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530526 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527#ifndef NO_PAD_TDLS_MIN_8023_SIZE
528 uint32_t padLen = 0;
529#endif
530 uint8_t smeSessionId = 0;
531
532 if (NULL == psessionEntry) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530533 pe_err("psessionEntry is NULL");
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700534 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535 }
536 smeSessionId = psessionEntry->smeSessionId;
537 /*
538 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
539 * and then hand it off to 'dot11f_pack_probe_request' (for
540 * serialization). We start by zero-initializing the structure:
541 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530542 qdf_mem_set((uint8_t *) &tdlsDisReq, sizeof(tDot11fTDLSDisReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543
544 /*
545 * setup Fixed fields,
546 */
547 tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS;
548 tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ;
549 tdlsDisReq.DialogToken.token = dialog;
550
551 size = sizeof(tSirMacAddr);
552
553 populate_dot11f_link_iden(pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
554 peer_mac, TDLS_INITIATOR);
555
556 /*
557 * now we pack it. First, how much space are we going to need?
558 */
559 status = dot11f_get_packed_tdls_dis_req_size(pMac, &tdlsDisReq, &nPayload);
560 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530561 pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562 status);
563 /* We'll fall back on the worst case scenario: */
564 nPayload = sizeof(tDot11fTDLSDisReq);
565 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530566 pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 status);
568 }
569
570 /*
571 * This frame is going out from PE as data frames with special ethertype
572 * 89-0d.
573 * 8 bytes of RFC 1042 header
574 */
575
576 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
577 ? sizeof(tSirMacDataHdr3a) :
578 sizeof(tSirMacMgmtHdr))
579 + sizeof(eth_890d_header)
580 + PAYLOAD_TYPE_TDLS_SIZE;
581
582#ifndef NO_PAD_TDLS_MIN_8023_SIZE
583 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
584 Hence AP itself padding some bytes, which caused teardown packet is dropped at
585 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
586 */
587 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
588 padLen =
589 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
590
591 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
592 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
593 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
594
595 nBytes += padLen;
596 }
597#endif
598
599 /* Ok-- try to allocate memory from MGMT PKT pool */
600
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530601 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530603 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530604 pe_err("Failed to allocate: %d bytes for a TDLS Discovery Request",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605 nBytes);
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700606 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 }
608
609 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530610 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611
612 /*
613 * IE formation, memory allocation is completed, Now form TDLS discovery
614 * request frame
615 */
616
617 /* fill out the buffer descriptor */
618
619 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +0530620 LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP,
621 TDLS_INITIATOR,
622 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
623 psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624
625 status = dot11f_pack_tdls_dis_req(pMac, &tdlsDisReq, pFrame
626 + header_offset, nPayload, &nPayload);
627
628 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530629 pe_err("Failed to pack a TDLS discovery req (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 status);
631 cds_packet_free((void *)pPacket);
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700632 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530634 pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635 status);
636 }
Srinivas Girigowda37bc3512017-03-10 14:29:54 -0800637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638#ifndef NO_PAD_TDLS_MIN_8023_SIZE
639 if (padLen != 0) {
640 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
641 uint8_t *padVendorSpecific = pFrame + header_offset + nPayload;
642 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
643 padVendorSpecific[0] = 221;
644 padVendorSpecific[1] = padLen - 2;
645 padVendorSpecific[2] = 0x00;
646 padVendorSpecific[3] = 0xA0;
647 padVendorSpecific[4] = 0xC6;
648
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530649 pe_debug("Padding Vendor Specific Ie Len: %d", padLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650
651 /* padding zero if more than 5 bytes are required */
652 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530653 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654 MIN_VENDOR_SPECIFIC_IE_SIZE,
655 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
656 }
657#endif
658
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530659 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800660 SIR_MAC_TDLS_DIS_REQ,
661 lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_REQ),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800662 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663
Ganesh Kondabattiniac570072016-12-21 12:45:48 +0530664 pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
Krunal Sonic65fc492018-03-09 15:53:28 -0800665 lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700666 psessionEntry, QDF_STATUS_SUCCESS,
667 QDF_STATUS_SUCCESS);
Selvaraj, Sridhare9199ab2016-09-14 17:13:22 +0530668 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket,
669 (uint16_t) nBytes,
670 TXRX_FRM_802_11_DATA,
671 ANI_TXDIR_TODS,
672 TID_AC_VI,
673 lim_tx_complete, pFrame,
674 lim_mgmt_tdls_tx_complete,
675 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME |
676 HAL_USE_PEER_STA_REQUESTED_MASK,
Naveen Rawat296a5182017-09-25 14:02:48 -0700677 smeSessionId, false, 0, RATEID_DEFAULT);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530678 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530679 pMac->lim.tdls_frm_session_id = NO_SESSION;
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530680 pe_err("could not send TDLS Discovery Request frame");
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700681 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682 }
683
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700684 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685
686}
687
688/*
689 * This static function is consistent with any kind of TDLS management
690 * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame,
691 * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame
692 */
693static void populate_dot11f_tdls_ht_vht_cap(tpAniSirGlobal pMac,
694 uint32_t selfDot11Mode,
695 tDot11fIEHTCaps *htCap,
696 tDot11fIEVHTCaps *vhtCap,
697 tpPESession psessionEntry)
698{
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -0700699 uint8_t nss;
700 uint32_t val;
701
702 if (IS_5G_CH(psessionEntry->currentOperChannel))
703 nss = pMac->vdev_type_nss_5g.tdls;
704 else
705 nss = pMac->vdev_type_nss_2g.tdls;
706
Archana Ramachandran5041b252016-04-25 14:29:25 -0700707 nss = QDF_MIN(nss, pMac->user_configured_nss);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708 if (IS_DOT11_MODE_HT(selfDot11Mode)) {
709 /* Include HT Capability IE */
710 populate_dot11f_ht_caps(pMac, NULL, htCap);
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -0700711 val = SIZE_OF_SUPPORTED_MCS_SET;
712 wlan_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
713 &htCap->supportedMCSSet[0], &val);
714 if (NSS_1x1_MODE == nss)
715 htCap->supportedMCSSet[1] = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800716 /*
717 * Advertise ht capability and max supported channel bandwidth
718 * when populating HT IE in TDLS Setup Request/Setup Response/
719 * Setup Confirmation frames.
720 * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz
721 * off-channel direct link may be started if both TDLS peer STAs
722 * indicated 40 MHz support in the Supported Channel Width Set
723 * field of the HT Capabilities element (which is included in
724 * the TDLS Setup Request frame and the TDLS Setup Response
725 * frame). Switching to a 40 MHz off-channel direct link is
726 * achieved by including the following information in the TDLS
727 * Channel Switch Request
728 * 11.21.1 General: The channel width of the TDLS direct link on
729 * the base channel shall not exceed the channel width of the
730 * BSS to which the TDLS peer STAs are associated.
731 */
732 htCap->supportedChannelWidthSet = 1;
733 } else {
734 htCap->present = 0;
735 }
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530736 pe_debug("HT present: %hu, Chan Width: %hu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737 htCap->present, htCap->supportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738 if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
739 pMac->roam.configParam.enableVhtFor24GHz) ||
740 (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
741 if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
742 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
743 /* Include VHT Capability IE */
744 populate_dot11f_vht_caps(pMac, psessionEntry, vhtCap);
Kabilan Kannan91765b42016-06-14 00:00:23 -0700745
746 /*
747 * Set to 0 if the TDLS STA does not support either 160
748 * or 80+80 MHz.
749 * Set to 1 if the TDLS STA supports 160 MHz.
750 * Set to 2 if the TDLS STA supports 160 MHz and
751 * 80+80 MHz.
752 * The value 3 is reserved
753 */
754 vhtCap->supportedChannelWidthSet = 0;
755
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 vhtCap->suBeamformeeCap = 0;
757 vhtCap->suBeamFormerCap = 0;
758 vhtCap->muBeamformeeCap = 0;
759 vhtCap->muBeamformerCap = 0;
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -0700760
761 wlan_cfg_get_int(pMac, WNI_CFG_VHT_RX_MCS_MAP, &val);
762 vhtCap->rxMCSMap = val;
763 wlan_cfg_get_int(pMac,
764 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
765 &val);
766 vhtCap->rxHighSupDataRate = val;
767 wlan_cfg_get_int(pMac, WNI_CFG_VHT_TX_MCS_MAP, &val);
768 vhtCap->txMCSMap = val;
769 wlan_cfg_get_int(pMac,
770 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
771 &val);
772 vhtCap->txSupDataRate = val;
773 if (nss == NSS_1x1_MODE) {
774 vhtCap->txMCSMap |= DISABLE_NSS2_MCS;
775 vhtCap->rxMCSMap |= DISABLE_NSS2_MCS;
776 vhtCap->txSupDataRate =
777 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
778 vhtCap->rxHighSupDataRate =
779 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
780 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 } else {
782 vhtCap->present = 0;
783 }
784 } else {
785 /* Vht Disable from ini in 2.4 GHz */
786 vhtCap->present = 0;
787 }
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530788 pe_debug("VHT present: %hu, Chan Width: %hu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800789 vhtCap->present, vhtCap->supportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790}
791
792/*
793 * Send TDLS discovery response frame on direct link.
794 */
795
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700796static QDF_STATUS lim_send_tdls_dis_rsp_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530797 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800798 uint8_t dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 tpPESession psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800800 uint8_t *addIe,
801 uint16_t addIeLen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802{
803 tDot11fTDLSDisRsp tdlsDisRsp;
804 uint16_t caps = 0;
805 uint32_t status = 0;
806 uint32_t nPayload = 0;
807 uint32_t nBytes = 0;
808 uint8_t *pFrame;
809 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530810 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 uint32_t selfDot11Mode;
812/* Placeholder to support different channel bonding mode of TDLS than AP. */
813/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
814/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
815/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
816/* uint32_t tdlsChannelBondingMode; */
817 uint8_t smeSessionId = 0;
818
819 if (NULL == psessionEntry) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530820 pe_err("psessionEntry is NULL");
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700821 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 }
823 smeSessionId = psessionEntry->smeSessionId;
824
825 /*
826 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
827 * and then hand it off to 'dot11f_pack_probe_request' (for
828 * serialization). We start by zero-initializing the structure:
829 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530830 qdf_mem_set((uint8_t *) &tdlsDisRsp, sizeof(tDot11fTDLSDisRsp), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831
832 /*
833 * setup Fixed fields,
834 */
835 tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
836 tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP;
837 tdlsDisRsp.DialogToken.token = dialog;
838
839 populate_dot11f_link_iden(pMac, psessionEntry,
840 &tdlsDisRsp.LinkIdentifier,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800841 peer_mac, TDLS_RESPONDER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842
843 if (cfg_get_capability_info(pMac, &caps, psessionEntry)
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700844 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845 /*
846 * Could not get Capabilities value
847 * from CFG. Log error.
848 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530849 pe_err("could not retrieve Capabilities value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 }
851 swap_bit_field16(caps, (uint16_t *) &tdlsDisRsp.Capabilities);
852
853 /* populate supported rate and ext supported rate IE */
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700854 if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(pMac,
Masti, Narayanraddid8a56fb2016-09-06 16:07:33 +0530855 &tdlsDisRsp.SuppRates,
856 &tdlsDisRsp.ExtSuppRates,
857 psessionEntry->currentOperChannel))
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530858 pe_err("could not populate supported data rates");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859
860 /* populate extended capability IE */
861 populate_dot11f_tdls_ext_capability(pMac,
862 psessionEntry,
863 &tdlsDisRsp.ExtCap);
864
865 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
866
867 /* Populate HT/VHT Capabilities */
868 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsDisRsp.HTCaps,
869 &tdlsDisRsp.VHTCaps, psessionEntry);
870
871 /* Populate TDLS offchannel param only if offchannel is enabled
872 * and TDLS Channel Switching is not prohibited by AP in ExtCap
873 * IE in assoc/re-assoc response.
874 */
875 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
876 (!psessionEntry->tdls_chan_swit_prohibited)) {
877 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
878 &tdlsDisRsp.SuppChannels,
879 &tdlsDisRsp.
880 SuppOperatingClasses);
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -0800881 if (pMac->roam.configParam.bandCapability != BAND_2G) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882 tdlsDisRsp.ht2040_bss_coexistence.present = 1;
883 tdlsDisRsp.ht2040_bss_coexistence.info_request = 1;
884 }
885 } else {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530886 pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887 pMac->lim.gLimTDLSOffChannelEnabled,
888 psessionEntry->tdls_chan_swit_prohibited);
889 }
890 /*
891 * now we pack it. First, how much space are we going to need?
892 */
893 status = dot11f_get_packed_tdls_dis_rsp_size(pMac, &tdlsDisRsp, &nPayload);
894 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530895 pe_err("Failed to calculate the packed size for a Discovery Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 status);
897 /* We'll fall back on the worst case scenario: */
898 nPayload = sizeof(tDot11fProbeRequest);
899 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530900 pe_warn("There were warnings while calculating the packed size for a Discovery Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901 status);
902 }
903
904 /*
905 * This frame is going out from PE as data frames with special ethertype
906 * 89-0d.
907 * 8 bytes of RFC 1042 header
908 */
909
910 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen;
911
912 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530913 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530915 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530916 pe_err("Failed to allocate %d bytes for a TDLS Discovery Request",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917 nBytes);
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700918 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919 }
920
921 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530922 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923
924 /*
925 * IE formation, memory allocation is completed, Now form TDLS discovery
926 * response frame
927 */
928
929 /* Make public Action Frame */
930
931 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800932 SIR_MAC_MGMT_ACTION, peer_mac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800933 psessionEntry->selfMacAddr);
934
935 {
936 tpSirMacMgmtHdr pMacHdr;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -0700937
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938 pMacHdr = (tpSirMacMgmtHdr) pFrame;
939 pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
940 pMacHdr->fc.powerMgmt = 0;
941 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
942 }
943
944 status = dot11f_pack_tdls_dis_rsp(pMac, &tdlsDisRsp, pFrame +
945 sizeof(tSirMacMgmtHdr),
946 nPayload, &nPayload);
947
948 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530949 pe_err("Failed to pack a TDLS discovery response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 status);
951 cds_packet_free((void *)pPacket);
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700952 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800953 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530954 pe_warn("There were warnings while packing TDLS Discovery Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800955 status);
956 }
Srinivas Girigowda37bc3512017-03-10 14:29:54 -0800957
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800958 if (0 != addIeLen) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530959 pe_debug("Copy Additional Ie Len: %d", addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530960 qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 addIeLen);
962 }
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530963 pe_debug("[TDLS] action: %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800964 SIR_MAC_TDLS_DIS_RSP,
965 lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_RSP),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800966 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800967
Ganesh Kondabattiniac570072016-12-21 12:45:48 +0530968 pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
Krunal Sonic65fc492018-03-09 15:53:28 -0800969 lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700970 psessionEntry, QDF_STATUS_SUCCESS,
971 QDF_STATUS_SUCCESS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972 /*
973 * Transmit Discovery response and watch if this is delivered to
974 * peer STA.
975 */
976 /* In CLD 2.0, pass Discovery Response as mgmt frame so that
977 * wma does not do header conversion to 802.3 before calling tx/rx
978 * routine and subsequenly target also sends frame as is OTA
979 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530980 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 TXRX_FRM_802_11_MGMT,
982 ANI_TXDIR_IBSS,
983 0,
984 lim_tx_complete, pFrame,
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530985 lim_mgmt_tdls_tx_complete,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800986 HAL_USE_SELF_STA_REQUESTED_MASK,
Naveen Rawat296a5182017-09-25 14:02:48 -0700987 smeSessionId, false, 0,
988 RATEID_DEFAULT);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530989 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530990 pMac->lim.tdls_frm_session_id = NO_SESSION;
Nishank Aggarwal550931a2017-03-22 19:33:11 +0530991 pe_err("could not send TDLS Discovery Response frame!");
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700992 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800993 }
994
Jeff Johnson0301ecb2018-06-29 09:36:23 -0700995 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996
997}
998
999/*
1000 * This static function is currently used by lim_send_tdls_link_setup_req_frame and
1001 * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable.
1002 */
1003static void populate_dotf_tdls_vht_aid(tpAniSirGlobal pMac, uint32_t selfDot11Mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301004 struct qdf_mac_addr peerMac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001005 tDot11fIEAID *Aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001006 tpPESession psessionEntry)
1007{
1008 if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
1009 pMac->roam.configParam.enableVhtFor24GHz) ||
1010 (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
1011 if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
1012 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
1013
1014 uint16_t aid;
1015 tpDphHashNode pStaDs;
1016
1017 pStaDs =
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001018 dph_lookup_hash_entry(pMac, peerMac.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001019 &psessionEntry->dph.
1020 dphHashTable);
1021 if (NULL != pStaDs) {
1022 Aid->present = 1;
1023 Aid->assocId = aid | LIM_AID_MASK; /* set bit 14 and 15 1's */
1024 } else {
1025 Aid->present = 0;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301026 pe_err("pStaDs is NULL for "
1027 MAC_ADDRESS_STR,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001028 MAC_ADDR_ARRAY(peerMac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029 }
1030 }
1031 } else {
1032 Aid->present = 0;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301033 pe_warn("Vht not enable from ini for 2.4GHz");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001034 }
1035}
1036
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301037#ifdef CONFIG_HL_SUPPORT
1038
1039/**
1040 * wma_tx_frame_with_tx_complete_send() - Send tx frames on Direct link or AP link
1041 * depend on reason code
1042 * @pMac: pointer to MAC Sirius parameter structure
1043 * @pPacket: pointer to mgmt packet
1044 * @nBytes: number of bytes to send
1045 * @tid:tid value for AC
1046 * @pFrame: pointer to tdls frame
1047 * @smeSessionId:session id
1048 * @flag: tdls flag
1049 *
1050 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1051 *
1052 * Return: None
1053 */
1054static inline QDF_STATUS
1055wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
1056 uint16_t nBytes,
1057 uint8_t tid,
1058 uint8_t *pFrame,
1059 uint8_t smeSessionId, bool flag)
1060{
1061 return wma_tx_frameWithTxComplete(pMac, pPacket,
1062 (uint16_t) nBytes,
1063 TXRX_FRM_802_11_DATA,
1064 ANI_TXDIR_TODS,
1065 tid,
1066 lim_tx_complete, pFrame,
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301067 lim_mgmt_tdls_tx_complete,
Selvaraj, Sridhare9199ab2016-09-14 17:13:22 +05301068 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
1069 | HAL_USE_PEER_STA_REQUESTED_MASK,
Naveen Rawat296a5182017-09-25 14:02:48 -07001070 smeSessionId, flag, 0,
1071 RATEID_DEFAULT);
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301072}
1073#else
1074
1075static inline QDF_STATUS
1076wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
1077 uint16_t nBytes,
1078 uint8_t tid,
1079 uint8_t *pFrame,
1080 uint8_t smeSessionId, bool flag)
1081{
1082 return wma_tx_frameWithTxComplete(pMac, pPacket,
1083 (uint16_t) nBytes,
1084 TXRX_FRM_802_11_DATA,
1085 ANI_TXDIR_TODS,
1086 tid,
1087 lim_tx_complete, pFrame,
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301088 lim_mgmt_tdls_tx_complete,
Selvaraj, Sridhare9199ab2016-09-14 17:13:22 +05301089 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
1090 | HAL_USE_PEER_STA_REQUESTED_MASK,
Naveen Rawat296a5182017-09-25 14:02:48 -07001091 smeSessionId, false, 0,
1092 RATEID_DEFAULT);
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301093}
1094#endif
1095
Kabilan Kannan32eb5022016-10-04 12:24:50 -07001096void lim_set_tdls_flags(roam_offload_synch_ind *roam_sync_ind_ptr,
1097 tpPESession ft_session_ptr)
1098{
1099 roam_sync_ind_ptr->join_rsp->tdls_prohibited =
1100 ft_session_ptr->tdls_prohibited;
1101 roam_sync_ind_ptr->join_rsp->tdls_chan_swit_prohibited =
1102 ft_session_ptr->tdls_chan_swit_prohibited;
1103}
1104
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001105/*
1106 * TDLS setup Request frame on AP link
1107 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -08001108static
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001109QDF_STATUS lim_send_tdls_link_setup_req_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301110 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001111 uint8_t dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001112 tpPESession psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001113 uint8_t *addIe,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301114 uint16_t addIeLen,
1115 enum wifi_traffic_ac ac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001116{
1117 tDot11fTDLSSetupReq tdlsSetupReq;
1118 uint16_t caps = 0;
1119 uint32_t status = 0;
1120 uint32_t nPayload = 0;
1121 uint32_t nBytes = 0;
1122 uint32_t header_offset = 0;
1123 uint8_t *pFrame;
1124 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301125 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001126 uint32_t selfDot11Mode;
1127 uint8_t smeSessionId = 0;
1128/* Placeholder to support different channel bonding mode of TDLS than AP. */
1129/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
1130/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
1131/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
1132/* uint32_t tdlsChannelBondingMode; */
1133
1134 /*
1135 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1136 * and then hand it off to 'dot11f_pack_probe_request' (for
1137 * serialization). We start by zero-initializing the structure:
1138 */
1139 smeSessionId = psessionEntry->smeSessionId;
1140
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301141 qdf_mem_set((uint8_t *) &tdlsSetupReq, sizeof(tDot11fTDLSSetupReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001142 tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS;
1143 tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ;
1144 tdlsSetupReq.DialogToken.token = dialog;
1145
1146 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001147 &tdlsSetupReq.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001148 TDLS_INITIATOR);
1149
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001150 if (cfg_get_capability_info(pMac, &caps, psessionEntry) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001151 /*
1152 * Could not get Capabilities value
1153 * from CFG. Log error.
1154 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301155 pe_err("could not retrieve Capabilities value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 }
1157 swap_bit_field16(caps, (uint16_t *) &tdlsSetupReq.Capabilities);
1158
1159 /* populate supported rate and ext supported rate IE */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001160 if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(pMac,
Masti, Narayanraddid8a56fb2016-09-06 16:07:33 +05301161 &tdlsSetupReq.SuppRates,
1162 &tdlsSetupReq.ExtSuppRates,
1163 psessionEntry->currentOperChannel))
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301164 pe_err("could not populate supported data rates");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165
1166 /* Populate extended capability IE */
1167 populate_dot11f_tdls_ext_capability(pMac,
1168 psessionEntry,
1169 &tdlsSetupReq.ExtCap);
1170
1171 if (1 == pMac->lim.gLimTDLSWmmMode) {
1172 uint32_t val = 0;
1173
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301174 pe_debug("populate WMM IE in Setup Request Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001175 /* include WMM IE */
1176 tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
1177 tdlsSetupReq.WMMInfoStation.acvo_uapsd =
1178 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1179 tdlsSetupReq.WMMInfoStation.acvi_uapsd =
1180 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1181 tdlsSetupReq.WMMInfoStation.acbk_uapsd =
1182 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1183 tdlsSetupReq.WMMInfoStation.acbe_uapsd =
1184 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1185
1186 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001187 QDF_STATUS_SUCCESS)
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301188 pe_warn("could not retrieve Max SP Length");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001189
1190 tdlsSetupReq.WMMInfoStation.max_sp_length = (uint8_t) val;
1191 tdlsSetupReq.WMMInfoStation.present = 1;
1192 } else {
1193 /*
1194 * TODO: we need to see if we have to support conditions where
1195 * we have EDCA parameter info element is needed a) if we need
1196 * different QOS parameters for off channel operations or QOS
1197 * is not supported on AP link and we wanted to QOS on direct
1198 * link.
1199 */
1200
1201 /* Populate QOS info, needed for Peer U-APSD session */
1202
1203 /*
1204 * TODO: Now hardcoded, since populate_dot11f_qos_caps_station()
1205 * depends on AP's capability, and TDLS doesn't want to depend
1206 * on AP's capability
1207 */
1208
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301209 pe_debug("populate QOS IE in Setup Request Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 tdlsSetupReq.QOSCapsStation.present = 1;
1211 tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
1212 tdlsSetupReq.QOSCapsStation.qack = 0;
1213 tdlsSetupReq.QOSCapsStation.acbe_uapsd =
1214 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1215 tdlsSetupReq.QOSCapsStation.acbk_uapsd =
1216 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1217 tdlsSetupReq.QOSCapsStation.acvi_uapsd =
1218 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1219 tdlsSetupReq.QOSCapsStation.acvo_uapsd =
1220 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1221 }
1222
1223 /*
1224 * we will always try to init TDLS link with 11n capabilities
1225 * let TDLS setup response to come, and we will set our caps based
1226 * of peer caps
1227 */
1228
1229 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
1230
1231 /* Populate HT/VHT Capabilities */
1232 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupReq.HTCaps,
1233 &tdlsSetupReq.VHTCaps, psessionEntry);
1234
1235 /* Populate AID */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001236 populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 &tdlsSetupReq.AID, psessionEntry);
1238
1239 /* Populate TDLS offchannel param only if offchannel is enabled
1240 * and TDLS Channel Switching is not prohibited by AP in ExtCap
1241 * IE in assoc/re-assoc response.
1242 */
1243 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
1244 (!psessionEntry->tdls_chan_swit_prohibited)) {
1245 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
1246 &tdlsSetupReq.SuppChannels,
1247 &tdlsSetupReq.
1248 SuppOperatingClasses);
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001249 if (pMac->roam.configParam.bandCapability != BAND_2G) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250 tdlsSetupReq.ht2040_bss_coexistence.present = 1;
1251 tdlsSetupReq.ht2040_bss_coexistence.info_request = 1;
1252 }
1253 } else {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301254 pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 pMac->lim.gLimTDLSOffChannelEnabled,
1256 psessionEntry->tdls_chan_swit_prohibited);
1257 }
1258 /*
1259 * now we pack it. First, how much space are we going to need?
1260 */
1261 status = dot11f_get_packed_tdls_setup_req_size(pMac, &tdlsSetupReq,
1262 &nPayload);
1263 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301264 pe_err("Failed to calculate the packed size for a Setup Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265 status);
1266 /* We'll fall back on the worst case scenario: */
1267 nPayload = sizeof(tDot11fProbeRequest);
1268 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301269 pe_warn("There were warnings while calculating the packed size for a Setup Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001270 status);
1271 }
1272
1273 /*
1274 * This frame is going out from PE as data frames with special ethertype
1275 * 89-0d.
1276 * 8 bytes of RFC 1042 header
1277 */
1278
1279 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1280 ? sizeof(tSirMacDataHdr3a) :
1281 sizeof(tSirMacMgmtHdr))
1282 + sizeof(eth_890d_header)
1283 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1284
1285 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301286 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301288 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301289 pe_err("Failed to allocate %d bytes for a TDLS Setup Request",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 nBytes);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001291 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292 }
1293
1294 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301295 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296
1297 /*
1298 * IE formation, memory allocation is completed, Now form TDLS discovery
1299 * request frame
1300 */
1301
1302 /* fill out the buffer descriptor */
1303
1304 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301305 LINK_IDEN_ADDR_OFFSET(tdlsSetupReq),
1306 TDLS_LINK_AP, TDLS_INITIATOR,
1307 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
1308 psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001309
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301310 pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311 tdlsSetupReq.VHTCaps.supportedChannelWidthSet,
1312 tdlsSetupReq.VHTCaps.rxMCSMap,
1313 tdlsSetupReq.VHTCaps.txMCSMap,
1314 tdlsSetupReq.VHTCaps.txSupDataRate);
1315
1316 status = dot11f_pack_tdls_setup_req(pMac, &tdlsSetupReq, pFrame
1317 + header_offset, nPayload, &nPayload);
1318
1319 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301320 pe_err("Failed to pack a TDLS Setup request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321 status);
1322 cds_packet_free((void *)pPacket);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001323 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001324 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301325 pe_warn("There were warnings while packing TDLS Setup Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326 status);
1327 }
Srinivas Girigowda37bc3512017-03-10 14:29:54 -08001328
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 /* Copy the additional IE. */
Jeff Johnson33142e62018-05-06 17:58:36 -07001330 /* TODO : addIe is added at the end of the frame. This means it doesn't */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331 /* follow the order. This should be ok, but we should consider changing this */
1332 /* if there is any IOT issue. */
1333 if (addIeLen != 0) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301334 pe_debug("Copy Additional Ie Len = %d", addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301335 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336 addIeLen);
1337 }
1338
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301339 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 SIR_MAC_TDLS_SETUP_REQ,
1341 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_REQ),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001342 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001343
Ganesh Kondabattiniac570072016-12-21 12:45:48 +05301344 pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
Krunal Sonic65fc492018-03-09 15:53:28 -08001345 lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001346 psessionEntry, QDF_STATUS_SUCCESS,
1347 QDF_STATUS_SUCCESS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301349 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
1350 (uint16_t) nBytes,
1351 TID_AC_VI,
1352 pFrame,
1353 smeSessionId, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301355 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301356 pMac->lim.tdls_frm_session_id = NO_SESSION;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301357 pe_err("could not send TDLS Setup Request frame!");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001358 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001359 }
1360
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001361 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362
1363}
1364
1365/*
1366 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1367 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -08001368static
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001369QDF_STATUS lim_send_tdls_teardown_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301370 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001371 uint16_t reason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372 uint8_t responder,
1373 tpPESession psessionEntry,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301374 uint8_t *addIe, uint16_t addIeLen,
1375 enum wifi_traffic_ac ac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001376{
1377 tDot11fTDLSTeardown teardown;
1378 uint32_t status = 0;
1379 uint32_t nPayload = 0;
1380 uint32_t nBytes = 0;
1381 uint32_t header_offset = 0;
1382 uint8_t *pFrame;
1383 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301384 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001385#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1386 uint32_t padLen = 0;
1387#endif
1388 uint8_t smeSessionId = 0;
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +05301389 tpDphHashNode sta_ds;
1390 uint16_t aid = 0;
1391 uint8_t qos_mode = 0;
1392 uint8_t tdls_link_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393
1394 if (NULL == psessionEntry) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301395 pe_err("psessionEntry is NULL");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001396 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001397 }
1398 smeSessionId = psessionEntry->smeSessionId;
1399 /*
1400 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1401 * and then hand it off to 'dot11f_pack_probe_request' (for
1402 * serialization). We start by zero-initializing the structure:
1403 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301404 qdf_mem_set((uint8_t *) &teardown, sizeof(tDot11fTDLSTeardown), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001405 teardown.Category.category = SIR_MAC_ACTION_TDLS;
1406 teardown.Action.action = SIR_MAC_TDLS_TEARDOWN;
1407 teardown.Reason.code = reason;
1408
1409 populate_dot11f_link_iden(pMac, psessionEntry, &teardown.LinkIdentifier,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001410 peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 (responder ==
1412 true) ? TDLS_RESPONDER : TDLS_INITIATOR);
1413
1414 /*
1415 * now we pack it. First, how much space are we going to need?
1416 */
1417 status = dot11f_get_packed_tdls_teardown_size(pMac, &teardown, &nPayload);
1418 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301419 pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001420 status);
1421 /* We'll fall back on the worst case scenario: */
1422 nPayload = sizeof(tDot11fProbeRequest);
1423 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301424 pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425 status);
1426 }
1427
1428 /*
1429 * This frame is going out from PE as data frames with special ethertype
1430 * 89-0d.
1431 * 8 bytes of RFC 1042 header
1432 */
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +05301433 sta_ds = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
1434 &psessionEntry->dph.dphHashTable);
1435 if (sta_ds)
1436 qos_mode = sta_ds->qosMode;
1437 tdls_link_type = (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1438 ? TDLS_LINK_AP : TDLS_LINK_DIRECT;
1439 nBytes = nPayload + (((IS_QOS_ENABLED(psessionEntry) &&
1440 (tdls_link_type == TDLS_LINK_AP)) ||
1441 ((tdls_link_type == TDLS_LINK_DIRECT) && qos_mode))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001442 ? sizeof(tSirMacDataHdr3a) :
1443 sizeof(tSirMacMgmtHdr))
1444 + sizeof(eth_890d_header)
1445 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1446
1447#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1448 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1449 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1450 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1451 */
1452 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
1453 padLen =
1454 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
1455
1456 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1457 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1458 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1459
1460 nBytes += padLen;
1461 }
1462#endif
1463
1464 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301465 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001466 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301467 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301468 pe_err("Failed to allocate %d bytes for a TDLS Teardown Frame.",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469 nBytes);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001470 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 }
1472
1473 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301474 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475
1476 /*
1477 * IE formation, memory allocation is completed, Now form TDLS discovery
1478 * request frame
1479 */
1480
1481 /* fill out the buffer descriptor */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301482 pe_debug("Reason of TDLS Teardown: %d", reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001483 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301484 LINK_IDEN_ADDR_OFFSET(teardown),
1485 (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ?
1486 TDLS_LINK_AP : TDLS_LINK_DIRECT,
1487 (responder == true) ? TDLS_RESPONDER : TDLS_INITIATOR,
1488 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
1489 psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490
1491 status = dot11f_pack_tdls_teardown(pMac, &teardown, pFrame
1492 + header_offset, nPayload, &nPayload);
1493
1494 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301495 pe_err("Failed to pack a TDLS Teardown frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496 status);
1497 cds_packet_free((void *)pPacket);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001498 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301500 pe_warn("There were warnings while packing TDLS Teardown frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001501 status);
1502 }
1503
1504 if (addIeLen != 0) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301505 pe_debug("Copy Additional Ie Len = %d", addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301506 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001507 addIeLen);
1508 }
1509#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1510 if (padLen != 0) {
1511 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1512 uint8_t *padVendorSpecific =
1513 pFrame + header_offset + nPayload + addIeLen;
1514 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1515 padVendorSpecific[0] = 221;
1516 padVendorSpecific[1] = padLen - 2;
1517 padVendorSpecific[2] = 0x00;
1518 padVendorSpecific[3] = 0xA0;
1519 padVendorSpecific[4] = 0xC6;
1520
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301521 pe_debug("Padding Vendor Specific Ie Len = %d", padLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522
1523 /* padding zero if more than 5 bytes are required */
1524 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301525 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
1527 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
1528 }
1529#endif
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301530 pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 SIR_MAC_TDLS_TEARDOWN,
1532 lim_trace_tdls_action_string(SIR_MAC_TDLS_TEARDOWN),
1533 ((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" :
1534 "DIRECT"),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001535 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001536
Ganesh Kondabattiniac570072016-12-21 12:45:48 +05301537 pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
Krunal Sonic65fc492018-03-09 15:53:28 -08001538 lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001539 psessionEntry, QDF_STATUS_SUCCESS,
1540 QDF_STATUS_SUCCESS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301542 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
1543 (uint16_t) nBytes,
1544 TID_AC_VI,
1545 pFrame,
1546 smeSessionId,
1547 (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1548 ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001549
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301550 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301551 pMac->lim.tdls_frm_session_id = NO_SESSION;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301552 pe_err("could not send TDLS Teardown frame");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001553 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554
1555 }
Krunal Sonic65fc492018-03-09 15:53:28 -08001556
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001557 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001558}
1559
1560/*
1561 * Send Setup RSP frame on AP link.
1562 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001563static QDF_STATUS lim_send_tdls_setup_rsp_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301564 struct qdf_mac_addr peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565 uint8_t dialog,
1566 tpPESession psessionEntry,
1567 etdlsLinkSetupStatus setupStatus,
1568 uint8_t *addIe,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301569 uint16_t addIeLen,
1570 enum wifi_traffic_ac ac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571{
1572 tDot11fTDLSSetupRsp tdlsSetupRsp;
1573 uint32_t status = 0;
1574 uint16_t caps = 0;
1575 uint32_t nPayload = 0;
1576 uint32_t header_offset = 0;
1577 uint32_t nBytes = 0;
1578 uint8_t *pFrame;
1579 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301580 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001581 uint32_t selfDot11Mode;
1582/* Placeholder to support different channel bonding mode of TDLS than AP. */
1583/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
1584/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
1585/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
1586/* uint32_t tdlsChannelBondingMode; */
1587 uint8_t smeSessionId = 0;
1588
1589 if (NULL == psessionEntry) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301590 pe_err("psessionEntry is NULL");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001591 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 }
1593 smeSessionId = psessionEntry->smeSessionId;
1594
1595 /*
1596 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1597 * and then hand it off to 'dot11f_pack_probe_request' (for
1598 * serialization). We start by zero-initializing the structure:
1599 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301600 qdf_mem_set((uint8_t *) &tdlsSetupRsp, sizeof(tDot11fTDLSSetupRsp), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601
1602 /*
1603 * setup Fixed fields,
1604 */
1605 tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
1606 tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP;
1607 tdlsSetupRsp.DialogToken.token = dialog;
1608
1609 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001610 &tdlsSetupRsp.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001611 TDLS_RESPONDER);
1612
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001613 if (cfg_get_capability_info(pMac, &caps, psessionEntry) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001614 /*
1615 * Could not get Capabilities value
1616 * from CFG. Log error.
1617 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301618 pe_err("could not retrieve Capabilities value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619 }
1620 swap_bit_field16(caps, (uint16_t *) &tdlsSetupRsp.Capabilities);
1621
1622 /* populate supported rate and ext supported rate IE */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001623 if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(pMac,
Masti, Narayanraddid8a56fb2016-09-06 16:07:33 +05301624 &tdlsSetupRsp.SuppRates,
1625 &tdlsSetupRsp.ExtSuppRates,
1626 psessionEntry->currentOperChannel))
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301627 pe_err("could not populate supported data rates");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628
1629 /* Populate extended capability IE */
1630 populate_dot11f_tdls_ext_capability(pMac,
1631 psessionEntry,
1632 &tdlsSetupRsp.ExtCap);
1633
1634 if (1 == pMac->lim.gLimTDLSWmmMode) {
1635 uint32_t val = 0;
1636
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301637 pe_debug("populate WMM IE in Setup Response frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638 /* include WMM IE */
1639 tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
1640 tdlsSetupRsp.WMMInfoStation.acvo_uapsd =
1641 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1642 tdlsSetupRsp.WMMInfoStation.acvi_uapsd =
1643 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1644 tdlsSetupRsp.WMMInfoStation.acbk_uapsd =
1645 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1646 tdlsSetupRsp.WMMInfoStation.acbe_uapsd =
1647 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1648 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001649 QDF_STATUS_SUCCESS)
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301650 pe_warn("could not retrieve Max SP Length");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651 tdlsSetupRsp.WMMInfoStation.max_sp_length = (uint8_t) val;
1652 tdlsSetupRsp.WMMInfoStation.present = 1;
1653 } else {
1654 /*
1655 * TODO: we need to see if we have to support conditions where
1656 * we have EDCA parameter info element is needed a) if we need
1657 * different QOS parameters for off channel operations or QOS
1658 * is not supported on AP link and we wanted to QOS on direct
1659 * link.
1660 */
1661 /* Populate QOS info, needed for Peer U-APSD session */
1662 /*
1663 * TODO: Now hardcoded, because
1664 * populate_dot11f_qos_caps_station() depends on AP's
1665 * capability, and TDLS doesn't want to depend on AP's
1666 * capability
1667 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301668 pe_debug("populate QOS IE in Setup Response frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 tdlsSetupRsp.QOSCapsStation.present = 1;
1670 tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
1671 tdlsSetupRsp.QOSCapsStation.qack = 0;
1672 tdlsSetupRsp.QOSCapsStation.acbe_uapsd =
1673 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1674 tdlsSetupRsp.QOSCapsStation.acbk_uapsd =
1675 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1676 tdlsSetupRsp.QOSCapsStation.acvi_uapsd =
1677 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1678 tdlsSetupRsp.QOSCapsStation.acvo_uapsd =
1679 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1680 }
1681
1682 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
1683
1684 /* Populate HT/VHT Capabilities */
1685 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
1686 &tdlsSetupRsp.VHTCaps, psessionEntry);
1687
1688 /* Populate AID */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001689 populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690 &tdlsSetupRsp.AID, psessionEntry);
1691
1692 /* Populate TDLS offchannel param only if offchannel is enabled
1693 * and TDLS Channel Switching is not prohibited by AP in ExtCap
1694 * IE in assoc/re-assoc response.
1695 */
1696 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
1697 (!psessionEntry->tdls_chan_swit_prohibited)) {
1698 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
1699 &tdlsSetupRsp.SuppChannels,
1700 &tdlsSetupRsp.
1701 SuppOperatingClasses);
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001702 if (pMac->roam.configParam.bandCapability != BAND_2G) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703 tdlsSetupRsp.ht2040_bss_coexistence.present = 1;
1704 tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1;
1705 }
1706 } else {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301707 pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001708 pMac->lim.gLimTDLSOffChannelEnabled,
1709 psessionEntry->tdls_chan_swit_prohibited);
1710 }
1711 tdlsSetupRsp.Status.status = setupStatus;
1712 /*
1713 * now we pack it. First, how much space are we going to need?
1714 */
1715 status = dot11f_get_packed_tdls_setup_rsp_size(pMac, &tdlsSetupRsp,
1716 &nPayload);
1717 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301718 pe_err("Failed to calculate the packed size for a Setup Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 status);
1720 /* We'll fall back on the worst case scenario: */
1721 nPayload = sizeof(tDot11fProbeRequest);
1722 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301723 pe_warn("There were warnings while calculating the packed size for Setup Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 status);
1725 }
1726
1727 /*
1728 * This frame is going out from PE as data frames with special ethertype
1729 * 89-0d.
1730 * 8 bytes of RFC 1042 header
1731 */
1732
1733 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1734 ? sizeof(tSirMacDataHdr3a) :
1735 sizeof(tSirMacMgmtHdr))
1736 + sizeof(eth_890d_header)
1737 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1738
1739 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301740 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301742 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301743 pe_err("Failed to allocate %d bytes for a TDLS Setup Response",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001744 nBytes);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001745 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001746 }
1747
1748 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301749 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001750
1751 /*
1752 * IE formation, memory allocation is completed, Now form TDLS discovery
1753 * request frame
1754 */
1755
1756 /* fill out the buffer descriptor */
1757
1758 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301759 LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp), TDLS_LINK_AP,
1760 TDLS_RESPONDER,
1761 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
1762 psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001763
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301764 pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001765 tdlsSetupRsp.VHTCaps.supportedChannelWidthSet,
1766 tdlsSetupRsp.VHTCaps.rxMCSMap,
1767 tdlsSetupRsp.VHTCaps.txMCSMap,
1768 tdlsSetupRsp.VHTCaps.txSupDataRate);
1769 status = dot11f_pack_tdls_setup_rsp(pMac, &tdlsSetupRsp,
1770 pFrame + header_offset,
1771 nPayload, &nPayload);
1772
1773 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301774 pe_err("Failed to pack a TDLS Setup Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775 status);
1776 cds_packet_free((void *)pPacket);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001777 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301779 pe_warn("There were warnings while packing TDLS Setup Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780 status);
1781 }
Srinivas Girigowda37bc3512017-03-10 14:29:54 -08001782
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001783 /* Copy the additional IE. */
Jeff Johnson33142e62018-05-06 17:58:36 -07001784 /* TODO : addIe is added at the end of the frame. This means it doesn't */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785 /* follow the order. This should be ok, but we should consider changing this */
1786 /* if there is any IOT issue. */
1787 if (addIeLen != 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301788 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001789 addIeLen);
1790 }
1791
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301792 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001793 SIR_MAC_TDLS_SETUP_RSP,
1794 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_RSP),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001795 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796
Ganesh Kondabattiniac570072016-12-21 12:45:48 +05301797 pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
Krunal Sonic65fc492018-03-09 15:53:28 -08001798 lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001799 psessionEntry, QDF_STATUS_SUCCESS,
1800 QDF_STATUS_SUCCESS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001801
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301802 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
1803 (uint16_t) nBytes,
1804 TID_AC_VI,
1805 pFrame,
1806 smeSessionId, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301808 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301809 pMac->lim.tdls_frm_session_id = NO_SESSION;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301810 pe_err("could not send TDLS Dis Request frame!");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001811 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 }
1813
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001814 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815}
1816
1817/*
1818 * Send TDLS setup CNF frame on AP link
1819 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -08001820static
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001821QDF_STATUS lim_send_tdls_link_setup_cnf_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301822 struct qdf_mac_addr peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823 uint8_t dialog,
1824 uint32_t peerCapability,
1825 tpPESession psessionEntry,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301826 uint8_t *addIe,
1827 uint16_t addIeLen,
1828 enum wifi_traffic_ac ac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001829{
1830 tDot11fTDLSSetupCnf tdlsSetupCnf;
1831 uint32_t status = 0;
1832 uint32_t nPayload = 0;
1833 uint32_t nBytes = 0;
1834 uint32_t header_offset = 0;
1835 uint8_t *pFrame;
1836 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301837 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1839 uint32_t padLen = 0;
1840#endif
1841 uint8_t smeSessionId = 0;
1842
1843 /*
1844 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1845 * and then hand it off to 'dot11f_pack_probe_request' (for
1846 * serialization). We start by zero-initializing the structure:
1847 */
1848 smeSessionId = psessionEntry->smeSessionId;
1849
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301850 qdf_mem_set((uint8_t *) &tdlsSetupCnf, sizeof(tDot11fTDLSSetupCnf), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851
1852 /*
1853 * setup Fixed fields,
1854 */
1855 tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
1856 tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF;
1857 tdlsSetupCnf.DialogToken.token = dialog;
1858
1859 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001860 &tdlsSetupCnf.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001861 TDLS_INITIATOR);
1862 /*
1863 * TODO: we need to see if we have to support conditions where we have
1864 * EDCA parameter info element is needed a) if we need different QOS
1865 * parameters for off channel operations or QOS is not supported on
1866 * AP link and we wanted to QOS on direct link.
1867 */
1868
1869 /* Check self and peer WMM capable */
1870 if ((1 == pMac->lim.gLimTDLSWmmMode) &&
1871 (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301872 pe_debug("populate WMM praram in Setup Confirm");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001873 populate_dot11f_wmm_params(pMac, &tdlsSetupCnf.WMMParams,
1874 psessionEntry);
1875 }
1876
1877 /* Check peer is VHT capable */
1878 if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) {
1879 populate_dot11f_vht_operation(pMac,
1880 psessionEntry,
1881 &tdlsSetupCnf.VHTOperation);
1882 populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
1883 } else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) { /* Check peer is HT capable */
1884 populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
1885 }
1886
1887 /*
1888 * now we pack it. First, how much space are we going to need?
1889 */
1890 status = dot11f_get_packed_tdls_setup_cnf_size(pMac, &tdlsSetupCnf,
1891 &nPayload);
1892 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301893 pe_err("Failed to calculate the packed size for a Setup Confirm (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001894 status);
1895 /* We'll fall back on the worst case scenario: */
1896 nPayload = sizeof(tDot11fProbeRequest);
1897 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301898 pe_warn("There were warnings while calculating the packed size for Setup Confirm (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001899 status);
1900 }
1901
1902 /*
1903 * This frame is going out from PE as data frames with special ethertype
1904 * 89-0d.
1905 * 8 bytes of RFC 1042 header
1906 */
1907
1908 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1909 ? sizeof(tSirMacDataHdr3a) :
1910 sizeof(tSirMacMgmtHdr))
1911 + sizeof(eth_890d_header)
1912 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1913
1914#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1915 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1916 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1917 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1918 */
1919 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
1920 padLen =
1921 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
1922
1923 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1924 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1925 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1926
1927 nBytes += padLen;
1928 }
1929#endif
1930
1931 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301932 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001933 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301934 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301935 pe_err("Failed to allocate %d bytes for a TDLS Setup Confirm",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001936 nBytes);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001937 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001938 }
1939
1940 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301941 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001942
1943 /*
1944 * IE formation, memory allocation is completed, Now form TDLS discovery
1945 * request frame
1946 */
1947
1948 /* fill out the buffer descriptor */
1949
1950 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05301951 LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf),
1952 TDLS_LINK_AP,
1953 TDLS_INITIATOR,
1954 (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
1955 psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001956
1957 status = dot11f_pack_tdls_setup_cnf(pMac, &tdlsSetupCnf, pFrame
1958 + header_offset, nPayload, &nPayload);
1959
1960 if (DOT11F_FAILED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301961 pe_err("Failed to pack a TDLS discovery req (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962 cds_packet_free((void *)pPacket);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07001963 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 } else if (DOT11F_WARNED(status)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301965 pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 status);
1967 }
Srinivas Girigowda37bc3512017-03-10 14:29:54 -08001968
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001969 /* Copy the additional IE. */
Jeff Johnson33142e62018-05-06 17:58:36 -07001970 /* TODO : addIe is added at the end of the frame. This means it doesn't */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001971 /* follow the order. This should be ok, but we should consider changing this */
1972 /* if there is any IOT issue. */
1973 if (addIeLen != 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301974 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975 addIeLen);
1976 }
1977#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1978 if (padLen != 0) {
1979 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1980 uint8_t *padVendorSpecific =
1981 pFrame + header_offset + nPayload + addIeLen;
1982 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1983 padVendorSpecific[0] = 221;
1984 padVendorSpecific[1] = padLen - 2;
1985 padVendorSpecific[2] = 0x00;
1986 padVendorSpecific[3] = 0xA0;
1987 padVendorSpecific[4] = 0xC6;
1988
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301989 pe_debug("Padding Vendor Specific Ie Len: %d", padLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990
1991 /* padding zero if more than 5 bytes are required */
1992 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301993 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
1995 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
1996 }
1997#endif
1998
Nishank Aggarwal550931a2017-03-22 19:33:11 +05301999 pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002000 SIR_MAC_TDLS_SETUP_CNF,
2001 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_CNF),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002002 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002003
Ganesh Kondabattiniac570072016-12-21 12:45:48 +05302004 pMac->lim.tdls_frm_session_id = psessionEntry->smeSessionId;
Krunal Sonic65fc492018-03-09 15:53:28 -08002005 lim_diag_mgmt_tx_event_report(pMac, (tpSirMacMgmtHdr) pFrame,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002006 psessionEntry, QDF_STATUS_SUCCESS,
2007 QDF_STATUS_SUCCESS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05302009 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
2010 (uint16_t) nBytes,
2011 TID_AC_VI,
2012 pFrame,
2013 smeSessionId, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302015 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05302016 pMac->lim.tdls_frm_session_id = NO_SESSION;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302017 pe_err("could not send TDLS Setup Confirm frame");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002018 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019
2020 }
2021
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002022 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002023}
2024
2025/* This Function is similar to populate_dot11f_ht_caps, except that the HT Capabilities
2026 * are considered from the AddStaReq rather from the cfg.dat as in populate_dot11f_ht_caps
2027 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002028static QDF_STATUS lim_tdls_populate_dot11f_ht_caps(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002029 tpPESession psessionEntry,
2030 tSirTdlsAddStaReq *
2031 pTdlsAddStaReq,
2032 tDot11fIEHTCaps *pDot11f)
2033{
2034 uint32_t nCfgValue;
2035 uint8_t nCfgValue8;
2036 tSirMacHTParametersInfo *pHTParametersInfo;
2037 union {
2038 uint16_t nCfgValue16;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302039 struct mlme_ht_capabilities_info htCapInfo;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040 tSirMacExtendedHTCapabilityInfo extHtCapInfo;
2041 } uHTCapabilityInfo;
2042
2043 tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
2044 tSirMacASCapabilityInfo *pASCapabilityInfo;
2045
2046 nCfgValue = pTdlsAddStaReq->htCap.capInfo;
2047
2048 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2049
2050 pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap;
2051 pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
2052 pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField;
2053 pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz;
2054 pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz;
2055 pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC;
2056 pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC;
2057 pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA;
2058 pDot11f->maximalAMSDUsize =
2059 uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
2060 pDot11f->dsssCckMode40MHz =
2061 uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
2062 pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp;
2063 pDot11f->stbcControlFrame =
2064 uHTCapabilityInfo.htCapInfo.stbcControlFrame;
2065 pDot11f->lsigTXOPProtection =
2066 uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;
2067
2068 /*
2069 * All sessionized entries will need the check below
2070 * Only in case of NO session
2071 */
2072 if (psessionEntry == NULL) {
2073 pDot11f->supportedChannelWidthSet =
2074 uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet;
2075 } else {
2076 pDot11f->supportedChannelWidthSet =
2077 psessionEntry->htSupportedChannelWidthSet;
2078 }
2079
2080 /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
2081 eHT_CHANNEL_WIDTH_20MHZ */
2082 if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
2083 pDot11f->shortGI40MHz = 0;
2084 }
2085
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302086 pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087 pDot11f->supportedChannelWidthSet,
2088 pDot11f->mimoPowerSave,
2089 pDot11f->greenField,
2090 pDot11f->shortGI20MHz,
2091 pDot11f->shortGI40MHz,
2092 pDot11f->dsssCckMode40MHz);
2093
2094 nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo;
2095
2096 nCfgValue8 = (uint8_t) nCfgValue;
2097 pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;
2098
2099 pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
2100 pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
2101 pDot11f->reserved1 = pHTParametersInfo->reserved;
2102
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302103 pe_debug("AMPDU Param: %x", nCfgValue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002104
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302105 qdf_mem_copy(pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 SIZE_OF_SUPPORTED_MCS_SET);
2107
2108 nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;
2109
2110 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2111
2112 pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
2113 pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
2114 pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
2115
2116 nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;
2117
2118 pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
2119 pDot11f->txBF = pTxBFCapabilityInfo->txBF;
2120 pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
2121 pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
2122 pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
2123 pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
2124 pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
2125 pDot11f->calibration = pTxBFCapabilityInfo->calibration;
2126 pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
2127 pDot11f->explicitUncompressedSteeringMatrix =
2128 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
2129 pDot11f->explicitBFCSIFeedback =
2130 pTxBFCapabilityInfo->explicitBFCSIFeedback;
2131 pDot11f->explicitUncompressedSteeringMatrixFeedback =
2132 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
2133 pDot11f->explicitCompressedSteeringMatrixFeedback =
2134 pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
2135 pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
2136 pDot11f->uncompressedSteeringMatrixBFAntennae =
2137 pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
2138 pDot11f->compressedSteeringMatrixBFAntennae =
2139 pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
2140
2141 nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo;
2142
2143 nCfgValue8 = (uint8_t) nCfgValue;
2144
2145 pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
2146 pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
2147 pDot11f->explicitCSIFeedbackTx =
2148 pASCapabilityInfo->explicitCSIFeedbackTx;
2149 pDot11f->antennaIndicesFeedbackTx =
2150 pASCapabilityInfo->antennaIndicesFeedbackTx;
2151 pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
2152 pDot11f->antennaIndicesFeedback =
2153 pASCapabilityInfo->antennaIndicesFeedback;
2154 pDot11f->rxAS = pASCapabilityInfo->rxAS;
2155 pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
2156
2157 pDot11f->present = pTdlsAddStaReq->htcap_present;
2158
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002159 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160
2161}
2162
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002163static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164lim_tdls_populate_dot11f_vht_caps(tpAniSirGlobal pMac,
2165 tSirTdlsAddStaReq *pTdlsAddStaReq,
2166 tDot11fIEVHTCaps *pDot11f)
2167{
2168 uint32_t nCfgValue = 0;
2169 union {
2170 uint32_t nCfgValue32;
2171 tSirMacVHTCapabilityInfo vhtCapInfo;
2172 } uVHTCapabilityInfo;
2173 union {
2174 uint16_t nCfgValue16;
2175 tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
2176 tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
2177 } uVHTSupDataRateInfo;
2178
2179 pDot11f->present = pTdlsAddStaReq->vhtcap_present;
2180
2181 nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
2182 uVHTCapabilityInfo.nCfgValue32 = nCfgValue;
2183
2184 pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
2185 pDot11f->supportedChannelWidthSet =
2186 uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
2187 pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
2188 pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
2189 pDot11f->shortGI160and80plus80MHz =
2190 uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
2191 pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
2192 pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
2193 pDot11f->suBeamFormerCap = 0;
2194 pDot11f->suBeamformeeCap = 0;
2195 pDot11f->csnofBeamformerAntSup =
2196 uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
2197 pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
2198 pDot11f->muBeamformerCap = 0;
2199 pDot11f->muBeamformeeCap = 0;
2200 pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
2201 pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
2202 pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
2203 pDot11f->vhtLinkAdaptCap =
2204 uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
2205 pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
2206 pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
2207 pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1;
2208
2209 pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;
2210
2211 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
2212 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2213 pDot11f->rxHighSupDataRate =
2214 uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;
2215
2216 pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;
2217
2218 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
2219 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2220 pDot11f->txSupDataRate =
2221 uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;
2222
2223 pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;
2224
2225 lim_log_vht_cap(pMac, pDot11f);
2226
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002227 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228
2229}
2230
2231/**
2232 * lim_tdls_populate_matching_rate_set() - populate matching rate set
2233 *
2234 * @mac_ctx - global MAC context
2235 * @stads - station hash entry
2236 * @supp_rate_set - pointer to supported rate set
2237 * @supp_rates_len - length of the supported rates
2238 * @supp_mcs_set - pointer to supported MSC set
2239 * @session_entry - pointer to PE session entry
2240 * @vht_caps - pointer to VHT capability
2241 *
2242 *
2243 * This function gets set of available rates from the config and compare them
2244 * against the set of received supported rates. After the comparison station
2245 * entry's rates is populated with 11A rates and 11B rates.
2246 *
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002247 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002249static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002250lim_tdls_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode stads,
2251 uint8_t *supp_rate_set,
2252 uint8_t supp_rates_len,
2253 uint8_t *supp_mcs_set,
2254 tpPESession session_entry,
2255 tDot11fIEVHTCaps *vht_caps)
2256{
2257 tSirMacRateSet temp_rate_set;
2258 uint32_t i, j, val, min, is_a_rate;
2259 tSirMacRateSet temp_rate_set2;
2260 uint32_t phymode;
2261 uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
2262 tpSirSupportedRates rates;
2263 uint8_t a_rateindex = 0;
2264 uint8_t b_rateindex = 0;
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002265 uint8_t nss;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07002266
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002267 is_a_rate = 0;
2268 temp_rate_set2.numRates = 0;
2269
2270 lim_get_phy_mode(mac_ctx, &phymode, NULL);
2271
2272 /* get own rate set */
2273 val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
2274 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_OPERATIONAL_RATE_SET,
2275 (uint8_t *) &temp_rate_set.rate,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002276 &val) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002277 /* Could not get rateset from CFG. Log error. */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302278 pe_err("could not retrieve rateset");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002279 val = 0;
2280 }
2281 temp_rate_set.numRates = val;
2282
2283 if (phymode == WNI_CFG_PHY_MODE_11G) {
2284 /* get own extended rate set */
2285 val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
2286 if (wlan_cfg_get_str(mac_ctx,
2287 WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
2288 (uint8_t *) &temp_rate_set2.rate,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002289 &val) != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002290 temp_rate_set2.numRates = val;
2291 }
2292
2293 if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302294 pe_err("more than 12 rates in CFG");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002295 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002296 }
2297
2298 /**
2299 * Handling of the rate set IEs is the following:
2300 * - keep only rates that we support and that the station supports
2301 * - sort and the rates into the pSta->rate array
2302 */
2303
2304 /* Copy all rates in temp_rate_set, there are 12 rates max */
2305 for (i = 0; i < temp_rate_set2.numRates; i++)
2306 temp_rate_set.rate[i + temp_rate_set.numRates] =
2307 temp_rate_set2.rate[i];
2308
2309 temp_rate_set.numRates += temp_rate_set2.numRates;
2310
2311 /**
2312 * Sort rates in temp_rate_set (they are likely to be already sorted)
2313 * put the result in temp_rate_set2
2314 */
2315 temp_rate_set2.numRates = 0;
2316
2317 for (i = 0; i < temp_rate_set.numRates; i++) {
2318 min = 0;
2319 val = 0xff;
2320
2321 for (j = 0; j < temp_rate_set.numRates; j++)
2322 if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
2323 val = temp_rate_set.rate[j] & 0x7f;
2324 min = j;
2325 }
2326
2327 temp_rate_set2.rate[temp_rate_set2.numRates++] =
2328 temp_rate_set.rate[min];
2329 temp_rate_set.rate[min] = 0xff;
2330 }
2331
2332 /**
2333 * Copy received rates in temp_rate_set, the parser has ensured
2334 * unicity of the rates so there cannot be more than 12 .
2335 */
2336 if (supp_rates_len > SIR_MAC_RATESET_EID_MAX) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302337 pe_warn("Supported rates length: %d more than the Max limit, reset to Max",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338 supp_rates_len);
2339 supp_rates_len = SIR_MAC_RATESET_EID_MAX;
2340 }
2341
2342 for (i = 0; i < supp_rates_len; i++)
2343 temp_rate_set.rate[i] = supp_rate_set[i];
2344
2345 temp_rate_set.numRates = supp_rates_len;
2346
2347 rates = &stads->supportedRates;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302348 qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002349
2350 for (i = 0; i < temp_rate_set2.numRates; i++) {
2351 for (j = 0; j < temp_rate_set.numRates; j++) {
2352 if ((temp_rate_set2.rate[i] & 0x7F) !=
2353 (temp_rate_set.rate[j] & 0x7F))
2354 continue;
2355
Sushant Kaushikb50010f2015-07-22 12:22:20 +05302356 if ((b_rateindex > SIR_NUM_11B_RATES) ||
2357 (a_rateindex > SIR_NUM_11A_RATES)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302358 pe_warn("Invalid number of rates (11b->%d, 11a->%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002359 b_rateindex, a_rateindex);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002360 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002361 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362 if (sirIsArate(temp_rate_set2.rate[i] & 0x7f)) {
2363 is_a_rate = 1;
2364 if (a_rateindex < SIR_NUM_11A_RATES)
2365 rates->llaRates[a_rateindex++] = temp_rate_set2.rate[i];
2366 } else {
2367 if (b_rateindex < SIR_NUM_11B_RATES)
2368 rates->llbRates[b_rateindex++] = temp_rate_set2.rate[i];
2369 }
2370 break;
2371 }
2372 }
2373
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002374 if (IS_5G_CH(session_entry->currentOperChannel))
2375 nss = mac_ctx->vdev_type_nss_5g.tdls;
2376 else
2377 nss = mac_ctx->vdev_type_nss_2g.tdls;
Archana Ramachandran5041b252016-04-25 14:29:25 -07002378
2379 nss = QDF_MIN(nss, mac_ctx->user_configured_nss);
2380
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 /* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */
2382#ifdef FEATURE_WLAN_TDLS
2383 if (stads->mlmStaContext.htCapability)
2384#else
2385 if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
2386 (stads->mlmStaContext.htCapability))
2387#endif
2388 {
2389 val = SIZE_OF_SUPPORTED_MCS_SET;
2390 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002391 mcsSet, &val) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 /* Could not get rateset from CFG. Log error. */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302393 pe_err("could not retrieve supportedMCSSet");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002394 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002395 }
2396
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002397 if (NSS_1x1_MODE == nss)
2398 mcsSet[1] = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002399 for (i = 0; i < val; i++)
2400 stads->supportedRates.supportedMCSSet[i] =
2401 mcsSet[i] & supp_mcs_set[i];
2402
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302403 pe_debug("MCS Rate Set Bitmap from CFG and DPH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302405 pe_debug("%x %x", mcsSet[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002406 stads->supportedRates.supportedMCSSet[i]);
2407 }
2408 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409 lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps,
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002410 session_entry, nss);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411 /**
2412 * Set the erpEnabled bit if the phy is in G mode and at least
2413 * one A rate is supported
2414 */
2415 if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate)
2416 stads->erpEnabled = eHAL_SET;
2417
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002418 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002419}
2420
2421/*
2422 * update HASH node entry info
2423 */
2424static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
2425 tDphHashNode *pStaDs,
2426 tSirTdlsAddStaReq *pTdlsAddStaReq,
2427 tpPESession psessionEntry)
2428{
2429 tDot11fIEHTCaps htCap = {0,};
2430 tDot11fIEHTCaps *htCaps;
2431 tDot11fIEVHTCaps *pVhtCaps = NULL;
2432 tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002433 tDot11fIEVHTCaps vhtCap;
2434 uint8_t cbMode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435
2436 if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
2437 populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
2438 } else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) {
2439 lim_tdls_populate_dot11f_ht_caps(pMac, NULL, pTdlsAddStaReq, &htCap);
2440 }
2441 htCaps = &htCap;
2442 if (htCaps->present) {
2443 pStaDs->mlmStaContext.htCapability = 1;
2444 pStaDs->htGreenfield = htCaps->greenField;
Naveen Rawat3e8322c2015-11-03 11:05:57 -08002445 /*
2446 * pStaDs->htSupportedChannelWidthSet should have the base
2447 * channel capability. The htSupportedChannelWidthSet of the
2448 * TDLS link on base channel should be less than or equal to
2449 * channel width of STA-AP link. So take this setting from the
2450 * psessionEntry.
2451 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302452 pe_debug("supportedChannelWidthSet: 0x%x htSupportedChannelWidthSet: 0x%x",
Selvaraj, Sridharba497d12016-06-24 11:17:08 +05302453 htCaps->supportedChannelWidthSet,
2454 psessionEntry->htSupportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002455 pStaDs->htSupportedChannelWidthSet =
Selvaraj, Sridharba497d12016-06-24 11:17:08 +05302456 (htCaps->supportedChannelWidthSet <
2457 psessionEntry->htSupportedChannelWidthSet) ?
2458 htCaps->supportedChannelWidthSet :
2459 psessionEntry->htSupportedChannelWidthSet;
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302460 pe_debug("pStaDs->htSupportedChannelWidthSet: 0x%x",
Selvaraj, Sridharba497d12016-06-24 11:17:08 +05302461 pStaDs->htSupportedChannelWidthSet);
2462
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002463 pStaDs->htMIMOPSState = htCaps->mimoPowerSave;
2464 pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
2465 pStaDs->htAMpduDensity = htCaps->mpduDensity;
2466 pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz;
2467 pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
2468 pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
2469 pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
2470 lim_fill_rx_highest_supported_rate(pMac,
2471 &pStaDs->supportedRates.
2472 rxHighestDataRate,
2473 htCaps->supportedMCSSet);
2474 pStaDs->baPolicyFlag = 0xFF;
2475 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N;
2476 pStaDs->ht_caps = pTdlsAddStaReq->htCap.capInfo;
2477 } else {
2478 pStaDs->mlmStaContext.htCapability = 0;
2479 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG;
2480 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002481 lim_tdls_populate_dot11f_vht_caps(pMac, pTdlsAddStaReq, &vhtCap);
2482 pVhtCaps = &vhtCap;
2483 if (pVhtCaps->present) {
2484 pStaDs->mlmStaContext.vhtCapability = 1;
2485
Kabilan Kannan7ae4d602016-06-13 18:35:54 -07002486 /*
2487 * 11.21.1 General: The channel width of the TDLS direct
2488 * link on the base channel shall not exceed the channel
2489 * width of the BSS to which the TDLS peer STAs are
2490 * associated.
2491 */
Kabilan Kannanb76eff22016-07-21 06:16:04 -07002492 if (psessionEntry->ch_width)
2493 pStaDs->vhtSupportedChannelWidthSet =
2494 psessionEntry->ch_width - 1;
2495 else
2496 pStaDs->vhtSupportedChannelWidthSet =
2497 psessionEntry->ch_width;
2498
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302499 pe_debug("vhtSupportedChannelWidthSet: %hu htSupportedChannelWidthSet: %hu",
Kabilan Kannanb76eff22016-07-21 06:16:04 -07002500 pStaDs->vhtSupportedChannelWidthSet,
Kabilan Kannan7ae4d602016-06-13 18:35:54 -07002501 pStaDs->htSupportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002502
2503 pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
2504 pStaDs->vhtBeamFormerCapable = 0;
2505 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
2506 pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&pTdlsAddStaReq->vhtCap);
2507 pVhtCaps_txbf->suBeamformeeCap = 0;
2508 pVhtCaps_txbf->suBeamFormerCap = 0;
2509 pVhtCaps_txbf->muBeamformerCap = 0;
2510 pVhtCaps_txbf->muBeamformeeCap = 0;
2511 pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo;
2512 } else {
2513 pStaDs->mlmStaContext.vhtCapability = 0;
2514 pStaDs->vhtSupportedChannelWidthSet =
2515 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
2516 }
Abhishek Singhe586ade2017-02-17 16:35:42 +05302517
2518 /*
2519 * Calculate the Secondary Coannel Offset if our
2520 * own channel bonding state is enabled
2521 */
2522 if (psessionEntry->htSupportedChannelWidthSet) {
2523 cbMode = lim_select_cb_mode(pStaDs, psessionEntry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524 psessionEntry->currentOperChannel,
2525 pStaDs->vhtSupportedChannelWidthSet);
2526
Abhishek Singhe586ade2017-02-17 16:35:42 +05302527 if (pStaDs->mlmStaContext.vhtCapability)
2528 pStaDs->htSecondaryChannelOffset =
2529 lim_get_htcb_state(cbMode);
2530 else
2531 pStaDs->htSecondaryChannelOffset = cbMode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002533 /* Lets enable QOS parameter */
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +05302534 pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
2535 || pTdlsAddStaReq->htcap_present;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002536 pStaDs->wmeEnabled = 1;
2537 pStaDs->lleEnabled = 0;
2538 /* TDLS Dummy AddSTA does not have qosInfo , is it OK ??
2539 */
2540 pStaDs->qos.capability.qosInfo =
2541 (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);
2542
2543 /* populate matching rate set */
2544
2545 /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
2546 */
2547 lim_tdls_populate_matching_rate_set(pMac, pStaDs,
2548 pTdlsAddStaReq->supported_rates,
2549 pTdlsAddStaReq->supported_rates_length,
2550 (uint8_t *) pTdlsAddStaReq->htCap.
2551 suppMcsSet, psessionEntry, pVhtCaps);
2552
2553 /* TDLS Dummy AddSTA does not have right capability , is it OK ??
2554 */
2555 pStaDs->mlmStaContext.capabilityInfo =
2556 (*(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);
2557
2558 return;
2559}
2560
2561/*
2562 * Add STA for TDLS setup procedure
2563 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002564static QDF_STATUS lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565 tSirTdlsAddStaReq *pAddStaReq,
2566 tpPESession psessionEntry)
2567{
2568 tpDphHashNode pStaDs = NULL;
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002569 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570 uint16_t aid = 0;
2571
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002572 pStaDs = dph_lookup_hash_entry(pMac, pAddStaReq->peermac.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002573 &psessionEntry->dph.dphHashTable);
Abhishek Singh3ed00d12018-03-07 11:16:57 +05302574
2575 if (pStaDs && pAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
2576 pe_err("TDLS entry for peer: "MAC_ADDRESS_STR " already exist, cannot add new entry",
2577 MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002578 return QDF_STATUS_E_FAILURE;
Abhishek Singh3ed00d12018-03-07 11:16:57 +05302579 }
2580
2581 if (pStaDs && pStaDs->staType != STA_ENTRY_TDLS_PEER) {
2582 pe_err("Non TDLS entry for peer: "MAC_ADDRESS_STR " already exist",
2583 MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002584 return QDF_STATUS_E_FAILURE;
Abhishek Singh3ed00d12018-03-07 11:16:57 +05302585 }
2586
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587 if (NULL == pStaDs) {
2588 aid = lim_assign_peer_idx(pMac, psessionEntry);
2589
2590 if (!aid) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302591 pe_err("No more free AID for peer: "MAC_ADDRESS_STR,
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002592 MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002593 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002594 }
2595
2596 /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
2597 SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
2598
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302599 pe_debug("Aid: %d, for peer: " MAC_ADDRESS_STR,
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002600 aid, MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002601 pStaDs =
2602 dph_get_hash_entry(pMac, aid,
2603 &psessionEntry->dph.dphHashTable);
2604
2605 if (pStaDs) {
2606 (void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
2607 psessionEntry);
2608 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, aid,
2609 psessionEntry);
2610 }
2611
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002612 pStaDs = dph_add_hash_entry(pMac, pAddStaReq->peermac.bytes,
2613 aid, &psessionEntry->dph.dphHashTable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614
2615 if (NULL == pStaDs) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302616 pe_err("add hash entry failed");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302617 QDF_ASSERT(0);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002618 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002619 }
2620 }
2621
2622 lim_tdls_update_hash_node_info(pMac, pStaDs, pAddStaReq, psessionEntry);
2623
2624 pStaDs->staType = STA_ENTRY_TDLS_PEER;
2625
2626 status =
2627 lim_add_sta(pMac, pStaDs,
2628 (pAddStaReq->tdlsAddOper ==
2629 TDLS_OPER_UPDATE) ? true : false, psessionEntry);
2630
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002631 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632 /* should not fail */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302633 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002634 }
2635 return status;
2636}
2637
2638/*
2639 * Del STA, after Link is teardown or discovery response sent on direct link
2640 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002641static QDF_STATUS lim_tdls_del_sta(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302642 struct qdf_mac_addr peerMac,
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05302643 tpPESession psessionEntry,
2644 bool resp_reqd)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645{
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002646 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002647 uint16_t peerIdx = 0;
Kabilan Kannan1622a472017-11-22 11:34:12 -08002648 tpDphHashNode pStaDs;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002649
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002650 pStaDs = dph_lookup_hash_entry(pMac, peerMac.bytes, &peerIdx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002651 &psessionEntry->dph.dphHashTable);
2652
2653 if (pStaDs) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302654 pe_debug("DEL STA peer MAC: "MAC_ADDRESS_STR,
Kabilan Kannan1622a472017-11-22 11:34:12 -08002655 MAC_ADDR_ARRAY(pStaDs->staAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302657 pe_debug("STA type: %x, sta idx: %x resp_reqd: %d",
Kabilan Kannan1622a472017-11-22 11:34:12 -08002658 pStaDs->staType,
2659 pStaDs->staIndex,
2660 resp_reqd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002661
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05302662 status = lim_del_sta(pMac, pStaDs, resp_reqd, psessionEntry);
Kabilan Kannan1622a472017-11-22 11:34:12 -08002663 } else {
2664 pe_debug("DEL STA peer MAC: "MAC_ADDRESS_STR" not found",
2665 MAC_ADDR_ARRAY(peerMac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666 }
2667
Kabilan Kannan1622a472017-11-22 11:34:12 -08002668 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669}
2670
2671/*
2672 * Once Link is setup with PEER, send Add STA ind to SME
2673 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302674static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002675 uint8_t sessionId,
2676 tSirMacAddr peerMac,
2677 uint8_t updateSta,
2678 tDphHashNode *pStaDs, uint8_t status)
2679{
Rajeev Kumar416b73f2017-01-21 16:45:21 -08002680 struct scheduler_msg mmhMsg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002681 tSirTdlsAddStaRsp *addStaRsp = NULL;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07002682
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002683 mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP;
2684
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302685 addStaRsp = qdf_mem_malloc(sizeof(tSirTdlsAddStaRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686 if (NULL == addStaRsp) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302687 pe_err("Failed to allocate memory");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302688 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002689 }
2690
2691 addStaRsp->sessionId = sessionId;
2692 addStaRsp->statusCode = status;
2693 if (pStaDs) {
2694 addStaRsp->staId = pStaDs->staIndex;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 }
2696 if (peerMac) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302697 qdf_mem_copy(addStaRsp->peermac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302698 (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002699 }
2700 if (updateSta)
2701 addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
2702 else
2703 addStaRsp->tdlsAddOper = TDLS_OPER_ADD;
2704
2705 addStaRsp->length = sizeof(tSirTdlsAddStaRsp);
2706 addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP;
Frank Liud4b2fa02017-03-29 11:46:48 +08002707 addStaRsp->psoc = pMac->psoc;
2708 mmhMsg.bodyptr = addStaRsp;
2709 mmhMsg.callback = tgt_tdls_add_peer_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002710
Frank Liud4b2fa02017-03-29 11:46:48 +08002711 return scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &mmhMsg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712}
2713
2714/*
2715 * STA RSP received from HAL
2716 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302717QDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002718 tpPESession psessionEntry)
2719{
2720 tAddStaParams *pAddStaParams = (tAddStaParams *) msg;
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002721 uint8_t status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002722 tDphHashNode *pStaDs = NULL;
2723 uint16_t aid = 0;
2724
2725 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302726 pe_debug("staIdx: %d, staMac: "MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002727 pAddStaParams->staIdx,
2728 MAC_ADDR_ARRAY(pAddStaParams->staMac));
2729
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302730 if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302731 QDF_ASSERT(0);
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302732 pe_err("Add sta failed ");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002733 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002734 goto add_sta_error;
2735 }
2736
2737 pStaDs = dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &aid,
2738 &psessionEntry->dph.dphHashTable);
2739 if (NULL == pStaDs) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302740 pe_err("pStaDs is NULL ");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002741 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002742 goto add_sta_error;
2743 }
2744
2745 pStaDs->bssId = pAddStaParams->bssIdx;
2746 pStaDs->staIndex = pAddStaParams->staIdx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
2748 pStaDs->valid = 1;
2749add_sta_error:
2750 status = lim_send_sme_tdls_add_sta_rsp(pMac, psessionEntry->smeSessionId,
2751 pAddStaParams->staMac,
2752 pAddStaParams->updateSta, pStaDs,
2753 status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302754 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002755 return status;
2756}
2757
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002758/**
2759 * lim_send_tdls_comp_mgmt_rsp() - Send Response to upper layers
2760 * @mac_ctx: Pointer to Global MAC structure
2761 * @msg_type: Indicates message type
2762 * @result_code: Indicates the result of previously issued
2763 * eWNI_SME_msg_type_REQ message
2764 *
2765 * This function is called by lim_process_sme_req_messages() to send
2766 * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
2767 * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
2768 * Software.
2769 *
2770 * Return: None
2771 */
2772
2773static void
2774lim_send_tdls_comp_mgmt_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
2775 tSirResultCodes result_code, uint8_t sme_session_id,
2776 uint16_t sme_transaction_id)
2777{
Kabilan Kannan1c1c4022017-04-06 22:49:26 -07002778 struct scheduler_msg msg = {0};
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002779 tSirSmeRsp *sme_rsp;
2780
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07002781 pe_debug("Sending message %s with reasonCode %s",
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002782 lim_msg_str(msg_type), lim_result_code_str(result_code));
2783
2784 sme_rsp = qdf_mem_malloc(sizeof(tSirSmeRsp));
2785 if (NULL == sme_rsp) {
2786 /* Buffer not available. Log error */
2787 QDF_TRACE(QDF_MODULE_ID_PE, LOGP,
2788 FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
2789 return;
2790 }
2791
2792 sme_rsp->messageType = msg_type;
2793 sme_rsp->length = sizeof(tSirSmeRsp);
2794 sme_rsp->statusCode = result_code;
2795
2796 sme_rsp->sessionId = sme_session_id;
2797 sme_rsp->transactionId = sme_transaction_id;
2798
2799 msg.type = msg_type;
2800 sme_rsp->psoc = mac_ctx->psoc;
2801 msg.bodyptr = sme_rsp;
2802 msg.callback = tgt_tdls_send_mgmt_rsp;
2803 scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg);
2804
2805}
Kabilan Kannan1c1c4022017-04-06 22:49:26 -07002806
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807/**
2808 * lim_process_sme_tdls_mgmt_send_req() - send out tdls management frames
2809 *
2810 * @mac_ctx - global mac context
2811 * @msg - message buffer received from SME.
2812 *
2813 * Process Send Mgmt Request from SME and transmit to AP.
2814 *
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002815 * Return: QDF_STATUS_SUCCESS on success, error code otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002816 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002817QDF_STATUS lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002818 uint32_t *msg)
2819{
2820 /* get all discovery request parameters */
2821 tSirTdlsSendMgmtReq *send_req = (tSirTdlsSendMgmtReq *) msg;
2822 tpPESession session_entry;
2823 uint8_t session_id;
2824 tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS;
2825
Jeff Johnson47d75242018-05-12 15:58:53 -07002826 pe_debug("Send Mgmt Received");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002827 session_entry = pe_find_session_by_bssid(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002828 send_req->bssid.bytes, &session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002829 if (NULL == session_entry) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302830 pe_err("PE Session does not exist for given sme session_id %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002831 send_req->sessionId);
2832 goto lim_tdls_send_mgmt_error;
2833 }
2834
2835 /* check if we are in proper state to work as TDLS client */
2836 if (!LIM_IS_STA_ROLE(session_entry)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302837 pe_err("send mgmt received in wrong system Role: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002838 GET_LIM_SYSTEM_ROLE(session_entry));
2839 goto lim_tdls_send_mgmt_error;
2840 }
2841
Nitesh Shah622d3122017-06-05 17:04:06 +05302842 if (lim_is_roam_synch_in_progress(session_entry)) {
2843 pe_err("roaming in progress, reject mgmt! for session %d",
2844 send_req->sessionId);
2845 result_code = eSIR_SME_REFUSED;
2846 goto lim_tdls_send_mgmt_error;
2847 }
2848
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002849 /*
2850 * if we are still good, go ahead and check if we are in proper state to
2851 * do TDLS discovery req/rsp/....frames.
2852 */
2853 if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
2854 (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302855 pe_err("send mgmt received in invalid LIMsme state: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002856 session_entry->limSmeState);
2857 goto lim_tdls_send_mgmt_error;
2858 }
2859
Abhishek Singh437606a2016-04-27 13:51:49 +05302860 cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
2861 SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION,
2862 send_req->reqType, send_req->peer_mac.bytes);
2863
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002864 switch (send_req->reqType) {
2865 case SIR_MAC_TDLS_DIS_REQ:
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302866 pe_debug("Transmit Discovery Request Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002867 /* format TDLS discovery request frame and transmit it */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002868 lim_send_tdls_dis_req_frame(mac_ctx, send_req->peer_mac,
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05302869 send_req->dialog, session_entry,
2870 send_req->ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002871 result_code = eSIR_SME_SUCCESS;
2872 break;
2873 case SIR_MAC_TDLS_DIS_RSP:
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302874 pe_debug("Transmit Discovery Response Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002875 /* Send a response mgmt action frame */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002876 lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002877 send_req->dialog, session_entry, &send_req->addIe[0],
2878 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2879 result_code = eSIR_SME_SUCCESS;
2880 break;
2881 case SIR_MAC_TDLS_SETUP_REQ:
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302882 pe_debug("Transmit Setup Request Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883 lim_send_tdls_link_setup_req_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002884 send_req->peer_mac, send_req->dialog, session_entry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002885 &send_req->addIe[0],
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05302886 (send_req->length - sizeof(tSirTdlsSendMgmtReq)),
2887 send_req->ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002888 result_code = eSIR_SME_SUCCESS;
2889 break;
2890 case SIR_MAC_TDLS_SETUP_RSP:
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302891 pe_debug("Transmit Setup Response Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002892 lim_send_tdls_setup_rsp_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002893 send_req->peer_mac, send_req->dialog, session_entry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002894 send_req->statusCode, &send_req->addIe[0],
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05302895 (send_req->length - sizeof(tSirTdlsSendMgmtReq)),
2896 send_req->ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002897 result_code = eSIR_SME_SUCCESS;
2898 break;
2899 case SIR_MAC_TDLS_SETUP_CNF:
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302900 pe_debug("Transmit Setup Confirm Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901 lim_send_tdls_link_setup_cnf_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002902 send_req->peer_mac, send_req->dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002903 send_req->peerCapability, session_entry,
2904 &send_req->addIe[0],
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05302905 (send_req->length - sizeof(tSirTdlsSendMgmtReq)),
2906 send_req->ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 result_code = eSIR_SME_SUCCESS;
2908 break;
2909 case SIR_MAC_TDLS_TEARDOWN:
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302910 pe_debug("Transmit Teardown Frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911 lim_send_tdls_teardown_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002912 send_req->peer_mac, send_req->statusCode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002913 send_req->responder, session_entry,
2914 &send_req->addIe[0],
Ganesh Kondabattinidd726522017-05-10 18:09:37 +05302915 (send_req->length - sizeof(tSirTdlsSendMgmtReq)),
2916 send_req->ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002917 result_code = eSIR_SME_SUCCESS;
2918 break;
2919 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
2920 break;
2921 case SIR_MAC_TDLS_CH_SWITCH_REQ:
2922 break;
2923 case SIR_MAC_TDLS_CH_SWITCH_RSP:
2924 break;
2925 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
2926 break;
2927 default:
2928 break;
2929 }
2930
2931lim_tdls_send_mgmt_error:
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002932 lim_send_tdls_comp_mgmt_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP,
2933 result_code, send_req->sessionId,
2934 send_req->transactionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002935
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002936 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937}
2938
2939/*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940 * Once link is teardown, send Del Peer Ind to SME
2941 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302942static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002943 uint8_t sessionId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302944 struct qdf_mac_addr peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002945 tDphHashNode *pStaDs, uint8_t status)
2946{
Rajeev Kumar416b73f2017-01-21 16:45:21 -08002947 struct scheduler_msg mmhMsg = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002948 tSirTdlsDelStaRsp *pDelSta = NULL;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07002949
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002950 mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP;
2951
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302952 pDelSta = qdf_mem_malloc(sizeof(tSirTdlsDelStaRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002953 if (NULL == pDelSta) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302954 pe_err("Failed to allocate memory");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302955 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002956 }
2957
2958 pDelSta->sessionId = sessionId;
2959 pDelSta->statusCode = status;
2960 if (pStaDs) {
2961 pDelSta->staId = pStaDs->staIndex;
2962 } else
2963 pDelSta->staId = STA_INVALID_IDX;
2964
Anurag Chouhanc5548422016-02-24 18:33:27 +05302965 qdf_copy_macaddr(&pDelSta->peermac, &peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002966
2967 pDelSta->length = sizeof(tSirTdlsDelStaRsp);
2968 pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP;
Frank Liud4b2fa02017-03-29 11:46:48 +08002969 pDelSta->psoc = pMac->psoc;
2970 mmhMsg.bodyptr = pDelSta;
2971 mmhMsg.callback = tgt_tdls_del_peer_rsp;
2972 return scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &mmhMsg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002973}
2974
2975/*
2976 * Process Send Mgmt Request from SME and transmit to AP.
2977 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07002978QDF_STATUS lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002979 uint32_t *pMsgBuf)
2980{
2981 /* get all discovery request parameters */
2982 tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq *) pMsgBuf;
2983 tpPESession psessionEntry;
2984 uint8_t sessionId;
2985
Jeff Johnson47d75242018-05-12 15:58:53 -07002986 pe_debug("TDLS Add STA Request Received");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002987 psessionEntry =
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002988 pe_find_session_by_bssid(pMac, pAddStaReq->bssid.bytes,
2989 &sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002990 if (psessionEntry == NULL) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302991 pe_err("PE Session does not exist for given sme sessionId: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002992 pAddStaReq->sessionId);
2993 goto lim_tdls_add_sta_error;
2994 }
2995
2996 /* check if we are in proper state to work as TDLS client */
2997 if (!LIM_IS_STA_ROLE(psessionEntry)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05302998 pe_err("send mgmt received in wrong system Role: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002999 GET_LIM_SYSTEM_ROLE(psessionEntry));
3000 goto lim_tdls_add_sta_error;
3001 }
3002
Nitesh Shah622d3122017-06-05 17:04:06 +05303003 if (lim_is_roam_synch_in_progress(psessionEntry)) {
3004 pe_err("roaming in progress, reject add sta! for session %d",
3005 pAddStaReq->sessionId);
3006 goto lim_tdls_add_sta_error;
3007 }
3008
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003009 /*
3010 * if we are still good, go ahead and check if we are in proper state to
3011 * do TDLS discovery req/rsp/....frames.
3012 */
3013 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3014 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303015 pe_err("send mgmt received in invalid LIMsme state: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003016 psessionEntry->limSmeState);
3017 goto lim_tdls_add_sta_error;
3018 }
3019
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003020
3021 /* To start with, send add STA request to HAL */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003022 if (QDF_STATUS_E_FAILURE == lim_tdls_setup_add_sta(pMac, pAddStaReq, psessionEntry)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303023 pe_err("Add TDLS Station request failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003024 goto lim_tdls_add_sta_error;
3025 }
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003026 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003027lim_tdls_add_sta_error:
3028 lim_send_sme_tdls_add_sta_rsp(pMac,
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08003029 pAddStaReq->sessionId,
3030 pAddStaReq->peermac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003031 (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE),
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003032 NULL, QDF_STATUS_E_FAILURE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003033
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003034 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003035}
3036
3037/*
3038 * Process Del Sta Request from SME .
3039 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003040QDF_STATUS lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003041 uint32_t *pMsgBuf)
3042{
3043 /* get all discovery request parameters */
3044 tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
3045 tpPESession psessionEntry;
3046 uint8_t sessionId;
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003047 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003048
Jeff Johnson47d75242018-05-12 15:58:53 -07003049 pe_debug("TDLS Delete STA Request Received");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003050 psessionEntry =
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003051 pe_find_session_by_bssid(pMac, pDelStaReq->bssid.bytes,
3052 &sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003053 if (psessionEntry == NULL) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303054 pe_err("PE Session does not exist for given sme sessionId: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003055 pDelStaReq->sessionId);
3056 lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003057 pDelStaReq->peermac, NULL,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003058 QDF_STATUS_E_FAILURE);
3059 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003060 }
3061
3062 /* check if we are in proper state to work as TDLS client */
3063 if (!LIM_IS_STA_ROLE(psessionEntry)) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303064 pe_err("Del sta received in wrong system Role %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065 GET_LIM_SYSTEM_ROLE(psessionEntry));
3066 goto lim_tdls_del_sta_error;
3067 }
3068
Nitesh Shah622d3122017-06-05 17:04:06 +05303069 if (lim_is_roam_synch_in_progress(psessionEntry)) {
3070 pe_err("roaming in progress, reject del sta! for session %d",
3071 pDelStaReq->sessionId);
3072 lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
3073 pDelStaReq->peermac, NULL,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003074 QDF_STATUS_E_FAILURE);
3075 return QDF_STATUS_E_FAILURE;
Nitesh Shah622d3122017-06-05 17:04:06 +05303076 }
3077
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003078 /*
3079 * if we are still good, go ahead and check if we are in proper state to
3080 * do TDLS discovery req/rsp/....frames.
3081 */
3082 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3083 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3084
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303085 pe_err("Del Sta received in invalid LIMsme state: (%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003086 psessionEntry->limSmeState);
3087 goto lim_tdls_del_sta_error;
3088 }
3089
Kabilan Kannan1622a472017-11-22 11:34:12 -08003090 status = lim_tdls_del_sta(pMac, pDelStaReq->peermac,
3091 psessionEntry, true);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003092 if (status == QDF_STATUS_SUCCESS)
Kabilan Kannan1622a472017-11-22 11:34:12 -08003093 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003094
3095lim_tdls_del_sta_error:
3096 lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003097 pDelStaReq->peermac, NULL, QDF_STATUS_E_FAILURE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003098
Kabilan Kannan1622a472017-11-22 11:34:12 -08003099 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003100}
3101
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102/**
Jeff Johnson47d75242018-05-12 15:58:53 -07003103 * lim_check_aid_and_delete_peer() - Function to check aid and delete peer
Nitesh Shah99dd9552017-03-20 19:27:47 +05303104 * @p_mac: pointer to mac context
3105 * @session_entry: pointer to PE session
3106 *
3107 * This function verifies aid and delete's peer with that aid from hash table
3108 *
3109 * Return: None
3110 */
3111static void lim_check_aid_and_delete_peer(tpAniSirGlobal p_mac,
3112 tpPESession session_entry)
3113{
3114 tpDphHashNode stads = NULL;
3115 int i, aid;
3116 size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap);
3117 struct qdf_mac_addr mac_addr;
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003118 QDF_STATUS status;
Nitesh Shah99dd9552017-03-20 19:27:47 +05303119
3120 /*
3121 * Check all the set bit in peerAIDBitmap and delete the peer
3122 * (with that aid) entry from the hash table and add the aid
3123 * in free pool
3124 */
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303125 pe_debug("Delete all the TDLS peer connected");
Nitesh Shah99dd9552017-03-20 19:27:47 +05303126 for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) {
3127 for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) {
3128 if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid))
3129 continue;
3130 stads = dph_get_hash_entry(p_mac,
3131 (aid + i * (sizeof(uint32_t) << 3)),
3132 &session_entry->dph.dphHashTable);
3133
3134 if (NULL == stads)
3135 goto skip;
3136
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07003137 pe_debug("Deleting "MAC_ADDRESS_STR,
Nitesh Shah99dd9552017-03-20 19:27:47 +05303138 MAC_ADDR_ARRAY(stads->staAddr));
3139
Nitesh Shah622d3122017-06-05 17:04:06 +05303140 if (!lim_is_roam_synch_in_progress(session_entry)) {
3141 lim_send_deauth_mgmt_frame(p_mac,
3142 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
3143 stads->staAddr, session_entry, false);
Nitesh Shah99dd9552017-03-20 19:27:47 +05303144
Nitesh Shah622d3122017-06-05 17:04:06 +05303145 /* Delete TDLS peer */
3146 qdf_mem_copy(mac_addr.bytes, stads->staAddr,
3147 QDF_MAC_ADDR_SIZE);
Nitesh Shah99dd9552017-03-20 19:27:47 +05303148
Kabilan Kannan1622a472017-11-22 11:34:12 -08003149 status = lim_tdls_del_sta(p_mac, mac_addr,
3150 session_entry, false);
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003151 if (status != QDF_STATUS_SUCCESS)
Kabilan Kannan1622a472017-11-22 11:34:12 -08003152 pe_debug("peer "MAC_ADDRESS_STR" not found",
3153 MAC_ADDR_ARRAY(stads->staAddr));
Nitesh Shah622d3122017-06-05 17:04:06 +05303154 }
Nitesh Shah99dd9552017-03-20 19:27:47 +05303155
3156 dph_delete_hash_entry(p_mac,
3157 stads->staAddr, stads->assocId,
3158 &session_entry->dph.dphHashTable);
3159skip:
3160 lim_release_peer_idx(p_mac,
3161 (aid + i * (sizeof(uint32_t) << 3)),
3162 session_entry);
3163 CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
3164 }
3165 }
3166}
3167
Kabilan Kannane8602fd2017-05-15 20:25:38 -07003168/**
3169 * lim_delete_tdls_peers() - delete tdls peers
3170 *
3171 * @mac_ctx - global MAC context
3172 * @session_entry - PE session entry
3173 *
3174 * Delete all the TDLS peer connected before leaving the BSS
3175 *
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003176 * Return: QDF_STATUS_SUCCESS on success, error code otherwise
Kabilan Kannane8602fd2017-05-15 20:25:38 -07003177 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003178QDF_STATUS lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
Kabilan Kannane8602fd2017-05-15 20:25:38 -07003179 tpPESession session_entry)
3180{
3181 pe_debug("Enter");
3182
3183 if (NULL == session_entry) {
3184 pe_err("NULL session_entry");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003185 return QDF_STATUS_E_FAILURE;
Kabilan Kannane8602fd2017-05-15 20:25:38 -07003186 }
3187
3188 lim_check_aid_and_delete_peer(mac_ctx, session_entry);
3189
3190 if (lim_is_roam_synch_in_progress(session_entry))
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003191 return QDF_STATUS_SUCCESS;
Kabilan Kannane8602fd2017-05-15 20:25:38 -07003192
3193 tgt_tdls_peers_deleted_notification(mac_ctx->psoc,
3194 session_entry->smeSessionId);
3195
3196 pe_debug("Exit");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003197 return QDF_STATUS_SUCCESS;
Kabilan Kannane8602fd2017-05-15 20:25:38 -07003198}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003199
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303200/**
Nitesh Shah99dd9552017-03-20 19:27:47 +05303201 * lim_process_sme_del_all_tdls_peers(): process delete tdls peers
3202 * @p_mac: pointer to mac context
3203 * @msg_buf: message buffer
3204 *
3205 * This function processes request to delete tdls peers
3206 *
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003207 * Return: Success: QDF_STATUS_SUCCESS Failure: Error value
Nitesh Shah99dd9552017-03-20 19:27:47 +05303208 */
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003209QDF_STATUS lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac,
Nitesh Shah99dd9552017-03-20 19:27:47 +05303210 uint32_t *msg_buf)
3211{
3212 struct sir_del_all_tdls_peers *msg;
3213 tpPESession session_entry;
3214 uint8_t session_id;
3215
3216 msg = (struct sir_del_all_tdls_peers *)msg_buf;
3217 if (msg == NULL) {
Srinivas Girigowda39ac6d72017-03-26 22:07:29 -07003218 pe_err("NULL msg");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003219 return QDF_STATUS_E_FAILURE;
Nitesh Shah99dd9552017-03-20 19:27:47 +05303220 }
3221
3222 session_entry = pe_find_session_by_bssid(p_mac,
3223 msg->bssid.bytes, &session_id);
3224 if (NULL == session_entry) {
Srinivas Girigowda39ac6d72017-03-26 22:07:29 -07003225 pe_err("NULL psessionEntry");
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003226 return QDF_STATUS_E_FAILURE;
Nitesh Shah99dd9552017-03-20 19:27:47 +05303227 }
3228
3229 lim_check_aid_and_delete_peer(p_mac, session_entry);
3230
Kabilan Kannanb6153b12017-07-13 17:54:02 -07003231 tgt_tdls_peers_deleted_notification(p_mac->psoc,
3232 session_entry->smeSessionId);
3233
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003234 return QDF_STATUS_SUCCESS;
Nitesh Shah99dd9552017-03-20 19:27:47 +05303235}
3236
3237/**
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303238 * lim_process_tdls_del_sta_rsp() - Handle WDA_DELETE_STA_RSP for TDLS
3239 * @mac_ctx: Global MAC context
3240 * @lim_msg: LIM message
3241 * @pe_session: PE session
3242 *
3243 * Return: None
3244 */
3245void lim_process_tdls_del_sta_rsp(tpAniSirGlobal mac_ctx,
3246 struct scheduler_msg *lim_msg,
3247 tpPESession session_entry)
3248{
3249 tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
3250 tpDphHashNode sta_ds;
3251 uint16_t peer_idx = 0;
3252 struct qdf_mac_addr peer_mac;
3253
3254 if (!del_sta_params) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303255 pe_err("del_sta_params is NULL");
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303256 return;
3257 }
3258
3259 sta_ds = dph_lookup_hash_entry(mac_ctx, del_sta_params->staMac,
3260 &peer_idx, &session_entry->dph.dphHashTable);
3261 if (!sta_ds) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303262 pe_err("DPH Entry for STA: %X is missing",
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303263 DPH_STA_HASH_INDEX_PEER);
3264 goto skip_event;
3265 }
3266
3267 qdf_mem_copy(peer_mac.bytes,
3268 del_sta_params->staMac, QDF_MAC_ADDR_SIZE);
3269
3270 if (QDF_STATUS_SUCCESS != del_sta_params->status) {
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303271 pe_err("DEL STA failed!");
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303272 lim_send_sme_tdls_del_sta_rsp(mac_ctx,
3273 session_entry->smeSessionId,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003274 peer_mac, NULL, QDF_STATUS_E_FAILURE);
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303275 goto skip_event;
3276 }
3277
Nishank Aggarwal550931a2017-03-22 19:33:11 +05303278 pe_debug("DEL STA success");
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303279
3280 /* now send indication to SME-->HDD->TL to remove STA from TL */
3281
3282 lim_send_sme_tdls_del_sta_rsp(mac_ctx, session_entry->smeSessionId,
3283 peer_mac, sta_ds,
Jeff Johnson0301ecb2018-06-29 09:36:23 -07003284 QDF_STATUS_SUCCESS);
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05303285 lim_release_peer_idx(mac_ctx, sta_ds->assocId, session_entry);
3286
3287 /* Clear the aid in peerAIDBitmap as this aid is now in freepool */
3288 CLEAR_PEER_AID_BITMAP(session_entry->peerAIDBitmap,
3289 sta_ds->assocId);
3290 lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, sta_ds->assocId,
3291 session_entry);
3292
3293skip_event:
3294 qdf_mem_free(del_sta_params);
3295 lim_msg->bodyptr = NULL;
3296}
3297
3298
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003299#endif