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