blob: 5950dd37370444bf5a5f45b5ba370420314e8323 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*===========================================================================
29 * lim_process_tdls.c
30 * OVERVIEW:
31 *
32 * DEPENDENCIES:
33 *
34 * Are listed for each API below.
35 * ===========================================================================*/
36
37/*===========================================================================
38
39 * EDIT HISTORY FOR FILE
40
41 * This section contains comments describing changes made to the module.
42 * Notice that changes are listed in reverse chronological order.
43
44 * $Header$$DateTime$$Author$
45
46 * when who what, where, why
47 * ---------- --- ------------------------------------------------------
48 * 05/05/2010 Ashwani Initial Creation, added TDLS action frame
49 * functionality,TDLS message exchange with SME..etc..
50
51 ===========================================================================*/
52
53/**
54 * \file lim_process_tdls.c
55 *
56 * \brief Code for preparing,processing and sending 802.11z action frames
57 *
58 */
59
60#ifdef FEATURE_WLAN_TDLS
61
62#include "sir_api.h"
63#include "ani_global.h"
64#include "sir_mac_prot_def.h"
65#include "cfg_api.h"
66#include "utils_api.h"
67#include "lim_types.h"
68#include "lim_utils.h"
69#include "lim_security_utils.h"
70#include "dot11f.h"
71#include "lim_sta_hash_api.h"
72#include "sch_api.h"
73#include "lim_send_messages.h"
74#include "utils_parser.h"
75#include "lim_assoc_utils.h"
76#include "dph_hash_table.h"
77#include "wma_types.h"
Naveen Rawat3b6068c2016-04-14 19:01:06 -070078#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079
80/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630
81 There was IOT issue with cisco 1252 open mode, where it pads
82 discovery req/teardown frame with some junk value up to min size.
83 To avoid this issue, we pad QCOM_VENDOR_IE.
84 If there is other IOT issue because of this bandage, define NO_PAD...
85 */
86#ifndef NO_PAD_TDLS_MIN_8023_SIZE
87#define MIN_IEEE_8023_SIZE 46
88#define MIN_VENDOR_SPECIFIC_IE_SIZE 5
89#endif
90
91static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
92 tSirTdlsAddStaReq * pAddStaReq, tpPESession psessionEntry);
93void populate_dot11f_link_iden(tpAniSirGlobal pMac, tpPESession psessionEntry,
94 tDot11fIELinkIdentifier *linkIden,
Anurag Chouhan6d760662016-02-20 16:05:43 +053095 struct qdf_mac_addr peer_mac, uint8_t reqType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
97 tpPESession psessionEntry,
98 tDot11fIEExtCap *extCapability);
99
100void populate_dot11f_tdls_offchannel_params(tpAniSirGlobal pMac,
101 tpPESession psessionEntry,
102 tDot11fIESuppChannels *suppChannels,
103 tDot11fIESuppOperatingClasses *
104 suppOperClasses);
105void lim_log_vht_cap(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f);
106tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal pMac,
107 tpSirSupportedRates pRates,
108 tDot11fIEVHTCaps *pPeerVHTCaps,
109 tpPESession psessionEntry);
110ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode);
111
112/*
113 * TDLS data frames will go out/come in as non-qos data.
114 * so, eth_890d_header will be aligned access..
115 */
116static const uint8_t eth_890d_header[] = {
117 0xaa, 0xaa, 0x03, 0x00,
118 0x00, 0x00, 0x89, 0x0d,
119};
120
121/*
122 * type of links used in TDLS
123 */
124enum tdlsLinks {
125 TDLS_LINK_AP,
126 TDLS_LINK_DIRECT
127} e_tdls_link;
128
129/*
130 * node status in node searching
131 */
132enum tdlsLinkNodeStatus {
133 TDLS_NODE_NOT_FOUND,
134 TDLS_NODE_FOUND
135} e_tdls_link_node_status;
136
137enum tdlsReqType {
138 TDLS_INITIATOR,
139 TDLS_RESPONDER
140} e_tdls_req_type;
141
142typedef enum tdlsLinkSetupStatus {
143 TDLS_SETUP_STATUS_SUCCESS = 0,
144 TDLS_SETUP_STATUS_FAILURE = 37
145} etdlsLinkSetupStatus;
146
147/* These maps to Kernel TDLS peer capability
148 * flags and should get changed as and when necessary
149 */
150enum tdls_peer_capability {
151 TDLS_PEER_HT_CAP = 0,
152 TDLS_PEER_VHT_CAP = 1,
153 TDLS_PEER_WMM_CAP = 2
154} e_tdls_peer_capability;
155
156/* some local defines */
157#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
158#define PTI_LINK_IDEN_OFFSET (5)
159#define PTI_BUF_STATUS_OFFSET (25)
160
161/* TODO, Move this parameters to configuration */
162#define PEER_PSM_SUPPORT (0)
163#define TDLS_SUPPORT (1)
164#define TDLS_PROHIBITED (0)
165#define TDLS_CH_SWITCH_PROHIBITED (1)
166/** @brief Set bit manipulation macro */
167#define SET_BIT(value, mask) ((value) |= (1 << (mask)))
168/** @brief Clear bit manipulation macro */
169#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask)))
170/** @brief Check bit manipulation macro */
171#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
172
173#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
174 do { \
175 if ((aid) < (sizeof(uint32_t) << 3)) \
176 SET_BIT(peer_bitmap[0], (aid)); \
177 else if ((aid) < (sizeof(uint32_t) << 4)) \
178 SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
179 } while (0);
180
181#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \
182 do { \
183 if ((aid) < (sizeof(uint32_t) << 3)) \
184 CLEAR_BIT(peer_bitmap[0], (aid)); \
185 else if ((aid) < (sizeof(uint32_t) << 4)) \
186 CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
187 } while (0);
188
189#ifdef LIM_DEBUG_TDLS
190
191#ifdef FEATURE_WLAN_TDLS
192#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800)
193#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200)
194#endif
195
196#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \
197 SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) || \
198 (((psessionEntry)->limWmeEnabled) && \
199 LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps)))
200
201#define TID_AC_VI 4
202#define TID_AC_BK 1
203
204const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode)
205{
206 switch (tdlsActionCode) {
207 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
208 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
209 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
210 CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
211 CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
212 CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
213 CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
214 CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
215 CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
216 CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
217 }
218 return (const uint8_t *)"UNKNOWN";
219}
220#endif
221/*
222 * initialize TDLS setup list and related data structures.
223 */
224void lim_init_tdls_data(tpAniSirGlobal pMac, tpPESession pSessionEntry)
225{
226 lim_init_peer_idxpool(pMac, pSessionEntry);
227
228 return;
229}
230
231/*
232 * prepare TDLS frame header, it includes
233 * | | | |
234 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
235 * | | | |
236 */
237static uint32_t lim_prepare_tdls_frame_header(tpAniSirGlobal pMac, uint8_t *pFrame,
238 tDot11fIELinkIdentifier *link_iden,
239 uint8_t tdlsLinkType, uint8_t reqType,
240 uint8_t tid,
241 tpPESession psessionEntry)
242{
243 tpSirMacDataHdr3a pMacHdr;
244 uint32_t header_offset = 0;
245 uint8_t *addr1 = NULL;
246 uint8_t *addr3 = NULL;
247 uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP)
248 ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS;
249 uint8_t *peerMac = (reqType == TDLS_INITIATOR)
250 ? link_iden->RespStaAddr : link_iden->InitStaAddr;
251 uint8_t *staMac = (reqType == TDLS_INITIATOR)
252 ? link_iden->InitStaAddr : link_iden->RespStaAddr;
253
254 pMacHdr = (tpSirMacDataHdr3a) (pFrame);
255
256 /*
257 * if TDLS frame goes through the AP link, it follows normal address
258 * pattern, if TDLS frame goes thorugh the direct link, then
259 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
260 */
261 (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
262 (addr3 = (peerMac)))
263 : ((addr1 = (peerMac)), (addr3 = (link_iden->bssid)));
264 /*
265 * prepare 802.11 header
266 */
267 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
268 pMacHdr->fc.type = SIR_MAC_DATA_FRAME;
269 pMacHdr->fc.subType =
270 IS_QOS_ENABLED(psessionEntry) ? SIR_MAC_DATA_QOS_DATA :
271 SIR_MAC_DATA_DATA;
272
273 /*
274 * TL is not setting up below fields, so we are doing it here
275 */
276 pMacHdr->fc.toDS = toDs;
277 pMacHdr->fc.powerMgmt = 0;
278 pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE) ? 0 : 1;
279
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530280 qdf_mem_copy((uint8_t *) pMacHdr->addr1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800281 (uint8_t *) addr1, sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530282 qdf_mem_copy((uint8_t *) pMacHdr->addr2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800283 (uint8_t *) staMac, sizeof(tSirMacAddr));
284
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530285 qdf_mem_copy((uint8_t *) pMacHdr->addr3,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800286 (uint8_t *) (addr3), sizeof(tSirMacAddr));
287
288 lim_log(pMac, LOG1,
289 FL(
290 "Preparing TDLS frame header to %s A1:"
291 MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"
292 MAC_ADDRESS_STR
293 ),
294 (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT",
295 MAC_ADDR_ARRAY(pMacHdr->addr1),
296 MAC_ADDR_ARRAY(pMacHdr->addr2),
297 MAC_ADDR_ARRAY(pMacHdr->addr3));
298
299 if (IS_QOS_ENABLED(psessionEntry)) {
300 pMacHdr->qosControl.tid = tid;
301 header_offset += sizeof(tSirMacDataHdr3a);
302 } else
303 header_offset += sizeof(tSirMacMgmtHdr);
304
305 /*
306 * Now form RFC1042 header
307 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530308 qdf_mem_copy((uint8_t *) (pFrame + header_offset),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309 (uint8_t *) eth_890d_header, sizeof(eth_890d_header));
310
311 header_offset += sizeof(eth_890d_header);
312
313 /* add payload type as TDLS */
314 *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
315 header_offset += PAYLOAD_TYPE_TDLS_SIZE;
316 return header_offset;
317}
318
319/*
320 * TX Complete for Management frames
321 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530322QDF_STATUS lim_mgmt_tx_complete(tpAniSirGlobal pMac, uint32_t txCompleteSuccess)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323{
324 tpPESession psessionEntry = NULL;
325
326 if (0xff != pMac->lim.mgmtFrameSessionId) {
327 psessionEntry =
328 pe_find_session_by_session_id(pMac,
329 pMac->lim.mgmtFrameSessionId);
330 if (NULL == psessionEntry) {
331 lim_log(pMac, LOGE, FL("sessionID %d is not found"),
332 pMac->lim.mgmtFrameSessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530333 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334 }
335 lim_send_sme_mgmt_tx_completion(pMac, psessionEntry,
336 txCompleteSuccess);
337 pMac->lim.mgmtFrameSessionId = 0xff;
338 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530339 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800340}
341
342/*
343 * This function can be used for bacst or unicast discovery request
344 * We are not differentiating it here, it will all depnds on peer MAC address,
345 */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800346tSirRetStatus lim_send_tdls_dis_req_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530347 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800348 uint8_t dialog,
349 tpPESession psessionEntry)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800350{
351 tDot11fTDLSDisReq tdlsDisReq;
352 uint32_t status = 0;
353 uint32_t nPayload = 0;
354 uint32_t size = 0;
355 uint32_t nBytes = 0;
356 uint32_t header_offset = 0;
357 uint8_t *pFrame;
358 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530359 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360#ifndef NO_PAD_TDLS_MIN_8023_SIZE
361 uint32_t padLen = 0;
362#endif
363 uint8_t smeSessionId = 0;
364
365 if (NULL == psessionEntry) {
366 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
367 return eSIR_FAILURE;
368 }
369 smeSessionId = psessionEntry->smeSessionId;
370 /*
371 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
372 * and then hand it off to 'dot11f_pack_probe_request' (for
373 * serialization). We start by zero-initializing the structure:
374 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530375 qdf_mem_set((uint8_t *) &tdlsDisReq, sizeof(tDot11fTDLSDisReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800376
377 /*
378 * setup Fixed fields,
379 */
380 tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS;
381 tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ;
382 tdlsDisReq.DialogToken.token = dialog;
383
384 size = sizeof(tSirMacAddr);
385
386 populate_dot11f_link_iden(pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
387 peer_mac, TDLS_INITIATOR);
388
389 /*
390 * now we pack it. First, how much space are we going to need?
391 */
392 status = dot11f_get_packed_tdls_dis_req_size(pMac, &tdlsDisReq, &nPayload);
393 if (DOT11F_FAILED(status)) {
394 lim_log(pMac, LOGP,
395 FL(
396 "Failed to calculate the packed size for a discovery Request (0x%08x)."
397 ),
398 status);
399 /* We'll fall back on the worst case scenario: */
400 nPayload = sizeof(tDot11fTDLSDisReq);
401 } else if (DOT11F_WARNED(status)) {
402 lim_log(pMac, LOGW,
403 FL(
404 "There were warnings while calculating the packed size for a discovery Request (0x%08x)."
405 ),
406 status);
407 }
408
409 /*
410 * This frame is going out from PE as data frames with special ethertype
411 * 89-0d.
412 * 8 bytes of RFC 1042 header
413 */
414
415 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
416 ? sizeof(tSirMacDataHdr3a) :
417 sizeof(tSirMacMgmtHdr))
418 + sizeof(eth_890d_header)
419 + PAYLOAD_TYPE_TDLS_SIZE;
420
421#ifndef NO_PAD_TDLS_MIN_8023_SIZE
422 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
423 Hence AP itself padding some bytes, which caused teardown packet is dropped at
424 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
425 */
426 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
427 padLen =
428 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
429
430 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
431 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
432 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
433
434 nBytes += padLen;
435 }
436#endif
437
438 /* Ok-- try to allocate memory from MGMT PKT pool */
439
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530440 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530442 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800443 lim_log(pMac, LOGP,
444 FL(
445 "Failed to allocate %d bytes for a TDLS Discovery Request."
446 ),
447 nBytes);
448 return eSIR_MEM_ALLOC_FAILED;
449 }
450
451 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530452 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453
454 /*
455 * IE formation, memory allocation is completed, Now form TDLS discovery
456 * request frame
457 */
458
459 /* fill out the buffer descriptor */
460
461 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
462 LINK_IDEN_ADDR_OFFSET
463 (tdlsDisReq), TDLS_LINK_AP,
464 TDLS_INITIATOR, TID_AC_VI,
465 psessionEntry);
466
467 status = dot11f_pack_tdls_dis_req(pMac, &tdlsDisReq, pFrame
468 + header_offset, nPayload, &nPayload);
469
470 if (DOT11F_FAILED(status)) {
471 lim_log(pMac, LOGE,
472 FL("Failed to pack a TDLS discovery req (0x%08x)."),
473 status);
474 cds_packet_free((void *)pPacket);
475 return eSIR_FAILURE;
476 } else if (DOT11F_WARNED(status)) {
477 lim_log(pMac, LOGW,
478 FL(
479 "There were warnings while packing TDLS Discovery Request (0x%08x)."
480 ),
481 status);
482 }
483#ifndef NO_PAD_TDLS_MIN_8023_SIZE
484 if (padLen != 0) {
485 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
486 uint8_t *padVendorSpecific = pFrame + header_offset + nPayload;
487 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
488 padVendorSpecific[0] = 221;
489 padVendorSpecific[1] = padLen - 2;
490 padVendorSpecific[2] = 0x00;
491 padVendorSpecific[3] = 0xA0;
492 padVendorSpecific[4] = 0xC6;
493
494 lim_log(pMac, LOGW,
495 FL("Padding Vendor Specific Ie Len = %d"), padLen);
496
497 /* padding zero if more than 5 bytes are required */
498 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530499 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 MIN_VENDOR_SPECIFIC_IE_SIZE,
501 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
502 }
503#endif
504
505 lim_log(pMac, LOG1,
506 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
507 SIR_MAC_TDLS_DIS_REQ,
508 lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_REQ),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800509 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510
511 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530512 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513 TXRX_FRM_802_11_DATA,
514 ANI_TXDIR_TODS,
515 TID_AC_VI,
516 lim_tx_complete, pFrame,
517 lim_mgmt_tx_complete,
518 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
519 smeSessionId, false, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530520 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521 pMac->lim.mgmtFrameSessionId = 0xff;
522 lim_log(pMac, LOGE,
523 FL("could not send TDLS Discovery Request frame"));
524 return eSIR_FAILURE;
525 }
526
527 return eSIR_SUCCESS;
528
529}
530
531/*
532 * This static function is consistent with any kind of TDLS management
533 * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame,
534 * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame
535 */
536static void populate_dot11f_tdls_ht_vht_cap(tpAniSirGlobal pMac,
537 uint32_t selfDot11Mode,
538 tDot11fIEHTCaps *htCap,
539 tDot11fIEVHTCaps *vhtCap,
540 tpPESession psessionEntry)
541{
542 if (IS_DOT11_MODE_HT(selfDot11Mode)) {
543 /* Include HT Capability IE */
544 populate_dot11f_ht_caps(pMac, NULL, htCap);
545 /*
546 * Advertise ht capability and max supported channel bandwidth
547 * when populating HT IE in TDLS Setup Request/Setup Response/
548 * Setup Confirmation frames.
549 * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz
550 * off-channel direct link may be started if both TDLS peer STAs
551 * indicated 40 MHz support in the Supported Channel Width Set
552 * field of the HT Capabilities element (which is included in
553 * the TDLS Setup Request frame and the TDLS Setup Response
554 * frame). Switching to a 40 MHz off-channel direct link is
555 * achieved by including the following information in the TDLS
556 * Channel Switch Request
557 * 11.21.1 General: The channel width of the TDLS direct link on
558 * the base channel shall not exceed the channel width of the
559 * BSS to which the TDLS peer STAs are associated.
560 */
561 htCap->supportedChannelWidthSet = 1;
562 } else {
563 htCap->present = 0;
564 }
565 lim_log(pMac, LOG1, FL("HT present = %hu, Chan Width = %hu"),
566 htCap->present, htCap->supportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
568 pMac->roam.configParam.enableVhtFor24GHz) ||
569 (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
570 if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
571 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
572 /* Include VHT Capability IE */
573 populate_dot11f_vht_caps(pMac, psessionEntry, vhtCap);
574 vhtCap->suBeamformeeCap = 0;
575 vhtCap->suBeamFormerCap = 0;
576 vhtCap->muBeamformeeCap = 0;
577 vhtCap->muBeamformerCap = 0;
578 } else {
579 vhtCap->present = 0;
580 }
581 } else {
582 /* Vht Disable from ini in 2.4 GHz */
583 vhtCap->present = 0;
584 }
585 lim_log(pMac, LOG1, FL("VHT present = %hu, Chan Width = %hu"),
586 vhtCap->present, vhtCap->supportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587}
588
589/*
590 * Send TDLS discovery response frame on direct link.
591 */
592
593static tSirRetStatus lim_send_tdls_dis_rsp_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530594 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800595 uint8_t dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 tpPESession psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800597 uint8_t *addIe,
598 uint16_t addIeLen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599{
600 tDot11fTDLSDisRsp tdlsDisRsp;
601 uint16_t caps = 0;
602 uint32_t status = 0;
603 uint32_t nPayload = 0;
604 uint32_t nBytes = 0;
605 uint8_t *pFrame;
606 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530607 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608 uint32_t selfDot11Mode;
609/* Placeholder to support different channel bonding mode of TDLS than AP. */
610/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
611/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
612/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
613/* uint32_t tdlsChannelBondingMode; */
614 uint8_t smeSessionId = 0;
615
616 if (NULL == psessionEntry) {
617 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
618 return eSIR_FAILURE;
619 }
620 smeSessionId = psessionEntry->smeSessionId;
621
622 /*
623 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
624 * and then hand it off to 'dot11f_pack_probe_request' (for
625 * serialization). We start by zero-initializing the structure:
626 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530627 qdf_mem_set((uint8_t *) &tdlsDisRsp, sizeof(tDot11fTDLSDisRsp), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628
629 /*
630 * setup Fixed fields,
631 */
632 tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
633 tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP;
634 tdlsDisRsp.DialogToken.token = dialog;
635
636 populate_dot11f_link_iden(pMac, psessionEntry,
637 &tdlsDisRsp.LinkIdentifier,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800638 peer_mac, TDLS_RESPONDER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639
640 if (cfg_get_capability_info(pMac, &caps, psessionEntry)
641 != eSIR_SUCCESS) {
642 /*
643 * Could not get Capabilities value
644 * from CFG. Log error.
645 */
646 lim_log(pMac, LOGE,
647 FL("could not retrieve Capabilities value"));
648 }
649 swap_bit_field16(caps, (uint16_t *) &tdlsDisRsp.Capabilities);
650
651 /* populate supported rate and ext supported rate IE */
652 if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
653 &tdlsDisRsp.SuppRates,
654 &tdlsDisRsp.ExtSuppRates))
655 lim_log(pMac, LOGE,
656 FL("could not populate supported data rates"));
657
658 /* populate extended capability IE */
659 populate_dot11f_tdls_ext_capability(pMac,
660 psessionEntry,
661 &tdlsDisRsp.ExtCap);
662
663 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
664
665 /* Populate HT/VHT Capabilities */
666 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsDisRsp.HTCaps,
667 &tdlsDisRsp.VHTCaps, psessionEntry);
668
669 /* Populate TDLS offchannel param only if offchannel is enabled
670 * and TDLS Channel Switching is not prohibited by AP in ExtCap
671 * IE in assoc/re-assoc response.
672 */
673 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
674 (!psessionEntry->tdls_chan_swit_prohibited)) {
675 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
676 &tdlsDisRsp.SuppChannels,
677 &tdlsDisRsp.
678 SuppOperatingClasses);
679 if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
680 tdlsDisRsp.ht2040_bss_coexistence.present = 1;
681 tdlsDisRsp.ht2040_bss_coexistence.info_request = 1;
682 }
683 } else {
684 lim_log(pMac, LOG1,
685 FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
686 pMac->lim.gLimTDLSOffChannelEnabled,
687 psessionEntry->tdls_chan_swit_prohibited);
688 }
689 /*
690 * now we pack it. First, how much space are we going to need?
691 */
692 status = dot11f_get_packed_tdls_dis_rsp_size(pMac, &tdlsDisRsp, &nPayload);
693 if (DOT11F_FAILED(status)) {
694 lim_log(pMac, LOGE,
695 FL(
696 "Failed to calculate the packed size for a Discovery Response (0x%08x)."
697 ),
698 status);
699 /* We'll fall back on the worst case scenario: */
700 nPayload = sizeof(tDot11fProbeRequest);
701 } else if (DOT11F_WARNED(status)) {
702 lim_log(pMac, LOGW,
703 FL(
704 "There were warnings while calculating the packed size for a Discovery Response (0x%08x)."
705 ),
706 status);
707 }
708
709 /*
710 * This frame is going out from PE as data frames with special ethertype
711 * 89-0d.
712 * 8 bytes of RFC 1042 header
713 */
714
715 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen;
716
717 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530718 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530720 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800721 lim_log(pMac, LOGE,
722 FL(
723 "Failed to allocate %d bytes for a TDLS Discovery Request."
724 ),
725 nBytes);
726 return eSIR_MEM_ALLOC_FAILED;
727 }
728
729 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530730 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731
732 /*
733 * IE formation, memory allocation is completed, Now form TDLS discovery
734 * response frame
735 */
736
737 /* Make public Action Frame */
738
739 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800740 SIR_MAC_MGMT_ACTION, peer_mac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741 psessionEntry->selfMacAddr);
742
743 {
744 tpSirMacMgmtHdr pMacHdr;
745 pMacHdr = (tpSirMacMgmtHdr) pFrame;
746 pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
747 pMacHdr->fc.powerMgmt = 0;
748 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
749 }
750
751 status = dot11f_pack_tdls_dis_rsp(pMac, &tdlsDisRsp, pFrame +
752 sizeof(tSirMacMgmtHdr),
753 nPayload, &nPayload);
754
755 if (DOT11F_FAILED(status)) {
756 lim_log(pMac, LOGE,
757 FL(
758 "Failed to pack a TDLS discovery response (0x%08x)."
759 ),
760 status);
761 cds_packet_free((void *)pPacket);
762 return eSIR_FAILURE;
763 } else if (DOT11F_WARNED(status)) {
764 lim_log(pMac, LOGW,
765 FL(
766 "There were warnings while packing TDLS Discovery Response (0x%08x)."
767 ),
768 status);
769 }
770 if (0 != addIeLen) {
771 lim_log(pMac, LOG1,
772 FL("Copy Additional Ie Len = %d"), addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530773 qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774 addIeLen);
775 }
776 lim_log(pMac, LOG1,
777 FL("[TDLS] action %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR),
778 SIR_MAC_TDLS_DIS_RSP,
779 lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_RSP),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800780 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781
782 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
783 /*
784 * Transmit Discovery response and watch if this is delivered to
785 * peer STA.
786 */
787 /* In CLD 2.0, pass Discovery Response as mgmt frame so that
788 * wma does not do header conversion to 802.3 before calling tx/rx
789 * routine and subsequenly target also sends frame as is OTA
790 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530791 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 TXRX_FRM_802_11_MGMT,
793 ANI_TXDIR_IBSS,
794 0,
795 lim_tx_complete, pFrame,
796 lim_mgmt_tx_complete,
797 HAL_USE_SELF_STA_REQUESTED_MASK,
798 smeSessionId, false, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530799 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 pMac->lim.mgmtFrameSessionId = 0xff;
801 lim_log(pMac, LOGE,
802 FL("could not send TDLS Discovery Response frame!"));
803 return eSIR_FAILURE;
804 }
805
806 return eSIR_SUCCESS;
807
808}
809
810/*
811 * This static function is currently used by lim_send_tdls_link_setup_req_frame and
812 * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable.
813 */
814static void populate_dotf_tdls_vht_aid(tpAniSirGlobal pMac, uint32_t selfDot11Mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530815 struct qdf_mac_addr peerMac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800816 tDot11fIEAID *Aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 tpPESession psessionEntry)
818{
819 if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
820 pMac->roam.configParam.enableVhtFor24GHz) ||
821 (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
822 if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
823 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
824
825 uint16_t aid;
826 tpDphHashNode pStaDs;
827
828 pStaDs =
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800829 dph_lookup_hash_entry(pMac, peerMac.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 &psessionEntry->dph.
831 dphHashTable);
832 if (NULL != pStaDs) {
833 Aid->present = 1;
834 Aid->assocId = aid | LIM_AID_MASK; /* set bit 14 and 15 1's */
835 } else {
836 Aid->present = 0;
837 lim_log(pMac, LOGE,
838 FL("pStaDs is NULL for "
839 MAC_ADDRESS_STR),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800840 MAC_ADDR_ARRAY(peerMac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 }
842 }
843 } else {
844 Aid->present = 0;
845 lim_log(pMac, LOGW, FL("Vht not enable from ini for 2.4GHz."));
846 }
847}
848
849/*
850 * TDLS setup Request frame on AP link
851 */
852
853tSirRetStatus lim_send_tdls_link_setup_req_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530854 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800855 uint8_t dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800856 tpPESession psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800857 uint8_t *addIe,
858 uint16_t addIeLen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859{
860 tDot11fTDLSSetupReq tdlsSetupReq;
861 uint16_t caps = 0;
862 uint32_t status = 0;
863 uint32_t nPayload = 0;
864 uint32_t nBytes = 0;
865 uint32_t header_offset = 0;
866 uint8_t *pFrame;
867 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530868 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869 uint32_t selfDot11Mode;
870 uint8_t smeSessionId = 0;
871/* Placeholder to support different channel bonding mode of TDLS than AP. */
872/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
873/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
874/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
875/* uint32_t tdlsChannelBondingMode; */
876
877 /*
878 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
879 * and then hand it off to 'dot11f_pack_probe_request' (for
880 * serialization). We start by zero-initializing the structure:
881 */
882 smeSessionId = psessionEntry->smeSessionId;
883
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530884 qdf_mem_set((uint8_t *) &tdlsSetupReq, sizeof(tDot11fTDLSSetupReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS;
886 tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ;
887 tdlsSetupReq.DialogToken.token = dialog;
888
889 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800890 &tdlsSetupReq.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 TDLS_INITIATOR);
892
893 if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
894 /*
895 * Could not get Capabilities value
896 * from CFG. Log error.
897 */
898 lim_log(pMac, LOGE,
899 FL("could not retrieve Capabilities value"));
900 }
901 swap_bit_field16(caps, (uint16_t *) &tdlsSetupReq.Capabilities);
902
903 /* populate supported rate and ext supported rate IE */
904 if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
905 &tdlsSetupReq.SuppRates,
906 &tdlsSetupReq.ExtSuppRates))
907 lim_log(pMac, LOGE,
908 FL("could not populate supported data rates"));
909
910 /* Populate extended capability IE */
911 populate_dot11f_tdls_ext_capability(pMac,
912 psessionEntry,
913 &tdlsSetupReq.ExtCap);
914
915 if (1 == pMac->lim.gLimTDLSWmmMode) {
916 uint32_t val = 0;
917
918 lim_log(pMac, LOG1,
919 FL("populate WMM IE in Setup Request Frame"));
920 /* include WMM IE */
921 tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
922 tdlsSetupReq.WMMInfoStation.acvo_uapsd =
923 (pMac->lim.gLimTDLSUapsdMask & 0x01);
924 tdlsSetupReq.WMMInfoStation.acvi_uapsd =
925 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
926 tdlsSetupReq.WMMInfoStation.acbk_uapsd =
927 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
928 tdlsSetupReq.WMMInfoStation.acbe_uapsd =
929 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
930
931 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
932 eSIR_SUCCESS)
933 lim_log(pMac, LOGE,
934 FL("could not retrieve Max SP Length"));
935
936 tdlsSetupReq.WMMInfoStation.max_sp_length = (uint8_t) val;
937 tdlsSetupReq.WMMInfoStation.present = 1;
938 } else {
939 /*
940 * TODO: we need to see if we have to support conditions where
941 * we have EDCA parameter info element is needed a) if we need
942 * different QOS parameters for off channel operations or QOS
943 * is not supported on AP link and we wanted to QOS on direct
944 * link.
945 */
946
947 /* Populate QOS info, needed for Peer U-APSD session */
948
949 /*
950 * TODO: Now hardcoded, since populate_dot11f_qos_caps_station()
951 * depends on AP's capability, and TDLS doesn't want to depend
952 * on AP's capability
953 */
954
955 lim_log(pMac, LOG1,
956 FL("populate QOS IE in Setup Request Frame"));
957 tdlsSetupReq.QOSCapsStation.present = 1;
958 tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
959 tdlsSetupReq.QOSCapsStation.qack = 0;
960 tdlsSetupReq.QOSCapsStation.acbe_uapsd =
961 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
962 tdlsSetupReq.QOSCapsStation.acbk_uapsd =
963 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
964 tdlsSetupReq.QOSCapsStation.acvi_uapsd =
965 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
966 tdlsSetupReq.QOSCapsStation.acvo_uapsd =
967 (pMac->lim.gLimTDLSUapsdMask & 0x01);
968 }
969
970 /*
971 * we will always try to init TDLS link with 11n capabilities
972 * let TDLS setup response to come, and we will set our caps based
973 * of peer caps
974 */
975
976 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
977
978 /* Populate HT/VHT Capabilities */
979 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupReq.HTCaps,
980 &tdlsSetupReq.VHTCaps, psessionEntry);
981
982 /* Populate AID */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800983 populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800984 &tdlsSetupReq.AID, psessionEntry);
985
986 /* Populate TDLS offchannel param only if offchannel is enabled
987 * and TDLS Channel Switching is not prohibited by AP in ExtCap
988 * IE in assoc/re-assoc response.
989 */
990 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
991 (!psessionEntry->tdls_chan_swit_prohibited)) {
992 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
993 &tdlsSetupReq.SuppChannels,
994 &tdlsSetupReq.
995 SuppOperatingClasses);
996 if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
997 tdlsSetupReq.ht2040_bss_coexistence.present = 1;
998 tdlsSetupReq.ht2040_bss_coexistence.info_request = 1;
999 }
1000 } else {
1001 lim_log(pMac, LOG1,
1002 FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
1003 pMac->lim.gLimTDLSOffChannelEnabled,
1004 psessionEntry->tdls_chan_swit_prohibited);
1005 }
1006 /*
1007 * now we pack it. First, how much space are we going to need?
1008 */
1009 status = dot11f_get_packed_tdls_setup_req_size(pMac, &tdlsSetupReq,
1010 &nPayload);
1011 if (DOT11F_FAILED(status)) {
1012 lim_log(pMac, LOGE,
1013 FL(
1014 "Failed to calculate the packed size for a Setup Request (0x%08x)."
1015 ),
1016 status);
1017 /* We'll fall back on the worst case scenario: */
1018 nPayload = sizeof(tDot11fProbeRequest);
1019 } else if (DOT11F_WARNED(status)) {
1020 lim_log(pMac, LOGW,
1021 FL(
1022 "There were warnings while calculating the packed size for a Setup Request (0x%08x)."
1023 ),
1024 status);
1025 }
1026
1027 /*
1028 * This frame is going out from PE as data frames with special ethertype
1029 * 89-0d.
1030 * 8 bytes of RFC 1042 header
1031 */
1032
1033 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1034 ? sizeof(tSirMacDataHdr3a) :
1035 sizeof(tSirMacMgmtHdr))
1036 + sizeof(eth_890d_header)
1037 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1038
1039 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301040 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001041 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301042 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 lim_log(pMac, LOGE,
1044 FL(
1045 "Failed to allocate %d bytes for a TDLS Setup Request."
1046 ),
1047 nBytes);
1048 return eSIR_MEM_ALLOC_FAILED;
1049 }
1050
1051 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301052 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001053
1054 /*
1055 * IE formation, memory allocation is completed, Now form TDLS discovery
1056 * request frame
1057 */
1058
1059 /* fill out the buffer descriptor */
1060
1061 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1062 LINK_IDEN_ADDR_OFFSET
1063 (tdlsSetupReq), TDLS_LINK_AP,
Pradeep Reddy POTTETI8226a1d2015-11-04 14:40:51 +05301064 TDLS_INITIATOR, TID_AC_VI,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001065 psessionEntry);
1066
1067 lim_log(pMac, LOGW,
1068 FL(
1069 "SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"
1070 ),
1071 tdlsSetupReq.VHTCaps.supportedChannelWidthSet,
1072 tdlsSetupReq.VHTCaps.rxMCSMap,
1073 tdlsSetupReq.VHTCaps.txMCSMap,
1074 tdlsSetupReq.VHTCaps.txSupDataRate);
1075
1076 status = dot11f_pack_tdls_setup_req(pMac, &tdlsSetupReq, pFrame
1077 + header_offset, nPayload, &nPayload);
1078
1079 if (DOT11F_FAILED(status)) {
1080 lim_log(pMac, LOGE,
1081 FL("Failed to pack a TDLS Setup request (0x%08x)."),
1082 status);
1083 cds_packet_free((void *)pPacket);
1084 return eSIR_FAILURE;
1085 } else if (DOT11F_WARNED(status)) {
1086 lim_log(pMac, LOGW,
1087 FL(
1088 "There were warnings while packing TDLS Setup Request (0x%08x)."
1089 ),
1090 status);
1091 }
1092 /* Copy the additional IE. */
1093 /* TODO : addIe is added at the end of the frame. This means it doesnt */
1094 /* follow the order. This should be ok, but we should consider changing this */
1095 /* if there is any IOT issue. */
1096 if (addIeLen != 0) {
1097 lim_log(pMac, LOG1, FL("Copy Additional Ie Len = %d"),
1098 addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301099 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001100 addIeLen);
1101 }
1102
1103 lim_log(pMac, LOG1,
1104 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
1105 SIR_MAC_TDLS_SETUP_REQ,
1106 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_REQ),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001107 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001108
1109 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
1110
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301111 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001112 TXRX_FRM_802_11_DATA,
1113 ANI_TXDIR_TODS,
Pradeep Reddy POTTETI8226a1d2015-11-04 14:40:51 +05301114 TID_AC_VI,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001115 lim_tx_complete, pFrame,
1116 lim_mgmt_tx_complete,
1117 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
1118 smeSessionId, false, 0);
1119
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 pMac->lim.mgmtFrameSessionId = 0xff;
1122 lim_log(pMac, LOGE,
1123 FL("could not send TDLS Setup Request frame!"));
1124 return eSIR_FAILURE;
1125 }
1126
1127 return eSIR_SUCCESS;
1128
1129}
1130
1131/*
1132 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1133 */
1134
1135tSirRetStatus lim_send_tdls_teardown_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301136 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001137 uint16_t reason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 uint8_t responder,
1139 tpPESession psessionEntry,
1140 uint8_t *addIe, uint16_t addIeLen)
1141{
1142 tDot11fTDLSTeardown teardown;
1143 uint32_t status = 0;
1144 uint32_t nPayload = 0;
1145 uint32_t nBytes = 0;
1146 uint32_t header_offset = 0;
1147 uint8_t *pFrame;
1148 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301149 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001150#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1151 uint32_t padLen = 0;
1152#endif
1153 uint8_t smeSessionId = 0;
1154
1155 if (NULL == psessionEntry) {
1156 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
1157 return eSIR_FAILURE;
1158 }
1159 smeSessionId = psessionEntry->smeSessionId;
1160 /*
1161 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1162 * and then hand it off to 'dot11f_pack_probe_request' (for
1163 * serialization). We start by zero-initializing the structure:
1164 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301165 qdf_mem_set((uint8_t *) &teardown, sizeof(tDot11fTDLSTeardown), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166 teardown.Category.category = SIR_MAC_ACTION_TDLS;
1167 teardown.Action.action = SIR_MAC_TDLS_TEARDOWN;
1168 teardown.Reason.code = reason;
1169
1170 populate_dot11f_link_iden(pMac, psessionEntry, &teardown.LinkIdentifier,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001171 peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001172 (responder ==
1173 true) ? TDLS_RESPONDER : TDLS_INITIATOR);
1174
1175 /*
1176 * now we pack it. First, how much space are we going to need?
1177 */
1178 status = dot11f_get_packed_tdls_teardown_size(pMac, &teardown, &nPayload);
1179 if (DOT11F_FAILED(status)) {
1180 lim_log(pMac, LOGE,
1181 FL(
1182 "Failed to calculate the packed size for a discovery Request (0x%08x)."
1183 ),
1184 status);
1185 /* We'll fall back on the worst case scenario: */
1186 nPayload = sizeof(tDot11fProbeRequest);
1187 } else if (DOT11F_WARNED(status)) {
1188 lim_log(pMac, LOGW,
1189 FL(
1190 "There were warnings while calculating the packed size for a discovery Request (0x%08x)."
1191 ),
1192 status);
1193 }
1194
1195 /*
1196 * This frame is going out from PE as data frames with special ethertype
1197 * 89-0d.
1198 * 8 bytes of RFC 1042 header
1199 */
1200
1201 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1202 ? sizeof(tSirMacDataHdr3a) :
1203 sizeof(tSirMacMgmtHdr))
1204 + sizeof(eth_890d_header)
1205 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1206
1207#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1208 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1209 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1210 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1211 */
1212 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
1213 padLen =
1214 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
1215
1216 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1217 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1218 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1219
1220 nBytes += padLen;
1221 }
1222#endif
1223
1224 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301227 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001228 lim_log(pMac, LOGE,
1229 FL(
1230 "Failed to allocate %d bytes for a TDLS Teardown Frame."
1231 ),
1232 nBytes);
1233 return eSIR_MEM_ALLOC_FAILED;
1234 }
1235
1236 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301237 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001238
1239 /*
1240 * IE formation, memory allocation is completed, Now form TDLS discovery
1241 * request frame
1242 */
1243
1244 /* fill out the buffer descriptor */
1245 lim_log(pMac, LOGE, FL("Reason of TDLS Teardown: %d"), reason);
1246 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1247 LINK_IDEN_ADDR_OFFSET
1248 (teardown),
1249 (reason ==
1250 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1251 ? TDLS_LINK_AP :
1252 TDLS_LINK_DIRECT,
1253 (responder ==
1254 true) ? TDLS_RESPONDER :
1255 TDLS_INITIATOR, TID_AC_VI,
1256 psessionEntry);
1257
1258 status = dot11f_pack_tdls_teardown(pMac, &teardown, pFrame
1259 + header_offset, nPayload, &nPayload);
1260
1261 if (DOT11F_FAILED(status)) {
1262 lim_log(pMac, LOGE,
1263 FL("Failed to pack a TDLS Teardown frame (0x%08x)."),
1264 status);
1265 cds_packet_free((void *)pPacket);
1266 return eSIR_FAILURE;
1267 } else if (DOT11F_WARNED(status)) {
1268 lim_log(pMac, LOGW,
1269 FL(
1270 "There were warnings while packing TDLS Teardown frame (0x%08x)."
1271 ),
1272 status);
1273 }
1274
1275 if (addIeLen != 0) {
1276 lim_log(pMac, LOGW,
1277 FL("Copy Additional Ie Len = %d"), addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301278 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 addIeLen);
1280 }
1281#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1282 if (padLen != 0) {
1283 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1284 uint8_t *padVendorSpecific =
1285 pFrame + header_offset + nPayload + addIeLen;
1286 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1287 padVendorSpecific[0] = 221;
1288 padVendorSpecific[1] = padLen - 2;
1289 padVendorSpecific[2] = 0x00;
1290 padVendorSpecific[3] = 0xA0;
1291 padVendorSpecific[4] = 0xC6;
1292
1293 lim_log(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"),
1294 padLen);
1295
1296 /* padding zero if more than 5 bytes are required */
1297 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301298 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
1300 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
1301 }
1302#endif
1303 lim_log(pMac, LOG1,
1304 FL("[TDLS] action %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR),
1305 SIR_MAC_TDLS_TEARDOWN,
1306 lim_trace_tdls_action_string(SIR_MAC_TDLS_TEARDOWN),
1307 ((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" :
1308 "DIRECT"),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001309 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310
1311 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
1312
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301313 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314 TXRX_FRM_802_11_DATA,
1315 ANI_TXDIR_TODS,
1316 TID_AC_VI,
1317 lim_tx_complete, pFrame,
1318 lim_mgmt_tx_complete,
1319 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
1320 smeSessionId, false, 0);
1321
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301322 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001323 pMac->lim.mgmtFrameSessionId = 0xff;
1324 lim_log(pMac, LOGE,
1325 FL("could not send TDLS Teardown frame"));
1326 return eSIR_FAILURE;
1327
1328 }
1329 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001330}
1331
1332/*
1333 * Send Setup RSP frame on AP link.
1334 */
1335static tSirRetStatus lim_send_tdls_setup_rsp_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301336 struct qdf_mac_addr peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001337 uint8_t dialog,
1338 tpPESession psessionEntry,
1339 etdlsLinkSetupStatus setupStatus,
1340 uint8_t *addIe,
1341 uint16_t addIeLen)
1342{
1343 tDot11fTDLSSetupRsp tdlsSetupRsp;
1344 uint32_t status = 0;
1345 uint16_t caps = 0;
1346 uint32_t nPayload = 0;
1347 uint32_t header_offset = 0;
1348 uint32_t nBytes = 0;
1349 uint8_t *pFrame;
1350 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301351 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001352 uint32_t selfDot11Mode;
1353/* Placeholder to support different channel bonding mode of TDLS than AP. */
1354/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
1355/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
1356/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
1357/* uint32_t tdlsChannelBondingMode; */
1358 uint8_t smeSessionId = 0;
1359
1360 if (NULL == psessionEntry) {
1361 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
1362 return eSIR_FAILURE;
1363 }
1364 smeSessionId = psessionEntry->smeSessionId;
1365
1366 /*
1367 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1368 * and then hand it off to 'dot11f_pack_probe_request' (for
1369 * serialization). We start by zero-initializing the structure:
1370 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301371 qdf_mem_set((uint8_t *) &tdlsSetupRsp, sizeof(tDot11fTDLSSetupRsp), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372
1373 /*
1374 * setup Fixed fields,
1375 */
1376 tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
1377 tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP;
1378 tdlsSetupRsp.DialogToken.token = dialog;
1379
1380 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001381 &tdlsSetupRsp.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001382 TDLS_RESPONDER);
1383
1384 if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
1385 /*
1386 * Could not get Capabilities value
1387 * from CFG. Log error.
1388 */
1389 lim_log(pMac, LOGE,
1390 FL("could not retrieve Capabilities value"));
1391 }
1392 swap_bit_field16(caps, (uint16_t *) &tdlsSetupRsp.Capabilities);
1393
1394 /* populate supported rate and ext supported rate IE */
1395 if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
1396 &tdlsSetupRsp.SuppRates,
1397 &tdlsSetupRsp.ExtSuppRates))
1398 lim_log(pMac, LOGE,
1399 FL("could not populate supported data rates"));
1400
1401 /* Populate extended capability IE */
1402 populate_dot11f_tdls_ext_capability(pMac,
1403 psessionEntry,
1404 &tdlsSetupRsp.ExtCap);
1405
1406 if (1 == pMac->lim.gLimTDLSWmmMode) {
1407 uint32_t val = 0;
1408
1409 lim_log(pMac, LOG1,
1410 FL("populate WMM IE in Setup Response frame"));
1411 /* include WMM IE */
1412 tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
1413 tdlsSetupRsp.WMMInfoStation.acvo_uapsd =
1414 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1415 tdlsSetupRsp.WMMInfoStation.acvi_uapsd =
1416 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1417 tdlsSetupRsp.WMMInfoStation.acbk_uapsd =
1418 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1419 tdlsSetupRsp.WMMInfoStation.acbe_uapsd =
1420 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1421 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
1422 eSIR_SUCCESS)
1423 lim_log(pMac, LOGE,
1424 FL("could not retrieve Max SP Length"));
1425 tdlsSetupRsp.WMMInfoStation.max_sp_length = (uint8_t) val;
1426 tdlsSetupRsp.WMMInfoStation.present = 1;
1427 } else {
1428 /*
1429 * TODO: we need to see if we have to support conditions where
1430 * we have EDCA parameter info element is needed a) if we need
1431 * different QOS parameters for off channel operations or QOS
1432 * is not supported on AP link and we wanted to QOS on direct
1433 * link.
1434 */
1435 /* Populate QOS info, needed for Peer U-APSD session */
1436 /*
1437 * TODO: Now hardcoded, because
1438 * populate_dot11f_qos_caps_station() depends on AP's
1439 * capability, and TDLS doesn't want to depend on AP's
1440 * capability
1441 */
1442 lim_log(pMac, LOG1,
1443 FL("populate QOS IE in Setup Response frame"));
1444 tdlsSetupRsp.QOSCapsStation.present = 1;
1445 tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
1446 tdlsSetupRsp.QOSCapsStation.qack = 0;
1447 tdlsSetupRsp.QOSCapsStation.acbe_uapsd =
1448 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1449 tdlsSetupRsp.QOSCapsStation.acbk_uapsd =
1450 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1451 tdlsSetupRsp.QOSCapsStation.acvi_uapsd =
1452 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1453 tdlsSetupRsp.QOSCapsStation.acvo_uapsd =
1454 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1455 }
1456
1457 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
1458
1459 /* Populate HT/VHT Capabilities */
1460 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
1461 &tdlsSetupRsp.VHTCaps, psessionEntry);
1462
1463 /* Populate AID */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001464 populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 &tdlsSetupRsp.AID, psessionEntry);
1466
1467 /* Populate TDLS offchannel param only if offchannel is enabled
1468 * and TDLS Channel Switching is not prohibited by AP in ExtCap
1469 * IE in assoc/re-assoc response.
1470 */
1471 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
1472 (!psessionEntry->tdls_chan_swit_prohibited)) {
1473 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
1474 &tdlsSetupRsp.SuppChannels,
1475 &tdlsSetupRsp.
1476 SuppOperatingClasses);
1477 if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
1478 tdlsSetupRsp.ht2040_bss_coexistence.present = 1;
1479 tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1;
1480 }
1481 } else {
1482 lim_log(pMac, LOG1,
1483 FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
1484 pMac->lim.gLimTDLSOffChannelEnabled,
1485 psessionEntry->tdls_chan_swit_prohibited);
1486 }
1487 tdlsSetupRsp.Status.status = setupStatus;
1488 /*
1489 * now we pack it. First, how much space are we going to need?
1490 */
1491 status = dot11f_get_packed_tdls_setup_rsp_size(pMac, &tdlsSetupRsp,
1492 &nPayload);
1493 if (DOT11F_FAILED(status)) {
1494 lim_log(pMac, LOGE,
1495 FL(
1496 "Failed to calculate the packed size for a Setup Response (0x%08x)."
1497 ),
1498 status);
1499 /* We'll fall back on the worst case scenario: */
1500 nPayload = sizeof(tDot11fProbeRequest);
1501 } else if (DOT11F_WARNED(status)) {
1502 lim_log(pMac, LOGW,
1503 FL(
1504 "There were warnings while calculating the packed size for Setup Response (0x%08x)."
1505 ),
1506 status);
1507 }
1508
1509 /*
1510 * This frame is going out from PE as data frames with special ethertype
1511 * 89-0d.
1512 * 8 bytes of RFC 1042 header
1513 */
1514
1515 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1516 ? sizeof(tSirMacDataHdr3a) :
1517 sizeof(tSirMacMgmtHdr))
1518 + sizeof(eth_890d_header)
1519 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1520
1521 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301522 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301524 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 lim_log(pMac, LOGE,
1526 FL(
1527 "Failed to allocate %d bytes for a TDLS Setup Response."
1528 ),
1529 nBytes);
1530 return eSIR_MEM_ALLOC_FAILED;
1531 }
1532
1533 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301534 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535
1536 /*
1537 * IE formation, memory allocation is completed, Now form TDLS discovery
1538 * request frame
1539 */
1540
1541 /* fill out the buffer descriptor */
1542
1543 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1544 LINK_IDEN_ADDR_OFFSET
1545 (tdlsSetupRsp), TDLS_LINK_AP,
Pradeep Reddy POTTETI8226a1d2015-11-04 14:40:51 +05301546 TDLS_RESPONDER, TID_AC_VI,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 psessionEntry);
1548
1549 lim_log(pMac, LOG1,
1550 FL(
1551 "SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"
1552 ),
1553 tdlsSetupRsp.VHTCaps.supportedChannelWidthSet,
1554 tdlsSetupRsp.VHTCaps.rxMCSMap,
1555 tdlsSetupRsp.VHTCaps.txMCSMap,
1556 tdlsSetupRsp.VHTCaps.txSupDataRate);
1557 status = dot11f_pack_tdls_setup_rsp(pMac, &tdlsSetupRsp,
1558 pFrame + header_offset,
1559 nPayload, &nPayload);
1560
1561 if (DOT11F_FAILED(status)) {
1562 lim_log(pMac, LOGE,
1563 FL("Failed to pack a TDLS Setup Response (0x%08x)."),
1564 status);
1565 cds_packet_free((void *)pPacket);
1566 return eSIR_FAILURE;
1567 } else if (DOT11F_WARNED(status)) {
1568 lim_log(pMac, LOGW,
1569 FL(
1570 "There were warnings while packing TDLS Setup Response (0x%08x)."
1571 ),
1572 status);
1573 }
1574 /* Copy the additional IE. */
1575 /* TODO : addIe is added at the end of the frame. This means it doesnt */
1576 /* follow the order. This should be ok, but we should consider changing this */
1577 /* if there is any IOT issue. */
1578 if (addIeLen != 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301579 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 addIeLen);
1581 }
1582
1583 lim_log(pMac, LOG1,
1584 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
1585 SIR_MAC_TDLS_SETUP_RSP,
1586 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_RSP),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001587 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001588
1589 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
1590
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301591 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 TXRX_FRM_802_11_DATA,
1593 ANI_TXDIR_TODS,
Pradeep Reddy POTTETI8226a1d2015-11-04 14:40:51 +05301594 TID_AC_VI,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595 lim_tx_complete, pFrame,
1596 lim_mgmt_tx_complete,
1597 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
1598 smeSessionId, false, 0);
1599
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301600 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601 pMac->lim.mgmtFrameSessionId = 0xff;
1602 lim_log(pMac, LOGE,
1603 FL("could not send TDLS Dis Request frame!"));
1604 return eSIR_FAILURE;
1605 }
1606
1607 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001608}
1609
1610/*
1611 * Send TDLS setup CNF frame on AP link
1612 */
1613
1614tSirRetStatus lim_send_tdls_link_setup_cnf_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301615 struct qdf_mac_addr peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 uint8_t dialog,
1617 uint32_t peerCapability,
1618 tpPESession psessionEntry,
1619 uint8_t *addIe, uint16_t addIeLen)
1620{
1621 tDot11fTDLSSetupCnf tdlsSetupCnf;
1622 uint32_t status = 0;
1623 uint32_t nPayload = 0;
1624 uint32_t nBytes = 0;
1625 uint32_t header_offset = 0;
1626 uint8_t *pFrame;
1627 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301628 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1630 uint32_t padLen = 0;
1631#endif
1632 uint8_t smeSessionId = 0;
1633
1634 /*
1635 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1636 * and then hand it off to 'dot11f_pack_probe_request' (for
1637 * serialization). We start by zero-initializing the structure:
1638 */
1639 smeSessionId = psessionEntry->smeSessionId;
1640
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301641 qdf_mem_set((uint8_t *) &tdlsSetupCnf, sizeof(tDot11fTDLSSetupCnf), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642
1643 /*
1644 * setup Fixed fields,
1645 */
1646 tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
1647 tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF;
1648 tdlsSetupCnf.DialogToken.token = dialog;
1649
1650 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001651 &tdlsSetupCnf.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 TDLS_INITIATOR);
1653 /*
1654 * TODO: we need to see if we have to support conditions where we have
1655 * EDCA parameter info element is needed a) if we need different QOS
1656 * parameters for off channel operations or QOS is not supported on
1657 * AP link and we wanted to QOS on direct link.
1658 */
1659
1660 /* Check self and peer WMM capable */
1661 if ((1 == pMac->lim.gLimTDLSWmmMode) &&
1662 (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) {
1663 lim_log(pMac, LOG1, FL("populate WMM praram in Setup Confirm"));
1664 populate_dot11f_wmm_params(pMac, &tdlsSetupCnf.WMMParams,
1665 psessionEntry);
1666 }
1667
1668 /* Check peer is VHT capable */
1669 if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) {
1670 populate_dot11f_vht_operation(pMac,
1671 psessionEntry,
1672 &tdlsSetupCnf.VHTOperation);
1673 populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
1674 } else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) { /* Check peer is HT capable */
1675 populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
1676 }
1677
1678 /*
1679 * now we pack it. First, how much space are we going to need?
1680 */
1681 status = dot11f_get_packed_tdls_setup_cnf_size(pMac, &tdlsSetupCnf,
1682 &nPayload);
1683 if (DOT11F_FAILED(status)) {
1684 lim_log(pMac, LOGE,
1685 FL(
1686 "Failed to calculate the packed size for a Setup Confirm (0x%08x)."
1687 ),
1688 status);
1689 /* We'll fall back on the worst case scenario: */
1690 nPayload = sizeof(tDot11fProbeRequest);
1691 } else if (DOT11F_WARNED(status)) {
1692 lim_log(pMac, LOGW,
1693 FL(
1694 "There were warnings while calculating the packed size for Setup Confirm (0x%08x)."
1695 ),
1696 status);
1697 }
1698
1699 /*
1700 * This frame is going out from PE as data frames with special ethertype
1701 * 89-0d.
1702 * 8 bytes of RFC 1042 header
1703 */
1704
1705 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1706 ? sizeof(tSirMacDataHdr3a) :
1707 sizeof(tSirMacMgmtHdr))
1708 + sizeof(eth_890d_header)
1709 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1710
1711#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1712 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1713 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1714 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1715 */
1716 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
1717 padLen =
1718 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
1719
1720 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1721 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1722 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1723
1724 nBytes += padLen;
1725 }
1726#endif
1727
1728 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301729 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301731 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 lim_log(pMac, LOGE,
1733 FL(
1734 "Failed to allocate %d bytes for a TDLS Setup Confirm."
1735 ),
1736 nBytes);
1737 return eSIR_MEM_ALLOC_FAILED;
1738 }
1739
1740 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301741 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742
1743 /*
1744 * IE formation, memory allocation is completed, Now form TDLS discovery
1745 * request frame
1746 */
1747
1748 /* fill out the buffer descriptor */
1749
1750 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1751 LINK_IDEN_ADDR_OFFSET
1752 (tdlsSetupCnf), TDLS_LINK_AP,
1753 TDLS_INITIATOR, TID_AC_VI,
1754 psessionEntry);
1755
1756 status = dot11f_pack_tdls_setup_cnf(pMac, &tdlsSetupCnf, pFrame
1757 + header_offset, nPayload, &nPayload);
1758
1759 if (DOT11F_FAILED(status)) {
1760 lim_log(pMac, LOGE,
1761 FL("Failed to pack a TDLS discovery req (0x%08x)."),
1762 status);
1763 cds_packet_free((void *)pPacket);
1764 return eSIR_FAILURE;
1765 } else if (DOT11F_WARNED(status)) {
1766 lim_log(pMac, LOGW,
1767 FL(
1768 "There were warnings while packing TDLS Discovery Request (0x%08x)."
1769 ),
1770 status);
1771 }
1772 /* Copy the additional IE. */
1773 /* TODO : addIe is added at the end of the frame. This means it doesnt */
1774 /* follow the order. This should be ok, but we should consider changing this */
1775 /* if there is any IOT issue. */
1776 if (addIeLen != 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301777 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778 addIeLen);
1779 }
1780#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1781 if (padLen != 0) {
1782 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1783 uint8_t *padVendorSpecific =
1784 pFrame + header_offset + nPayload + addIeLen;
1785 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1786 padVendorSpecific[0] = 221;
1787 padVendorSpecific[1] = padLen - 2;
1788 padVendorSpecific[2] = 0x00;
1789 padVendorSpecific[3] = 0xA0;
1790 padVendorSpecific[4] = 0xC6;
1791
1792 lim_log(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"),
1793 padLen);
1794
1795 /* padding zero if more than 5 bytes are required */
1796 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301797 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001798 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
1799 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
1800 }
1801#endif
1802
1803 lim_log(pMac, LOG1,
1804 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
1805 SIR_MAC_TDLS_SETUP_CNF,
1806 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_CNF),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001807 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808
1809 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
1810
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301811 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 TXRX_FRM_802_11_DATA,
1813 ANI_TXDIR_TODS,
1814 TID_AC_VI,
1815 lim_tx_complete, pFrame,
1816 lim_mgmt_tx_complete,
1817 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
1818 smeSessionId, false, 0);
1819
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301820 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001821 pMac->lim.mgmtFrameSessionId = 0xff;
1822 lim_log(pMac, LOGE,
1823 FL("could not send TDLS Setup Confirm frame"));
1824 return eSIR_FAILURE;
1825
1826 }
1827
1828 return eSIR_SUCCESS;
1829}
1830
1831/* This Function is similar to populate_dot11f_ht_caps, except that the HT Capabilities
1832 * are considered from the AddStaReq rather from the cfg.dat as in populate_dot11f_ht_caps
1833 */
1834static tSirRetStatus lim_tdls_populate_dot11f_ht_caps(tpAniSirGlobal pMac,
1835 tpPESession psessionEntry,
1836 tSirTdlsAddStaReq *
1837 pTdlsAddStaReq,
1838 tDot11fIEHTCaps *pDot11f)
1839{
1840 uint32_t nCfgValue;
1841 uint8_t nCfgValue8;
1842 tSirMacHTParametersInfo *pHTParametersInfo;
1843 union {
1844 uint16_t nCfgValue16;
1845 tSirMacHTCapabilityInfo htCapInfo;
1846 tSirMacExtendedHTCapabilityInfo extHtCapInfo;
1847 } uHTCapabilityInfo;
1848
1849 tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
1850 tSirMacASCapabilityInfo *pASCapabilityInfo;
1851
1852 nCfgValue = pTdlsAddStaReq->htCap.capInfo;
1853
1854 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
1855
1856 pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap;
1857 pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
1858 pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField;
1859 pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz;
1860 pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz;
1861 pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC;
1862 pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC;
1863 pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA;
1864 pDot11f->maximalAMSDUsize =
1865 uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
1866 pDot11f->dsssCckMode40MHz =
1867 uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
1868 pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp;
1869 pDot11f->stbcControlFrame =
1870 uHTCapabilityInfo.htCapInfo.stbcControlFrame;
1871 pDot11f->lsigTXOPProtection =
1872 uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;
1873
1874 /*
1875 * All sessionized entries will need the check below
1876 * Only in case of NO session
1877 */
1878 if (psessionEntry == NULL) {
1879 pDot11f->supportedChannelWidthSet =
1880 uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet;
1881 } else {
1882 pDot11f->supportedChannelWidthSet =
1883 psessionEntry->htSupportedChannelWidthSet;
1884 }
1885
1886 /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
1887 eHT_CHANNEL_WIDTH_20MHZ */
1888 if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
1889 pDot11f->shortGI40MHz = 0;
1890 }
1891
1892 lim_log(pMac, LOG1,
1893 FL(
1894 "SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d"
1895 ),
1896 pDot11f->supportedChannelWidthSet,
1897 pDot11f->mimoPowerSave,
1898 pDot11f->greenField,
1899 pDot11f->shortGI20MHz,
1900 pDot11f->shortGI40MHz,
1901 pDot11f->dsssCckMode40MHz);
1902
1903 nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo;
1904
1905 nCfgValue8 = (uint8_t) nCfgValue;
1906 pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;
1907
1908 pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
1909 pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
1910 pDot11f->reserved1 = pHTParametersInfo->reserved;
1911
1912 lim_log(pMac, LOG1, FL("AMPDU Param: %x"), nCfgValue);
1913
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301914 qdf_mem_copy(pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001915 SIZE_OF_SUPPORTED_MCS_SET);
1916
1917 nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;
1918
1919 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
1920
1921 pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
1922 pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
1923 pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
1924
1925 nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;
1926
1927 pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
1928 pDot11f->txBF = pTxBFCapabilityInfo->txBF;
1929 pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
1930 pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
1931 pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
1932 pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
1933 pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
1934 pDot11f->calibration = pTxBFCapabilityInfo->calibration;
1935 pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
1936 pDot11f->explicitUncompressedSteeringMatrix =
1937 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
1938 pDot11f->explicitBFCSIFeedback =
1939 pTxBFCapabilityInfo->explicitBFCSIFeedback;
1940 pDot11f->explicitUncompressedSteeringMatrixFeedback =
1941 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
1942 pDot11f->explicitCompressedSteeringMatrixFeedback =
1943 pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
1944 pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
1945 pDot11f->uncompressedSteeringMatrixBFAntennae =
1946 pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
1947 pDot11f->compressedSteeringMatrixBFAntennae =
1948 pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
1949
1950 nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo;
1951
1952 nCfgValue8 = (uint8_t) nCfgValue;
1953
1954 pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
1955 pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
1956 pDot11f->explicitCSIFeedbackTx =
1957 pASCapabilityInfo->explicitCSIFeedbackTx;
1958 pDot11f->antennaIndicesFeedbackTx =
1959 pASCapabilityInfo->antennaIndicesFeedbackTx;
1960 pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
1961 pDot11f->antennaIndicesFeedback =
1962 pASCapabilityInfo->antennaIndicesFeedback;
1963 pDot11f->rxAS = pASCapabilityInfo->rxAS;
1964 pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
1965
1966 pDot11f->present = pTdlsAddStaReq->htcap_present;
1967
1968 return eSIR_SUCCESS;
1969
1970}
1971
1972tSirRetStatus
1973lim_tdls_populate_dot11f_vht_caps(tpAniSirGlobal pMac,
1974 tSirTdlsAddStaReq *pTdlsAddStaReq,
1975 tDot11fIEVHTCaps *pDot11f)
1976{
1977 uint32_t nCfgValue = 0;
1978 union {
1979 uint32_t nCfgValue32;
1980 tSirMacVHTCapabilityInfo vhtCapInfo;
1981 } uVHTCapabilityInfo;
1982 union {
1983 uint16_t nCfgValue16;
1984 tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
1985 tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
1986 } uVHTSupDataRateInfo;
1987
1988 pDot11f->present = pTdlsAddStaReq->vhtcap_present;
1989
1990 nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
1991 uVHTCapabilityInfo.nCfgValue32 = nCfgValue;
1992
1993 pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
1994 pDot11f->supportedChannelWidthSet =
1995 uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
1996 pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
1997 pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
1998 pDot11f->shortGI160and80plus80MHz =
1999 uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
2000 pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
2001 pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
2002 pDot11f->suBeamFormerCap = 0;
2003 pDot11f->suBeamformeeCap = 0;
2004 pDot11f->csnofBeamformerAntSup =
2005 uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
2006 pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
2007 pDot11f->muBeamformerCap = 0;
2008 pDot11f->muBeamformeeCap = 0;
2009 pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
2010 pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
2011 pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
2012 pDot11f->vhtLinkAdaptCap =
2013 uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
2014 pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
2015 pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
2016 pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1;
2017
2018 pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;
2019
2020 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
2021 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2022 pDot11f->rxHighSupDataRate =
2023 uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;
2024
2025 pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;
2026
2027 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
2028 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2029 pDot11f->txSupDataRate =
2030 uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;
2031
2032 pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;
2033
2034 lim_log_vht_cap(pMac, pDot11f);
2035
2036 return eSIR_SUCCESS;
2037
2038}
2039
2040/**
2041 * lim_tdls_populate_matching_rate_set() - populate matching rate set
2042 *
2043 * @mac_ctx - global MAC context
2044 * @stads - station hash entry
2045 * @supp_rate_set - pointer to supported rate set
2046 * @supp_rates_len - length of the supported rates
2047 * @supp_mcs_set - pointer to supported MSC set
2048 * @session_entry - pointer to PE session entry
2049 * @vht_caps - pointer to VHT capability
2050 *
2051 *
2052 * This function gets set of available rates from the config and compare them
2053 * against the set of received supported rates. After the comparison station
2054 * entry's rates is populated with 11A rates and 11B rates.
2055 *
2056 * Return: eSIR_SUCCESS on success, eSIR_FAILURE on failure.
2057 */
2058static tSirRetStatus
2059lim_tdls_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode stads,
2060 uint8_t *supp_rate_set,
2061 uint8_t supp_rates_len,
2062 uint8_t *supp_mcs_set,
2063 tpPESession session_entry,
2064 tDot11fIEVHTCaps *vht_caps)
2065{
2066 tSirMacRateSet temp_rate_set;
2067 uint32_t i, j, val, min, is_a_rate;
2068 tSirMacRateSet temp_rate_set2;
2069 uint32_t phymode;
2070 uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
2071 tpSirSupportedRates rates;
2072 uint8_t a_rateindex = 0;
2073 uint8_t b_rateindex = 0;
2074 is_a_rate = 0;
2075 temp_rate_set2.numRates = 0;
2076
2077 lim_get_phy_mode(mac_ctx, &phymode, NULL);
2078
2079 /* get own rate set */
2080 val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
2081 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_OPERATIONAL_RATE_SET,
2082 (uint8_t *) &temp_rate_set.rate,
2083 &val) != eSIR_SUCCESS) {
2084 /* Could not get rateset from CFG. Log error. */
2085 lim_log(mac_ctx, LOGE, FL("could not retrieve rateset"));
2086 val = 0;
2087 }
2088 temp_rate_set.numRates = val;
2089
2090 if (phymode == WNI_CFG_PHY_MODE_11G) {
2091 /* get own extended rate set */
2092 val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
2093 if (wlan_cfg_get_str(mac_ctx,
2094 WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
2095 (uint8_t *) &temp_rate_set2.rate,
2096 &val) != eSIR_SUCCESS)
2097 temp_rate_set2.numRates = val;
2098 }
2099
2100 if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
2101 lim_log(mac_ctx, LOGE, FL("more than 12 rates in CFG"));
Kiran Kumar Lokere9a733a72016-02-17 19:01:15 -08002102 return eSIR_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103 }
2104
2105 /**
2106 * Handling of the rate set IEs is the following:
2107 * - keep only rates that we support and that the station supports
2108 * - sort and the rates into the pSta->rate array
2109 */
2110
2111 /* Copy all rates in temp_rate_set, there are 12 rates max */
2112 for (i = 0; i < temp_rate_set2.numRates; i++)
2113 temp_rate_set.rate[i + temp_rate_set.numRates] =
2114 temp_rate_set2.rate[i];
2115
2116 temp_rate_set.numRates += temp_rate_set2.numRates;
2117
2118 /**
2119 * Sort rates in temp_rate_set (they are likely to be already sorted)
2120 * put the result in temp_rate_set2
2121 */
2122 temp_rate_set2.numRates = 0;
2123
2124 for (i = 0; i < temp_rate_set.numRates; i++) {
2125 min = 0;
2126 val = 0xff;
2127
2128 for (j = 0; j < temp_rate_set.numRates; j++)
2129 if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
2130 val = temp_rate_set.rate[j] & 0x7f;
2131 min = j;
2132 }
2133
2134 temp_rate_set2.rate[temp_rate_set2.numRates++] =
2135 temp_rate_set.rate[min];
2136 temp_rate_set.rate[min] = 0xff;
2137 }
2138
2139 /**
2140 * Copy received rates in temp_rate_set, the parser has ensured
2141 * unicity of the rates so there cannot be more than 12 .
2142 */
2143 if (supp_rates_len > SIR_MAC_RATESET_EID_MAX) {
2144 lim_log(mac_ctx, LOGW,
2145 FL(
2146 "Supported rates length %d more than the Max limit, reset to Max"
2147 ),
2148 supp_rates_len);
2149 supp_rates_len = SIR_MAC_RATESET_EID_MAX;
2150 }
2151
2152 for (i = 0; i < supp_rates_len; i++)
2153 temp_rate_set.rate[i] = supp_rate_set[i];
2154
2155 temp_rate_set.numRates = supp_rates_len;
2156
2157 rates = &stads->supportedRates;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302158 qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002159
2160 for (i = 0; i < temp_rate_set2.numRates; i++) {
2161 for (j = 0; j < temp_rate_set.numRates; j++) {
2162 if ((temp_rate_set2.rate[i] & 0x7F) !=
2163 (temp_rate_set.rate[j] & 0x7F))
2164 continue;
2165
Sushant Kaushikb50010f2015-07-22 12:22:20 +05302166 if ((b_rateindex > SIR_NUM_11B_RATES) ||
2167 (a_rateindex > SIR_NUM_11A_RATES)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002168 lim_log(mac_ctx, LOGE,
2169 FL("Invalid number of rates (11b->%d, 11a->%d)"),
2170 b_rateindex, a_rateindex);
2171 return eSIR_FAILURE;
2172 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002173 if (sirIsArate(temp_rate_set2.rate[i] & 0x7f)) {
2174 is_a_rate = 1;
2175 if (a_rateindex < SIR_NUM_11A_RATES)
2176 rates->llaRates[a_rateindex++] = temp_rate_set2.rate[i];
2177 } else {
2178 if (b_rateindex < SIR_NUM_11B_RATES)
2179 rates->llbRates[b_rateindex++] = temp_rate_set2.rate[i];
2180 }
2181 break;
2182 }
2183 }
2184
2185 /* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */
2186#ifdef FEATURE_WLAN_TDLS
2187 if (stads->mlmStaContext.htCapability)
2188#else
2189 if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
2190 (stads->mlmStaContext.htCapability))
2191#endif
2192 {
2193 val = SIZE_OF_SUPPORTED_MCS_SET;
2194 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
2195 mcsSet, &val) != eSIR_SUCCESS) {
2196 /* Could not get rateset from CFG. Log error. */
2197 lim_log(mac_ctx, LOGP,
2198 FL("could not retrieve supportedMCSSet"));
Kiran Kumar Lokere9a733a72016-02-17 19:01:15 -08002199 return eSIR_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 }
2201
2202 for (i = 0; i < val; i++)
2203 stads->supportedRates.supportedMCSSet[i] =
2204 mcsSet[i] & supp_mcs_set[i];
2205
2206 lim_log(mac_ctx, LOG1,
2207 FL("MCS Rate Set Bitmap from CFG and DPH"));
2208 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
2209 lim_log(mac_ctx, LOG1, FL("%x %x"), mcsSet[i],
2210 stads->supportedRates.supportedMCSSet[i]);
2211 }
2212 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213 lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps,
2214 session_entry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 /**
2216 * Set the erpEnabled bit if the phy is in G mode and at least
2217 * one A rate is supported
2218 */
2219 if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate)
2220 stads->erpEnabled = eHAL_SET;
2221
2222 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223}
2224
2225/*
2226 * update HASH node entry info
2227 */
2228static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
2229 tDphHashNode *pStaDs,
2230 tSirTdlsAddStaReq *pTdlsAddStaReq,
2231 tpPESession psessionEntry)
2232{
2233 tDot11fIEHTCaps htCap = {0,};
2234 tDot11fIEHTCaps *htCaps;
2235 tDot11fIEVHTCaps *pVhtCaps = NULL;
2236 tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237 tDot11fIEVHTCaps vhtCap;
2238 uint8_t cbMode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002239 tpDphHashNode pSessStaDs = NULL;
2240 uint16_t aid;
2241
2242 if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
2243 populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
2244 } else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) {
2245 lim_tdls_populate_dot11f_ht_caps(pMac, NULL, pTdlsAddStaReq, &htCap);
2246 }
2247 htCaps = &htCap;
2248 if (htCaps->present) {
2249 pStaDs->mlmStaContext.htCapability = 1;
2250 pStaDs->htGreenfield = htCaps->greenField;
Naveen Rawat3e8322c2015-11-03 11:05:57 -08002251 /*
2252 * pStaDs->htSupportedChannelWidthSet should have the base
2253 * channel capability. The htSupportedChannelWidthSet of the
2254 * TDLS link on base channel should be less than or equal to
2255 * channel width of STA-AP link. So take this setting from the
2256 * psessionEntry.
2257 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002258 pStaDs->htSupportedChannelWidthSet =
Naveen Rawat3e8322c2015-11-03 11:05:57 -08002259 psessionEntry->htSupportedChannelWidthSet;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002260 pStaDs->htMIMOPSState = htCaps->mimoPowerSave;
2261 pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
2262 pStaDs->htAMpduDensity = htCaps->mpduDensity;
2263 pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz;
2264 pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
2265 pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
2266 pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
2267 lim_fill_rx_highest_supported_rate(pMac,
2268 &pStaDs->supportedRates.
2269 rxHighestDataRate,
2270 htCaps->supportedMCSSet);
2271 pStaDs->baPolicyFlag = 0xFF;
2272 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N;
2273 pStaDs->ht_caps = pTdlsAddStaReq->htCap.capInfo;
2274 } else {
2275 pStaDs->mlmStaContext.htCapability = 0;
2276 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG;
2277 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002278 lim_tdls_populate_dot11f_vht_caps(pMac, pTdlsAddStaReq, &vhtCap);
2279 pVhtCaps = &vhtCap;
2280 if (pVhtCaps->present) {
2281 pStaDs->mlmStaContext.vhtCapability = 1;
2282
2283 if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) {
2284 /*
2285 * if the channel is 2G then update the min channel
2286 * widthset in pStaDs. These values are used when
2287 * sending a AddSta request to firmware
2288 * 11.21.1 General: The channel width of the TDLS direct
2289 * link on the base channel shall not exceed the channel
2290 * width of the BSS to which the TDLS peer STAs are
2291 * associated.
2292 */
2293 pStaDs->vhtSupportedChannelWidthSet =
2294 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
2295 pStaDs->htSupportedChannelWidthSet =
2296 eHT_CHANNEL_WIDTH_20MHZ;
2297 lim_log(pMac, LOG1, FL("vhtSupportedChannelWidthSet = %hu, htSupportedChannelWidthSet %hu"),
2298 pStaDs->htSupportedChannelWidthSet,
2299 pStaDs->htSupportedChannelWidthSet);
2300 } else {
2301 pStaDs->vhtSupportedChannelWidthSet =
2302 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
2303 pStaDs->htSupportedChannelWidthSet =
2304 eHT_CHANNEL_WIDTH_40MHZ;
2305 }
2306
2307 pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
2308 pStaDs->vhtBeamFormerCapable = 0;
2309 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
2310 pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&pTdlsAddStaReq->vhtCap);
2311 pVhtCaps_txbf->suBeamformeeCap = 0;
2312 pVhtCaps_txbf->suBeamFormerCap = 0;
2313 pVhtCaps_txbf->muBeamformerCap = 0;
2314 pVhtCaps_txbf->muBeamformeeCap = 0;
2315 pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo;
2316 } else {
2317 pStaDs->mlmStaContext.vhtCapability = 0;
2318 pStaDs->vhtSupportedChannelWidthSet =
2319 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
2320 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002321 /*Calculate the Secondary Coannel Offset */
2322 cbMode = lim_select_cb_mode(pStaDs, psessionEntry,
2323 psessionEntry->currentOperChannel,
2324 pStaDs->vhtSupportedChannelWidthSet);
2325
2326 pStaDs->htSecondaryChannelOffset = cbMode;
2327
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002328 if (pStaDs->mlmStaContext.vhtCapability) {
2329 pStaDs->htSecondaryChannelOffset = lim_get_htcb_state(cbMode);
2330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002331 pSessStaDs = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
2332 &psessionEntry->dph.dphHashTable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 /* Lets enable QOS parameter */
2334 pStaDs->qosMode = 1;
2335 pStaDs->wmeEnabled = 1;
2336 pStaDs->lleEnabled = 0;
2337 /* TDLS Dummy AddSTA does not have qosInfo , is it OK ??
2338 */
2339 pStaDs->qos.capability.qosInfo =
2340 (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);
2341
2342 /* populate matching rate set */
2343
2344 /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
2345 */
2346 lim_tdls_populate_matching_rate_set(pMac, pStaDs,
2347 pTdlsAddStaReq->supported_rates,
2348 pTdlsAddStaReq->supported_rates_length,
2349 (uint8_t *) pTdlsAddStaReq->htCap.
2350 suppMcsSet, psessionEntry, pVhtCaps);
2351
2352 /* TDLS Dummy AddSTA does not have right capability , is it OK ??
2353 */
2354 pStaDs->mlmStaContext.capabilityInfo =
2355 (*(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);
2356
2357 return;
2358}
2359
2360/*
2361 * Add STA for TDLS setup procedure
2362 */
2363static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
2364 tSirTdlsAddStaReq *pAddStaReq,
2365 tpPESession psessionEntry)
2366{
2367 tpDphHashNode pStaDs = NULL;
2368 tSirRetStatus status = eSIR_SUCCESS;
2369 uint16_t aid = 0;
2370
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002371 pStaDs = dph_lookup_hash_entry(pMac, pAddStaReq->peermac.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 &psessionEntry->dph.dphHashTable);
2373 if (NULL == pStaDs) {
2374 aid = lim_assign_peer_idx(pMac, psessionEntry);
2375
2376 if (!aid) {
2377 lim_log(pMac, LOGE,
2378 FL("No more free AID for peer "
2379 MAC_ADDRESS_STR),
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002380 MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 return eSIR_FAILURE;
2382 }
2383
2384 /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
2385 SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
2386
2387 lim_log(pMac, LOG1, FL("Aid = %d, for peer =" MAC_ADDRESS_STR),
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002388 aid, MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002389 pStaDs =
2390 dph_get_hash_entry(pMac, aid,
2391 &psessionEntry->dph.dphHashTable);
2392
2393 if (pStaDs) {
2394 (void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
2395 psessionEntry);
2396 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, aid,
2397 psessionEntry);
2398 }
2399
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002400 pStaDs = dph_add_hash_entry(pMac, pAddStaReq->peermac.bytes,
2401 aid, &psessionEntry->dph.dphHashTable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402
2403 if (NULL == pStaDs) {
2404 lim_log(pMac, LOGE, FL("add hash entry failed"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302405 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002406 return eSIR_FAILURE;
2407 }
2408 }
2409
2410 lim_tdls_update_hash_node_info(pMac, pStaDs, pAddStaReq, psessionEntry);
2411
2412 pStaDs->staType = STA_ENTRY_TDLS_PEER;
2413
2414 status =
2415 lim_add_sta(pMac, pStaDs,
2416 (pAddStaReq->tdlsAddOper ==
2417 TDLS_OPER_UPDATE) ? true : false, psessionEntry);
2418
2419 if (eSIR_SUCCESS != status) {
2420 /* should not fail */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302421 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002422 }
2423 return status;
2424}
2425
2426/*
2427 * Del STA, after Link is teardown or discovery response sent on direct link
2428 */
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002429static tpDphHashNode lim_tdls_del_sta(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302430 struct qdf_mac_addr peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002431 tpPESession psessionEntry)
2432{
2433 tSirRetStatus status = eSIR_SUCCESS;
2434 uint16_t peerIdx = 0;
2435 tpDphHashNode pStaDs = NULL;
2436
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002437 pStaDs = dph_lookup_hash_entry(pMac, peerMac.bytes, &peerIdx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002438 &psessionEntry->dph.dphHashTable);
2439
2440 if (pStaDs) {
2441
2442 lim_log(pMac, LOG1, FL("DEL STA peer MAC: "MAC_ADDRESS_STR),
2443 MAC_ADDR_ARRAY(pStaDs->staAddr));
2444
2445 lim_log(pMac, LOG1, FL("STA type = %x, sta idx = %x"),
2446 pStaDs->staType,
2447 pStaDs->staIndex);
2448
2449 status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
2450 }
2451
2452 return pStaDs;
2453}
2454
2455/*
2456 * Once Link is setup with PEER, send Add STA ind to SME
2457 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302458static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459 uint8_t sessionId,
2460 tSirMacAddr peerMac,
2461 uint8_t updateSta,
2462 tDphHashNode *pStaDs, uint8_t status)
2463{
2464 tSirMsgQ mmhMsg = { 0 };
2465 tSirTdlsAddStaRsp *addStaRsp = NULL;
2466 mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP;
2467
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302468 addStaRsp = qdf_mem_malloc(sizeof(tSirTdlsAddStaRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 if (NULL == addStaRsp) {
2470 lim_log(pMac, LOGE, FL("Failed to allocate memory"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302471 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472 }
2473
2474 addStaRsp->sessionId = sessionId;
2475 addStaRsp->statusCode = status;
2476 if (pStaDs) {
2477 addStaRsp->staId = pStaDs->staIndex;
2478 addStaRsp->ucastSig = pStaDs->ucUcastSig;
2479 addStaRsp->bcastSig = pStaDs->ucBcastSig;
2480 }
2481 if (peerMac) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302482 qdf_mem_copy(addStaRsp->peermac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302483 (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002484 }
2485 if (updateSta)
2486 addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
2487 else
2488 addStaRsp->tdlsAddOper = TDLS_OPER_ADD;
2489
2490 addStaRsp->length = sizeof(tSirTdlsAddStaRsp);
2491 addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP;
2492
2493 mmhMsg.bodyptr = addStaRsp;
2494 mmhMsg.bodyval = 0;
2495 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2496
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302497 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002498}
2499
2500/*
2501 * STA RSP received from HAL
2502 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302503QDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002504 tpPESession psessionEntry)
2505{
2506 tAddStaParams *pAddStaParams = (tAddStaParams *) msg;
2507 uint8_t status = eSIR_SUCCESS;
2508 tDphHashNode *pStaDs = NULL;
2509 uint16_t aid = 0;
2510
2511 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2512 lim_log(pMac, LOG1, FL("staIdx=%d, staMac="MAC_ADDRESS_STR),
2513 pAddStaParams->staIdx,
2514 MAC_ADDR_ARRAY(pAddStaParams->staMac));
2515
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302516 if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302517 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002518 lim_log(pMac, LOGE, FL("Add sta failed "));
2519 status = eSIR_FAILURE;
2520 goto add_sta_error;
2521 }
2522
2523 pStaDs = dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &aid,
2524 &psessionEntry->dph.dphHashTable);
2525 if (NULL == pStaDs) {
2526 lim_log(pMac, LOGE, FL("pStaDs is NULL "));
2527 status = eSIR_FAILURE;
2528 goto add_sta_error;
2529 }
2530
2531 pStaDs->bssId = pAddStaParams->bssIdx;
2532 pStaDs->staIndex = pAddStaParams->staIdx;
2533 pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
2534 pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
2535 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
2536 pStaDs->valid = 1;
2537add_sta_error:
2538 status = lim_send_sme_tdls_add_sta_rsp(pMac, psessionEntry->smeSessionId,
2539 pAddStaParams->staMac,
2540 pAddStaParams->updateSta, pStaDs,
2541 status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302542 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002543 return status;
2544}
2545
2546void populate_dot11f_tdls_offchannel_params(tpAniSirGlobal pMac,
2547 tpPESession psessionEntry,
2548 tDot11fIESuppChannels *suppChannels,
2549 tDot11fIESuppOperatingClasses *
2550 suppOperClasses)
2551{
2552 uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
2553 uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
2554 uint8_t i;
2555 uint8_t valid_count = 0;
2556 uint8_t chanOffset;
2557 uint8_t op_class;
2558 uint8_t numClasses;
Naveen Rawat3b6068c2016-04-14 19:01:06 -07002559 uint8_t classes[CDS_MAX_SUPP_OPER_CLASSES];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002560 if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
2561 validChan, &numChans) != eSIR_SUCCESS) {
2562 /**
2563 * Could not get Valid channel list from CFG.
2564 * Log error.
2565 */
2566 lim_log(pMac, LOGE,
2567 FL("could not retrieve Valid channel list"));
2568 return;
2569 }
2570
2571 /* validating the channel list for DFS channels */
2572 for (i = 0U; i < numChans; i++) {
2573 if (CHANNEL_STATE_DFS ==
2574 cds_get_channel_state(validChan[i])) {
2575 lim_log(pMac, LOG1,
2576 FL(
2577 "skipping DFS channel %d from the valid channel list"
2578 ),
2579 validChan[i]);
2580 continue;
2581 }
2582
2583 if (valid_count >= ARRAY_SIZE(suppChannels->bands))
2584 break;
2585 suppChannels->bands[valid_count][0] = validChan[i];
2586 suppChannels->bands[valid_count][1] = 1;
2587 valid_count++;
2588 }
2589
2590 suppChannels->num_bands = valid_count;
2591 suppChannels->present = 1;
2592
2593 /* find channel offset and get op class for current operating channel */
2594 switch (psessionEntry->htSecondaryChannelOffset) {
2595 case PHY_SINGLE_CHANNEL_CENTERED:
2596 chanOffset = BW20;
2597 break;
2598
2599 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
2600 chanOffset = BW40_LOW_PRIMARY;
2601 break;
2602
2603 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
2604 chanOffset = BW40_HIGH_PRIMARY;
2605 break;
2606
2607 default:
2608 chanOffset = BWALL;
2609 break;
2610
2611 }
2612
Amar Singhal22995112016-01-22 10:42:33 -08002613 op_class = cds_reg_dmn_get_opclass_from_channel(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 pMac->scan.countryCodeCurrent,
2615 psessionEntry->currentOperChannel,
2616 chanOffset);
2617
2618 if (op_class == 0) {
2619 lim_log(pMac, LOGE,
2620 FL(
2621 "Present Operating class is wrong, countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d"
2622 ),
2623 pMac->scan.countryCodeCurrent,
2624 psessionEntry->currentOperChannel,
2625 psessionEntry->htSecondaryChannelOffset,
2626 chanOffset);
2627 } else {
2628 lim_log(pMac, LOG1,
2629 FL(
2630 "Present Operating channel: %d chanOffset: %d, op class=%d"
2631 ),
2632 psessionEntry->currentOperChannel, chanOffset,
2633 op_class);
2634 }
2635 suppOperClasses->present = 1;
2636 suppOperClasses->classes[0] = op_class;
2637
Amar Singhal22995112016-01-22 10:42:33 -08002638 cds_reg_dmn_get_curr_opclasses(&numClasses, &classes[0]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002639
2640 for (i = 0; i < numClasses; i++) {
2641 suppOperClasses->classes[i + 1] = classes[i];
2642 }
2643 /* add one for present operating class, added in the beginning */
2644 suppOperClasses->num_classes = numClasses + 1;
2645
2646 return;
2647}
2648
2649/*
2650 * FUNCTION: Populate Link Identifier element IE
2651 *
2652 */
2653
2654void populate_dot11f_link_iden(tpAniSirGlobal pMac, tpPESession psessionEntry,
2655 tDot11fIELinkIdentifier *linkIden,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302656 struct qdf_mac_addr peer_mac, uint8_t reqType)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657{
2658 uint8_t *initStaAddr = NULL;
2659 uint8_t *respStaAddr = NULL;
2660
2661 (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
2662 (respStaAddr = linkIden->RespStaAddr))
2663 : ((respStaAddr = linkIden->InitStaAddr),
2664 (initStaAddr = linkIden->RespStaAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302665 qdf_mem_copy((uint8_t *) linkIden->bssid,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302666 (uint8_t *) psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302668 qdf_mem_copy((uint8_t *) initStaAddr,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302669 psessionEntry->selfMacAddr, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302671 qdf_mem_copy((uint8_t *) respStaAddr, (uint8_t *) peer_mac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302672 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673
2674 linkIden->present = 1;
2675 return;
2676
2677}
2678
2679void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
2680 tpPESession psessionEntry,
2681 tDot11fIEExtCap *extCapability)
2682{
2683 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes;
2684
2685 p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT;
2686 p_ext_cap->tdls_peer_uapsd_buffer_sta = pMac->lim.gLimTDLSBufStaEnabled;
2687
2688 /*
2689 * Set TDLS channel switching bits only if offchannel is enabled
2690 * and TDLS Channel Switching is not prohibited by AP in ExtCap
2691 * IE in assoc/re-assoc response.
2692 */
2693 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
2694 (!psessionEntry->tdls_chan_swit_prohibited)) {
2695 p_ext_cap->tdls_channel_switching = 1;
2696 p_ext_cap->tdls_chan_swit_prohibited = 0;
2697 } else {
2698 p_ext_cap->tdls_channel_switching = 0;
2699 p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED;
2700 }
2701 p_ext_cap->tdls_support = TDLS_SUPPORT;
2702 p_ext_cap->tdls_prohibited = TDLS_PROHIBITED;
2703
2704 extCapability->present = 1;
2705 /* For STA cases we alwasy support 11mc - Allow MAX length */
2706 extCapability->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
2707
2708 return;
2709}
2710
2711/**
2712 * lim_process_sme_tdls_mgmt_send_req() - send out tdls management frames
2713 *
2714 * @mac_ctx - global mac context
2715 * @msg - message buffer received from SME.
2716 *
2717 * Process Send Mgmt Request from SME and transmit to AP.
2718 *
2719 * Return: eSIR_SUCCESS on success, error code otherwise
2720 */
2721tSirRetStatus lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx,
2722 uint32_t *msg)
2723{
2724 /* get all discovery request parameters */
2725 tSirTdlsSendMgmtReq *send_req = (tSirTdlsSendMgmtReq *) msg;
2726 tpPESession session_entry;
2727 uint8_t session_id;
2728 tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS;
2729
2730 lim_log(mac_ctx, LOG1, FL("Send Mgmt Recieved"));
2731 session_entry = pe_find_session_by_bssid(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002732 send_req->bssid.bytes, &session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002733 if (NULL == session_entry) {
2734 lim_log(mac_ctx, LOGE,
2735 FL("PE Session does not exist for given sme session_id %d"),
2736 send_req->sessionId);
2737 goto lim_tdls_send_mgmt_error;
2738 }
2739
2740 /* check if we are in proper state to work as TDLS client */
2741 if (!LIM_IS_STA_ROLE(session_entry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302742 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 FL("send mgmt received in wrong system Role %d"),
2744 GET_LIM_SYSTEM_ROLE(session_entry));
2745 goto lim_tdls_send_mgmt_error;
2746 }
2747
2748 /*
2749 * if we are still good, go ahead and check if we are in proper state to
2750 * do TDLS discovery req/rsp/....frames.
2751 */
2752 if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
2753 (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
2754 lim_log(mac_ctx, LOGE,
2755 FL("send mgmt received in invalid LIMsme state (%d)"),
2756 session_entry->limSmeState);
2757 goto lim_tdls_send_mgmt_error;
2758 }
2759
2760 switch (send_req->reqType) {
2761 case SIR_MAC_TDLS_DIS_REQ:
2762 lim_log(mac_ctx, LOG1, FL("Transmit Discovery Request Frame"));
2763 /* format TDLS discovery request frame and transmit it */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002764 lim_send_tdls_dis_req_frame(mac_ctx, send_req->peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002765 send_req->dialog, session_entry);
2766 result_code = eSIR_SME_SUCCESS;
2767 break;
2768 case SIR_MAC_TDLS_DIS_RSP:
2769 lim_log(mac_ctx, LOG1, FL("Transmit Discovery Response Frame"));
2770 /* Send a response mgmt action frame */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002771 lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002772 send_req->dialog, session_entry, &send_req->addIe[0],
2773 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2774 result_code = eSIR_SME_SUCCESS;
2775 break;
2776 case SIR_MAC_TDLS_SETUP_REQ:
2777 lim_log(mac_ctx, LOG1, FL("Transmit Setup Request Frame"));
2778 lim_send_tdls_link_setup_req_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002779 send_req->peer_mac, send_req->dialog, session_entry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 &send_req->addIe[0],
2781 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2782 result_code = eSIR_SME_SUCCESS;
2783 break;
2784 case SIR_MAC_TDLS_SETUP_RSP:
2785 lim_log(mac_ctx, LOG1, FL("Transmit Setup Response Frame"));
2786 lim_send_tdls_setup_rsp_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002787 send_req->peer_mac, send_req->dialog, session_entry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002788 send_req->statusCode, &send_req->addIe[0],
2789 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2790 result_code = eSIR_SME_SUCCESS;
2791 break;
2792 case SIR_MAC_TDLS_SETUP_CNF:
2793 lim_log(mac_ctx, LOG1, FL("Transmit Setup Confirm Frame"));
2794 lim_send_tdls_link_setup_cnf_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002795 send_req->peer_mac, send_req->dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002796 send_req->peerCapability, session_entry,
2797 &send_req->addIe[0],
2798 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2799 result_code = eSIR_SME_SUCCESS;
2800 break;
2801 case SIR_MAC_TDLS_TEARDOWN:
2802 lim_log(mac_ctx, LOG1, FL("Transmit Teardown Frame"));
2803 lim_send_tdls_teardown_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002804 send_req->peer_mac, send_req->statusCode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002805 send_req->responder, session_entry,
2806 &send_req->addIe[0],
2807 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2808 result_code = eSIR_SME_SUCCESS;
2809 break;
2810 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
2811 break;
2812 case SIR_MAC_TDLS_CH_SWITCH_REQ:
2813 break;
2814 case SIR_MAC_TDLS_CH_SWITCH_RSP:
2815 break;
2816 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
2817 break;
2818 default:
2819 break;
2820 }
2821
2822lim_tdls_send_mgmt_error:
2823 lim_send_sme_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP,
2824 result_code, send_req->sessionId,
2825 send_req->transactionId);
2826
2827 return eSIR_SUCCESS;
2828}
2829
2830/*
2831 * Send Response to Link Establish Request to SME
2832 */
2833void lim_send_sme_tdls_link_establish_req_rsp(tpAniSirGlobal pMac,
Srinivas Girigowda2e602872015-11-20 20:58:13 -08002834 uint8_t sessionId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302835 struct qdf_mac_addr *peermac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002836 tDphHashNode *pStaDs, uint8_t status)
2837{
2838 tSirMsgQ mmhMsg = { 0 };
2839
2840 tSirTdlsLinkEstablishReqRsp *pTdlsLinkEstablishReqRsp = NULL;
2841
2842 pTdlsLinkEstablishReqRsp =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302843 qdf_mem_malloc(sizeof(tSirTdlsLinkEstablishReqRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002844 if (NULL == pTdlsLinkEstablishReqRsp) {
2845 lim_log(pMac, LOGE, FL("Failed to allocate memory"));
2846 return;
2847 }
2848 pTdlsLinkEstablishReqRsp->statusCode = status;
Srinivas Girigowda2e602872015-11-20 20:58:13 -08002849 if (peermac)
Anurag Chouhanc5548422016-02-24 18:33:27 +05302850 qdf_copy_macaddr(&pTdlsLinkEstablishReqRsp->peermac, peermac);
Srinivas Girigowda2e602872015-11-20 20:58:13 -08002851
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002852 pTdlsLinkEstablishReqRsp->sessionId = sessionId;
2853 mmhMsg.type = eWNI_SME_TDLS_LINK_ESTABLISH_RSP;
2854 mmhMsg.bodyptr = pTdlsLinkEstablishReqRsp;
2855 mmhMsg.bodyval = 0;
2856 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2857 return;
2858
2859}
2860
2861/*
2862 * Once link is teardown, send Del Peer Ind to SME
2863 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302864static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002865 uint8_t sessionId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302866 struct qdf_mac_addr peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002867 tDphHashNode *pStaDs, uint8_t status)
2868{
2869 tSirMsgQ mmhMsg = { 0 };
2870 tSirTdlsDelStaRsp *pDelSta = NULL;
2871 mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP;
2872
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302873 pDelSta = qdf_mem_malloc(sizeof(tSirTdlsDelStaRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002874 if (NULL == pDelSta) {
2875 lim_log(pMac, LOGE, FL("Failed to allocate memory"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302876 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002877 }
2878
2879 pDelSta->sessionId = sessionId;
2880 pDelSta->statusCode = status;
2881 if (pStaDs) {
2882 pDelSta->staId = pStaDs->staIndex;
2883 } else
2884 pDelSta->staId = STA_INVALID_IDX;
2885
Anurag Chouhanc5548422016-02-24 18:33:27 +05302886 qdf_copy_macaddr(&pDelSta->peermac, &peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002887
2888 pDelSta->length = sizeof(tSirTdlsDelStaRsp);
2889 pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP;
2890
2891 mmhMsg.bodyptr = pDelSta;
2892
2893 mmhMsg.bodyval = 0;
2894 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302895 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896
2897}
2898
2899/*
2900 * Process Send Mgmt Request from SME and transmit to AP.
2901 */
2902tSirRetStatus lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
2903 uint32_t *pMsgBuf)
2904{
2905 /* get all discovery request parameters */
2906 tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq *) pMsgBuf;
2907 tpPESession psessionEntry;
2908 uint8_t sessionId;
2909
2910 lim_log(pMac, LOG1, FL("TDLS Add STA Request Recieved"));
2911 psessionEntry =
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002912 pe_find_session_by_bssid(pMac, pAddStaReq->bssid.bytes,
2913 &sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002914 if (psessionEntry == NULL) {
2915 lim_log(pMac, LOGE,
2916 FL(
2917 "PE Session does not exist for given sme sessionId %d"
2918 ),
2919 pAddStaReq->sessionId);
2920 goto lim_tdls_add_sta_error;
2921 }
2922
2923 /* check if we are in proper state to work as TDLS client */
2924 if (!LIM_IS_STA_ROLE(psessionEntry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302925 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002926 "send mgmt received in wrong system Role %d",
2927 GET_LIM_SYSTEM_ROLE(psessionEntry));
2928 goto lim_tdls_add_sta_error;
2929 }
2930
2931 /*
2932 * if we are still good, go ahead and check if we are in proper state to
2933 * do TDLS discovery req/rsp/....frames.
2934 */
2935 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
2936 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
2937
2938 lim_log(pMac, LOGE,
2939 FL("send mgmt received in invalid LIMsme state (%d)"),
2940 psessionEntry->limSmeState);
2941 goto lim_tdls_add_sta_error;
2942 }
2943
2944 pMac->lim.gLimAddStaTdls = true;
2945
2946 /* To start with, send add STA request to HAL */
2947 if (eSIR_FAILURE == lim_tdls_setup_add_sta(pMac, pAddStaReq, psessionEntry)) {
2948 lim_log(pMac, LOGE,
2949 FL("Add TDLS Station request failed"));
2950 goto lim_tdls_add_sta_error;
2951 }
2952 return eSIR_SUCCESS;
2953lim_tdls_add_sta_error:
2954 lim_send_sme_tdls_add_sta_rsp(pMac,
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002955 pAddStaReq->sessionId,
2956 pAddStaReq->peermac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002957 (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE),
2958 NULL, eSIR_FAILURE);
2959
2960 return eSIR_SUCCESS;
2961}
2962
2963/*
2964 * Process Del Sta Request from SME .
2965 */
2966tSirRetStatus lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
2967 uint32_t *pMsgBuf)
2968{
2969 /* get all discovery request parameters */
2970 tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
2971 tpPESession psessionEntry;
2972 uint8_t sessionId;
2973 tpDphHashNode pStaDs = NULL;
2974
2975 lim_log(pMac, LOG1, FL("TDLS Delete STA Request Recieved"));
2976 psessionEntry =
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002977 pe_find_session_by_bssid(pMac, pDelStaReq->bssid.bytes,
2978 &sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002979 if (psessionEntry == NULL) {
2980 lim_log(pMac, LOGE,
2981 FL(
2982 "PE Session does not exist for given sme sessionId %d"
2983 ),
2984 pDelStaReq->sessionId);
2985 lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002986 pDelStaReq->peermac, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002987 eSIR_FAILURE);
2988 return eSIR_FAILURE;
2989 }
2990
2991 /* check if we are in proper state to work as TDLS client */
2992 if (!LIM_IS_STA_ROLE(psessionEntry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302993 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002994 "Del sta received in wrong system Role %d",
2995 GET_LIM_SYSTEM_ROLE(psessionEntry));
2996 goto lim_tdls_del_sta_error;
2997 }
2998
2999 /*
3000 * if we are still good, go ahead and check if we are in proper state to
3001 * do TDLS discovery req/rsp/....frames.
3002 */
3003 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3004 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3005
3006 lim_log(pMac, LOGE,
3007 FL("Del Sta received in invalid LIMsme state (%d)"),
3008 psessionEntry->limSmeState);
3009 goto lim_tdls_del_sta_error;
3010 }
3011
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003012 pStaDs = lim_tdls_del_sta(pMac, pDelStaReq->peermac, psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003013
3014 /* now send indication to SME-->HDD->TL to remove STA from TL */
3015
3016 if (pStaDs) {
3017 lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003018 pDelStaReq->peermac, pStaDs,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003019 eSIR_SUCCESS);
3020 lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
3021
3022 /* Clear the aid in peerAIDBitmap as this aid is now in freepool */
3023 CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap,
3024 pStaDs->assocId);
3025 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
3026 psessionEntry);
3027
3028 return eSIR_SUCCESS;
3029
3030 }
3031
3032lim_tdls_del_sta_error:
3033 lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003034 pDelStaReq->peermac, NULL, eSIR_FAILURE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003035
3036 return eSIR_SUCCESS;
3037}
3038
3039/* Intersects the two input arrays and outputs an array */
3040/* For now the array length of uint8_t suffices */
3041static void lim_tdls_get_intersection(uint8_t *input_array1,
3042 uint8_t input1_length,
3043 uint8_t *input_array2,
3044 uint8_t input2_length,
3045 uint8_t *output_array,
3046 uint8_t *output_length)
3047{
3048 uint8_t i, j, k = 0, flag = 0;
3049 for (i = 0; i < input1_length; i++) {
3050 flag = 0;
3051 for (j = 0; j < input2_length; j++) {
3052 if (input_array1[i] == input_array2[j]) {
3053 flag = 1;
3054 break;
3055 }
3056 }
3057 if (flag == 1) {
3058 output_array[k] = input_array1[i];
3059 k++;
3060 }
3061 }
3062 *output_length = k;
3063}
3064
3065/**
3066 * lim_process_sme_tdls_link_establish_req() - process tdls link establishment
3067 * request
3068 *
3069 * @mac_ctx - global MAC context
3070 * @msg_buf - message buffer from SME
3071 *
3072 * Process Link Establishment Request from SME
3073 *
3074 * Return: eSIR_SUCCESS on success, failure code otherwise.
3075 */
3076tSirRetStatus lim_process_sme_tdls_link_establish_req(tpAniSirGlobal mac_ctx,
3077 uint32_t *msg_buf)
3078{
3079 /* get all discovery request parameters */
3080 tSirTdlsLinkEstablishReq *tdls_req =
3081 (tSirTdlsLinkEstablishReq *) msg_buf;
3082 tpPESession session_entry;
3083 uint8_t session_id;
3084 tpTdlsLinkEstablishParams tdls_req_params;
3085 tSirMsgQ msg;
3086 uint16_t peer_idx = 0;
3087 tpDphHashNode stads = NULL;
3088 uint32_t self_num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3089 uint8_t self_supp_chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3090
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303091 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003092 FL("Send Mgmt Recieved"));
3093
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003094 session_entry = pe_find_session_by_bssid(mac_ctx, tdls_req->bssid.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095 &session_id);
3096 if (NULL == session_entry) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303097 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003098 FL("PE Session does not exist for sme session_id %d"),
3099 tdls_req->sessionId);
3100 lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003101 tdls_req->sessionId, &tdls_req->peermac, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102 eSIR_FAILURE);
3103 return eSIR_FAILURE;
3104 }
3105
3106 /* check if we are in proper state to work as TDLS client */
3107 if (!LIM_IS_STA_ROLE(session_entry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303108 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003109 FL("TDLS Link Establish Request received in wrong system Role %d"),
3110 GET_LIM_SYSTEM_ROLE(session_entry));
3111 goto lim_tdls_link_establish_error;
3112 }
3113
3114 /*
3115 * if we are still good, go ahead and check if we are in proper state to
3116 * do TDLS discovery req/rsp/....frames.
3117 */
3118 if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3119 (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3120 lim_log(mac_ctx, LOGE,
3121 FL("TDLS Link Establish Request received in invalid LIMsme state (%d)"),
3122 session_entry->limSmeState);
3123 goto lim_tdls_link_establish_error;
3124 }
3125
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003126 stads = dph_lookup_hash_entry(mac_ctx, tdls_req->peermac.bytes,
3127 &peer_idx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003128 &session_entry->dph.dphHashTable);
3129 if (NULL == stads) {
3130 lim_log(mac_ctx, LOGE, FL("stads is NULL"));
3131 goto lim_tdls_link_establish_error;
3132 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303133 tdls_req_params = qdf_mem_malloc(sizeof(tTdlsLinkEstablishParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003134 if (NULL == tdls_req_params) {
3135 lim_log(mac_ctx, LOGE,
3136 FL("Unable to allocate memory TDLS Link Establish Request"));
3137 return eSIR_MEM_ALLOC_FAILED;
3138 }
3139
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303140 qdf_mem_set((uint8_t *) tdls_req_params,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003141 sizeof(tTdlsLinkEstablishParams), 0);
3142
3143 tdls_req_params->staIdx = stads->staIndex;
3144 tdls_req_params->isResponder = tdls_req->isResponder;
3145 tdls_req_params->uapsdQueues = tdls_req->uapsdQueues;
3146 tdls_req_params->maxSp = tdls_req->maxSp;
3147 tdls_req_params->isBufsta = tdls_req->isBufSta;
3148 tdls_req_params->isOffChannelSupported =
3149 tdls_req->isOffChannelSupported;
3150
3151 if (0 == tdls_req->supportedChannelsLen)
3152 goto send_tdls_establish_request;
3153
3154 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_VALID_CHANNEL_LIST,
3155 self_supp_chan,
3156 &self_num_chan) != eSIR_SUCCESS) {
3157 /**
3158 * Could not get Valid channel list from CFG.
3159 * Log error.
3160 */
3161 lim_log(mac_ctx, LOGE,
3162 FL("could not retrieve Valid channel list"));
3163 }
3164
3165 if (self_num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
3166 lim_log(mac_ctx, LOGE,
3167 FL("Channel List more than Valid Channel list"));
3168 self_num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3169 }
3170
3171 if (tdls_req->supportedChannelsLen > SIR_MAC_MAX_SUPP_CHANNELS) {
3172 lim_log(mac_ctx, LOGE,
3173 FL("Channel List is more than the supported Channel list"));
3174 tdls_req->supportedChannelsLen = SIR_MAC_MAX_SUPP_CHANNELS;
3175 }
3176
3177 lim_tdls_get_intersection(self_supp_chan, self_num_chan,
3178 tdls_req->supportedChannels, tdls_req->supportedChannelsLen,
3179 tdls_req_params->validChannels,
3180 &tdls_req_params->validChannelsLen);
3181
3182send_tdls_establish_request:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303183 qdf_mem_copy(tdls_req_params->validOperClasses,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003184 tdls_req->supportedOperClasses,
3185 tdls_req->supportedOperClassesLen);
3186 tdls_req_params->validOperClassesLen =
3187 tdls_req->supportedOperClassesLen;
3188
3189 msg.type = WMA_SET_TDLS_LINK_ESTABLISH_REQ;
3190 msg.reserved = 0;
3191 msg.bodyptr = tdls_req_params;
3192 msg.bodyval = 0;
3193 if (eSIR_SUCCESS != wma_post_ctrl_msg(mac_ctx, &msg)) {
3194 lim_log(mac_ctx, LOGE, FL("halPostMsgApi failed"));
3195 goto lim_tdls_link_establish_error;
3196 }
3197 return eSIR_SUCCESS;
3198
3199lim_tdls_link_establish_error:
3200 lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003201 session_entry->smeSessionId, &tdls_req->peermac, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003202 eSIR_FAILURE);
3203
3204 return eSIR_SUCCESS;
3205}
3206
3207/**
3208 * lim_delete_tdls_peers() - delete tdls peers
3209 *
3210 * @mac_ctx - global MAC context
3211 * @session_entry - PE session entry
3212 *
3213 * Delete all the TDLS peer connected before leaving the BSS
3214 *
3215 * Return: eSIR_SUCCESS on success, error code otherwise
3216 */
3217tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
3218 tpPESession session_entry)
3219{
3220 tpDphHashNode stads = NULL;
3221 int i, aid;
3222 size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap);
3223
3224 if (NULL == session_entry) {
3225 lim_log(mac_ctx, LOGE, FL("NULL session_entry"));
3226 return eSIR_FAILURE;
3227 }
3228
3229 /*
3230 * Check all the set bit in peerAIDBitmap and delete the peer
3231 * (with that aid) entry from the hash table and add the aid
3232 * in free pool
3233 */
3234 for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) {
3235 for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) {
3236 if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid))
3237 continue;
3238 stads = dph_get_hash_entry(mac_ctx,
3239 (aid + i * (sizeof(uint32_t) << 3)),
3240 &session_entry->dph.dphHashTable);
3241
3242 if (NULL != stads) {
3243 lim_log(mac_ctx, LOGE,
3244 FL("Deleting "MAC_ADDRESS_STR),
3245 MAC_ADDR_ARRAY(stads->staAddr));
3246
3247 lim_send_deauth_mgmt_frame(mac_ctx,
3248 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
3249 stads->staAddr, session_entry, false);
3250 dph_delete_hash_entry(mac_ctx,
3251 stads->staAddr, stads->assocId,
3252 &session_entry->dph.dphHashTable);
3253 }
3254 lim_release_peer_idx(mac_ctx,
3255 (aid + i * (sizeof(uint32_t) << 3)),
3256 session_entry);
3257 CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
3258 }
3259 }
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08003260 if (lim_is_roam_synch_in_progress(session_entry))
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08003261 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003262 lim_send_sme_tdls_delete_all_peer_ind(mac_ctx, session_entry);
3263
3264 return eSIR_SUCCESS;
3265}
3266
3267#endif