blob: 53bcfbc6b2bf7b009b582f77ab522c700f534ae7 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302 * Copyright (c) 2012-2017 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"
Jeff Johnson1396a3c2016-11-04 07:54:41 -070076#include "lim_prop_exts_utils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077#include "dph_hash_table.h"
78#include "wma_types.h"
Naveen Rawat3b6068c2016-04-14 19:01:06 -070079#include "cds_regdomain.h"
Archana Ramachandran63f64dd2016-04-28 15:13:35 -070080#include "cds_utils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081
82/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630
83 There was IOT issue with cisco 1252 open mode, where it pads
84 discovery req/teardown frame with some junk value up to min size.
85 To avoid this issue, we pad QCOM_VENDOR_IE.
86 If there is other IOT issue because of this bandage, define NO_PAD...
87 */
88#ifndef NO_PAD_TDLS_MIN_8023_SIZE
89#define MIN_IEEE_8023_SIZE 46
90#define MIN_VENDOR_SPECIFIC_IE_SIZE 5
91#endif
92
93static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
94 tSirTdlsAddStaReq * pAddStaReq, tpPESession psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080095
96/*
97 * TDLS data frames will go out/come in as non-qos data.
98 * so, eth_890d_header will be aligned access..
99 */
100static const uint8_t eth_890d_header[] = {
101 0xaa, 0xaa, 0x03, 0x00,
102 0x00, 0x00, 0x89, 0x0d,
103};
104
105/*
106 * type of links used in TDLS
107 */
108enum tdlsLinks {
109 TDLS_LINK_AP,
110 TDLS_LINK_DIRECT
111} e_tdls_link;
112
113/*
114 * node status in node searching
115 */
116enum tdlsLinkNodeStatus {
117 TDLS_NODE_NOT_FOUND,
118 TDLS_NODE_FOUND
119} e_tdls_link_node_status;
120
121enum tdlsReqType {
122 TDLS_INITIATOR,
123 TDLS_RESPONDER
124} e_tdls_req_type;
125
126typedef enum tdlsLinkSetupStatus {
127 TDLS_SETUP_STATUS_SUCCESS = 0,
128 TDLS_SETUP_STATUS_FAILURE = 37
129} etdlsLinkSetupStatus;
130
131/* These maps to Kernel TDLS peer capability
132 * flags and should get changed as and when necessary
133 */
134enum tdls_peer_capability {
135 TDLS_PEER_HT_CAP = 0,
136 TDLS_PEER_VHT_CAP = 1,
137 TDLS_PEER_WMM_CAP = 2
138} e_tdls_peer_capability;
139
140/* some local defines */
141#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
142#define PTI_LINK_IDEN_OFFSET (5)
143#define PTI_BUF_STATUS_OFFSET (25)
144
145/* TODO, Move this parameters to configuration */
146#define PEER_PSM_SUPPORT (0)
147#define TDLS_SUPPORT (1)
148#define TDLS_PROHIBITED (0)
149#define TDLS_CH_SWITCH_PROHIBITED (1)
150/** @brief Set bit manipulation macro */
151#define SET_BIT(value, mask) ((value) |= (1 << (mask)))
152/** @brief Clear bit manipulation macro */
153#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask)))
154/** @brief Check bit manipulation macro */
155#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
156
157#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
158 do { \
159 if ((aid) < (sizeof(uint32_t) << 3)) \
160 SET_BIT(peer_bitmap[0], (aid)); \
161 else if ((aid) < (sizeof(uint32_t) << 4)) \
162 SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
163 } while (0);
164
165#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \
166 do { \
167 if ((aid) < (sizeof(uint32_t) << 3)) \
168 CLEAR_BIT(peer_bitmap[0], (aid)); \
169 else if ((aid) < (sizeof(uint32_t) << 4)) \
170 CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
171 } while (0);
172
173#ifdef LIM_DEBUG_TDLS
174
175#ifdef FEATURE_WLAN_TDLS
176#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800)
177#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200)
178#endif
179
180#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \
181 SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) || \
182 (((psessionEntry)->limWmeEnabled) && \
183 LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps)))
184
185#define TID_AC_VI 4
186#define TID_AC_BK 1
187
Jeff Johnson43fee1c2016-11-23 13:12:03 -0800188static const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189{
190 switch (tdlsActionCode) {
191 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
192 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
193 CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
194 CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
195 CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
196 CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
197 CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
198 CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
199 CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
200 CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
201 }
202 return (const uint8_t *)"UNKNOWN";
203}
204#endif
205/*
206 * initialize TDLS setup list and related data structures.
207 */
208void lim_init_tdls_data(tpAniSirGlobal pMac, tpPESession pSessionEntry)
209{
210 lim_init_peer_idxpool(pMac, pSessionEntry);
211
212 return;
213}
214
Jeff Johnsona38de672016-11-04 06:53:58 -0700215static void populate_dot11f_tdls_offchannel_params(
216 tpAniSirGlobal pMac,
217 tpPESession psessionEntry,
218 tDot11fIESuppChannels *suppChannels,
219 tDot11fIESuppOperatingClasses *suppOperClasses)
220{
221 uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
222 uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
223 uint8_t i;
224 uint8_t valid_count = 0;
225 uint8_t chanOffset;
226 uint8_t op_class;
227 uint8_t numClasses;
228 uint8_t classes[CDS_MAX_SUPP_OPER_CLASSES];
229 uint32_t band;
230 uint8_t nss_2g;
231 uint8_t nss_5g;
232
233 if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
234 validChan, &numChans) != eSIR_SUCCESS) {
235 /**
236 * Could not get Valid channel list from CFG.
237 * Log error.
238 */
239 lim_log(pMac, LOGE,
240 FL("could not retrieve Valid channel list"));
241 return;
242 }
243
244 if (IS_5G_CH(psessionEntry->currentOperChannel))
245 band = eCSR_BAND_5G;
246 else
247 band = eCSR_BAND_24;
248
249 nss_5g = QDF_MIN(pMac->vdev_type_nss_5g.tdls,
250 pMac->user_configured_nss);
251 nss_2g = QDF_MIN(pMac->vdev_type_nss_2g.tdls,
252 pMac->user_configured_nss);
253
254 /* validating the channel list for DFS and 2G channels */
255 for (i = 0U; i < numChans; i++) {
256 if ((band == eCSR_BAND_5G) &&
257 (NSS_2x2_MODE == nss_5g) &&
258 (NSS_1x1_MODE == nss_2g) &&
259 (true == CDS_IS_DFS_CH(validChan[i]))) {
260 lim_log(pMac, LOG1,
261 FL("skipping channel %d, nss_5g: %d, nss_2g: %d"),
262 validChan[i], nss_5g, nss_2g);
263 continue;
264 } else {
265 if (true == cds_is_dsrc_channel(
266 cds_chan_to_freq(validChan[i]))) {
267 lim_log(pMac, LOG1,
268 FL("skipping channel %d from the valid channel list"),
269 validChan[i]);
270 continue;
271 }
272 }
273
274 if (valid_count >= ARRAY_SIZE(suppChannels->bands))
275 break;
276 suppChannels->bands[valid_count][0] = validChan[i];
277 suppChannels->bands[valid_count][1] = 1;
278 valid_count++;
279 }
280
281 suppChannels->num_bands = valid_count;
282 suppChannels->present = 1;
283
284 /* find channel offset and get op class for current operating channel */
285 switch (psessionEntry->htSecondaryChannelOffset) {
286 case PHY_SINGLE_CHANNEL_CENTERED:
287 chanOffset = BW20;
288 break;
289
290 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
291 chanOffset = BW40_LOW_PRIMARY;
292 break;
293
294 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
295 chanOffset = BW40_HIGH_PRIMARY;
296 break;
297
298 default:
299 chanOffset = BWALL;
300 break;
301
302 }
303
304 op_class = cds_reg_dmn_get_opclass_from_channel(
305 pMac->scan.countryCodeCurrent,
306 psessionEntry->currentOperChannel,
307 chanOffset);
308
309 if (op_class == 0) {
310 lim_log(pMac, LOGE,
311 FL(
312 "Present Operating class is wrong, countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d"
313 ),
314 pMac->scan.countryCodeCurrent,
315 psessionEntry->currentOperChannel,
316 psessionEntry->htSecondaryChannelOffset,
317 chanOffset);
318 } else {
319 lim_log(pMac, LOG1,
320 FL(
321 "Present Operating channel: %d chanOffset: %d, op class=%d"
322 ),
323 psessionEntry->currentOperChannel, chanOffset,
324 op_class);
325 }
326 suppOperClasses->present = 1;
327 suppOperClasses->classes[0] = op_class;
328
329 cds_reg_dmn_get_curr_opclasses(&numClasses, &classes[0]);
330
331 for (i = 0; i < numClasses; i++) {
332 suppOperClasses->classes[i + 1] = classes[i];
333 }
334 /* add one for present operating class, added in the beginning */
335 suppOperClasses->num_classes = numClasses + 1;
336
337 return;
338}
339
340/*
341 * FUNCTION: Populate Link Identifier element IE
342 *
343 */
344
345static void populate_dot11f_link_iden(tpAniSirGlobal pMac,
346 tpPESession psessionEntry,
347 tDot11fIELinkIdentifier *linkIden,
348 struct qdf_mac_addr peer_mac,
349 uint8_t reqType)
350{
351 uint8_t *initStaAddr = NULL;
352 uint8_t *respStaAddr = NULL;
353
354 (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
355 (respStaAddr = linkIden->RespStaAddr))
356 : ((respStaAddr = linkIden->InitStaAddr),
357 (initStaAddr = linkIden->RespStaAddr));
358 qdf_mem_copy((uint8_t *) linkIden->bssid,
359 (uint8_t *) psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
360
361 qdf_mem_copy((uint8_t *) initStaAddr,
362 psessionEntry->selfMacAddr, QDF_MAC_ADDR_SIZE);
363
364 qdf_mem_copy((uint8_t *) respStaAddr, (uint8_t *) peer_mac.bytes,
365 QDF_MAC_ADDR_SIZE);
366
367 linkIden->present = 1;
368 return;
369
370}
371
372static void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
373 tpPESession psessionEntry,
374 tDot11fIEExtCap *extCapability)
375{
376 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes;
377
378 p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT;
379 p_ext_cap->tdls_peer_uapsd_buffer_sta = pMac->lim.gLimTDLSBufStaEnabled;
380
381 /*
382 * Set TDLS channel switching bits only if offchannel is enabled
383 * and TDLS Channel Switching is not prohibited by AP in ExtCap
384 * IE in assoc/re-assoc response.
385 */
386 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
387 (!psessionEntry->tdls_chan_swit_prohibited)) {
388 p_ext_cap->tdls_channel_switching = 1;
389 p_ext_cap->tdls_chan_swit_prohibited = 0;
390 } else {
391 p_ext_cap->tdls_channel_switching = 0;
392 p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED;
393 }
394 p_ext_cap->tdls_support = TDLS_SUPPORT;
395 p_ext_cap->tdls_prohibited = TDLS_PROHIBITED;
396
397 extCapability->present = 1;
398 /* For STA cases we alwasy support 11mc - Allow MAX length */
399 extCapability->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
400
401 return;
402}
403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404/*
405 * prepare TDLS frame header, it includes
406 * | | | |
407 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
408 * | | | |
409 */
410static uint32_t lim_prepare_tdls_frame_header(tpAniSirGlobal pMac, uint8_t *pFrame,
411 tDot11fIELinkIdentifier *link_iden,
412 uint8_t tdlsLinkType, uint8_t reqType,
413 uint8_t tid,
414 tpPESession psessionEntry)
415{
416 tpSirMacDataHdr3a pMacHdr;
417 uint32_t header_offset = 0;
418 uint8_t *addr1 = NULL;
419 uint8_t *addr3 = NULL;
420 uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP)
421 ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS;
422 uint8_t *peerMac = (reqType == TDLS_INITIATOR)
423 ? link_iden->RespStaAddr : link_iden->InitStaAddr;
424 uint8_t *staMac = (reqType == TDLS_INITIATOR)
425 ? link_iden->InitStaAddr : link_iden->RespStaAddr;
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530426 tpDphHashNode sta_ds;
427 uint16_t aid = 0;
428 uint8_t qos_mode = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429
430 pMacHdr = (tpSirMacDataHdr3a) (pFrame);
431
432 /*
433 * if TDLS frame goes through the AP link, it follows normal address
434 * pattern, if TDLS frame goes thorugh the direct link, then
435 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
436 */
437 (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
438 (addr3 = (peerMac)))
439 : ((addr1 = (peerMac)), (addr3 = (link_iden->bssid)));
440 /*
441 * prepare 802.11 header
442 */
443 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
444 pMacHdr->fc.type = SIR_MAC_DATA_FRAME;
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530445
446 sta_ds = dph_lookup_hash_entry(pMac, peerMac, &aid,
447 &psessionEntry->dph.dphHashTable);
448 if (sta_ds)
449 qos_mode = sta_ds->qosMode;
450
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 pMacHdr->fc.subType =
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530452 ((IS_QOS_ENABLED(psessionEntry) &&
453 (tdlsLinkType == TDLS_LINK_AP)) ||
454 ((tdlsLinkType == TDLS_LINK_DIRECT) && qos_mode))
455 ? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456
457 /*
458 * TL is not setting up below fields, so we are doing it here
459 */
460 pMacHdr->fc.toDS = toDs;
461 pMacHdr->fc.powerMgmt = 0;
462 pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE) ? 0 : 1;
463
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530464 qdf_mem_copy((uint8_t *) pMacHdr->addr1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465 (uint8_t *) addr1, sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530466 qdf_mem_copy((uint8_t *) pMacHdr->addr2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467 (uint8_t *) staMac, sizeof(tSirMacAddr));
468
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530469 qdf_mem_copy((uint8_t *) pMacHdr->addr3,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470 (uint8_t *) (addr3), sizeof(tSirMacAddr));
471
472 lim_log(pMac, LOG1,
473 FL(
474 "Preparing TDLS frame header to %s A1:"
475 MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"
476 MAC_ADDRESS_STR
477 ),
478 (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT",
479 MAC_ADDR_ARRAY(pMacHdr->addr1),
480 MAC_ADDR_ARRAY(pMacHdr->addr2),
481 MAC_ADDR_ARRAY(pMacHdr->addr3));
482
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +0530483 if (pMacHdr->fc.subType == SIR_MAC_DATA_QOS_DATA) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 pMacHdr->qosControl.tid = tid;
485 header_offset += sizeof(tSirMacDataHdr3a);
486 } else
487 header_offset += sizeof(tSirMacMgmtHdr);
488
489 /*
490 * Now form RFC1042 header
491 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530492 qdf_mem_copy((uint8_t *) (pFrame + header_offset),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493 (uint8_t *) eth_890d_header, sizeof(eth_890d_header));
494
495 header_offset += sizeof(eth_890d_header);
496
497 /* add payload type as TDLS */
498 *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
499 header_offset += PAYLOAD_TYPE_TDLS_SIZE;
500 return header_offset;
501}
502
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530503/**
504 * lim_mgmt_tdls_tx_complete - callback to indicate Tx completion
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530505 * @context: pointer to mac structure
506 * @buf: buffer
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530507 * @tx_complete: indicates tx sucess/failure
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530508 * @params: tx completion params
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530509 *
510 * function will be invoked on receiving tx completion indication
511 *
512 * return: success: eHAL_STATUS_SUCCESS failure: eHAL_STATUS_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530514static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context,
515 qdf_nbuf_t buf,
516 uint32_t tx_complete,
517 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518{
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530519 tpPESession session_entry = NULL;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530520 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530522 lim_log(mac_ctx, LOG1, FL("tdls_frm_session_id %x tx_complete %x"),
523 mac_ctx->lim.tdls_frm_session_id, tx_complete);
524
525 if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) {
526 session_entry = pe_find_session_by_session_id(mac_ctx,
527 mac_ctx->lim.tdls_frm_session_id);
528 if (!session_entry) {
529 lim_log(mac_ctx, LOGE, FL("session id %d is not found"),
530 mac_ctx->lim.tdls_frm_session_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530531 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 }
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530533 lim_send_sme_mgmt_tx_completion(mac_ctx, session_entry,
534 tx_complete);
535 mac_ctx->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800536 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530537 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538}
539
540/*
541 * This function can be used for bacst or unicast discovery request
542 * We are not differentiating it here, it will all depnds on peer MAC address,
543 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -0800544static tSirRetStatus lim_send_tdls_dis_req_frame(tpAniSirGlobal pMac,
545 struct qdf_mac_addr peer_mac,
546 uint8_t dialog,
547 tpPESession psessionEntry)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548{
549 tDot11fTDLSDisReq tdlsDisReq;
550 uint32_t status = 0;
551 uint32_t nPayload = 0;
552 uint32_t size = 0;
553 uint32_t nBytes = 0;
554 uint32_t header_offset = 0;
555 uint8_t *pFrame;
556 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530557 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558#ifndef NO_PAD_TDLS_MIN_8023_SIZE
559 uint32_t padLen = 0;
560#endif
561 uint8_t smeSessionId = 0;
562
563 if (NULL == psessionEntry) {
564 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
565 return eSIR_FAILURE;
566 }
567 smeSessionId = psessionEntry->smeSessionId;
568 /*
569 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
570 * and then hand it off to 'dot11f_pack_probe_request' (for
571 * serialization). We start by zero-initializing the structure:
572 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530573 qdf_mem_set((uint8_t *) &tdlsDisReq, sizeof(tDot11fTDLSDisReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574
575 /*
576 * setup Fixed fields,
577 */
578 tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS;
579 tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ;
580 tdlsDisReq.DialogToken.token = dialog;
581
582 size = sizeof(tSirMacAddr);
583
584 populate_dot11f_link_iden(pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
585 peer_mac, TDLS_INITIATOR);
586
587 /*
588 * now we pack it. First, how much space are we going to need?
589 */
590 status = dot11f_get_packed_tdls_dis_req_size(pMac, &tdlsDisReq, &nPayload);
591 if (DOT11F_FAILED(status)) {
592 lim_log(pMac, LOGP,
593 FL(
594 "Failed to calculate the packed size for a discovery Request (0x%08x)."
595 ),
596 status);
597 /* We'll fall back on the worst case scenario: */
598 nPayload = sizeof(tDot11fTDLSDisReq);
599 } else if (DOT11F_WARNED(status)) {
600 lim_log(pMac, LOGW,
601 FL(
602 "There were warnings while calculating the packed size for a discovery Request (0x%08x)."
603 ),
604 status);
605 }
606
607 /*
608 * This frame is going out from PE as data frames with special ethertype
609 * 89-0d.
610 * 8 bytes of RFC 1042 header
611 */
612
613 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
614 ? sizeof(tSirMacDataHdr3a) :
615 sizeof(tSirMacMgmtHdr))
616 + sizeof(eth_890d_header)
617 + PAYLOAD_TYPE_TDLS_SIZE;
618
619#ifndef NO_PAD_TDLS_MIN_8023_SIZE
620 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
621 Hence AP itself padding some bytes, which caused teardown packet is dropped at
622 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
623 */
624 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
625 padLen =
626 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
627
628 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
629 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
630 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
631
632 nBytes += padLen;
633 }
634#endif
635
636 /* Ok-- try to allocate memory from MGMT PKT pool */
637
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530638 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530640 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800641 lim_log(pMac, LOGP,
642 FL(
643 "Failed to allocate %d bytes for a TDLS Discovery Request."
644 ),
645 nBytes);
646 return eSIR_MEM_ALLOC_FAILED;
647 }
648
649 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530650 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651
652 /*
653 * IE formation, memory allocation is completed, Now form TDLS discovery
654 * request frame
655 */
656
657 /* fill out the buffer descriptor */
658
659 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
660 LINK_IDEN_ADDR_OFFSET
661 (tdlsDisReq), TDLS_LINK_AP,
662 TDLS_INITIATOR, TID_AC_VI,
663 psessionEntry);
664
665 status = dot11f_pack_tdls_dis_req(pMac, &tdlsDisReq, pFrame
666 + header_offset, nPayload, &nPayload);
667
668 if (DOT11F_FAILED(status)) {
669 lim_log(pMac, LOGE,
670 FL("Failed to pack a TDLS discovery req (0x%08x)."),
671 status);
672 cds_packet_free((void *)pPacket);
673 return eSIR_FAILURE;
674 } else if (DOT11F_WARNED(status)) {
675 lim_log(pMac, LOGW,
676 FL(
677 "There were warnings while packing TDLS Discovery Request (0x%08x)."
678 ),
679 status);
680 }
681#ifndef NO_PAD_TDLS_MIN_8023_SIZE
682 if (padLen != 0) {
683 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
684 uint8_t *padVendorSpecific = pFrame + header_offset + nPayload;
685 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
686 padVendorSpecific[0] = 221;
687 padVendorSpecific[1] = padLen - 2;
688 padVendorSpecific[2] = 0x00;
689 padVendorSpecific[3] = 0xA0;
690 padVendorSpecific[4] = 0xC6;
691
692 lim_log(pMac, LOGW,
693 FL("Padding Vendor Specific Ie Len = %d"), padLen);
694
695 /* padding zero if more than 5 bytes are required */
696 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530697 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 MIN_VENDOR_SPECIFIC_IE_SIZE,
699 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
700 }
701#endif
702
703 lim_log(pMac, LOG1,
704 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
705 SIR_MAC_TDLS_DIS_REQ,
706 lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_REQ),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800707 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530709 pMac->lim.tdls_frm_session_id = psessionEntry->peSessionId;
Selvaraj, Sridhare9199ab2016-09-14 17:13:22 +0530710 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket,
711 (uint16_t) nBytes,
712 TXRX_FRM_802_11_DATA,
713 ANI_TXDIR_TODS,
714 TID_AC_VI,
715 lim_tx_complete, pFrame,
716 lim_mgmt_tdls_tx_complete,
717 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME |
718 HAL_USE_PEER_STA_REQUESTED_MASK,
719 smeSessionId, false, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530720 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +0530721 pMac->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800722 lim_log(pMac, LOGE,
723 FL("could not send TDLS Discovery Request frame"));
724 return eSIR_FAILURE;
725 }
726
727 return eSIR_SUCCESS;
728
729}
730
731/*
732 * This static function is consistent with any kind of TDLS management
733 * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame,
734 * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame
735 */
736static void populate_dot11f_tdls_ht_vht_cap(tpAniSirGlobal pMac,
737 uint32_t selfDot11Mode,
738 tDot11fIEHTCaps *htCap,
739 tDot11fIEVHTCaps *vhtCap,
740 tpPESession psessionEntry)
741{
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -0700742 uint8_t nss;
743 uint32_t val;
744
745 if (IS_5G_CH(psessionEntry->currentOperChannel))
746 nss = pMac->vdev_type_nss_5g.tdls;
747 else
748 nss = pMac->vdev_type_nss_2g.tdls;
749
Archana Ramachandran5041b252016-04-25 14:29:25 -0700750 nss = QDF_MIN(nss, pMac->user_configured_nss);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751 if (IS_DOT11_MODE_HT(selfDot11Mode)) {
752 /* Include HT Capability IE */
753 populate_dot11f_ht_caps(pMac, NULL, htCap);
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -0700754 val = SIZE_OF_SUPPORTED_MCS_SET;
755 wlan_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
756 &htCap->supportedMCSSet[0], &val);
757 if (NSS_1x1_MODE == nss)
758 htCap->supportedMCSSet[1] = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 /*
760 * Advertise ht capability and max supported channel bandwidth
761 * when populating HT IE in TDLS Setup Request/Setup Response/
762 * Setup Confirmation frames.
763 * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz
764 * off-channel direct link may be started if both TDLS peer STAs
765 * indicated 40 MHz support in the Supported Channel Width Set
766 * field of the HT Capabilities element (which is included in
767 * the TDLS Setup Request frame and the TDLS Setup Response
768 * frame). Switching to a 40 MHz off-channel direct link is
769 * achieved by including the following information in the TDLS
770 * Channel Switch Request
771 * 11.21.1 General: The channel width of the TDLS direct link on
772 * the base channel shall not exceed the channel width of the
773 * BSS to which the TDLS peer STAs are associated.
774 */
775 htCap->supportedChannelWidthSet = 1;
776 } else {
777 htCap->present = 0;
778 }
779 lim_log(pMac, LOG1, FL("HT present = %hu, Chan Width = %hu"),
780 htCap->present, htCap->supportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
782 pMac->roam.configParam.enableVhtFor24GHz) ||
783 (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
784 if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
785 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
786 /* Include VHT Capability IE */
787 populate_dot11f_vht_caps(pMac, psessionEntry, vhtCap);
Kabilan Kannan91765b42016-06-14 00:00:23 -0700788
789 /*
790 * Set to 0 if the TDLS STA does not support either 160
791 * or 80+80 MHz.
792 * Set to 1 if the TDLS STA supports 160 MHz.
793 * Set to 2 if the TDLS STA supports 160 MHz and
794 * 80+80 MHz.
795 * The value 3 is reserved
796 */
797 vhtCap->supportedChannelWidthSet = 0;
798
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 vhtCap->suBeamformeeCap = 0;
800 vhtCap->suBeamFormerCap = 0;
801 vhtCap->muBeamformeeCap = 0;
802 vhtCap->muBeamformerCap = 0;
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -0700803
804 wlan_cfg_get_int(pMac, WNI_CFG_VHT_RX_MCS_MAP, &val);
805 vhtCap->rxMCSMap = val;
806 wlan_cfg_get_int(pMac,
807 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
808 &val);
809 vhtCap->rxHighSupDataRate = val;
810 wlan_cfg_get_int(pMac, WNI_CFG_VHT_TX_MCS_MAP, &val);
811 vhtCap->txMCSMap = val;
812 wlan_cfg_get_int(pMac,
813 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
814 &val);
815 vhtCap->txSupDataRate = val;
816 if (nss == NSS_1x1_MODE) {
817 vhtCap->txMCSMap |= DISABLE_NSS2_MCS;
818 vhtCap->rxMCSMap |= DISABLE_NSS2_MCS;
819 vhtCap->txSupDataRate =
820 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
821 vhtCap->rxHighSupDataRate =
822 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
823 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 } else {
825 vhtCap->present = 0;
826 }
827 } else {
828 /* Vht Disable from ini in 2.4 GHz */
829 vhtCap->present = 0;
830 }
831 lim_log(pMac, LOG1, FL("VHT present = %hu, Chan Width = %hu"),
832 vhtCap->present, vhtCap->supportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800833}
834
835/*
836 * Send TDLS discovery response frame on direct link.
837 */
838
839static tSirRetStatus lim_send_tdls_dis_rsp_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530840 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800841 uint8_t dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 tpPESession psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800843 uint8_t *addIe,
844 uint16_t addIeLen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845{
846 tDot11fTDLSDisRsp tdlsDisRsp;
847 uint16_t caps = 0;
848 uint32_t status = 0;
849 uint32_t nPayload = 0;
850 uint32_t nBytes = 0;
851 uint8_t *pFrame;
852 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530853 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800854 uint32_t selfDot11Mode;
855/* Placeholder to support different channel bonding mode of TDLS than AP. */
856/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
857/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
858/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
859/* uint32_t tdlsChannelBondingMode; */
860 uint8_t smeSessionId = 0;
861
862 if (NULL == psessionEntry) {
863 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
864 return eSIR_FAILURE;
865 }
866 smeSessionId = psessionEntry->smeSessionId;
867
868 /*
869 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
870 * and then hand it off to 'dot11f_pack_probe_request' (for
871 * serialization). We start by zero-initializing the structure:
872 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530873 qdf_mem_set((uint8_t *) &tdlsDisRsp, sizeof(tDot11fTDLSDisRsp), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800874
875 /*
876 * setup Fixed fields,
877 */
878 tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
879 tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP;
880 tdlsDisRsp.DialogToken.token = dialog;
881
882 populate_dot11f_link_iden(pMac, psessionEntry,
883 &tdlsDisRsp.LinkIdentifier,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800884 peer_mac, TDLS_RESPONDER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885
886 if (cfg_get_capability_info(pMac, &caps, psessionEntry)
887 != eSIR_SUCCESS) {
888 /*
889 * Could not get Capabilities value
890 * from CFG. Log error.
891 */
892 lim_log(pMac, LOGE,
893 FL("could not retrieve Capabilities value"));
894 }
895 swap_bit_field16(caps, (uint16_t *) &tdlsDisRsp.Capabilities);
896
897 /* populate supported rate and ext supported rate IE */
898 if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
Masti, Narayanraddid8a56fb2016-09-06 16:07:33 +0530899 &tdlsDisRsp.SuppRates,
900 &tdlsDisRsp.ExtSuppRates,
901 psessionEntry->currentOperChannel))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902 lim_log(pMac, LOGE,
903 FL("could not populate supported data rates"));
904
905 /* populate extended capability IE */
906 populate_dot11f_tdls_ext_capability(pMac,
907 psessionEntry,
908 &tdlsDisRsp.ExtCap);
909
910 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
911
912 /* Populate HT/VHT Capabilities */
913 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsDisRsp.HTCaps,
914 &tdlsDisRsp.VHTCaps, psessionEntry);
915
916 /* Populate TDLS offchannel param only if offchannel is enabled
917 * and TDLS Channel Switching is not prohibited by AP in ExtCap
918 * IE in assoc/re-assoc response.
919 */
920 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
921 (!psessionEntry->tdls_chan_swit_prohibited)) {
922 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
923 &tdlsDisRsp.SuppChannels,
924 &tdlsDisRsp.
925 SuppOperatingClasses);
926 if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
927 tdlsDisRsp.ht2040_bss_coexistence.present = 1;
928 tdlsDisRsp.ht2040_bss_coexistence.info_request = 1;
929 }
930 } else {
931 lim_log(pMac, LOG1,
932 FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
933 pMac->lim.gLimTDLSOffChannelEnabled,
934 psessionEntry->tdls_chan_swit_prohibited);
935 }
936 /*
937 * now we pack it. First, how much space are we going to need?
938 */
939 status = dot11f_get_packed_tdls_dis_rsp_size(pMac, &tdlsDisRsp, &nPayload);
940 if (DOT11F_FAILED(status)) {
941 lim_log(pMac, LOGE,
942 FL(
943 "Failed to calculate the packed size for a Discovery Response (0x%08x)."
944 ),
945 status);
946 /* We'll fall back on the worst case scenario: */
947 nPayload = sizeof(tDot11fProbeRequest);
948 } else if (DOT11F_WARNED(status)) {
949 lim_log(pMac, LOGW,
950 FL(
951 "There were warnings while calculating the packed size for a Discovery Response (0x%08x)."
952 ),
953 status);
954 }
955
956 /*
957 * This frame is going out from PE as data frames with special ethertype
958 * 89-0d.
959 * 8 bytes of RFC 1042 header
960 */
961
962 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen;
963
964 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530965 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530967 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800968 lim_log(pMac, LOGE,
969 FL(
970 "Failed to allocate %d bytes for a TDLS Discovery Request."
971 ),
972 nBytes);
973 return eSIR_MEM_ALLOC_FAILED;
974 }
975
976 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530977 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978
979 /*
980 * IE formation, memory allocation is completed, Now form TDLS discovery
981 * response frame
982 */
983
984 /* Make public Action Frame */
985
986 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -0800987 SIR_MAC_MGMT_ACTION, peer_mac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 psessionEntry->selfMacAddr);
989
990 {
991 tpSirMacMgmtHdr pMacHdr;
992 pMacHdr = (tpSirMacMgmtHdr) pFrame;
993 pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
994 pMacHdr->fc.powerMgmt = 0;
995 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
996 }
997
998 status = dot11f_pack_tdls_dis_rsp(pMac, &tdlsDisRsp, pFrame +
999 sizeof(tSirMacMgmtHdr),
1000 nPayload, &nPayload);
1001
1002 if (DOT11F_FAILED(status)) {
1003 lim_log(pMac, LOGE,
1004 FL(
1005 "Failed to pack a TDLS discovery response (0x%08x)."
1006 ),
1007 status);
1008 cds_packet_free((void *)pPacket);
1009 return eSIR_FAILURE;
1010 } else if (DOT11F_WARNED(status)) {
1011 lim_log(pMac, LOGW,
1012 FL(
1013 "There were warnings while packing TDLS Discovery Response (0x%08x)."
1014 ),
1015 status);
1016 }
1017 if (0 != addIeLen) {
1018 lim_log(pMac, LOG1,
1019 FL("Copy Additional Ie Len = %d"), addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301020 qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 addIeLen);
1022 }
1023 lim_log(pMac, LOG1,
1024 FL("[TDLS] action %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR),
1025 SIR_MAC_TDLS_DIS_RSP,
1026 lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_RSP),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001027 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001028
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301029 pMac->lim.tdls_frm_session_id = psessionEntry->peSessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 /*
1031 * Transmit Discovery response and watch if this is delivered to
1032 * peer STA.
1033 */
1034 /* In CLD 2.0, pass Discovery Response as mgmt frame so that
1035 * wma does not do header conversion to 802.3 before calling tx/rx
1036 * routine and subsequenly target also sends frame as is OTA
1037 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301038 qdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039 TXRX_FRM_802_11_MGMT,
1040 ANI_TXDIR_IBSS,
1041 0,
1042 lim_tx_complete, pFrame,
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301043 lim_mgmt_tdls_tx_complete,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 HAL_USE_SELF_STA_REQUESTED_MASK,
1045 smeSessionId, false, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301046 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301047 pMac->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 lim_log(pMac, LOGE,
1049 FL("could not send TDLS Discovery Response frame!"));
1050 return eSIR_FAILURE;
1051 }
1052
1053 return eSIR_SUCCESS;
1054
1055}
1056
1057/*
1058 * This static function is currently used by lim_send_tdls_link_setup_req_frame and
1059 * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable.
1060 */
1061static void populate_dotf_tdls_vht_aid(tpAniSirGlobal pMac, uint32_t selfDot11Mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301062 struct qdf_mac_addr peerMac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001063 tDot11fIEAID *Aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064 tpPESession psessionEntry)
1065{
1066 if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
1067 pMac->roam.configParam.enableVhtFor24GHz) ||
1068 (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
1069 if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
1070 IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
1071
1072 uint16_t aid;
1073 tpDphHashNode pStaDs;
1074
1075 pStaDs =
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001076 dph_lookup_hash_entry(pMac, peerMac.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001077 &psessionEntry->dph.
1078 dphHashTable);
1079 if (NULL != pStaDs) {
1080 Aid->present = 1;
1081 Aid->assocId = aid | LIM_AID_MASK; /* set bit 14 and 15 1's */
1082 } else {
1083 Aid->present = 0;
1084 lim_log(pMac, LOGE,
1085 FL("pStaDs is NULL for "
1086 MAC_ADDRESS_STR),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001087 MAC_ADDR_ARRAY(peerMac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001088 }
1089 }
1090 } else {
1091 Aid->present = 0;
1092 lim_log(pMac, LOGW, FL("Vht not enable from ini for 2.4GHz."));
1093 }
1094}
1095
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301096#ifdef CONFIG_HL_SUPPORT
1097
1098/**
1099 * wma_tx_frame_with_tx_complete_send() - Send tx frames on Direct link or AP link
1100 * depend on reason code
1101 * @pMac: pointer to MAC Sirius parameter structure
1102 * @pPacket: pointer to mgmt packet
1103 * @nBytes: number of bytes to send
1104 * @tid:tid value for AC
1105 * @pFrame: pointer to tdls frame
1106 * @smeSessionId:session id
1107 * @flag: tdls flag
1108 *
1109 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1110 *
1111 * Return: None
1112 */
1113static inline QDF_STATUS
1114wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
1115 uint16_t nBytes,
1116 uint8_t tid,
1117 uint8_t *pFrame,
1118 uint8_t smeSessionId, bool flag)
1119{
1120 return wma_tx_frameWithTxComplete(pMac, pPacket,
1121 (uint16_t) nBytes,
1122 TXRX_FRM_802_11_DATA,
1123 ANI_TXDIR_TODS,
1124 tid,
1125 lim_tx_complete, pFrame,
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301126 lim_mgmt_tdls_tx_complete,
Selvaraj, Sridhare9199ab2016-09-14 17:13:22 +05301127 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
1128 | HAL_USE_PEER_STA_REQUESTED_MASK,
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301129 smeSessionId, flag, 0);
1130}
1131#else
1132
1133static inline QDF_STATUS
1134wma_tx_frame_with_tx_complete_send(tpAniSirGlobal pMac, void *pPacket,
1135 uint16_t nBytes,
1136 uint8_t tid,
1137 uint8_t *pFrame,
1138 uint8_t smeSessionId, bool flag)
1139{
1140 return wma_tx_frameWithTxComplete(pMac, pPacket,
1141 (uint16_t) nBytes,
1142 TXRX_FRM_802_11_DATA,
1143 ANI_TXDIR_TODS,
1144 tid,
1145 lim_tx_complete, pFrame,
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301146 lim_mgmt_tdls_tx_complete,
Selvaraj, Sridhare9199ab2016-09-14 17:13:22 +05301147 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
1148 | HAL_USE_PEER_STA_REQUESTED_MASK,
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301149 smeSessionId, false, 0);
1150}
1151#endif
1152
Kabilan Kannan32eb5022016-10-04 12:24:50 -07001153void lim_set_tdls_flags(roam_offload_synch_ind *roam_sync_ind_ptr,
1154 tpPESession ft_session_ptr)
1155{
1156 roam_sync_ind_ptr->join_rsp->tdls_prohibited =
1157 ft_session_ptr->tdls_prohibited;
1158 roam_sync_ind_ptr->join_rsp->tdls_chan_swit_prohibited =
1159 ft_session_ptr->tdls_chan_swit_prohibited;
1160}
1161
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001162/*
1163 * TDLS setup Request frame on AP link
1164 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -08001165static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166tSirRetStatus lim_send_tdls_link_setup_req_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301167 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001168 uint8_t dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001169 tpPESession psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001170 uint8_t *addIe,
1171 uint16_t addIeLen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001172{
1173 tDot11fTDLSSetupReq tdlsSetupReq;
1174 uint16_t caps = 0;
1175 uint32_t status = 0;
1176 uint32_t nPayload = 0;
1177 uint32_t nBytes = 0;
1178 uint32_t header_offset = 0;
1179 uint8_t *pFrame;
1180 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301181 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001182 uint32_t selfDot11Mode;
1183 uint8_t smeSessionId = 0;
1184/* Placeholder to support different channel bonding mode of TDLS than AP. */
1185/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
1186/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
1187/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
1188/* uint32_t tdlsChannelBondingMode; */
1189
1190 /*
1191 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1192 * and then hand it off to 'dot11f_pack_probe_request' (for
1193 * serialization). We start by zero-initializing the structure:
1194 */
1195 smeSessionId = psessionEntry->smeSessionId;
1196
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301197 qdf_mem_set((uint8_t *) &tdlsSetupReq, sizeof(tDot11fTDLSSetupReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198 tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS;
1199 tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ;
1200 tdlsSetupReq.DialogToken.token = dialog;
1201
1202 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001203 &tdlsSetupReq.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204 TDLS_INITIATOR);
1205
1206 if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
1207 /*
1208 * Could not get Capabilities value
1209 * from CFG. Log error.
1210 */
1211 lim_log(pMac, LOGE,
1212 FL("could not retrieve Capabilities value"));
1213 }
1214 swap_bit_field16(caps, (uint16_t *) &tdlsSetupReq.Capabilities);
1215
1216 /* populate supported rate and ext supported rate IE */
1217 if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
Masti, Narayanraddid8a56fb2016-09-06 16:07:33 +05301218 &tdlsSetupReq.SuppRates,
1219 &tdlsSetupReq.ExtSuppRates,
1220 psessionEntry->currentOperChannel))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 lim_log(pMac, LOGE,
1222 FL("could not populate supported data rates"));
1223
1224 /* Populate extended capability IE */
1225 populate_dot11f_tdls_ext_capability(pMac,
1226 psessionEntry,
1227 &tdlsSetupReq.ExtCap);
1228
1229 if (1 == pMac->lim.gLimTDLSWmmMode) {
1230 uint32_t val = 0;
1231
1232 lim_log(pMac, LOG1,
1233 FL("populate WMM IE in Setup Request Frame"));
1234 /* include WMM IE */
1235 tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
1236 tdlsSetupReq.WMMInfoStation.acvo_uapsd =
1237 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1238 tdlsSetupReq.WMMInfoStation.acvi_uapsd =
1239 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1240 tdlsSetupReq.WMMInfoStation.acbk_uapsd =
1241 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1242 tdlsSetupReq.WMMInfoStation.acbe_uapsd =
1243 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1244
1245 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
1246 eSIR_SUCCESS)
1247 lim_log(pMac, LOGE,
1248 FL("could not retrieve Max SP Length"));
1249
1250 tdlsSetupReq.WMMInfoStation.max_sp_length = (uint8_t) val;
1251 tdlsSetupReq.WMMInfoStation.present = 1;
1252 } else {
1253 /*
1254 * TODO: we need to see if we have to support conditions where
1255 * we have EDCA parameter info element is needed a) if we need
1256 * different QOS parameters for off channel operations or QOS
1257 * is not supported on AP link and we wanted to QOS on direct
1258 * link.
1259 */
1260
1261 /* Populate QOS info, needed for Peer U-APSD session */
1262
1263 /*
1264 * TODO: Now hardcoded, since populate_dot11f_qos_caps_station()
1265 * depends on AP's capability, and TDLS doesn't want to depend
1266 * on AP's capability
1267 */
1268
1269 lim_log(pMac, LOG1,
1270 FL("populate QOS IE in Setup Request Frame"));
1271 tdlsSetupReq.QOSCapsStation.present = 1;
1272 tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
1273 tdlsSetupReq.QOSCapsStation.qack = 0;
1274 tdlsSetupReq.QOSCapsStation.acbe_uapsd =
1275 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1276 tdlsSetupReq.QOSCapsStation.acbk_uapsd =
1277 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1278 tdlsSetupReq.QOSCapsStation.acvi_uapsd =
1279 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1280 tdlsSetupReq.QOSCapsStation.acvo_uapsd =
1281 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1282 }
1283
1284 /*
1285 * we will always try to init TDLS link with 11n capabilities
1286 * let TDLS setup response to come, and we will set our caps based
1287 * of peer caps
1288 */
1289
1290 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
1291
1292 /* Populate HT/VHT Capabilities */
1293 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupReq.HTCaps,
1294 &tdlsSetupReq.VHTCaps, psessionEntry);
1295
1296 /* Populate AID */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001297 populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001298 &tdlsSetupReq.AID, psessionEntry);
1299
1300 /* Populate TDLS offchannel param only if offchannel is enabled
1301 * and TDLS Channel Switching is not prohibited by AP in ExtCap
1302 * IE in assoc/re-assoc response.
1303 */
1304 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
1305 (!psessionEntry->tdls_chan_swit_prohibited)) {
1306 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
1307 &tdlsSetupReq.SuppChannels,
1308 &tdlsSetupReq.
1309 SuppOperatingClasses);
1310 if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
1311 tdlsSetupReq.ht2040_bss_coexistence.present = 1;
1312 tdlsSetupReq.ht2040_bss_coexistence.info_request = 1;
1313 }
1314 } else {
1315 lim_log(pMac, LOG1,
1316 FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
1317 pMac->lim.gLimTDLSOffChannelEnabled,
1318 psessionEntry->tdls_chan_swit_prohibited);
1319 }
1320 /*
1321 * now we pack it. First, how much space are we going to need?
1322 */
1323 status = dot11f_get_packed_tdls_setup_req_size(pMac, &tdlsSetupReq,
1324 &nPayload);
1325 if (DOT11F_FAILED(status)) {
1326 lim_log(pMac, LOGE,
1327 FL(
1328 "Failed to calculate the packed size for a Setup Request (0x%08x)."
1329 ),
1330 status);
1331 /* We'll fall back on the worst case scenario: */
1332 nPayload = sizeof(tDot11fProbeRequest);
1333 } else if (DOT11F_WARNED(status)) {
1334 lim_log(pMac, LOGW,
1335 FL(
1336 "There were warnings while calculating the packed size for a Setup Request (0x%08x)."
1337 ),
1338 status);
1339 }
1340
1341 /*
1342 * This frame is going out from PE as data frames with special ethertype
1343 * 89-0d.
1344 * 8 bytes of RFC 1042 header
1345 */
1346
1347 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1348 ? sizeof(tSirMacDataHdr3a) :
1349 sizeof(tSirMacMgmtHdr))
1350 + sizeof(eth_890d_header)
1351 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1352
1353 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301354 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301356 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 lim_log(pMac, LOGE,
1358 FL(
1359 "Failed to allocate %d bytes for a TDLS Setup Request."
1360 ),
1361 nBytes);
1362 return eSIR_MEM_ALLOC_FAILED;
1363 }
1364
1365 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301366 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001367
1368 /*
1369 * IE formation, memory allocation is completed, Now form TDLS discovery
1370 * request frame
1371 */
1372
1373 /* fill out the buffer descriptor */
1374
1375 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1376 LINK_IDEN_ADDR_OFFSET
1377 (tdlsSetupReq), TDLS_LINK_AP,
Pradeep Reddy POTTETI8226a1d2015-11-04 14:40:51 +05301378 TDLS_INITIATOR, TID_AC_VI,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379 psessionEntry);
1380
1381 lim_log(pMac, LOGW,
1382 FL(
1383 "SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"
1384 ),
1385 tdlsSetupReq.VHTCaps.supportedChannelWidthSet,
1386 tdlsSetupReq.VHTCaps.rxMCSMap,
1387 tdlsSetupReq.VHTCaps.txMCSMap,
1388 tdlsSetupReq.VHTCaps.txSupDataRate);
1389
1390 status = dot11f_pack_tdls_setup_req(pMac, &tdlsSetupReq, pFrame
1391 + header_offset, nPayload, &nPayload);
1392
1393 if (DOT11F_FAILED(status)) {
1394 lim_log(pMac, LOGE,
1395 FL("Failed to pack a TDLS Setup request (0x%08x)."),
1396 status);
1397 cds_packet_free((void *)pPacket);
1398 return eSIR_FAILURE;
1399 } else if (DOT11F_WARNED(status)) {
1400 lim_log(pMac, LOGW,
1401 FL(
1402 "There were warnings while packing TDLS Setup Request (0x%08x)."
1403 ),
1404 status);
1405 }
1406 /* Copy the additional IE. */
1407 /* TODO : addIe is added at the end of the frame. This means it doesnt */
1408 /* follow the order. This should be ok, but we should consider changing this */
1409 /* if there is any IOT issue. */
1410 if (addIeLen != 0) {
1411 lim_log(pMac, LOG1, FL("Copy Additional Ie Len = %d"),
1412 addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301413 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001414 addIeLen);
1415 }
1416
1417 lim_log(pMac, LOG1,
1418 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
1419 SIR_MAC_TDLS_SETUP_REQ,
1420 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_REQ),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001421 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301423 pMac->lim.tdls_frm_session_id = psessionEntry->peSessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001424
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301425 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
1426 (uint16_t) nBytes,
1427 TID_AC_VI,
1428 pFrame,
1429 smeSessionId, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001430
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301431 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301432 pMac->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 lim_log(pMac, LOGE,
1434 FL("could not send TDLS Setup Request frame!"));
1435 return eSIR_FAILURE;
1436 }
1437
1438 return eSIR_SUCCESS;
1439
1440}
1441
1442/*
1443 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1444 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -08001445static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446tSirRetStatus lim_send_tdls_teardown_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301447 struct qdf_mac_addr peer_mac,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001448 uint16_t reason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 uint8_t responder,
1450 tpPESession psessionEntry,
1451 uint8_t *addIe, uint16_t addIeLen)
1452{
1453 tDot11fTDLSTeardown teardown;
1454 uint32_t status = 0;
1455 uint32_t nPayload = 0;
1456 uint32_t nBytes = 0;
1457 uint32_t header_offset = 0;
1458 uint8_t *pFrame;
1459 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301460 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1462 uint32_t padLen = 0;
1463#endif
1464 uint8_t smeSessionId = 0;
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +05301465 tpDphHashNode sta_ds;
1466 uint16_t aid = 0;
1467 uint8_t qos_mode = 0;
1468 uint8_t tdls_link_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469
1470 if (NULL == psessionEntry) {
1471 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
1472 return eSIR_FAILURE;
1473 }
1474 smeSessionId = psessionEntry->smeSessionId;
1475 /*
1476 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1477 * and then hand it off to 'dot11f_pack_probe_request' (for
1478 * serialization). We start by zero-initializing the structure:
1479 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301480 qdf_mem_set((uint8_t *) &teardown, sizeof(tDot11fTDLSTeardown), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001481 teardown.Category.category = SIR_MAC_ACTION_TDLS;
1482 teardown.Action.action = SIR_MAC_TDLS_TEARDOWN;
1483 teardown.Reason.code = reason;
1484
1485 populate_dot11f_link_iden(pMac, psessionEntry, &teardown.LinkIdentifier,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001486 peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487 (responder ==
1488 true) ? TDLS_RESPONDER : TDLS_INITIATOR);
1489
1490 /*
1491 * now we pack it. First, how much space are we going to need?
1492 */
1493 status = dot11f_get_packed_tdls_teardown_size(pMac, &teardown, &nPayload);
1494 if (DOT11F_FAILED(status)) {
1495 lim_log(pMac, LOGE,
1496 FL(
1497 "Failed to calculate the packed size for a discovery Request (0x%08x)."
1498 ),
1499 status);
1500 /* We'll fall back on the worst case scenario: */
1501 nPayload = sizeof(tDot11fProbeRequest);
1502 } else if (DOT11F_WARNED(status)) {
1503 lim_log(pMac, LOGW,
1504 FL(
1505 "There were warnings while calculating the packed size for a discovery Request (0x%08x)."
1506 ),
1507 status);
1508 }
1509
1510 /*
1511 * This frame is going out from PE as data frames with special ethertype
1512 * 89-0d.
1513 * 8 bytes of RFC 1042 header
1514 */
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +05301515 sta_ds = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
1516 &psessionEntry->dph.dphHashTable);
1517 if (sta_ds)
1518 qos_mode = sta_ds->qosMode;
1519 tdls_link_type = (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1520 ? TDLS_LINK_AP : TDLS_LINK_DIRECT;
1521 nBytes = nPayload + (((IS_QOS_ENABLED(psessionEntry) &&
1522 (tdls_link_type == TDLS_LINK_AP)) ||
1523 ((tdls_link_type == TDLS_LINK_DIRECT) && qos_mode))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524 ? sizeof(tSirMacDataHdr3a) :
1525 sizeof(tSirMacMgmtHdr))
1526 + sizeof(eth_890d_header)
1527 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1528
1529#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1530 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1531 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1532 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1533 */
1534 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
1535 padLen =
1536 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
1537
1538 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1539 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1540 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1541
1542 nBytes += padLen;
1543 }
1544#endif
1545
1546 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301547 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301549 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550 lim_log(pMac, LOGE,
1551 FL(
1552 "Failed to allocate %d bytes for a TDLS Teardown Frame."
1553 ),
1554 nBytes);
1555 return eSIR_MEM_ALLOC_FAILED;
1556 }
1557
1558 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301559 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560
1561 /*
1562 * IE formation, memory allocation is completed, Now form TDLS discovery
1563 * request frame
1564 */
1565
1566 /* fill out the buffer descriptor */
1567 lim_log(pMac, LOGE, FL("Reason of TDLS Teardown: %d"), reason);
1568 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1569 LINK_IDEN_ADDR_OFFSET
1570 (teardown),
1571 (reason ==
1572 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1573 ? TDLS_LINK_AP :
1574 TDLS_LINK_DIRECT,
1575 (responder ==
1576 true) ? TDLS_RESPONDER :
1577 TDLS_INITIATOR, TID_AC_VI,
1578 psessionEntry);
1579
1580 status = dot11f_pack_tdls_teardown(pMac, &teardown, pFrame
1581 + header_offset, nPayload, &nPayload);
1582
1583 if (DOT11F_FAILED(status)) {
1584 lim_log(pMac, LOGE,
1585 FL("Failed to pack a TDLS Teardown frame (0x%08x)."),
1586 status);
1587 cds_packet_free((void *)pPacket);
1588 return eSIR_FAILURE;
1589 } else if (DOT11F_WARNED(status)) {
1590 lim_log(pMac, LOGW,
1591 FL(
1592 "There were warnings while packing TDLS Teardown frame (0x%08x)."
1593 ),
1594 status);
1595 }
1596
1597 if (addIeLen != 0) {
1598 lim_log(pMac, LOGW,
1599 FL("Copy Additional Ie Len = %d"), addIeLen);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301600 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601 addIeLen);
1602 }
1603#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1604 if (padLen != 0) {
1605 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1606 uint8_t *padVendorSpecific =
1607 pFrame + header_offset + nPayload + addIeLen;
1608 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1609 padVendorSpecific[0] = 221;
1610 padVendorSpecific[1] = padLen - 2;
1611 padVendorSpecific[2] = 0x00;
1612 padVendorSpecific[3] = 0xA0;
1613 padVendorSpecific[4] = 0xC6;
1614
1615 lim_log(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"),
1616 padLen);
1617
1618 /* padding zero if more than 5 bytes are required */
1619 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301620 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
1622 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
1623 }
1624#endif
1625 lim_log(pMac, LOG1,
1626 FL("[TDLS] action %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR),
1627 SIR_MAC_TDLS_TEARDOWN,
1628 lim_trace_tdls_action_string(SIR_MAC_TDLS_TEARDOWN),
1629 ((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" :
1630 "DIRECT"),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001631 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001632
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301633 pMac->lim.tdls_frm_session_id = psessionEntry->peSessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001634
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301635 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
1636 (uint16_t) nBytes,
1637 TID_AC_VI,
1638 pFrame,
1639 smeSessionId,
1640 (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1641 ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301643 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301644 pMac->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 lim_log(pMac, LOGE,
1646 FL("could not send TDLS Teardown frame"));
1647 return eSIR_FAILURE;
1648
1649 }
1650 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651}
1652
1653/*
1654 * Send Setup RSP frame on AP link.
1655 */
1656static tSirRetStatus lim_send_tdls_setup_rsp_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301657 struct qdf_mac_addr peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 uint8_t dialog,
1659 tpPESession psessionEntry,
1660 etdlsLinkSetupStatus setupStatus,
1661 uint8_t *addIe,
1662 uint16_t addIeLen)
1663{
1664 tDot11fTDLSSetupRsp tdlsSetupRsp;
1665 uint32_t status = 0;
1666 uint16_t caps = 0;
1667 uint32_t nPayload = 0;
1668 uint32_t header_offset = 0;
1669 uint32_t nBytes = 0;
1670 uint8_t *pFrame;
1671 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301672 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 uint32_t selfDot11Mode;
1674/* Placeholder to support different channel bonding mode of TDLS than AP. */
1675/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
1676/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
1677/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
1678/* uint32_t tdlsChannelBondingMode; */
1679 uint8_t smeSessionId = 0;
1680
1681 if (NULL == psessionEntry) {
1682 lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
1683 return eSIR_FAILURE;
1684 }
1685 smeSessionId = psessionEntry->smeSessionId;
1686
1687 /*
1688 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1689 * and then hand it off to 'dot11f_pack_probe_request' (for
1690 * serialization). We start by zero-initializing the structure:
1691 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301692 qdf_mem_set((uint8_t *) &tdlsSetupRsp, sizeof(tDot11fTDLSSetupRsp), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001693
1694 /*
1695 * setup Fixed fields,
1696 */
1697 tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
1698 tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP;
1699 tdlsSetupRsp.DialogToken.token = dialog;
1700
1701 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001702 &tdlsSetupRsp.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703 TDLS_RESPONDER);
1704
1705 if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
1706 /*
1707 * Could not get Capabilities value
1708 * from CFG. Log error.
1709 */
1710 lim_log(pMac, LOGE,
1711 FL("could not retrieve Capabilities value"));
1712 }
1713 swap_bit_field16(caps, (uint16_t *) &tdlsSetupRsp.Capabilities);
1714
1715 /* populate supported rate and ext supported rate IE */
1716 if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
Masti, Narayanraddid8a56fb2016-09-06 16:07:33 +05301717 &tdlsSetupRsp.SuppRates,
1718 &tdlsSetupRsp.ExtSuppRates,
1719 psessionEntry->currentOperChannel))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 lim_log(pMac, LOGE,
1721 FL("could not populate supported data rates"));
1722
1723 /* Populate extended capability IE */
1724 populate_dot11f_tdls_ext_capability(pMac,
1725 psessionEntry,
1726 &tdlsSetupRsp.ExtCap);
1727
1728 if (1 == pMac->lim.gLimTDLSWmmMode) {
1729 uint32_t val = 0;
1730
1731 lim_log(pMac, LOG1,
1732 FL("populate WMM IE in Setup Response frame"));
1733 /* include WMM IE */
1734 tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
1735 tdlsSetupRsp.WMMInfoStation.acvo_uapsd =
1736 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1737 tdlsSetupRsp.WMMInfoStation.acvi_uapsd =
1738 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1739 tdlsSetupRsp.WMMInfoStation.acbk_uapsd =
1740 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1741 tdlsSetupRsp.WMMInfoStation.acbe_uapsd =
1742 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1743 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
1744 eSIR_SUCCESS)
1745 lim_log(pMac, LOGE,
1746 FL("could not retrieve Max SP Length"));
1747 tdlsSetupRsp.WMMInfoStation.max_sp_length = (uint8_t) val;
1748 tdlsSetupRsp.WMMInfoStation.present = 1;
1749 } else {
1750 /*
1751 * TODO: we need to see if we have to support conditions where
1752 * we have EDCA parameter info element is needed a) if we need
1753 * different QOS parameters for off channel operations or QOS
1754 * is not supported on AP link and we wanted to QOS on direct
1755 * link.
1756 */
1757 /* Populate QOS info, needed for Peer U-APSD session */
1758 /*
1759 * TODO: Now hardcoded, because
1760 * populate_dot11f_qos_caps_station() depends on AP's
1761 * capability, and TDLS doesn't want to depend on AP's
1762 * capability
1763 */
1764 lim_log(pMac, LOG1,
1765 FL("populate QOS IE in Setup Response frame"));
1766 tdlsSetupRsp.QOSCapsStation.present = 1;
1767 tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
1768 tdlsSetupRsp.QOSCapsStation.qack = 0;
1769 tdlsSetupRsp.QOSCapsStation.acbe_uapsd =
1770 ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
1771 tdlsSetupRsp.QOSCapsStation.acbk_uapsd =
1772 ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
1773 tdlsSetupRsp.QOSCapsStation.acvi_uapsd =
1774 ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
1775 tdlsSetupRsp.QOSCapsStation.acvo_uapsd =
1776 (pMac->lim.gLimTDLSUapsdMask & 0x01);
1777 }
1778
1779 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
1780
1781 /* Populate HT/VHT Capabilities */
1782 populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
1783 &tdlsSetupRsp.VHTCaps, psessionEntry);
1784
1785 /* Populate AID */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001786 populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001787 &tdlsSetupRsp.AID, psessionEntry);
1788
1789 /* Populate TDLS offchannel param only if offchannel is enabled
1790 * and TDLS Channel Switching is not prohibited by AP in ExtCap
1791 * IE in assoc/re-assoc response.
1792 */
1793 if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
1794 (!psessionEntry->tdls_chan_swit_prohibited)) {
1795 populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
1796 &tdlsSetupRsp.SuppChannels,
1797 &tdlsSetupRsp.
1798 SuppOperatingClasses);
1799 if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
1800 tdlsSetupRsp.ht2040_bss_coexistence.present = 1;
1801 tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1;
1802 }
1803 } else {
1804 lim_log(pMac, LOG1,
1805 FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
1806 pMac->lim.gLimTDLSOffChannelEnabled,
1807 psessionEntry->tdls_chan_swit_prohibited);
1808 }
1809 tdlsSetupRsp.Status.status = setupStatus;
1810 /*
1811 * now we pack it. First, how much space are we going to need?
1812 */
1813 status = dot11f_get_packed_tdls_setup_rsp_size(pMac, &tdlsSetupRsp,
1814 &nPayload);
1815 if (DOT11F_FAILED(status)) {
1816 lim_log(pMac, LOGE,
1817 FL(
1818 "Failed to calculate the packed size for a Setup Response (0x%08x)."
1819 ),
1820 status);
1821 /* We'll fall back on the worst case scenario: */
1822 nPayload = sizeof(tDot11fProbeRequest);
1823 } else if (DOT11F_WARNED(status)) {
1824 lim_log(pMac, LOGW,
1825 FL(
1826 "There were warnings while calculating the packed size for Setup Response (0x%08x)."
1827 ),
1828 status);
1829 }
1830
1831 /*
1832 * This frame is going out from PE as data frames with special ethertype
1833 * 89-0d.
1834 * 8 bytes of RFC 1042 header
1835 */
1836
1837 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
1838 ? sizeof(tSirMacDataHdr3a) :
1839 sizeof(tSirMacMgmtHdr))
1840 + sizeof(eth_890d_header)
1841 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
1842
1843 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301844 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301846 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001847 lim_log(pMac, LOGE,
1848 FL(
1849 "Failed to allocate %d bytes for a TDLS Setup Response."
1850 ),
1851 nBytes);
1852 return eSIR_MEM_ALLOC_FAILED;
1853 }
1854
1855 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301856 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857
1858 /*
1859 * IE formation, memory allocation is completed, Now form TDLS discovery
1860 * request frame
1861 */
1862
1863 /* fill out the buffer descriptor */
1864
1865 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
1866 LINK_IDEN_ADDR_OFFSET
1867 (tdlsSetupRsp), TDLS_LINK_AP,
Pradeep Reddy POTTETI8226a1d2015-11-04 14:40:51 +05301868 TDLS_RESPONDER, TID_AC_VI,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869 psessionEntry);
1870
1871 lim_log(pMac, LOG1,
1872 FL(
1873 "SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"
1874 ),
1875 tdlsSetupRsp.VHTCaps.supportedChannelWidthSet,
1876 tdlsSetupRsp.VHTCaps.rxMCSMap,
1877 tdlsSetupRsp.VHTCaps.txMCSMap,
1878 tdlsSetupRsp.VHTCaps.txSupDataRate);
1879 status = dot11f_pack_tdls_setup_rsp(pMac, &tdlsSetupRsp,
1880 pFrame + header_offset,
1881 nPayload, &nPayload);
1882
1883 if (DOT11F_FAILED(status)) {
1884 lim_log(pMac, LOGE,
1885 FL("Failed to pack a TDLS Setup Response (0x%08x)."),
1886 status);
1887 cds_packet_free((void *)pPacket);
1888 return eSIR_FAILURE;
1889 } else if (DOT11F_WARNED(status)) {
1890 lim_log(pMac, LOGW,
1891 FL(
1892 "There were warnings while packing TDLS Setup Response (0x%08x)."
1893 ),
1894 status);
1895 }
1896 /* Copy the additional IE. */
1897 /* TODO : addIe is added at the end of the frame. This means it doesnt */
1898 /* follow the order. This should be ok, but we should consider changing this */
1899 /* if there is any IOT issue. */
1900 if (addIeLen != 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301901 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001902 addIeLen);
1903 }
1904
1905 lim_log(pMac, LOG1,
1906 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
1907 SIR_MAC_TDLS_SETUP_RSP,
1908 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_RSP),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001909 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301911 pMac->lim.tdls_frm_session_id = psessionEntry->peSessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001912
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05301913 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
1914 (uint16_t) nBytes,
1915 TID_AC_VI,
1916 pFrame,
1917 smeSessionId, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301919 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05301920 pMac->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001921 lim_log(pMac, LOGE,
1922 FL("could not send TDLS Dis Request frame!"));
1923 return eSIR_FAILURE;
1924 }
1925
1926 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001927}
1928
1929/*
1930 * Send TDLS setup CNF frame on AP link
1931 */
Jeff Johnson43fee1c2016-11-23 13:12:03 -08001932static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001933tSirRetStatus lim_send_tdls_link_setup_cnf_frame(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301934 struct qdf_mac_addr peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 uint8_t dialog,
1936 uint32_t peerCapability,
1937 tpPESession psessionEntry,
1938 uint8_t *addIe, uint16_t addIeLen)
1939{
1940 tDot11fTDLSSetupCnf tdlsSetupCnf;
1941 uint32_t status = 0;
1942 uint32_t nPayload = 0;
1943 uint32_t nBytes = 0;
1944 uint32_t header_offset = 0;
1945 uint8_t *pFrame;
1946 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301947 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001948#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1949 uint32_t padLen = 0;
1950#endif
1951 uint8_t smeSessionId = 0;
1952
1953 /*
1954 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1955 * and then hand it off to 'dot11f_pack_probe_request' (for
1956 * serialization). We start by zero-initializing the structure:
1957 */
1958 smeSessionId = psessionEntry->smeSessionId;
1959
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301960 qdf_mem_set((uint8_t *) &tdlsSetupCnf, sizeof(tDot11fTDLSSetupCnf), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961
1962 /*
1963 * setup Fixed fields,
1964 */
1965 tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
1966 tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF;
1967 tdlsSetupCnf.DialogToken.token = dialog;
1968
1969 populate_dot11f_link_iden(pMac, psessionEntry,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08001970 &tdlsSetupCnf.LinkIdentifier, peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001971 TDLS_INITIATOR);
1972 /*
1973 * TODO: we need to see if we have to support conditions where we have
1974 * EDCA parameter info element is needed a) if we need different QOS
1975 * parameters for off channel operations or QOS is not supported on
1976 * AP link and we wanted to QOS on direct link.
1977 */
1978
1979 /* Check self and peer WMM capable */
1980 if ((1 == pMac->lim.gLimTDLSWmmMode) &&
1981 (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) {
1982 lim_log(pMac, LOG1, FL("populate WMM praram in Setup Confirm"));
1983 populate_dot11f_wmm_params(pMac, &tdlsSetupCnf.WMMParams,
1984 psessionEntry);
1985 }
1986
1987 /* Check peer is VHT capable */
1988 if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) {
1989 populate_dot11f_vht_operation(pMac,
1990 psessionEntry,
1991 &tdlsSetupCnf.VHTOperation);
1992 populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
1993 } else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) { /* Check peer is HT capable */
1994 populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
1995 }
1996
1997 /*
1998 * now we pack it. First, how much space are we going to need?
1999 */
2000 status = dot11f_get_packed_tdls_setup_cnf_size(pMac, &tdlsSetupCnf,
2001 &nPayload);
2002 if (DOT11F_FAILED(status)) {
2003 lim_log(pMac, LOGE,
2004 FL(
2005 "Failed to calculate the packed size for a Setup Confirm (0x%08x)."
2006 ),
2007 status);
2008 /* We'll fall back on the worst case scenario: */
2009 nPayload = sizeof(tDot11fProbeRequest);
2010 } else if (DOT11F_WARNED(status)) {
2011 lim_log(pMac, LOGW,
2012 FL(
2013 "There were warnings while calculating the packed size for Setup Confirm (0x%08x)."
2014 ),
2015 status);
2016 }
2017
2018 /*
2019 * This frame is going out from PE as data frames with special ethertype
2020 * 89-0d.
2021 * 8 bytes of RFC 1042 header
2022 */
2023
2024 nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
2025 ? sizeof(tSirMacDataHdr3a) :
2026 sizeof(tSirMacMgmtHdr))
2027 + sizeof(eth_890d_header)
2028 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
2029
2030#ifndef NO_PAD_TDLS_MIN_8023_SIZE
2031 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
2032 Hence AP itself padding some bytes, which caused teardown packet is dropped at
2033 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
2034 */
2035 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
2036 padLen =
2037 MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
2038
2039 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
2040 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
2041 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
2042
2043 nBytes += padLen;
2044 }
2045#endif
2046
2047 /* Ok-- try to allocate memory from MGMT PKT pool */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302048 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002049 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302050 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002051 lim_log(pMac, LOGE,
2052 FL(
2053 "Failed to allocate %d bytes for a TDLS Setup Confirm."
2054 ),
2055 nBytes);
2056 return eSIR_MEM_ALLOC_FAILED;
2057 }
2058
2059 /* zero out the memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302060 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002061
2062 /*
2063 * IE formation, memory allocation is completed, Now form TDLS discovery
2064 * request frame
2065 */
2066
2067 /* fill out the buffer descriptor */
2068
2069 header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
2070 LINK_IDEN_ADDR_OFFSET
2071 (tdlsSetupCnf), TDLS_LINK_AP,
2072 TDLS_INITIATOR, TID_AC_VI,
2073 psessionEntry);
2074
2075 status = dot11f_pack_tdls_setup_cnf(pMac, &tdlsSetupCnf, pFrame
2076 + header_offset, nPayload, &nPayload);
2077
2078 if (DOT11F_FAILED(status)) {
2079 lim_log(pMac, LOGE,
2080 FL("Failed to pack a TDLS discovery req (0x%08x)."),
2081 status);
2082 cds_packet_free((void *)pPacket);
2083 return eSIR_FAILURE;
2084 } else if (DOT11F_WARNED(status)) {
2085 lim_log(pMac, LOGW,
2086 FL(
2087 "There were warnings while packing TDLS Discovery Request (0x%08x)."
2088 ),
2089 status);
2090 }
2091 /* Copy the additional IE. */
2092 /* TODO : addIe is added at the end of the frame. This means it doesnt */
2093 /* follow the order. This should be ok, but we should consider changing this */
2094 /* if there is any IOT issue. */
2095 if (addIeLen != 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302096 qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 addIeLen);
2098 }
2099#ifndef NO_PAD_TDLS_MIN_8023_SIZE
2100 if (padLen != 0) {
2101 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
2102 uint8_t *padVendorSpecific =
2103 pFrame + header_offset + nPayload + addIeLen;
2104 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
2105 padVendorSpecific[0] = 221;
2106 padVendorSpecific[1] = padLen - 2;
2107 padVendorSpecific[2] = 0x00;
2108 padVendorSpecific[3] = 0xA0;
2109 padVendorSpecific[4] = 0xC6;
2110
2111 lim_log(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"),
2112 padLen);
2113
2114 /* padding zero if more than 5 bytes are required */
2115 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302116 qdf_mem_set(pFrame + header_offset + nPayload +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002117 addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
2118 padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
2119 }
2120#endif
2121
2122 lim_log(pMac, LOG1,
2123 FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
2124 SIR_MAC_TDLS_SETUP_CNF,
2125 lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_CNF),
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002126 MAC_ADDR_ARRAY(peer_mac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002127
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05302128 pMac->lim.tdls_frm_session_id = psessionEntry->peSessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002129
Poddar, Siddarthb61cf642016-04-28 16:02:39 +05302130 qdf_status = wma_tx_frame_with_tx_complete_send(pMac, pPacket,
2131 (uint16_t) nBytes,
2132 TID_AC_VI,
2133 pFrame,
2134 smeSessionId, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002135
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302136 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Masti, Narayanraddi6319f062016-09-03 18:49:22 +05302137 pMac->lim.tdls_frm_session_id = NO_SESSION;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 lim_log(pMac, LOGE,
2139 FL("could not send TDLS Setup Confirm frame"));
2140 return eSIR_FAILURE;
2141
2142 }
2143
2144 return eSIR_SUCCESS;
2145}
2146
2147/* This Function is similar to populate_dot11f_ht_caps, except that the HT Capabilities
2148 * are considered from the AddStaReq rather from the cfg.dat as in populate_dot11f_ht_caps
2149 */
2150static tSirRetStatus lim_tdls_populate_dot11f_ht_caps(tpAniSirGlobal pMac,
2151 tpPESession psessionEntry,
2152 tSirTdlsAddStaReq *
2153 pTdlsAddStaReq,
2154 tDot11fIEHTCaps *pDot11f)
2155{
2156 uint32_t nCfgValue;
2157 uint8_t nCfgValue8;
2158 tSirMacHTParametersInfo *pHTParametersInfo;
2159 union {
2160 uint16_t nCfgValue16;
2161 tSirMacHTCapabilityInfo htCapInfo;
2162 tSirMacExtendedHTCapabilityInfo extHtCapInfo;
2163 } uHTCapabilityInfo;
2164
2165 tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
2166 tSirMacASCapabilityInfo *pASCapabilityInfo;
2167
2168 nCfgValue = pTdlsAddStaReq->htCap.capInfo;
2169
2170 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2171
2172 pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap;
2173 pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
2174 pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField;
2175 pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz;
2176 pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz;
2177 pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC;
2178 pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC;
2179 pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA;
2180 pDot11f->maximalAMSDUsize =
2181 uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
2182 pDot11f->dsssCckMode40MHz =
2183 uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
2184 pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp;
2185 pDot11f->stbcControlFrame =
2186 uHTCapabilityInfo.htCapInfo.stbcControlFrame;
2187 pDot11f->lsigTXOPProtection =
2188 uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;
2189
2190 /*
2191 * All sessionized entries will need the check below
2192 * Only in case of NO session
2193 */
2194 if (psessionEntry == NULL) {
2195 pDot11f->supportedChannelWidthSet =
2196 uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet;
2197 } else {
2198 pDot11f->supportedChannelWidthSet =
2199 psessionEntry->htSupportedChannelWidthSet;
2200 }
2201
2202 /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
2203 eHT_CHANNEL_WIDTH_20MHZ */
2204 if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
2205 pDot11f->shortGI40MHz = 0;
2206 }
2207
2208 lim_log(pMac, LOG1,
2209 FL(
2210 "SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d"
2211 ),
2212 pDot11f->supportedChannelWidthSet,
2213 pDot11f->mimoPowerSave,
2214 pDot11f->greenField,
2215 pDot11f->shortGI20MHz,
2216 pDot11f->shortGI40MHz,
2217 pDot11f->dsssCckMode40MHz);
2218
2219 nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo;
2220
2221 nCfgValue8 = (uint8_t) nCfgValue;
2222 pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;
2223
2224 pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
2225 pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
2226 pDot11f->reserved1 = pHTParametersInfo->reserved;
2227
2228 lim_log(pMac, LOG1, FL("AMPDU Param: %x"), nCfgValue);
2229
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302230 qdf_mem_copy(pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002231 SIZE_OF_SUPPORTED_MCS_SET);
2232
2233 nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;
2234
2235 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2236
2237 pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
2238 pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
2239 pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
2240
2241 nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;
2242
2243 pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
2244 pDot11f->txBF = pTxBFCapabilityInfo->txBF;
2245 pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
2246 pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
2247 pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
2248 pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
2249 pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
2250 pDot11f->calibration = pTxBFCapabilityInfo->calibration;
2251 pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
2252 pDot11f->explicitUncompressedSteeringMatrix =
2253 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
2254 pDot11f->explicitBFCSIFeedback =
2255 pTxBFCapabilityInfo->explicitBFCSIFeedback;
2256 pDot11f->explicitUncompressedSteeringMatrixFeedback =
2257 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
2258 pDot11f->explicitCompressedSteeringMatrixFeedback =
2259 pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
2260 pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
2261 pDot11f->uncompressedSteeringMatrixBFAntennae =
2262 pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
2263 pDot11f->compressedSteeringMatrixBFAntennae =
2264 pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
2265
2266 nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo;
2267
2268 nCfgValue8 = (uint8_t) nCfgValue;
2269
2270 pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
2271 pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
2272 pDot11f->explicitCSIFeedbackTx =
2273 pASCapabilityInfo->explicitCSIFeedbackTx;
2274 pDot11f->antennaIndicesFeedbackTx =
2275 pASCapabilityInfo->antennaIndicesFeedbackTx;
2276 pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
2277 pDot11f->antennaIndicesFeedback =
2278 pASCapabilityInfo->antennaIndicesFeedback;
2279 pDot11f->rxAS = pASCapabilityInfo->rxAS;
2280 pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
2281
2282 pDot11f->present = pTdlsAddStaReq->htcap_present;
2283
2284 return eSIR_SUCCESS;
2285
2286}
2287
Jeff Johnson43fee1c2016-11-23 13:12:03 -08002288static tSirRetStatus
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002289lim_tdls_populate_dot11f_vht_caps(tpAniSirGlobal pMac,
2290 tSirTdlsAddStaReq *pTdlsAddStaReq,
2291 tDot11fIEVHTCaps *pDot11f)
2292{
2293 uint32_t nCfgValue = 0;
2294 union {
2295 uint32_t nCfgValue32;
2296 tSirMacVHTCapabilityInfo vhtCapInfo;
2297 } uVHTCapabilityInfo;
2298 union {
2299 uint16_t nCfgValue16;
2300 tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
2301 tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
2302 } uVHTSupDataRateInfo;
2303
2304 pDot11f->present = pTdlsAddStaReq->vhtcap_present;
2305
2306 nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
2307 uVHTCapabilityInfo.nCfgValue32 = nCfgValue;
2308
2309 pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
2310 pDot11f->supportedChannelWidthSet =
2311 uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
2312 pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
2313 pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
2314 pDot11f->shortGI160and80plus80MHz =
2315 uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
2316 pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
2317 pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
2318 pDot11f->suBeamFormerCap = 0;
2319 pDot11f->suBeamformeeCap = 0;
2320 pDot11f->csnofBeamformerAntSup =
2321 uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
2322 pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
2323 pDot11f->muBeamformerCap = 0;
2324 pDot11f->muBeamformeeCap = 0;
2325 pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
2326 pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
2327 pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
2328 pDot11f->vhtLinkAdaptCap =
2329 uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
2330 pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
2331 pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
2332 pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1;
2333
2334 pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;
2335
2336 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
2337 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2338 pDot11f->rxHighSupDataRate =
2339 uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;
2340
2341 pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;
2342
2343 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
2344 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2345 pDot11f->txSupDataRate =
2346 uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;
2347
2348 pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;
2349
2350 lim_log_vht_cap(pMac, pDot11f);
2351
2352 return eSIR_SUCCESS;
2353
2354}
2355
2356/**
2357 * lim_tdls_populate_matching_rate_set() - populate matching rate set
2358 *
2359 * @mac_ctx - global MAC context
2360 * @stads - station hash entry
2361 * @supp_rate_set - pointer to supported rate set
2362 * @supp_rates_len - length of the supported rates
2363 * @supp_mcs_set - pointer to supported MSC set
2364 * @session_entry - pointer to PE session entry
2365 * @vht_caps - pointer to VHT capability
2366 *
2367 *
2368 * This function gets set of available rates from the config and compare them
2369 * against the set of received supported rates. After the comparison station
2370 * entry's rates is populated with 11A rates and 11B rates.
2371 *
2372 * Return: eSIR_SUCCESS on success, eSIR_FAILURE on failure.
2373 */
2374static tSirRetStatus
2375lim_tdls_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode stads,
2376 uint8_t *supp_rate_set,
2377 uint8_t supp_rates_len,
2378 uint8_t *supp_mcs_set,
2379 tpPESession session_entry,
2380 tDot11fIEVHTCaps *vht_caps)
2381{
2382 tSirMacRateSet temp_rate_set;
2383 uint32_t i, j, val, min, is_a_rate;
2384 tSirMacRateSet temp_rate_set2;
2385 uint32_t phymode;
2386 uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
2387 tpSirSupportedRates rates;
2388 uint8_t a_rateindex = 0;
2389 uint8_t b_rateindex = 0;
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002390 uint8_t nss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391 is_a_rate = 0;
2392 temp_rate_set2.numRates = 0;
2393
2394 lim_get_phy_mode(mac_ctx, &phymode, NULL);
2395
2396 /* get own rate set */
2397 val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
2398 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_OPERATIONAL_RATE_SET,
2399 (uint8_t *) &temp_rate_set.rate,
2400 &val) != eSIR_SUCCESS) {
2401 /* Could not get rateset from CFG. Log error. */
2402 lim_log(mac_ctx, LOGE, FL("could not retrieve rateset"));
2403 val = 0;
2404 }
2405 temp_rate_set.numRates = val;
2406
2407 if (phymode == WNI_CFG_PHY_MODE_11G) {
2408 /* get own extended rate set */
2409 val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
2410 if (wlan_cfg_get_str(mac_ctx,
2411 WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
2412 (uint8_t *) &temp_rate_set2.rate,
2413 &val) != eSIR_SUCCESS)
2414 temp_rate_set2.numRates = val;
2415 }
2416
2417 if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
2418 lim_log(mac_ctx, LOGE, FL("more than 12 rates in CFG"));
Kiran Kumar Lokere9a733a72016-02-17 19:01:15 -08002419 return eSIR_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002420 }
2421
2422 /**
2423 * Handling of the rate set IEs is the following:
2424 * - keep only rates that we support and that the station supports
2425 * - sort and the rates into the pSta->rate array
2426 */
2427
2428 /* Copy all rates in temp_rate_set, there are 12 rates max */
2429 for (i = 0; i < temp_rate_set2.numRates; i++)
2430 temp_rate_set.rate[i + temp_rate_set.numRates] =
2431 temp_rate_set2.rate[i];
2432
2433 temp_rate_set.numRates += temp_rate_set2.numRates;
2434
2435 /**
2436 * Sort rates in temp_rate_set (they are likely to be already sorted)
2437 * put the result in temp_rate_set2
2438 */
2439 temp_rate_set2.numRates = 0;
2440
2441 for (i = 0; i < temp_rate_set.numRates; i++) {
2442 min = 0;
2443 val = 0xff;
2444
2445 for (j = 0; j < temp_rate_set.numRates; j++)
2446 if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
2447 val = temp_rate_set.rate[j] & 0x7f;
2448 min = j;
2449 }
2450
2451 temp_rate_set2.rate[temp_rate_set2.numRates++] =
2452 temp_rate_set.rate[min];
2453 temp_rate_set.rate[min] = 0xff;
2454 }
2455
2456 /**
2457 * Copy received rates in temp_rate_set, the parser has ensured
2458 * unicity of the rates so there cannot be more than 12 .
2459 */
2460 if (supp_rates_len > SIR_MAC_RATESET_EID_MAX) {
2461 lim_log(mac_ctx, LOGW,
2462 FL(
2463 "Supported rates length %d more than the Max limit, reset to Max"
2464 ),
2465 supp_rates_len);
2466 supp_rates_len = SIR_MAC_RATESET_EID_MAX;
2467 }
2468
2469 for (i = 0; i < supp_rates_len; i++)
2470 temp_rate_set.rate[i] = supp_rate_set[i];
2471
2472 temp_rate_set.numRates = supp_rates_len;
2473
2474 rates = &stads->supportedRates;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302475 qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002476
2477 for (i = 0; i < temp_rate_set2.numRates; i++) {
2478 for (j = 0; j < temp_rate_set.numRates; j++) {
2479 if ((temp_rate_set2.rate[i] & 0x7F) !=
2480 (temp_rate_set.rate[j] & 0x7F))
2481 continue;
2482
Sushant Kaushikb50010f2015-07-22 12:22:20 +05302483 if ((b_rateindex > SIR_NUM_11B_RATES) ||
2484 (a_rateindex > SIR_NUM_11A_RATES)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002485 lim_log(mac_ctx, LOGE,
2486 FL("Invalid number of rates (11b->%d, 11a->%d)"),
2487 b_rateindex, a_rateindex);
2488 return eSIR_FAILURE;
2489 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490 if (sirIsArate(temp_rate_set2.rate[i] & 0x7f)) {
2491 is_a_rate = 1;
2492 if (a_rateindex < SIR_NUM_11A_RATES)
2493 rates->llaRates[a_rateindex++] = temp_rate_set2.rate[i];
2494 } else {
2495 if (b_rateindex < SIR_NUM_11B_RATES)
2496 rates->llbRates[b_rateindex++] = temp_rate_set2.rate[i];
2497 }
2498 break;
2499 }
2500 }
2501
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002502 if (IS_5G_CH(session_entry->currentOperChannel))
2503 nss = mac_ctx->vdev_type_nss_5g.tdls;
2504 else
2505 nss = mac_ctx->vdev_type_nss_2g.tdls;
Archana Ramachandran5041b252016-04-25 14:29:25 -07002506
2507 nss = QDF_MIN(nss, mac_ctx->user_configured_nss);
2508
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002509 /* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */
2510#ifdef FEATURE_WLAN_TDLS
2511 if (stads->mlmStaContext.htCapability)
2512#else
2513 if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
2514 (stads->mlmStaContext.htCapability))
2515#endif
2516 {
2517 val = SIZE_OF_SUPPORTED_MCS_SET;
2518 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
2519 mcsSet, &val) != eSIR_SUCCESS) {
2520 /* Could not get rateset from CFG. Log error. */
2521 lim_log(mac_ctx, LOGP,
2522 FL("could not retrieve supportedMCSSet"));
Kiran Kumar Lokere9a733a72016-02-17 19:01:15 -08002523 return eSIR_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524 }
2525
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002526 if (NSS_1x1_MODE == nss)
2527 mcsSet[1] = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 for (i = 0; i < val; i++)
2529 stads->supportedRates.supportedMCSSet[i] =
2530 mcsSet[i] & supp_mcs_set[i];
2531
2532 lim_log(mac_ctx, LOG1,
2533 FL("MCS Rate Set Bitmap from CFG and DPH"));
2534 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
2535 lim_log(mac_ctx, LOG1, FL("%x %x"), mcsSet[i],
2536 stads->supportedRates.supportedMCSSet[i]);
2537 }
2538 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002539 lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps,
Kiran Kumar Lokere6671abd2016-05-02 19:36:19 -07002540 session_entry, nss);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002541 /**
2542 * Set the erpEnabled bit if the phy is in G mode and at least
2543 * one A rate is supported
2544 */
2545 if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate)
2546 stads->erpEnabled = eHAL_SET;
2547
2548 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002549}
2550
2551/*
2552 * update HASH node entry info
2553 */
2554static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
2555 tDphHashNode *pStaDs,
2556 tSirTdlsAddStaReq *pTdlsAddStaReq,
2557 tpPESession psessionEntry)
2558{
2559 tDot11fIEHTCaps htCap = {0,};
2560 tDot11fIEHTCaps *htCaps;
2561 tDot11fIEVHTCaps *pVhtCaps = NULL;
2562 tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002563 tDot11fIEVHTCaps vhtCap;
2564 uint8_t cbMode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565 tpDphHashNode pSessStaDs = NULL;
2566 uint16_t aid;
2567
2568 if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
2569 populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
2570 } else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) {
2571 lim_tdls_populate_dot11f_ht_caps(pMac, NULL, pTdlsAddStaReq, &htCap);
2572 }
2573 htCaps = &htCap;
2574 if (htCaps->present) {
2575 pStaDs->mlmStaContext.htCapability = 1;
2576 pStaDs->htGreenfield = htCaps->greenField;
Naveen Rawat3e8322c2015-11-03 11:05:57 -08002577 /*
2578 * pStaDs->htSupportedChannelWidthSet should have the base
2579 * channel capability. The htSupportedChannelWidthSet of the
2580 * TDLS link on base channel should be less than or equal to
2581 * channel width of STA-AP link. So take this setting from the
2582 * psessionEntry.
2583 */
Selvaraj, Sridharba497d12016-06-24 11:17:08 +05302584 lim_log(pMac, LOG1,
2585 FL("supportedChannelWidthSet 0x%x htSupportedChannelWidthSet 0x%x"),
2586 htCaps->supportedChannelWidthSet,
2587 psessionEntry->htSupportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588 pStaDs->htSupportedChannelWidthSet =
Selvaraj, Sridharba497d12016-06-24 11:17:08 +05302589 (htCaps->supportedChannelWidthSet <
2590 psessionEntry->htSupportedChannelWidthSet) ?
2591 htCaps->supportedChannelWidthSet :
2592 psessionEntry->htSupportedChannelWidthSet;
2593 lim_log(pMac, LOG1, FL("pStaDs->htSupportedChannelWidthSet 0x%x"),
2594 pStaDs->htSupportedChannelWidthSet);
2595
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596 pStaDs->htMIMOPSState = htCaps->mimoPowerSave;
2597 pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
2598 pStaDs->htAMpduDensity = htCaps->mpduDensity;
2599 pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz;
2600 pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
2601 pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
2602 pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
2603 lim_fill_rx_highest_supported_rate(pMac,
2604 &pStaDs->supportedRates.
2605 rxHighestDataRate,
2606 htCaps->supportedMCSSet);
2607 pStaDs->baPolicyFlag = 0xFF;
2608 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N;
2609 pStaDs->ht_caps = pTdlsAddStaReq->htCap.capInfo;
2610 } else {
2611 pStaDs->mlmStaContext.htCapability = 0;
2612 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG;
2613 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 lim_tdls_populate_dot11f_vht_caps(pMac, pTdlsAddStaReq, &vhtCap);
2615 pVhtCaps = &vhtCap;
2616 if (pVhtCaps->present) {
2617 pStaDs->mlmStaContext.vhtCapability = 1;
2618
Kabilan Kannan7ae4d602016-06-13 18:35:54 -07002619 /*
2620 * 11.21.1 General: The channel width of the TDLS direct
2621 * link on the base channel shall not exceed the channel
2622 * width of the BSS to which the TDLS peer STAs are
2623 * associated.
2624 */
Kabilan Kannanb76eff22016-07-21 06:16:04 -07002625 if (psessionEntry->ch_width)
2626 pStaDs->vhtSupportedChannelWidthSet =
2627 psessionEntry->ch_width - 1;
2628 else
2629 pStaDs->vhtSupportedChannelWidthSet =
2630 psessionEntry->ch_width;
2631
Kabilan Kannan7ae4d602016-06-13 18:35:54 -07002632 lim_log(pMac, LOG1, FL("vhtSupportedChannelWidthSet = %hu, htSupportedChannelWidthSet %hu"),
Kabilan Kannanb76eff22016-07-21 06:16:04 -07002633 pStaDs->vhtSupportedChannelWidthSet,
Kabilan Kannan7ae4d602016-06-13 18:35:54 -07002634 pStaDs->htSupportedChannelWidthSet);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002635
2636 pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
2637 pStaDs->vhtBeamFormerCapable = 0;
2638 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
2639 pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&pTdlsAddStaReq->vhtCap);
2640 pVhtCaps_txbf->suBeamformeeCap = 0;
2641 pVhtCaps_txbf->suBeamFormerCap = 0;
2642 pVhtCaps_txbf->muBeamformerCap = 0;
2643 pVhtCaps_txbf->muBeamformeeCap = 0;
2644 pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo;
2645 } else {
2646 pStaDs->mlmStaContext.vhtCapability = 0;
2647 pStaDs->vhtSupportedChannelWidthSet =
2648 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
2649 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002650 /*Calculate the Secondary Coannel Offset */
2651 cbMode = lim_select_cb_mode(pStaDs, psessionEntry,
2652 psessionEntry->currentOperChannel,
2653 pStaDs->vhtSupportedChannelWidthSet);
2654
2655 pStaDs->htSecondaryChannelOffset = cbMode;
2656
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657 if (pStaDs->mlmStaContext.vhtCapability) {
2658 pStaDs->htSecondaryChannelOffset = lim_get_htcb_state(cbMode);
2659 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002660 pSessStaDs = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
2661 &psessionEntry->dph.dphHashTable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002662 /* Lets enable QOS parameter */
Pradeep Reddy POTTETI983107d2016-09-30 15:03:41 +05302663 pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
2664 || pTdlsAddStaReq->htcap_present;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002665 pStaDs->wmeEnabled = 1;
2666 pStaDs->lleEnabled = 0;
2667 /* TDLS Dummy AddSTA does not have qosInfo , is it OK ??
2668 */
2669 pStaDs->qos.capability.qosInfo =
2670 (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);
2671
2672 /* populate matching rate set */
2673
2674 /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
2675 */
2676 lim_tdls_populate_matching_rate_set(pMac, pStaDs,
2677 pTdlsAddStaReq->supported_rates,
2678 pTdlsAddStaReq->supported_rates_length,
2679 (uint8_t *) pTdlsAddStaReq->htCap.
2680 suppMcsSet, psessionEntry, pVhtCaps);
2681
2682 /* TDLS Dummy AddSTA does not have right capability , is it OK ??
2683 */
2684 pStaDs->mlmStaContext.capabilityInfo =
2685 (*(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);
2686
2687 return;
2688}
2689
2690/*
2691 * Add STA for TDLS setup procedure
2692 */
2693static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
2694 tSirTdlsAddStaReq *pAddStaReq,
2695 tpPESession psessionEntry)
2696{
2697 tpDphHashNode pStaDs = NULL;
2698 tSirRetStatus status = eSIR_SUCCESS;
2699 uint16_t aid = 0;
2700
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002701 pStaDs = dph_lookup_hash_entry(pMac, pAddStaReq->peermac.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702 &psessionEntry->dph.dphHashTable);
2703 if (NULL == pStaDs) {
2704 aid = lim_assign_peer_idx(pMac, psessionEntry);
2705
2706 if (!aid) {
2707 lim_log(pMac, LOGE,
2708 FL("No more free AID for peer "
2709 MAC_ADDRESS_STR),
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002710 MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711 return eSIR_FAILURE;
2712 }
2713
2714 /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
2715 SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
2716
2717 lim_log(pMac, LOG1, FL("Aid = %d, for peer =" MAC_ADDRESS_STR),
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002718 aid, MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002719 pStaDs =
2720 dph_get_hash_entry(pMac, aid,
2721 &psessionEntry->dph.dphHashTable);
2722
2723 if (pStaDs) {
2724 (void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
2725 psessionEntry);
2726 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, aid,
2727 psessionEntry);
2728 }
2729
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08002730 pStaDs = dph_add_hash_entry(pMac, pAddStaReq->peermac.bytes,
2731 aid, &psessionEntry->dph.dphHashTable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002732
2733 if (NULL == pStaDs) {
2734 lim_log(pMac, LOGE, FL("add hash entry failed"));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302735 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002736 return eSIR_FAILURE;
2737 }
2738 }
2739
2740 lim_tdls_update_hash_node_info(pMac, pStaDs, pAddStaReq, psessionEntry);
2741
2742 pStaDs->staType = STA_ENTRY_TDLS_PEER;
2743
2744 status =
2745 lim_add_sta(pMac, pStaDs,
2746 (pAddStaReq->tdlsAddOper ==
2747 TDLS_OPER_UPDATE) ? true : false, psessionEntry);
2748
2749 if (eSIR_SUCCESS != status) {
2750 /* should not fail */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302751 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002752 }
2753 return status;
2754}
2755
2756/*
2757 * Del STA, after Link is teardown or discovery response sent on direct link
2758 */
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002759static tpDphHashNode lim_tdls_del_sta(tpAniSirGlobal pMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302760 struct qdf_mac_addr peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002761 tpPESession psessionEntry)
2762{
2763 tSirRetStatus status = eSIR_SUCCESS;
2764 uint16_t peerIdx = 0;
2765 tpDphHashNode pStaDs = NULL;
2766
Srinivas Girigowda84f42922015-11-19 16:28:05 -08002767 pStaDs = dph_lookup_hash_entry(pMac, peerMac.bytes, &peerIdx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002768 &psessionEntry->dph.dphHashTable);
2769
2770 if (pStaDs) {
2771
2772 lim_log(pMac, LOG1, FL("DEL STA peer MAC: "MAC_ADDRESS_STR),
2773 MAC_ADDR_ARRAY(pStaDs->staAddr));
2774
2775 lim_log(pMac, LOG1, FL("STA type = %x, sta idx = %x"),
2776 pStaDs->staType,
2777 pStaDs->staIndex);
2778
2779 status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
2780 }
2781
2782 return pStaDs;
2783}
2784
2785/*
2786 * Once Link is setup with PEER, send Add STA ind to SME
2787 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302788static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002789 uint8_t sessionId,
2790 tSirMacAddr peerMac,
2791 uint8_t updateSta,
2792 tDphHashNode *pStaDs, uint8_t status)
2793{
2794 tSirMsgQ mmhMsg = { 0 };
2795 tSirTdlsAddStaRsp *addStaRsp = NULL;
2796 mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP;
2797
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302798 addStaRsp = qdf_mem_malloc(sizeof(tSirTdlsAddStaRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799 if (NULL == addStaRsp) {
2800 lim_log(pMac, LOGE, FL("Failed to allocate memory"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302801 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002802 }
2803
2804 addStaRsp->sessionId = sessionId;
2805 addStaRsp->statusCode = status;
2806 if (pStaDs) {
2807 addStaRsp->staId = pStaDs->staIndex;
2808 addStaRsp->ucastSig = pStaDs->ucUcastSig;
2809 addStaRsp->bcastSig = pStaDs->ucBcastSig;
2810 }
2811 if (peerMac) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302812 qdf_mem_copy(addStaRsp->peermac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302813 (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002814 }
2815 if (updateSta)
2816 addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
2817 else
2818 addStaRsp->tdlsAddOper = TDLS_OPER_ADD;
2819
2820 addStaRsp->length = sizeof(tSirTdlsAddStaRsp);
2821 addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP;
2822
2823 mmhMsg.bodyptr = addStaRsp;
2824 mmhMsg.bodyval = 0;
2825 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2826
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302827 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002828}
2829
2830/*
2831 * STA RSP received from HAL
2832 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302833QDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002834 tpPESession psessionEntry)
2835{
2836 tAddStaParams *pAddStaParams = (tAddStaParams *) msg;
2837 uint8_t status = eSIR_SUCCESS;
2838 tDphHashNode *pStaDs = NULL;
2839 uint16_t aid = 0;
2840
2841 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2842 lim_log(pMac, LOG1, FL("staIdx=%d, staMac="MAC_ADDRESS_STR),
2843 pAddStaParams->staIdx,
2844 MAC_ADDR_ARRAY(pAddStaParams->staMac));
2845
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302846 if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302847 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002848 lim_log(pMac, LOGE, FL("Add sta failed "));
2849 status = eSIR_FAILURE;
2850 goto add_sta_error;
2851 }
2852
2853 pStaDs = dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &aid,
2854 &psessionEntry->dph.dphHashTable);
2855 if (NULL == pStaDs) {
2856 lim_log(pMac, LOGE, FL("pStaDs is NULL "));
2857 status = eSIR_FAILURE;
2858 goto add_sta_error;
2859 }
2860
2861 pStaDs->bssId = pAddStaParams->bssIdx;
2862 pStaDs->staIndex = pAddStaParams->staIdx;
2863 pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
2864 pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
2865 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
2866 pStaDs->valid = 1;
2867add_sta_error:
2868 status = lim_send_sme_tdls_add_sta_rsp(pMac, psessionEntry->smeSessionId,
2869 pAddStaParams->staMac,
2870 pAddStaParams->updateSta, pStaDs,
2871 status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302872 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002873 return status;
2874}
2875
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002876/**
2877 * lim_process_sme_tdls_mgmt_send_req() - send out tdls management frames
2878 *
2879 * @mac_ctx - global mac context
2880 * @msg - message buffer received from SME.
2881 *
2882 * Process Send Mgmt Request from SME and transmit to AP.
2883 *
2884 * Return: eSIR_SUCCESS on success, error code otherwise
2885 */
2886tSirRetStatus lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx,
2887 uint32_t *msg)
2888{
2889 /* get all discovery request parameters */
2890 tSirTdlsSendMgmtReq *send_req = (tSirTdlsSendMgmtReq *) msg;
2891 tpPESession session_entry;
2892 uint8_t session_id;
2893 tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS;
2894
2895 lim_log(mac_ctx, LOG1, FL("Send Mgmt Recieved"));
2896 session_entry = pe_find_session_by_bssid(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002897 send_req->bssid.bytes, &session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002898 if (NULL == session_entry) {
2899 lim_log(mac_ctx, LOGE,
2900 FL("PE Session does not exist for given sme session_id %d"),
2901 send_req->sessionId);
2902 goto lim_tdls_send_mgmt_error;
2903 }
2904
2905 /* check if we are in proper state to work as TDLS client */
2906 if (!LIM_IS_STA_ROLE(session_entry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302907 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908 FL("send mgmt received in wrong system Role %d"),
2909 GET_LIM_SYSTEM_ROLE(session_entry));
2910 goto lim_tdls_send_mgmt_error;
2911 }
2912
2913 /*
2914 * if we are still good, go ahead and check if we are in proper state to
2915 * do TDLS discovery req/rsp/....frames.
2916 */
2917 if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
2918 (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
2919 lim_log(mac_ctx, LOGE,
2920 FL("send mgmt received in invalid LIMsme state (%d)"),
2921 session_entry->limSmeState);
2922 goto lim_tdls_send_mgmt_error;
2923 }
2924
Abhishek Singh437606a2016-04-27 13:51:49 +05302925 cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
2926 SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION,
2927 send_req->reqType, send_req->peer_mac.bytes);
2928
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002929 switch (send_req->reqType) {
2930 case SIR_MAC_TDLS_DIS_REQ:
2931 lim_log(mac_ctx, LOG1, FL("Transmit Discovery Request Frame"));
2932 /* format TDLS discovery request frame and transmit it */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002933 lim_send_tdls_dis_req_frame(mac_ctx, send_req->peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002934 send_req->dialog, session_entry);
2935 result_code = eSIR_SME_SUCCESS;
2936 break;
2937 case SIR_MAC_TDLS_DIS_RSP:
2938 lim_log(mac_ctx, LOG1, FL("Transmit Discovery Response Frame"));
2939 /* Send a response mgmt action frame */
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002940 lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002941 send_req->dialog, session_entry, &send_req->addIe[0],
2942 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2943 result_code = eSIR_SME_SUCCESS;
2944 break;
2945 case SIR_MAC_TDLS_SETUP_REQ:
2946 lim_log(mac_ctx, LOG1, FL("Transmit Setup Request Frame"));
2947 lim_send_tdls_link_setup_req_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002948 send_req->peer_mac, send_req->dialog, session_entry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002949 &send_req->addIe[0],
2950 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2951 result_code = eSIR_SME_SUCCESS;
2952 break;
2953 case SIR_MAC_TDLS_SETUP_RSP:
2954 lim_log(mac_ctx, LOG1, FL("Transmit Setup Response Frame"));
2955 lim_send_tdls_setup_rsp_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002956 send_req->peer_mac, send_req->dialog, session_entry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002957 send_req->statusCode, &send_req->addIe[0],
2958 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2959 result_code = eSIR_SME_SUCCESS;
2960 break;
2961 case SIR_MAC_TDLS_SETUP_CNF:
2962 lim_log(mac_ctx, LOG1, FL("Transmit Setup Confirm Frame"));
2963 lim_send_tdls_link_setup_cnf_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002964 send_req->peer_mac, send_req->dialog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002965 send_req->peerCapability, session_entry,
2966 &send_req->addIe[0],
2967 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2968 result_code = eSIR_SME_SUCCESS;
2969 break;
2970 case SIR_MAC_TDLS_TEARDOWN:
2971 lim_log(mac_ctx, LOG1, FL("Transmit Teardown Frame"));
2972 lim_send_tdls_teardown_frame(mac_ctx,
Srinivas Girigowdaa9d12f12015-11-24 11:26:40 -08002973 send_req->peer_mac, send_req->statusCode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002974 send_req->responder, session_entry,
2975 &send_req->addIe[0],
2976 (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
2977 result_code = eSIR_SME_SUCCESS;
2978 break;
2979 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
2980 break;
2981 case SIR_MAC_TDLS_CH_SWITCH_REQ:
2982 break;
2983 case SIR_MAC_TDLS_CH_SWITCH_RSP:
2984 break;
2985 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
2986 break;
2987 default:
2988 break;
2989 }
2990
2991lim_tdls_send_mgmt_error:
2992 lim_send_sme_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP,
2993 result_code, send_req->sessionId,
2994 send_req->transactionId);
2995
2996 return eSIR_SUCCESS;
2997}
2998
2999/*
3000 * Send Response to Link Establish Request to SME
3001 */
3002void lim_send_sme_tdls_link_establish_req_rsp(tpAniSirGlobal pMac,
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003003 uint8_t sessionId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303004 struct qdf_mac_addr *peermac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003005 tDphHashNode *pStaDs, uint8_t status)
3006{
3007 tSirMsgQ mmhMsg = { 0 };
3008
3009 tSirTdlsLinkEstablishReqRsp *pTdlsLinkEstablishReqRsp = NULL;
3010
3011 pTdlsLinkEstablishReqRsp =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303012 qdf_mem_malloc(sizeof(tSirTdlsLinkEstablishReqRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003013 if (NULL == pTdlsLinkEstablishReqRsp) {
3014 lim_log(pMac, LOGE, FL("Failed to allocate memory"));
3015 return;
3016 }
3017 pTdlsLinkEstablishReqRsp->statusCode = status;
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003018 if (peermac)
Anurag Chouhanc5548422016-02-24 18:33:27 +05303019 qdf_copy_macaddr(&pTdlsLinkEstablishReqRsp->peermac, peermac);
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003020
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003021 pTdlsLinkEstablishReqRsp->sessionId = sessionId;
3022 mmhMsg.type = eWNI_SME_TDLS_LINK_ESTABLISH_RSP;
3023 mmhMsg.bodyptr = pTdlsLinkEstablishReqRsp;
3024 mmhMsg.bodyval = 0;
3025 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
3026 return;
3027
3028}
3029
3030/*
3031 * Once link is teardown, send Del Peer Ind to SME
3032 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303033static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003034 uint8_t sessionId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303035 struct qdf_mac_addr peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003036 tDphHashNode *pStaDs, uint8_t status)
3037{
3038 tSirMsgQ mmhMsg = { 0 };
3039 tSirTdlsDelStaRsp *pDelSta = NULL;
3040 mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP;
3041
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303042 pDelSta = qdf_mem_malloc(sizeof(tSirTdlsDelStaRsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003043 if (NULL == pDelSta) {
3044 lim_log(pMac, LOGE, FL("Failed to allocate memory"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303045 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003046 }
3047
3048 pDelSta->sessionId = sessionId;
3049 pDelSta->statusCode = status;
3050 if (pStaDs) {
3051 pDelSta->staId = pStaDs->staIndex;
3052 } else
3053 pDelSta->staId = STA_INVALID_IDX;
3054
Anurag Chouhanc5548422016-02-24 18:33:27 +05303055 qdf_copy_macaddr(&pDelSta->peermac, &peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003056
3057 pDelSta->length = sizeof(tSirTdlsDelStaRsp);
3058 pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP;
3059
3060 mmhMsg.bodyptr = pDelSta;
3061
3062 mmhMsg.bodyval = 0;
3063 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303064 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065
3066}
3067
3068/*
3069 * Process Send Mgmt Request from SME and transmit to AP.
3070 */
3071tSirRetStatus lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
3072 uint32_t *pMsgBuf)
3073{
3074 /* get all discovery request parameters */
3075 tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq *) pMsgBuf;
3076 tpPESession psessionEntry;
3077 uint8_t sessionId;
3078
3079 lim_log(pMac, LOG1, FL("TDLS Add STA Request Recieved"));
3080 psessionEntry =
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08003081 pe_find_session_by_bssid(pMac, pAddStaReq->bssid.bytes,
3082 &sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003083 if (psessionEntry == NULL) {
3084 lim_log(pMac, LOGE,
3085 FL(
3086 "PE Session does not exist for given sme sessionId %d"
3087 ),
3088 pAddStaReq->sessionId);
3089 goto lim_tdls_add_sta_error;
3090 }
3091
3092 /* check if we are in proper state to work as TDLS client */
3093 if (!LIM_IS_STA_ROLE(psessionEntry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303094 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095 "send mgmt received in wrong system Role %d",
3096 GET_LIM_SYSTEM_ROLE(psessionEntry));
3097 goto lim_tdls_add_sta_error;
3098 }
3099
3100 /*
3101 * if we are still good, go ahead and check if we are in proper state to
3102 * do TDLS discovery req/rsp/....frames.
3103 */
3104 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3105 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3106
3107 lim_log(pMac, LOGE,
3108 FL("send mgmt received in invalid LIMsme state (%d)"),
3109 psessionEntry->limSmeState);
3110 goto lim_tdls_add_sta_error;
3111 }
3112
3113 pMac->lim.gLimAddStaTdls = true;
3114
3115 /* To start with, send add STA request to HAL */
3116 if (eSIR_FAILURE == lim_tdls_setup_add_sta(pMac, pAddStaReq, psessionEntry)) {
3117 lim_log(pMac, LOGE,
3118 FL("Add TDLS Station request failed"));
3119 goto lim_tdls_add_sta_error;
3120 }
3121 return eSIR_SUCCESS;
3122lim_tdls_add_sta_error:
3123 lim_send_sme_tdls_add_sta_rsp(pMac,
Srinivas Girigowdaa35f1092015-11-19 19:38:00 -08003124 pAddStaReq->sessionId,
3125 pAddStaReq->peermac.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003126 (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE),
3127 NULL, eSIR_FAILURE);
3128
3129 return eSIR_SUCCESS;
3130}
3131
3132/*
3133 * Process Del Sta Request from SME .
3134 */
3135tSirRetStatus lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
3136 uint32_t *pMsgBuf)
3137{
3138 /* get all discovery request parameters */
3139 tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
3140 tpPESession psessionEntry;
3141 uint8_t sessionId;
3142 tpDphHashNode pStaDs = NULL;
3143
3144 lim_log(pMac, LOG1, FL("TDLS Delete STA Request Recieved"));
3145 psessionEntry =
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003146 pe_find_session_by_bssid(pMac, pDelStaReq->bssid.bytes,
3147 &sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003148 if (psessionEntry == NULL) {
3149 lim_log(pMac, LOGE,
3150 FL(
3151 "PE Session does not exist for given sme sessionId %d"
3152 ),
3153 pDelStaReq->sessionId);
3154 lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003155 pDelStaReq->peermac, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003156 eSIR_FAILURE);
3157 return eSIR_FAILURE;
3158 }
3159
3160 /* check if we are in proper state to work as TDLS client */
3161 if (!LIM_IS_STA_ROLE(psessionEntry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303162 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163 "Del sta received in wrong system Role %d",
3164 GET_LIM_SYSTEM_ROLE(psessionEntry));
3165 goto lim_tdls_del_sta_error;
3166 }
3167
3168 /*
3169 * if we are still good, go ahead and check if we are in proper state to
3170 * do TDLS discovery req/rsp/....frames.
3171 */
3172 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3173 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3174
3175 lim_log(pMac, LOGE,
3176 FL("Del Sta received in invalid LIMsme state (%d)"),
3177 psessionEntry->limSmeState);
3178 goto lim_tdls_del_sta_error;
3179 }
3180
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003181 pStaDs = lim_tdls_del_sta(pMac, pDelStaReq->peermac, psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003182
3183 /* now send indication to SME-->HDD->TL to remove STA from TL */
3184
3185 if (pStaDs) {
3186 lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003187 pDelStaReq->peermac, pStaDs,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003188 eSIR_SUCCESS);
3189 lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
3190
3191 /* Clear the aid in peerAIDBitmap as this aid is now in freepool */
3192 CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap,
3193 pStaDs->assocId);
3194 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
3195 psessionEntry);
3196
3197 return eSIR_SUCCESS;
3198
3199 }
3200
3201lim_tdls_del_sta_error:
3202 lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
Srinivas Girigowda84f42922015-11-19 16:28:05 -08003203 pDelStaReq->peermac, NULL, eSIR_FAILURE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003204
3205 return eSIR_SUCCESS;
3206}
3207
3208/* Intersects the two input arrays and outputs an array */
3209/* For now the array length of uint8_t suffices */
3210static void lim_tdls_get_intersection(uint8_t *input_array1,
3211 uint8_t input1_length,
3212 uint8_t *input_array2,
3213 uint8_t input2_length,
3214 uint8_t *output_array,
3215 uint8_t *output_length)
3216{
3217 uint8_t i, j, k = 0, flag = 0;
3218 for (i = 0; i < input1_length; i++) {
3219 flag = 0;
3220 for (j = 0; j < input2_length; j++) {
3221 if (input_array1[i] == input_array2[j]) {
3222 flag = 1;
3223 break;
3224 }
3225 }
3226 if (flag == 1) {
3227 output_array[k] = input_array1[i];
3228 k++;
3229 }
3230 }
3231 *output_length = k;
3232}
3233
3234/**
3235 * lim_process_sme_tdls_link_establish_req() - process tdls link establishment
3236 * request
3237 *
3238 * @mac_ctx - global MAC context
3239 * @msg_buf - message buffer from SME
3240 *
3241 * Process Link Establishment Request from SME
3242 *
3243 * Return: eSIR_SUCCESS on success, failure code otherwise.
3244 */
3245tSirRetStatus lim_process_sme_tdls_link_establish_req(tpAniSirGlobal mac_ctx,
3246 uint32_t *msg_buf)
3247{
3248 /* get all discovery request parameters */
3249 tSirTdlsLinkEstablishReq *tdls_req =
3250 (tSirTdlsLinkEstablishReq *) msg_buf;
3251 tpPESession session_entry;
3252 uint8_t session_id;
3253 tpTdlsLinkEstablishParams tdls_req_params;
3254 tSirMsgQ msg;
3255 uint16_t peer_idx = 0;
3256 tpDphHashNode stads = NULL;
3257 uint32_t self_num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3258 uint8_t self_supp_chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3259
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303260 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003261 FL("Send Mgmt Recieved"));
3262
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003263 session_entry = pe_find_session_by_bssid(mac_ctx, tdls_req->bssid.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003264 &session_id);
3265 if (NULL == session_entry) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303266 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267 FL("PE Session does not exist for sme session_id %d"),
3268 tdls_req->sessionId);
3269 lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003270 tdls_req->sessionId, &tdls_req->peermac, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271 eSIR_FAILURE);
3272 return eSIR_FAILURE;
3273 }
3274
3275 /* check if we are in proper state to work as TDLS client */
3276 if (!LIM_IS_STA_ROLE(session_entry)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303277 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 FL("TDLS Link Establish Request received in wrong system Role %d"),
3279 GET_LIM_SYSTEM_ROLE(session_entry));
3280 goto lim_tdls_link_establish_error;
3281 }
3282
3283 /*
3284 * if we are still good, go ahead and check if we are in proper state to
3285 * do TDLS discovery req/rsp/....frames.
3286 */
3287 if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3288 (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3289 lim_log(mac_ctx, LOGE,
3290 FL("TDLS Link Establish Request received in invalid LIMsme state (%d)"),
3291 session_entry->limSmeState);
3292 goto lim_tdls_link_establish_error;
3293 }
3294
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003295 stads = dph_lookup_hash_entry(mac_ctx, tdls_req->peermac.bytes,
3296 &peer_idx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003297 &session_entry->dph.dphHashTable);
3298 if (NULL == stads) {
3299 lim_log(mac_ctx, LOGE, FL("stads is NULL"));
3300 goto lim_tdls_link_establish_error;
3301 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303302 tdls_req_params = qdf_mem_malloc(sizeof(tTdlsLinkEstablishParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003303 if (NULL == tdls_req_params) {
3304 lim_log(mac_ctx, LOGE,
3305 FL("Unable to allocate memory TDLS Link Establish Request"));
3306 return eSIR_MEM_ALLOC_FAILED;
3307 }
3308
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003309 tdls_req_params->staIdx = stads->staIndex;
3310 tdls_req_params->isResponder = tdls_req->isResponder;
3311 tdls_req_params->uapsdQueues = tdls_req->uapsdQueues;
3312 tdls_req_params->maxSp = tdls_req->maxSp;
3313 tdls_req_params->isBufsta = tdls_req->isBufSta;
3314 tdls_req_params->isOffChannelSupported =
3315 tdls_req->isOffChannelSupported;
3316
3317 if (0 == tdls_req->supportedChannelsLen)
3318 goto send_tdls_establish_request;
3319
3320 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_VALID_CHANNEL_LIST,
3321 self_supp_chan,
3322 &self_num_chan) != eSIR_SUCCESS) {
3323 /**
3324 * Could not get Valid channel list from CFG.
3325 * Log error.
3326 */
3327 lim_log(mac_ctx, LOGE,
3328 FL("could not retrieve Valid channel list"));
3329 }
3330
3331 if (self_num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
3332 lim_log(mac_ctx, LOGE,
3333 FL("Channel List more than Valid Channel list"));
3334 self_num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3335 }
3336
3337 if (tdls_req->supportedChannelsLen > SIR_MAC_MAX_SUPP_CHANNELS) {
3338 lim_log(mac_ctx, LOGE,
3339 FL("Channel List is more than the supported Channel list"));
3340 tdls_req->supportedChannelsLen = SIR_MAC_MAX_SUPP_CHANNELS;
3341 }
3342
3343 lim_tdls_get_intersection(self_supp_chan, self_num_chan,
3344 tdls_req->supportedChannels, tdls_req->supportedChannelsLen,
3345 tdls_req_params->validChannels,
3346 &tdls_req_params->validChannelsLen);
3347
3348send_tdls_establish_request:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303349 qdf_mem_copy(tdls_req_params->validOperClasses,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003350 tdls_req->supportedOperClasses,
3351 tdls_req->supportedOperClassesLen);
3352 tdls_req_params->validOperClassesLen =
3353 tdls_req->supportedOperClassesLen;
3354
3355 msg.type = WMA_SET_TDLS_LINK_ESTABLISH_REQ;
3356 msg.reserved = 0;
3357 msg.bodyptr = tdls_req_params;
3358 msg.bodyval = 0;
3359 if (eSIR_SUCCESS != wma_post_ctrl_msg(mac_ctx, &msg)) {
3360 lim_log(mac_ctx, LOGE, FL("halPostMsgApi failed"));
3361 goto lim_tdls_link_establish_error;
3362 }
3363 return eSIR_SUCCESS;
3364
3365lim_tdls_link_establish_error:
3366 lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
Srinivas Girigowda2e602872015-11-20 20:58:13 -08003367 session_entry->smeSessionId, &tdls_req->peermac, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 eSIR_FAILURE);
3369
3370 return eSIR_SUCCESS;
3371}
3372
3373/**
3374 * lim_delete_tdls_peers() - delete tdls peers
3375 *
3376 * @mac_ctx - global MAC context
3377 * @session_entry - PE session entry
3378 *
3379 * Delete all the TDLS peer connected before leaving the BSS
3380 *
3381 * Return: eSIR_SUCCESS on success, error code otherwise
3382 */
3383tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
3384 tpPESession session_entry)
3385{
3386 tpDphHashNode stads = NULL;
3387 int i, aid;
3388 size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap);
3389
3390 if (NULL == session_entry) {
3391 lim_log(mac_ctx, LOGE, FL("NULL session_entry"));
3392 return eSIR_FAILURE;
3393 }
3394
3395 /*
3396 * Check all the set bit in peerAIDBitmap and delete the peer
3397 * (with that aid) entry from the hash table and add the aid
3398 * in free pool
3399 */
3400 for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) {
3401 for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) {
3402 if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid))
3403 continue;
3404 stads = dph_get_hash_entry(mac_ctx,
3405 (aid + i * (sizeof(uint32_t) << 3)),
3406 &session_entry->dph.dphHashTable);
3407
3408 if (NULL != stads) {
3409 lim_log(mac_ctx, LOGE,
3410 FL("Deleting "MAC_ADDRESS_STR),
3411 MAC_ADDR_ARRAY(stads->staAddr));
3412
3413 lim_send_deauth_mgmt_frame(mac_ctx,
3414 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
3415 stads->staAddr, session_entry, false);
3416 dph_delete_hash_entry(mac_ctx,
3417 stads->staAddr, stads->assocId,
3418 &session_entry->dph.dphHashTable);
3419 }
3420 lim_release_peer_idx(mac_ctx,
3421 (aid + i * (sizeof(uint32_t) << 3)),
3422 session_entry);
3423 CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
3424 }
3425 }
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08003426 if (lim_is_roam_synch_in_progress(session_entry))
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08003427 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003428 lim_send_sme_tdls_delete_all_peer_ind(mac_ctx, session_entry);
3429
3430 return eSIR_SUCCESS;
3431}
3432
3433#endif