tdls.c (44816B)
1/* 2 * NXP Wireless LAN device driver: TDLS handling 3 * 4 * Copyright 2011-2020 NXP 5 * 6 * This software file (the "File") is distributed by NXP 7 * under the terms of the GNU General Public License Version 2, June 1991 8 * (the "License"). You may use, redistribute and/or modify this File in 9 * accordance with the terms and conditions of the License, a copy of which 10 * is available on the worldwide web at 11 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 12 * 13 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 14 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 15 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 16 * this warranty disclaimer. 17 */ 18 19#include "main.h" 20#include "wmm.h" 21#include "11n.h" 22#include "11n_rxreorder.h" 23#include "11ac.h" 24 25#define TDLS_REQ_FIX_LEN 6 26#define TDLS_RESP_FIX_LEN 8 27#define TDLS_CONFIRM_FIX_LEN 6 28#define MWIFIEX_TDLS_WMM_INFO_SIZE 7 29 30static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv, 31 const u8 *mac, u8 status) 32{ 33 struct mwifiex_ra_list_tbl *ra_list; 34 struct list_head *tid_list; 35 struct sk_buff *skb, *tmp; 36 struct mwifiex_txinfo *tx_info; 37 u32 tid; 38 u8 tid_down; 39 40 mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac); 41 spin_lock_bh(&priv->wmm.ra_list_spinlock); 42 43 skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) { 44 if (!ether_addr_equal(mac, skb->data)) 45 continue; 46 47 __skb_unlink(skb, &priv->tdls_txq); 48 tx_info = MWIFIEX_SKB_TXCB(skb); 49 tid = skb->priority; 50 tid_down = mwifiex_wmm_downgrade_tid(priv, tid); 51 52 if (mwifiex_is_tdls_link_setup(status)) { 53 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid, mac); 54 ra_list->tdls_link = true; 55 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 56 } else { 57 tid_list = &priv->wmm.tid_tbl_ptr[tid_down].ra_list; 58 ra_list = list_first_entry_or_null(tid_list, 59 struct mwifiex_ra_list_tbl, list); 60 tx_info->flags &= ~MWIFIEX_BUF_FLAG_TDLS_PKT; 61 } 62 63 if (!ra_list) { 64 mwifiex_write_data_complete(priv->adapter, skb, 0, -1); 65 continue; 66 } 67 68 skb_queue_tail(&ra_list->skb_head, skb); 69 70 ra_list->ba_pkt_count++; 71 ra_list->total_pkt_count++; 72 73 if (atomic_read(&priv->wmm.highest_queued_prio) < 74 tos_to_tid_inv[tid_down]) 75 atomic_set(&priv->wmm.highest_queued_prio, 76 tos_to_tid_inv[tid_down]); 77 78 atomic_inc(&priv->wmm.tx_pkts_queued); 79 } 80 81 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 82 return; 83} 84 85static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv, 86 const u8 *mac) 87{ 88 struct mwifiex_ra_list_tbl *ra_list; 89 struct list_head *ra_list_head; 90 struct sk_buff *skb, *tmp; 91 int i; 92 93 mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac); 94 spin_lock_bh(&priv->wmm.ra_list_spinlock); 95 96 for (i = 0; i < MAX_NUM_TID; i++) { 97 if (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) { 98 ra_list_head = &priv->wmm.tid_tbl_ptr[i].ra_list; 99 list_for_each_entry(ra_list, ra_list_head, list) { 100 skb_queue_walk_safe(&ra_list->skb_head, skb, 101 tmp) { 102 if (!ether_addr_equal(mac, skb->data)) 103 continue; 104 __skb_unlink(skb, &ra_list->skb_head); 105 atomic_dec(&priv->wmm.tx_pkts_queued); 106 ra_list->total_pkt_count--; 107 skb_queue_tail(&priv->tdls_txq, skb); 108 } 109 } 110 } 111 } 112 113 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 114 return; 115} 116 117/* This function appends rate TLV to scan config command. */ 118static int 119mwifiex_tdls_append_rates_ie(struct mwifiex_private *priv, 120 struct sk_buff *skb) 121{ 122 u8 rates[MWIFIEX_SUPPORTED_RATES], *pos; 123 u16 rates_size, supp_rates_size, ext_rates_size; 124 125 memset(rates, 0, sizeof(rates)); 126 rates_size = mwifiex_get_supported_rates(priv, rates); 127 128 supp_rates_size = min_t(u16, rates_size, MWIFIEX_TDLS_SUPPORTED_RATES); 129 130 if (skb_tailroom(skb) < rates_size + 4) { 131 mwifiex_dbg(priv->adapter, ERROR, 132 "Insufficient space while adding rates\n"); 133 return -ENOMEM; 134 } 135 136 pos = skb_put(skb, supp_rates_size + 2); 137 *pos++ = WLAN_EID_SUPP_RATES; 138 *pos++ = supp_rates_size; 139 memcpy(pos, rates, supp_rates_size); 140 141 if (rates_size > MWIFIEX_TDLS_SUPPORTED_RATES) { 142 ext_rates_size = rates_size - MWIFIEX_TDLS_SUPPORTED_RATES; 143 pos = skb_put(skb, ext_rates_size + 2); 144 *pos++ = WLAN_EID_EXT_SUPP_RATES; 145 *pos++ = ext_rates_size; 146 memcpy(pos, rates + MWIFIEX_TDLS_SUPPORTED_RATES, 147 ext_rates_size); 148 } 149 150 return 0; 151} 152 153static void mwifiex_tdls_add_aid(struct mwifiex_private *priv, 154 struct sk_buff *skb) 155{ 156 struct ieee_types_assoc_rsp *assoc_rsp; 157 u8 *pos; 158 159 assoc_rsp = (struct ieee_types_assoc_rsp *)&priv->assoc_rsp_buf; 160 pos = skb_put(skb, 4); 161 *pos++ = WLAN_EID_AID; 162 *pos++ = 2; 163 memcpy(pos, &assoc_rsp->a_id, sizeof(assoc_rsp->a_id)); 164 165 return; 166} 167 168static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv, 169 struct sk_buff *skb) 170{ 171 struct ieee80211_vht_cap vht_cap; 172 u8 *pos; 173 174 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); 175 *pos++ = WLAN_EID_VHT_CAPABILITY; 176 *pos++ = sizeof(struct ieee80211_vht_cap); 177 178 memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap)); 179 180 mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band); 181 memcpy(pos, &vht_cap, sizeof(vht_cap)); 182 183 return 0; 184} 185 186static int 187mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, const u8 *mac, 188 u8 vht_enabled, struct sk_buff *skb) 189{ 190 struct ieee80211_ht_operation *ht_oper; 191 struct mwifiex_sta_node *sta_ptr; 192 struct mwifiex_bssdescriptor *bss_desc = 193 &priv->curr_bss_params.bss_descriptor; 194 u8 *pos; 195 196 sta_ptr = mwifiex_get_sta_entry(priv, mac); 197 if (unlikely(!sta_ptr)) { 198 mwifiex_dbg(priv->adapter, ERROR, 199 "TDLS peer station not found in list\n"); 200 return -1; 201 } 202 203 if (!(le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info))) { 204 mwifiex_dbg(priv->adapter, WARN, 205 "TDLS peer doesn't support ht capabilities\n"); 206 return 0; 207 } 208 209 pos = skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2); 210 *pos++ = WLAN_EID_HT_OPERATION; 211 *pos++ = sizeof(struct ieee80211_ht_operation); 212 ht_oper = (void *)pos; 213 214 ht_oper->primary_chan = bss_desc->channel; 215 216 /* follow AP's channel bandwidth */ 217 if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) && 218 bss_desc->bcn_ht_cap && 219 ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param)) 220 ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param; 221 222 if (vht_enabled) { 223 ht_oper->ht_param = 224 mwifiex_get_sec_chan_offset(bss_desc->channel); 225 ht_oper->ht_param |= BIT(2); 226 } 227 228 memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper, 229 sizeof(struct ieee80211_ht_operation)); 230 231 return 0; 232} 233 234static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv, 235 const u8 *mac, struct sk_buff *skb) 236{ 237 struct mwifiex_bssdescriptor *bss_desc; 238 struct ieee80211_vht_operation *vht_oper; 239 struct ieee80211_vht_cap *vht_cap, *ap_vht_cap = NULL; 240 struct mwifiex_sta_node *sta_ptr; 241 struct mwifiex_adapter *adapter = priv->adapter; 242 u8 supp_chwd_set, peer_supp_chwd_set; 243 u8 *pos, ap_supp_chwd_set, chan_bw; 244 u16 mcs_map_user, mcs_map_resp, mcs_map_result; 245 u16 mcs_user, mcs_resp, nss; 246 u32 usr_vht_cap_info; 247 248 bss_desc = &priv->curr_bss_params.bss_descriptor; 249 250 sta_ptr = mwifiex_get_sta_entry(priv, mac); 251 if (unlikely(!sta_ptr)) { 252 mwifiex_dbg(adapter, ERROR, 253 "TDLS peer station not found in list\n"); 254 return -1; 255 } 256 257 if (!(le32_to_cpu(sta_ptr->tdls_cap.vhtcap.vht_cap_info))) { 258 mwifiex_dbg(adapter, WARN, 259 "TDLS peer doesn't support vht capabilities\n"); 260 return 0; 261 } 262 263 if (!mwifiex_is_bss_in_11ac_mode(priv)) { 264 if (sta_ptr->tdls_cap.extcap.ext_capab[7] & 265 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) { 266 mwifiex_dbg(adapter, WARN, 267 "TDLS peer doesn't support wider bandwidth\n"); 268 return 0; 269 } 270 } else { 271 ap_vht_cap = bss_desc->bcn_vht_cap; 272 } 273 274 pos = skb_put(skb, sizeof(struct ieee80211_vht_operation) + 2); 275 *pos++ = WLAN_EID_VHT_OPERATION; 276 *pos++ = sizeof(struct ieee80211_vht_operation); 277 vht_oper = (struct ieee80211_vht_operation *)pos; 278 279 if (bss_desc->bss_band & BAND_A) 280 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a; 281 else 282 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg; 283 284 /* find the minimum bandwidth between AP/TDLS peers */ 285 vht_cap = &sta_ptr->tdls_cap.vhtcap; 286 supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info); 287 peer_supp_chwd_set = 288 GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap->vht_cap_info)); 289 supp_chwd_set = min_t(u8, supp_chwd_set, peer_supp_chwd_set); 290 291 /* We need check AP's bandwidth when TDLS_WIDER_BANDWIDTH is off */ 292 293 if (ap_vht_cap && sta_ptr->tdls_cap.extcap.ext_capab[7] & 294 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) { 295 ap_supp_chwd_set = 296 GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap->vht_cap_info)); 297 supp_chwd_set = min_t(u8, supp_chwd_set, ap_supp_chwd_set); 298 } 299 300 switch (supp_chwd_set) { 301 case IEEE80211_VHT_CHANWIDTH_80MHZ: 302 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; 303 break; 304 case IEEE80211_VHT_CHANWIDTH_160MHZ: 305 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ; 306 break; 307 case IEEE80211_VHT_CHANWIDTH_80P80MHZ: 308 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ; 309 break; 310 default: 311 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT; 312 break; 313 } 314 315 mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support); 316 mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map); 317 mcs_map_result = 0; 318 319 for (nss = 1; nss <= 8; nss++) { 320 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss); 321 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss); 322 323 if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) || 324 (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED)) 325 SET_VHTNSSMCS(mcs_map_result, nss, 326 IEEE80211_VHT_MCS_NOT_SUPPORTED); 327 else 328 SET_VHTNSSMCS(mcs_map_result, nss, 329 min_t(u16, mcs_user, mcs_resp)); 330 } 331 332 vht_oper->basic_mcs_set = cpu_to_le16(mcs_map_result); 333 334 switch (vht_oper->chan_width) { 335 case IEEE80211_VHT_CHANWIDTH_80MHZ: 336 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ; 337 break; 338 case IEEE80211_VHT_CHANWIDTH_160MHZ: 339 chan_bw = IEEE80211_VHT_CHANWIDTH_160MHZ; 340 break; 341 case IEEE80211_VHT_CHANWIDTH_80P80MHZ: 342 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ; 343 break; 344 default: 345 chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT; 346 break; 347 } 348 vht_oper->center_freq_seg0_idx = 349 mwifiex_get_center_freq_index(priv, BAND_AAC, 350 bss_desc->channel, 351 chan_bw); 352 353 return 0; 354} 355 356static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv, 357 struct sk_buff *skb) 358{ 359 struct ieee_types_extcap *extcap; 360 361 extcap = skb_put(skb, sizeof(struct ieee_types_extcap)); 362 extcap->ieee_hdr.element_id = WLAN_EID_EXT_CAPABILITY; 363 extcap->ieee_hdr.len = 8; 364 memset(extcap->ext_capab, 0, 8); 365 extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED; 366 extcap->ext_capab[3] |= WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH; 367 368 if (priv->adapter->is_hw_11ac_capable) 369 extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED; 370} 371 372static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb) 373{ 374 u8 *pos = skb_put(skb, 3); 375 376 *pos++ = WLAN_EID_QOS_CAPA; 377 *pos++ = 1; 378 *pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB; 379} 380 381static void 382mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private *priv, struct sk_buff *skb) 383{ 384 struct ieee80211_wmm_param_ie *wmm; 385 u8 ac_vi[] = {0x42, 0x43, 0x5e, 0x00}; 386 u8 ac_vo[] = {0x62, 0x32, 0x2f, 0x00}; 387 u8 ac_be[] = {0x03, 0xa4, 0x00, 0x00}; 388 u8 ac_bk[] = {0x27, 0xa4, 0x00, 0x00}; 389 390 wmm = skb_put_zero(skb, sizeof(*wmm)); 391 392 wmm->element_id = WLAN_EID_VENDOR_SPECIFIC; 393 wmm->len = sizeof(*wmm) - 2; 394 wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */ 395 wmm->oui[1] = 0x50; 396 wmm->oui[2] = 0xf2; 397 wmm->oui_type = 2; /* WME */ 398 wmm->oui_subtype = 1; /* WME param */ 399 wmm->version = 1; /* WME ver */ 400 wmm->qos_info = 0; /* U-APSD not in use */ 401 402 /* use default WMM AC parameters for TDLS link*/ 403 memcpy(&wmm->ac[0], ac_be, sizeof(ac_be)); 404 memcpy(&wmm->ac[1], ac_bk, sizeof(ac_bk)); 405 memcpy(&wmm->ac[2], ac_vi, sizeof(ac_vi)); 406 memcpy(&wmm->ac[3], ac_vo, sizeof(ac_vo)); 407} 408 409static void 410mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb, 411 u8 qosinfo) 412{ 413 u8 *buf; 414 415 buf = skb_put(skb, 416 MWIFIEX_TDLS_WMM_INFO_SIZE + sizeof(struct ieee_types_header)); 417 418 *buf++ = WLAN_EID_VENDOR_SPECIFIC; 419 *buf++ = 7; /* len */ 420 *buf++ = 0x00; /* Microsoft OUI 00:50:F2 */ 421 *buf++ = 0x50; 422 *buf++ = 0xf2; 423 *buf++ = 2; /* WME */ 424 *buf++ = 0; /* WME info */ 425 *buf++ = 1; /* WME ver */ 426 *buf++ = qosinfo; /* U-APSD no in use */ 427} 428 429static void mwifiex_tdls_add_bss_co_2040(struct sk_buff *skb) 430{ 431 struct ieee_types_bss_co_2040 *bssco; 432 433 bssco = skb_put(skb, sizeof(struct ieee_types_bss_co_2040)); 434 bssco->ieee_hdr.element_id = WLAN_EID_BSS_COEX_2040; 435 bssco->ieee_hdr.len = sizeof(struct ieee_types_bss_co_2040) - 436 sizeof(struct ieee_types_header); 437 bssco->bss_2040co = 0x01; 438} 439 440static void mwifiex_tdls_add_supported_chan(struct sk_buff *skb) 441{ 442 struct ieee_types_generic *supp_chan; 443 u8 chan_supp[] = {1, 11}; 444 445 supp_chan = skb_put(skb, 446 (sizeof(struct ieee_types_header) + sizeof(chan_supp))); 447 supp_chan->ieee_hdr.element_id = WLAN_EID_SUPPORTED_CHANNELS; 448 supp_chan->ieee_hdr.len = sizeof(chan_supp); 449 memcpy(supp_chan->data, chan_supp, sizeof(chan_supp)); 450} 451 452static void mwifiex_tdls_add_oper_class(struct sk_buff *skb) 453{ 454 struct ieee_types_generic *reg_class; 455 u8 rc_list[] = {1, 456 1, 2, 3, 4, 12, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33}; 457 reg_class = skb_put(skb, 458 (sizeof(struct ieee_types_header) + sizeof(rc_list))); 459 reg_class->ieee_hdr.element_id = WLAN_EID_SUPPORTED_REGULATORY_CLASSES; 460 reg_class->ieee_hdr.len = sizeof(rc_list); 461 memcpy(reg_class->data, rc_list, sizeof(rc_list)); 462} 463 464static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, 465 const u8 *peer, u8 action_code, 466 u8 dialog_token, 467 u16 status_code, struct sk_buff *skb) 468{ 469 struct ieee80211_tdls_data *tf; 470 int ret; 471 u16 capab; 472 struct ieee80211_ht_cap *ht_cap; 473 u8 radio, *pos; 474 475 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; 476 477 tf = skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); 478 memcpy(tf->da, peer, ETH_ALEN); 479 memcpy(tf->sa, priv->curr_addr, ETH_ALEN); 480 tf->ether_type = cpu_to_be16(ETH_P_TDLS); 481 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; 482 483 switch (action_code) { 484 case WLAN_TDLS_SETUP_REQUEST: 485 tf->category = WLAN_CATEGORY_TDLS; 486 tf->action_code = WLAN_TDLS_SETUP_REQUEST; 487 skb_put(skb, sizeof(tf->u.setup_req)); 488 tf->u.setup_req.dialog_token = dialog_token; 489 tf->u.setup_req.capability = cpu_to_le16(capab); 490 ret = mwifiex_tdls_append_rates_ie(priv, skb); 491 if (ret) { 492 dev_kfree_skb_any(skb); 493 return ret; 494 } 495 496 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 497 *pos++ = WLAN_EID_HT_CAPABILITY; 498 *pos++ = sizeof(struct ieee80211_ht_cap); 499 ht_cap = (void *)pos; 500 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 501 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 502 if (ret) { 503 dev_kfree_skb_any(skb); 504 return ret; 505 } 506 507 if (priv->adapter->is_hw_11ac_capable) { 508 ret = mwifiex_tdls_add_vht_capab(priv, skb); 509 if (ret) { 510 dev_kfree_skb_any(skb); 511 return ret; 512 } 513 mwifiex_tdls_add_aid(priv, skb); 514 } 515 516 mwifiex_tdls_add_ext_capab(priv, skb); 517 mwifiex_tdls_add_bss_co_2040(skb); 518 mwifiex_tdls_add_supported_chan(skb); 519 mwifiex_tdls_add_oper_class(skb); 520 mwifiex_add_wmm_info_ie(priv, skb, 0); 521 break; 522 523 case WLAN_TDLS_SETUP_RESPONSE: 524 tf->category = WLAN_CATEGORY_TDLS; 525 tf->action_code = WLAN_TDLS_SETUP_RESPONSE; 526 skb_put(skb, sizeof(tf->u.setup_resp)); 527 tf->u.setup_resp.status_code = cpu_to_le16(status_code); 528 tf->u.setup_resp.dialog_token = dialog_token; 529 tf->u.setup_resp.capability = cpu_to_le16(capab); 530 ret = mwifiex_tdls_append_rates_ie(priv, skb); 531 if (ret) { 532 dev_kfree_skb_any(skb); 533 return ret; 534 } 535 536 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 537 *pos++ = WLAN_EID_HT_CAPABILITY; 538 *pos++ = sizeof(struct ieee80211_ht_cap); 539 ht_cap = (void *)pos; 540 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 541 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 542 if (ret) { 543 dev_kfree_skb_any(skb); 544 return ret; 545 } 546 547 if (priv->adapter->is_hw_11ac_capable) { 548 ret = mwifiex_tdls_add_vht_capab(priv, skb); 549 if (ret) { 550 dev_kfree_skb_any(skb); 551 return ret; 552 } 553 mwifiex_tdls_add_aid(priv, skb); 554 } 555 556 mwifiex_tdls_add_ext_capab(priv, skb); 557 mwifiex_tdls_add_bss_co_2040(skb); 558 mwifiex_tdls_add_supported_chan(skb); 559 mwifiex_tdls_add_oper_class(skb); 560 mwifiex_add_wmm_info_ie(priv, skb, 0); 561 break; 562 563 case WLAN_TDLS_SETUP_CONFIRM: 564 tf->category = WLAN_CATEGORY_TDLS; 565 tf->action_code = WLAN_TDLS_SETUP_CONFIRM; 566 skb_put(skb, sizeof(tf->u.setup_cfm)); 567 tf->u.setup_cfm.status_code = cpu_to_le16(status_code); 568 tf->u.setup_cfm.dialog_token = dialog_token; 569 570 mwifiex_tdls_add_wmm_param_ie(priv, skb); 571 if (priv->adapter->is_hw_11ac_capable) { 572 ret = mwifiex_tdls_add_vht_oper(priv, peer, skb); 573 if (ret) { 574 dev_kfree_skb_any(skb); 575 return ret; 576 } 577 ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb); 578 if (ret) { 579 dev_kfree_skb_any(skb); 580 return ret; 581 } 582 } else { 583 ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb); 584 if (ret) { 585 dev_kfree_skb_any(skb); 586 return ret; 587 } 588 } 589 break; 590 591 case WLAN_TDLS_TEARDOWN: 592 tf->category = WLAN_CATEGORY_TDLS; 593 tf->action_code = WLAN_TDLS_TEARDOWN; 594 skb_put(skb, sizeof(tf->u.teardown)); 595 tf->u.teardown.reason_code = cpu_to_le16(status_code); 596 break; 597 598 case WLAN_TDLS_DISCOVERY_REQUEST: 599 tf->category = WLAN_CATEGORY_TDLS; 600 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; 601 skb_put(skb, sizeof(tf->u.discover_req)); 602 tf->u.discover_req.dialog_token = dialog_token; 603 break; 604 default: 605 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); 606 return -EINVAL; 607 } 608 609 return 0; 610} 611 612static void 613mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, 614 const u8 *peer, const u8 *bssid) 615{ 616 struct ieee80211_tdls_lnkie *lnkid; 617 618 lnkid = skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); 619 lnkid->ie_type = WLAN_EID_LINK_ID; 620 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 621 sizeof(struct ieee_types_header); 622 623 memcpy(lnkid->bssid, bssid, ETH_ALEN); 624 memcpy(lnkid->init_sta, src_addr, ETH_ALEN); 625 memcpy(lnkid->resp_sta, peer, ETH_ALEN); 626} 627 628int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, 629 u8 action_code, u8 dialog_token, 630 u16 status_code, const u8 *extra_ies, 631 size_t extra_ies_len) 632{ 633 struct sk_buff *skb; 634 struct mwifiex_txinfo *tx_info; 635 int ret; 636 u16 skb_len; 637 638 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN + 639 max(sizeof(struct ieee80211_mgmt), 640 sizeof(struct ieee80211_tdls_data)) + 641 MWIFIEX_MGMT_FRAME_HEADER_SIZE + 642 MWIFIEX_SUPPORTED_RATES + 643 3 + /* Qos Info */ 644 sizeof(struct ieee_types_extcap) + 645 sizeof(struct ieee80211_ht_cap) + 646 sizeof(struct ieee_types_bss_co_2040) + 647 sizeof(struct ieee80211_ht_operation) + 648 sizeof(struct ieee80211_tdls_lnkie) + 649 (2 * (sizeof(struct ieee_types_header))) + 650 MWIFIEX_SUPPORTED_CHANNELS + 651 MWIFIEX_OPERATING_CLASSES + 652 sizeof(struct ieee80211_wmm_param_ie) + 653 extra_ies_len; 654 655 if (priv->adapter->is_hw_11ac_capable) 656 skb_len += sizeof(struct ieee_types_vht_cap) + 657 sizeof(struct ieee_types_vht_oper) + 658 sizeof(struct ieee_types_aid); 659 660 skb = dev_alloc_skb(skb_len); 661 if (!skb) { 662 mwifiex_dbg(priv->adapter, ERROR, 663 "allocate skb failed for management frame\n"); 664 return -ENOMEM; 665 } 666 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN); 667 668 switch (action_code) { 669 case WLAN_TDLS_SETUP_REQUEST: 670 case WLAN_TDLS_SETUP_CONFIRM: 671 case WLAN_TDLS_TEARDOWN: 672 case WLAN_TDLS_DISCOVERY_REQUEST: 673 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code, 674 dialog_token, status_code, 675 skb); 676 if (ret) { 677 dev_kfree_skb_any(skb); 678 return ret; 679 } 680 if (extra_ies_len) 681 skb_put_data(skb, extra_ies, extra_ies_len); 682 mwifiex_tdls_add_link_ie(skb, priv->curr_addr, peer, 683 priv->cfg_bssid); 684 break; 685 case WLAN_TDLS_SETUP_RESPONSE: 686 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code, 687 dialog_token, status_code, 688 skb); 689 if (ret) { 690 dev_kfree_skb_any(skb); 691 return ret; 692 } 693 if (extra_ies_len) 694 skb_put_data(skb, extra_ies, extra_ies_len); 695 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr, 696 priv->cfg_bssid); 697 break; 698 } 699 700 switch (action_code) { 701 case WLAN_TDLS_SETUP_REQUEST: 702 case WLAN_TDLS_SETUP_RESPONSE: 703 skb->priority = MWIFIEX_PRIO_BK; 704 break; 705 default: 706 skb->priority = MWIFIEX_PRIO_VI; 707 break; 708 } 709 710 tx_info = MWIFIEX_SKB_TXCB(skb); 711 memset(tx_info, 0, sizeof(*tx_info)); 712 tx_info->bss_num = priv->bss_num; 713 tx_info->bss_type = priv->bss_type; 714 715 __net_timestamp(skb); 716 mwifiex_queue_tx_pkt(priv, skb); 717 718 /* Delay 10ms to make sure tdls setup confirm/teardown frame 719 * is received by peer 720 */ 721 if (action_code == WLAN_TDLS_SETUP_CONFIRM || 722 action_code == WLAN_TDLS_TEARDOWN) 723 msleep_interruptible(10); 724 725 return 0; 726} 727 728static int 729mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, 730 const u8 *peer, 731 u8 action_code, u8 dialog_token, 732 u16 status_code, struct sk_buff *skb) 733{ 734 struct ieee80211_mgmt *mgmt; 735 int ret; 736 u16 capab; 737 struct ieee80211_ht_cap *ht_cap; 738 u8 radio, *pos; 739 740 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; 741 742 mgmt = skb_put(skb, offsetof(struct ieee80211_mgmt, u)); 743 744 memset(mgmt, 0, 24); 745 memcpy(mgmt->da, peer, ETH_ALEN); 746 memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN); 747 memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN); 748 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 749 IEEE80211_STYPE_ACTION); 750 751 /* add address 4 */ 752 pos = skb_put(skb, ETH_ALEN); 753 754 switch (action_code) { 755 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 756 skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); 757 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 758 mgmt->u.action.u.tdls_discover_resp.action_code = 759 WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 760 mgmt->u.action.u.tdls_discover_resp.dialog_token = 761 dialog_token; 762 mgmt->u.action.u.tdls_discover_resp.capability = 763 cpu_to_le16(capab); 764 /* move back for addr4 */ 765 memmove(pos + ETH_ALEN, &mgmt->u.action.category, 766 sizeof(mgmt->u.action.u.tdls_discover_resp)); 767 /* init address 4 */ 768 eth_broadcast_addr(pos); 769 770 ret = mwifiex_tdls_append_rates_ie(priv, skb); 771 if (ret) { 772 dev_kfree_skb_any(skb); 773 return ret; 774 } 775 776 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 777 *pos++ = WLAN_EID_HT_CAPABILITY; 778 *pos++ = sizeof(struct ieee80211_ht_cap); 779 ht_cap = (void *)pos; 780 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 781 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 782 if (ret) { 783 dev_kfree_skb_any(skb); 784 return ret; 785 } 786 787 if (priv->adapter->is_hw_11ac_capable) { 788 ret = mwifiex_tdls_add_vht_capab(priv, skb); 789 if (ret) { 790 dev_kfree_skb_any(skb); 791 return ret; 792 } 793 mwifiex_tdls_add_aid(priv, skb); 794 } 795 796 mwifiex_tdls_add_ext_capab(priv, skb); 797 mwifiex_tdls_add_bss_co_2040(skb); 798 mwifiex_tdls_add_supported_chan(skb); 799 mwifiex_tdls_add_qos_capab(skb); 800 mwifiex_tdls_add_oper_class(skb); 801 break; 802 default: 803 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n"); 804 return -EINVAL; 805 } 806 807 return 0; 808} 809 810int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, 811 u8 action_code, u8 dialog_token, 812 u16 status_code, const u8 *extra_ies, 813 size_t extra_ies_len) 814{ 815 struct sk_buff *skb; 816 struct mwifiex_txinfo *tx_info; 817 u8 *pos; 818 u32 pkt_type, tx_control; 819 u16 pkt_len, skb_len; 820 821 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN + 822 max(sizeof(struct ieee80211_mgmt), 823 sizeof(struct ieee80211_tdls_data)) + 824 MWIFIEX_MGMT_FRAME_HEADER_SIZE + 825 MWIFIEX_SUPPORTED_RATES + 826 sizeof(struct ieee_types_extcap) + 827 sizeof(struct ieee80211_ht_cap) + 828 sizeof(struct ieee_types_bss_co_2040) + 829 sizeof(struct ieee80211_ht_operation) + 830 sizeof(struct ieee80211_tdls_lnkie) + 831 extra_ies_len + 832 3 + /* Qos Info */ 833 ETH_ALEN; /* Address4 */ 834 835 if (priv->adapter->is_hw_11ac_capable) 836 skb_len += sizeof(struct ieee_types_vht_cap) + 837 sizeof(struct ieee_types_vht_oper) + 838 sizeof(struct ieee_types_aid); 839 840 skb = dev_alloc_skb(skb_len); 841 if (!skb) { 842 mwifiex_dbg(priv->adapter, ERROR, 843 "allocate skb failed for management frame\n"); 844 return -ENOMEM; 845 } 846 847 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN); 848 849 pkt_type = PKT_TYPE_MGMT; 850 tx_control = 0; 851 pos = skb_put_zero(skb, 852 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len)); 853 memcpy(pos, &pkt_type, sizeof(pkt_type)); 854 memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control)); 855 856 if (mwifiex_construct_tdls_action_frame(priv, peer, action_code, 857 dialog_token, status_code, 858 skb)) { 859 dev_kfree_skb_any(skb); 860 return -EINVAL; 861 } 862 863 if (extra_ies_len) 864 skb_put_data(skb, extra_ies, extra_ies_len); 865 866 /* the TDLS link IE is always added last we are the responder */ 867 868 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr, 869 priv->cfg_bssid); 870 871 skb->priority = MWIFIEX_PRIO_VI; 872 873 tx_info = MWIFIEX_SKB_TXCB(skb); 874 memset(tx_info, 0, sizeof(*tx_info)); 875 tx_info->bss_num = priv->bss_num; 876 tx_info->bss_type = priv->bss_type; 877 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 878 879 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len); 880 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len, 881 sizeof(pkt_len)); 882 __net_timestamp(skb); 883 mwifiex_queue_tx_pkt(priv, skb); 884 885 return 0; 886} 887 888/* This function process tdls action frame from peer. 889 * Peer capabilities are stored into station node structure. 890 */ 891void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, 892 u8 *buf, int len) 893{ 894 struct mwifiex_sta_node *sta_ptr; 895 u8 *peer, *pos, *end; 896 u8 i, action, basic; 897 u16 cap = 0; 898 int ies_len = 0; 899 900 if (len < (sizeof(struct ethhdr) + 3)) 901 return; 902 if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE) 903 return; 904 if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS) 905 return; 906 907 peer = buf + ETH_ALEN; 908 action = *(buf + sizeof(struct ethhdr) + 2); 909 mwifiex_dbg(priv->adapter, DATA, 910 "rx:tdls action: peer=%pM, action=%d\n", peer, action); 911 912 switch (action) { 913 case WLAN_TDLS_SETUP_REQUEST: 914 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN)) 915 return; 916 917 pos = buf + sizeof(struct ethhdr) + 4; 918 /* payload 1+ category 1 + action 1 + dialog 1 */ 919 cap = get_unaligned_le16(pos); 920 ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; 921 pos += 2; 922 break; 923 924 case WLAN_TDLS_SETUP_RESPONSE: 925 if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN)) 926 return; 927 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ 928 pos = buf + sizeof(struct ethhdr) + 6; 929 cap = get_unaligned_le16(pos); 930 ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; 931 pos += 2; 932 break; 933 934 case WLAN_TDLS_SETUP_CONFIRM: 935 if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN)) 936 return; 937 pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN; 938 ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; 939 break; 940 default: 941 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); 942 return; 943 } 944 945 sta_ptr = mwifiex_add_sta_entry(priv, peer); 946 if (!sta_ptr) 947 return; 948 949 sta_ptr->tdls_cap.capab = cpu_to_le16(cap); 950 951 for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) { 952 u8 ie_len = pos[1]; 953 954 if (pos + 2 + ie_len > end) 955 break; 956 957 switch (*pos) { 958 case WLAN_EID_SUPP_RATES: 959 if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) 960 return; 961 sta_ptr->tdls_cap.rates_len = ie_len; 962 for (i = 0; i < ie_len; i++) 963 sta_ptr->tdls_cap.rates[i] = pos[i + 2]; 964 break; 965 966 case WLAN_EID_EXT_SUPP_RATES: 967 if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) 968 return; 969 basic = sta_ptr->tdls_cap.rates_len; 970 if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic) 971 return; 972 for (i = 0; i < ie_len; i++) 973 sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; 974 sta_ptr->tdls_cap.rates_len += ie_len; 975 break; 976 case WLAN_EID_HT_CAPABILITY: 977 if (ie_len != sizeof(struct ieee80211_ht_cap)) 978 return; 979 /* copy the ie's value into ht_capb*/ 980 memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, 981 sizeof(struct ieee80211_ht_cap)); 982 sta_ptr->is_11n_enabled = 1; 983 break; 984 case WLAN_EID_HT_OPERATION: 985 if (ie_len != sizeof(struct ieee80211_ht_operation)) 986 return; 987 /* copy the ie's value into ht_oper*/ 988 memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, 989 sizeof(struct ieee80211_ht_operation)); 990 break; 991 case WLAN_EID_BSS_COEX_2040: 992 if (ie_len != sizeof(pos[2])) 993 return; 994 sta_ptr->tdls_cap.coex_2040 = pos[2]; 995 break; 996 case WLAN_EID_EXT_CAPABILITY: 997 if (ie_len < sizeof(struct ieee_types_header)) 998 return; 999 if (ie_len > 8) 1000 return; 1001 memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, 1002 sizeof(struct ieee_types_header) + 1003 min_t(u8, ie_len, 8)); 1004 break; 1005 case WLAN_EID_RSN: 1006 if (ie_len < sizeof(struct ieee_types_header)) 1007 return; 1008 if (ie_len > IEEE_MAX_IE_SIZE - 1009 sizeof(struct ieee_types_header)) 1010 return; 1011 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, 1012 sizeof(struct ieee_types_header) + 1013 min_t(u8, ie_len, IEEE_MAX_IE_SIZE - 1014 sizeof(struct ieee_types_header))); 1015 break; 1016 case WLAN_EID_QOS_CAPA: 1017 if (ie_len != sizeof(pos[2])) 1018 return; 1019 sta_ptr->tdls_cap.qos_info = pos[2]; 1020 break; 1021 case WLAN_EID_VHT_OPERATION: 1022 if (priv->adapter->is_hw_11ac_capable) { 1023 if (ie_len != 1024 sizeof(struct ieee80211_vht_operation)) 1025 return; 1026 /* copy the ie's value into vhtoper*/ 1027 memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2, 1028 sizeof(struct ieee80211_vht_operation)); 1029 } 1030 break; 1031 case WLAN_EID_VHT_CAPABILITY: 1032 if (priv->adapter->is_hw_11ac_capable) { 1033 if (ie_len != sizeof(struct ieee80211_vht_cap)) 1034 return; 1035 /* copy the ie's value into vhtcap*/ 1036 memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, 1037 sizeof(struct ieee80211_vht_cap)); 1038 sta_ptr->is_11ac_enabled = 1; 1039 } 1040 break; 1041 case WLAN_EID_AID: 1042 if (priv->adapter->is_hw_11ac_capable) { 1043 if (ie_len != sizeof(u16)) 1044 return; 1045 sta_ptr->tdls_cap.aid = 1046 get_unaligned_le16((pos + 2)); 1047 } 1048 break; 1049 default: 1050 break; 1051 } 1052 } 1053 1054 return; 1055} 1056 1057static int 1058mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer) 1059{ 1060 struct mwifiex_sta_node *sta_ptr; 1061 struct mwifiex_ds_tdls_oper tdls_oper; 1062 1063 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1064 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1065 1066 if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) { 1067 mwifiex_dbg(priv->adapter, ERROR, 1068 "link absent for peer %pM; cannot config\n", peer); 1069 return -EINVAL; 1070 } 1071 1072 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1073 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK; 1074 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1075 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1076} 1077 1078static int 1079mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer) 1080{ 1081 struct mwifiex_sta_node *sta_ptr; 1082 struct mwifiex_ds_tdls_oper tdls_oper; 1083 1084 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1085 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1086 1087 if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) { 1088 mwifiex_dbg(priv->adapter, WARN, 1089 "Setup already in progress for peer %pM\n", peer); 1090 return 0; 1091 } 1092 1093 sta_ptr = mwifiex_add_sta_entry(priv, peer); 1094 if (!sta_ptr) 1095 return -ENOMEM; 1096 1097 sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS; 1098 mwifiex_hold_tdls_packets(priv, peer); 1099 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1100 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK; 1101 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1102 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1103} 1104 1105static int 1106mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer) 1107{ 1108 struct mwifiex_sta_node *sta_ptr; 1109 struct mwifiex_ds_tdls_oper tdls_oper; 1110 1111 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1112 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1113 1114 if (sta_ptr) { 1115 if (sta_ptr->is_11n_enabled) { 1116 mwifiex_11n_cleanup_reorder_tbl(priv); 1117 spin_lock_bh(&priv->wmm.ra_list_spinlock); 1118 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1119 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 1120 } 1121 mwifiex_del_sta_entry(priv, peer); 1122 } 1123 1124 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 1125 mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP); 1126 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1127 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1128 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1129 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1130} 1131 1132static int 1133mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) 1134{ 1135 struct mwifiex_sta_node *sta_ptr; 1136 struct ieee80211_mcs_info mcs; 1137 int i; 1138 1139 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1140 1141 if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) { 1142 mwifiex_dbg(priv->adapter, MSG, 1143 "tdls: enable link %pM success\n", peer); 1144 1145 sta_ptr->tdls_status = TDLS_SETUP_COMPLETE; 1146 1147 mcs = sta_ptr->tdls_cap.ht_capb.mcs; 1148 if (mcs.rx_mask[0] != 0xff) 1149 sta_ptr->is_11n_enabled = true; 1150 if (sta_ptr->is_11n_enabled) { 1151 if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) & 1152 IEEE80211_HT_CAP_MAX_AMSDU) 1153 sta_ptr->max_amsdu = 1154 MWIFIEX_TX_DATA_BUF_SIZE_8K; 1155 else 1156 sta_ptr->max_amsdu = 1157 MWIFIEX_TX_DATA_BUF_SIZE_4K; 1158 1159 for (i = 0; i < MAX_NUM_TID; i++) 1160 sta_ptr->ampdu_sta[i] = 1161 priv->aggr_prio_tbl[i].ampdu_user; 1162 } else { 1163 for (i = 0; i < MAX_NUM_TID; i++) 1164 sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED; 1165 } 1166 if (sta_ptr->tdls_cap.extcap.ext_capab[3] & 1167 WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) { 1168 mwifiex_config_tdls_enable(priv); 1169 mwifiex_config_tdls_cs_params(priv); 1170 } 1171 1172 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq)); 1173 mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE); 1174 mwifiex_auto_tdls_update_peer_status(priv, peer, 1175 TDLS_SETUP_COMPLETE); 1176 } else { 1177 mwifiex_dbg(priv->adapter, ERROR, 1178 "tdls: enable link %pM failed\n", peer); 1179 if (sta_ptr) { 1180 mwifiex_11n_cleanup_reorder_tbl(priv); 1181 spin_lock_bh(&priv->wmm.ra_list_spinlock); 1182 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1183 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 1184 mwifiex_del_sta_entry(priv, peer); 1185 } 1186 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 1187 mwifiex_auto_tdls_update_peer_status(priv, peer, 1188 TDLS_NOT_SETUP); 1189 1190 return -1; 1191 } 1192 1193 return 0; 1194} 1195 1196int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action) 1197{ 1198 switch (action) { 1199 case MWIFIEX_TDLS_ENABLE_LINK: 1200 return mwifiex_tdls_process_enable_link(priv, peer); 1201 case MWIFIEX_TDLS_DISABLE_LINK: 1202 return mwifiex_tdls_process_disable_link(priv, peer); 1203 case MWIFIEX_TDLS_CREATE_LINK: 1204 return mwifiex_tdls_process_create_link(priv, peer); 1205 case MWIFIEX_TDLS_CONFIG_LINK: 1206 return mwifiex_tdls_process_config_link(priv, peer); 1207 } 1208 return 0; 1209} 1210 1211int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac) 1212{ 1213 struct mwifiex_sta_node *sta_ptr; 1214 1215 sta_ptr = mwifiex_get_sta_entry(priv, mac); 1216 if (sta_ptr) 1217 return sta_ptr->tdls_status; 1218 1219 return TDLS_NOT_SETUP; 1220} 1221 1222int mwifiex_get_tdls_list(struct mwifiex_private *priv, 1223 struct tdls_peer_info *buf) 1224{ 1225 struct mwifiex_sta_node *sta_ptr; 1226 struct tdls_peer_info *peer = buf; 1227 int count = 0; 1228 1229 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) 1230 return 0; 1231 1232 /* make sure we are in station mode and connected */ 1233 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) 1234 return 0; 1235 1236 spin_lock_bh(&priv->sta_list_spinlock); 1237 list_for_each_entry(sta_ptr, &priv->sta_list, list) { 1238 if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) { 1239 ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr); 1240 peer++; 1241 count++; 1242 if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED) 1243 break; 1244 } 1245 } 1246 spin_unlock_bh(&priv->sta_list_spinlock); 1247 1248 return count; 1249} 1250 1251void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv) 1252{ 1253 struct mwifiex_sta_node *sta_ptr; 1254 struct mwifiex_ds_tdls_oper tdls_oper; 1255 1256 if (list_empty(&priv->sta_list)) 1257 return; 1258 1259 list_for_each_entry(sta_ptr, &priv->sta_list, list) { 1260 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1261 1262 if (sta_ptr->is_11n_enabled) { 1263 mwifiex_11n_cleanup_reorder_tbl(priv); 1264 spin_lock_bh(&priv->wmm.ra_list_spinlock); 1265 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1266 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 1267 } 1268 1269 mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr, 1270 TDLS_LINK_TEARDOWN); 1271 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN); 1272 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1273 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1274 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false)) 1275 mwifiex_dbg(priv->adapter, ERROR, 1276 "Disable link failed for TDLS peer %pM", 1277 sta_ptr->mac_addr); 1278 } 1279 1280 mwifiex_del_all_sta_list(priv); 1281} 1282 1283int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb) 1284{ 1285 struct mwifiex_auto_tdls_peer *peer; 1286 u8 mac[ETH_ALEN]; 1287 1288 ether_addr_copy(mac, skb->data); 1289 1290 spin_lock_bh(&priv->auto_tdls_lock); 1291 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1292 if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) { 1293 if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && 1294 peer->tdls_status == TDLS_NOT_SETUP && 1295 (peer->failure_count < 1296 MWIFIEX_TDLS_MAX_FAIL_COUNT)) { 1297 peer->tdls_status = TDLS_SETUP_INPROGRESS; 1298 mwifiex_dbg(priv->adapter, INFO, 1299 "setup TDLS link, peer=%pM rssi=%d\n", 1300 peer->mac_addr, peer->rssi); 1301 1302 cfg80211_tdls_oper_request(priv->netdev, 1303 peer->mac_addr, 1304 NL80211_TDLS_SETUP, 1305 0, GFP_ATOMIC); 1306 peer->do_setup = false; 1307 priv->check_tdls_tx = false; 1308 } else if (peer->failure_count < 1309 MWIFIEX_TDLS_MAX_FAIL_COUNT && 1310 peer->do_discover) { 1311 mwifiex_send_tdls_data_frame(priv, 1312 peer->mac_addr, 1313 WLAN_TDLS_DISCOVERY_REQUEST, 1314 1, 0, NULL, 0); 1315 peer->do_discover = false; 1316 } 1317 } 1318 } 1319 spin_unlock_bh(&priv->auto_tdls_lock); 1320 1321 return 0; 1322} 1323 1324void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv) 1325{ 1326 struct mwifiex_auto_tdls_peer *peer, *tmp_node; 1327 1328 spin_lock_bh(&priv->auto_tdls_lock); 1329 list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) { 1330 list_del(&peer->list); 1331 kfree(peer); 1332 } 1333 1334 INIT_LIST_HEAD(&priv->auto_tdls_list); 1335 spin_unlock_bh(&priv->auto_tdls_lock); 1336 priv->check_tdls_tx = false; 1337} 1338 1339void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac) 1340{ 1341 struct mwifiex_auto_tdls_peer *tdls_peer; 1342 1343 if (!priv->adapter->auto_tdls) 1344 return; 1345 1346 spin_lock_bh(&priv->auto_tdls_lock); 1347 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { 1348 if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) { 1349 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; 1350 tdls_peer->rssi_jiffies = jiffies; 1351 spin_unlock_bh(&priv->auto_tdls_lock); 1352 return; 1353 } 1354 } 1355 1356 /* create new TDLS peer */ 1357 tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC); 1358 if (tdls_peer) { 1359 ether_addr_copy(tdls_peer->mac_addr, mac); 1360 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; 1361 tdls_peer->rssi_jiffies = jiffies; 1362 INIT_LIST_HEAD(&tdls_peer->list); 1363 list_add_tail(&tdls_peer->list, &priv->auto_tdls_list); 1364 mwifiex_dbg(priv->adapter, INFO, 1365 "Add auto TDLS peer= %pM to list\n", mac); 1366 } 1367 1368 spin_unlock_bh(&priv->auto_tdls_lock); 1369} 1370 1371void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, 1372 const u8 *mac, u8 link_status) 1373{ 1374 struct mwifiex_auto_tdls_peer *peer; 1375 1376 if (!priv->adapter->auto_tdls) 1377 return; 1378 1379 spin_lock_bh(&priv->auto_tdls_lock); 1380 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1381 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { 1382 if ((link_status == TDLS_NOT_SETUP) && 1383 (peer->tdls_status == TDLS_SETUP_INPROGRESS)) 1384 peer->failure_count++; 1385 else if (mwifiex_is_tdls_link_setup(link_status)) 1386 peer->failure_count = 0; 1387 1388 peer->tdls_status = link_status; 1389 break; 1390 } 1391 } 1392 spin_unlock_bh(&priv->auto_tdls_lock); 1393} 1394 1395void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv, 1396 u8 *mac, s8 snr, s8 nflr) 1397{ 1398 struct mwifiex_auto_tdls_peer *peer; 1399 1400 if (!priv->adapter->auto_tdls) 1401 return; 1402 1403 spin_lock_bh(&priv->auto_tdls_lock); 1404 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1405 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { 1406 peer->rssi = nflr - snr; 1407 peer->rssi_jiffies = jiffies; 1408 break; 1409 } 1410 } 1411 spin_unlock_bh(&priv->auto_tdls_lock); 1412} 1413 1414void mwifiex_check_auto_tdls(struct timer_list *t) 1415{ 1416 struct mwifiex_private *priv = from_timer(priv, t, auto_tdls_timer); 1417 struct mwifiex_auto_tdls_peer *tdls_peer; 1418 u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; 1419 1420 if (WARN_ON_ONCE(!priv || !priv->adapter)) { 1421 pr_err("mwifiex: %s: adapter or private structure is NULL\n", 1422 __func__); 1423 return; 1424 } 1425 1426 if (unlikely(!priv->adapter->auto_tdls)) 1427 return; 1428 1429 if (!priv->auto_tdls_timer_active) { 1430 mwifiex_dbg(priv->adapter, INFO, 1431 "auto TDLS timer inactive; return"); 1432 return; 1433 } 1434 1435 priv->check_tdls_tx = false; 1436 1437 spin_lock_bh(&priv->auto_tdls_lock); 1438 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { 1439 if ((jiffies - tdls_peer->rssi_jiffies) > 1440 (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) { 1441 tdls_peer->rssi = 0; 1442 tdls_peer->do_discover = true; 1443 priv->check_tdls_tx = true; 1444 } 1445 1446 if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) || 1447 !tdls_peer->rssi) && 1448 mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) { 1449 tdls_peer->tdls_status = TDLS_LINK_TEARDOWN; 1450 mwifiex_dbg(priv->adapter, MSG, 1451 "teardown TDLS link,peer=%pM rssi=%d\n", 1452 tdls_peer->mac_addr, -tdls_peer->rssi); 1453 tdls_peer->do_discover = true; 1454 priv->check_tdls_tx = true; 1455 cfg80211_tdls_oper_request(priv->netdev, 1456 tdls_peer->mac_addr, 1457 NL80211_TDLS_TEARDOWN, 1458 reason, GFP_ATOMIC); 1459 } else if (tdls_peer->rssi && 1460 tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && 1461 tdls_peer->tdls_status == TDLS_NOT_SETUP && 1462 tdls_peer->failure_count < 1463 MWIFIEX_TDLS_MAX_FAIL_COUNT) { 1464 priv->check_tdls_tx = true; 1465 tdls_peer->do_setup = true; 1466 mwifiex_dbg(priv->adapter, INFO, 1467 "check TDLS with peer=%pM\t" 1468 "rssi=%d\n", tdls_peer->mac_addr, 1469 tdls_peer->rssi); 1470 } 1471 } 1472 spin_unlock_bh(&priv->auto_tdls_lock); 1473 1474 mod_timer(&priv->auto_tdls_timer, 1475 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1476} 1477 1478void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv) 1479{ 1480 timer_setup(&priv->auto_tdls_timer, mwifiex_check_auto_tdls, 0); 1481 priv->auto_tdls_timer_active = true; 1482 mod_timer(&priv->auto_tdls_timer, 1483 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1484} 1485 1486void mwifiex_clean_auto_tdls(struct mwifiex_private *priv) 1487{ 1488 if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && 1489 priv->adapter->auto_tdls && 1490 priv->bss_type == MWIFIEX_BSS_TYPE_STA) { 1491 priv->auto_tdls_timer_active = false; 1492 del_timer(&priv->auto_tdls_timer); 1493 mwifiex_flush_auto_tdls_list(priv); 1494 } 1495} 1496 1497static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable) 1498{ 1499 struct mwifiex_tdls_config config; 1500 1501 config.enable = cpu_to_le16(enable); 1502 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1503 ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true); 1504} 1505 1506int mwifiex_config_tdls_enable(struct mwifiex_private *priv) 1507{ 1508 return mwifiex_config_tdls(priv, true); 1509} 1510 1511int mwifiex_config_tdls_disable(struct mwifiex_private *priv) 1512{ 1513 return mwifiex_config_tdls(priv, false); 1514} 1515 1516int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv) 1517{ 1518 struct mwifiex_tdls_config_cs_params config_tdls_cs_params; 1519 1520 config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME; 1521 config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK; 1522 config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK; 1523 1524 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1525 ACT_TDLS_CS_PARAMS, 0, 1526 &config_tdls_cs_params, true); 1527} 1528 1529int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac) 1530{ 1531 struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params; 1532 1533 ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac); 1534 1535 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1536 ACT_TDLS_CS_STOP, 0, 1537 &stop_tdls_cs_params, true); 1538} 1539 1540int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac, 1541 u8 primary_chan, u8 second_chan_offset, u8 band) 1542{ 1543 struct mwifiex_tdls_init_cs_params start_tdls_cs_params; 1544 1545 ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac); 1546 start_tdls_cs_params.primary_chan = primary_chan; 1547 start_tdls_cs_params.second_chan_offset = second_chan_offset; 1548 start_tdls_cs_params.band = band; 1549 1550 start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME); 1551 start_tdls_cs_params.switch_timeout = 1552 cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT); 1553 start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS; 1554 start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY; 1555 1556 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1557 ACT_TDLS_CS_INIT, 0, 1558 &start_tdls_cs_params, true); 1559}