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 30 static 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 85 static 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. */ 118 static int 119 mwifiex_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 153 static 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 168 static 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 186 static int 187 mwifiex_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 234 static 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 356 static 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 372 static 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 381 static void 382 mwifiex_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 409 static void 410 mwifiex_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 429 static 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 440 static 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 452 static 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 464 static 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 612 static void 613 mwifiex_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 628 int 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 728 static int 729 mwifiex_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 unsigned int extra; 739 u8 radio, *pos; 740 741 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; 742 743 mgmt = skb_put(skb, offsetof(struct ieee80211_mgmt, u)); 744 745 memset(mgmt, 0, 24); 746 memcpy(mgmt->da, peer, ETH_ALEN); 747 memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN); 748 memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN); 749 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 750 IEEE80211_STYPE_ACTION); 751 752 /* add address 4 */ 753 pos = skb_put(skb, ETH_ALEN); 754 755 switch (action_code) { 756 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 757 /* See the layout of 'struct ieee80211_mgmt'. */ 758 extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + 759 sizeof(mgmt->u.action.category); 760 skb_put(skb, extra); 761 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 762 mgmt->u.action.u.tdls_discover_resp.action_code = 763 WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 764 mgmt->u.action.u.tdls_discover_resp.dialog_token = 765 dialog_token; 766 mgmt->u.action.u.tdls_discover_resp.capability = 767 cpu_to_le16(capab); 768 /* move back for addr4 */ 769 memmove(pos + ETH_ALEN, &mgmt->u.action, extra); 770 /* init address 4 */ 771 eth_broadcast_addr(pos); 772 773 ret = mwifiex_tdls_append_rates_ie(priv, skb); 774 if (ret) { 775 dev_kfree_skb_any(skb); 776 return ret; 777 } 778 779 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 780 *pos++ = WLAN_EID_HT_CAPABILITY; 781 *pos++ = sizeof(struct ieee80211_ht_cap); 782 ht_cap = (void *)pos; 783 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 784 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 785 if (ret) { 786 dev_kfree_skb_any(skb); 787 return ret; 788 } 789 790 if (priv->adapter->is_hw_11ac_capable) { 791 ret = mwifiex_tdls_add_vht_capab(priv, skb); 792 if (ret) { 793 dev_kfree_skb_any(skb); 794 return ret; 795 } 796 mwifiex_tdls_add_aid(priv, skb); 797 } 798 799 mwifiex_tdls_add_ext_capab(priv, skb); 800 mwifiex_tdls_add_bss_co_2040(skb); 801 mwifiex_tdls_add_supported_chan(skb); 802 mwifiex_tdls_add_qos_capab(skb); 803 mwifiex_tdls_add_oper_class(skb); 804 break; 805 default: 806 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n"); 807 return -EINVAL; 808 } 809 810 return 0; 811 } 812 813 int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, 814 u8 action_code, u8 dialog_token, 815 u16 status_code, const u8 *extra_ies, 816 size_t extra_ies_len) 817 { 818 struct sk_buff *skb; 819 struct mwifiex_txinfo *tx_info; 820 u8 *pos; 821 u32 pkt_type, tx_control; 822 u16 pkt_len, skb_len; 823 824 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN + 825 max(sizeof(struct ieee80211_mgmt), 826 sizeof(struct ieee80211_tdls_data)) + 827 MWIFIEX_MGMT_FRAME_HEADER_SIZE + 828 MWIFIEX_SUPPORTED_RATES + 829 sizeof(struct ieee_types_extcap) + 830 sizeof(struct ieee80211_ht_cap) + 831 sizeof(struct ieee_types_bss_co_2040) + 832 sizeof(struct ieee80211_ht_operation) + 833 sizeof(struct ieee80211_tdls_lnkie) + 834 extra_ies_len + 835 3 + /* Qos Info */ 836 ETH_ALEN; /* Address4 */ 837 838 if (priv->adapter->is_hw_11ac_capable) 839 skb_len += sizeof(struct ieee_types_vht_cap) + 840 sizeof(struct ieee_types_vht_oper) + 841 sizeof(struct ieee_types_aid); 842 843 skb = dev_alloc_skb(skb_len); 844 if (!skb) { 845 mwifiex_dbg(priv->adapter, ERROR, 846 "allocate skb failed for management frame\n"); 847 return -ENOMEM; 848 } 849 850 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN); 851 852 pkt_type = PKT_TYPE_MGMT; 853 tx_control = 0; 854 pos = skb_put_zero(skb, 855 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len)); 856 memcpy(pos, &pkt_type, sizeof(pkt_type)); 857 memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control)); 858 859 if (mwifiex_construct_tdls_action_frame(priv, peer, action_code, 860 dialog_token, status_code, 861 skb)) { 862 dev_kfree_skb_any(skb); 863 return -EINVAL; 864 } 865 866 if (extra_ies_len) 867 skb_put_data(skb, extra_ies, extra_ies_len); 868 869 /* the TDLS link IE is always added last we are the responder */ 870 871 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr, 872 priv->cfg_bssid); 873 874 skb->priority = MWIFIEX_PRIO_VI; 875 876 tx_info = MWIFIEX_SKB_TXCB(skb); 877 memset(tx_info, 0, sizeof(*tx_info)); 878 tx_info->bss_num = priv->bss_num; 879 tx_info->bss_type = priv->bss_type; 880 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 881 882 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len); 883 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len, 884 sizeof(pkt_len)); 885 __net_timestamp(skb); 886 mwifiex_queue_tx_pkt(priv, skb); 887 888 return 0; 889 } 890 891 /* This function process tdls action frame from peer. 892 * Peer capabilities are stored into station node structure. 893 */ 894 void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, 895 u8 *buf, int len) 896 { 897 struct mwifiex_sta_node *sta_ptr; 898 u8 *peer, *pos, *end; 899 u8 i, action, basic; 900 u16 cap = 0; 901 int ies_len = 0; 902 903 if (len < (sizeof(struct ethhdr) + 3)) 904 return; 905 if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE) 906 return; 907 if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS) 908 return; 909 910 peer = buf + ETH_ALEN; 911 action = *(buf + sizeof(struct ethhdr) + 2); 912 mwifiex_dbg(priv->adapter, DATA, 913 "rx:tdls action: peer=%pM, action=%d\n", peer, action); 914 915 switch (action) { 916 case WLAN_TDLS_SETUP_REQUEST: 917 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN)) 918 return; 919 920 pos = buf + sizeof(struct ethhdr) + 4; 921 /* payload 1+ category 1 + action 1 + dialog 1 */ 922 cap = get_unaligned_le16(pos); 923 ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; 924 pos += 2; 925 break; 926 927 case WLAN_TDLS_SETUP_RESPONSE: 928 if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN)) 929 return; 930 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ 931 pos = buf + sizeof(struct ethhdr) + 6; 932 cap = get_unaligned_le16(pos); 933 ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; 934 pos += 2; 935 break; 936 937 case WLAN_TDLS_SETUP_CONFIRM: 938 if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN)) 939 return; 940 pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN; 941 ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; 942 break; 943 default: 944 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); 945 return; 946 } 947 948 sta_ptr = mwifiex_add_sta_entry(priv, peer); 949 if (!sta_ptr) 950 return; 951 952 sta_ptr->tdls_cap.capab = cpu_to_le16(cap); 953 954 for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) { 955 u8 ie_len = pos[1]; 956 957 if (pos + 2 + ie_len > end) 958 break; 959 960 switch (*pos) { 961 case WLAN_EID_SUPP_RATES: 962 if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) 963 return; 964 sta_ptr->tdls_cap.rates_len = ie_len; 965 for (i = 0; i < ie_len; i++) 966 sta_ptr->tdls_cap.rates[i] = pos[i + 2]; 967 break; 968 969 case WLAN_EID_EXT_SUPP_RATES: 970 if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) 971 return; 972 basic = sta_ptr->tdls_cap.rates_len; 973 if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic) 974 return; 975 for (i = 0; i < ie_len; i++) 976 sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; 977 sta_ptr->tdls_cap.rates_len += ie_len; 978 break; 979 case WLAN_EID_HT_CAPABILITY: 980 if (ie_len != sizeof(struct ieee80211_ht_cap)) 981 return; 982 /* copy the ie's value into ht_capb*/ 983 memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, 984 sizeof(struct ieee80211_ht_cap)); 985 sta_ptr->is_11n_enabled = 1; 986 break; 987 case WLAN_EID_HT_OPERATION: 988 if (ie_len != sizeof(struct ieee80211_ht_operation)) 989 return; 990 /* copy the ie's value into ht_oper*/ 991 memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, 992 sizeof(struct ieee80211_ht_operation)); 993 break; 994 case WLAN_EID_BSS_COEX_2040: 995 if (ie_len != sizeof(pos[2])) 996 return; 997 sta_ptr->tdls_cap.coex_2040 = pos[2]; 998 break; 999 case WLAN_EID_EXT_CAPABILITY: 1000 if (ie_len < sizeof(struct ieee_types_header)) 1001 return; 1002 if (ie_len > 8) 1003 return; 1004 memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, 1005 sizeof(struct ieee_types_header) + 1006 min_t(u8, ie_len, 8)); 1007 break; 1008 case WLAN_EID_RSN: 1009 if (ie_len < sizeof(struct ieee_types_header)) 1010 return; 1011 if (ie_len > IEEE_MAX_IE_SIZE - 1012 sizeof(struct ieee_types_header)) 1013 return; 1014 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, 1015 sizeof(struct ieee_types_header) + 1016 min_t(u8, ie_len, IEEE_MAX_IE_SIZE - 1017 sizeof(struct ieee_types_header))); 1018 break; 1019 case WLAN_EID_QOS_CAPA: 1020 if (ie_len != sizeof(pos[2])) 1021 return; 1022 sta_ptr->tdls_cap.qos_info = pos[2]; 1023 break; 1024 case WLAN_EID_VHT_OPERATION: 1025 if (priv->adapter->is_hw_11ac_capable) { 1026 if (ie_len != 1027 sizeof(struct ieee80211_vht_operation)) 1028 return; 1029 /* copy the ie's value into vhtoper*/ 1030 memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2, 1031 sizeof(struct ieee80211_vht_operation)); 1032 } 1033 break; 1034 case WLAN_EID_VHT_CAPABILITY: 1035 if (priv->adapter->is_hw_11ac_capable) { 1036 if (ie_len != sizeof(struct ieee80211_vht_cap)) 1037 return; 1038 /* copy the ie's value into vhtcap*/ 1039 memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, 1040 sizeof(struct ieee80211_vht_cap)); 1041 sta_ptr->is_11ac_enabled = 1; 1042 } 1043 break; 1044 case WLAN_EID_AID: 1045 if (priv->adapter->is_hw_11ac_capable) { 1046 if (ie_len != sizeof(u16)) 1047 return; 1048 sta_ptr->tdls_cap.aid = 1049 get_unaligned_le16((pos + 2)); 1050 } 1051 break; 1052 default: 1053 break; 1054 } 1055 } 1056 1057 return; 1058 } 1059 1060 static int 1061 mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer) 1062 { 1063 struct mwifiex_sta_node *sta_ptr; 1064 struct mwifiex_ds_tdls_oper tdls_oper; 1065 1066 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1067 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1068 1069 if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) { 1070 mwifiex_dbg(priv->adapter, ERROR, 1071 "link absent for peer %pM; cannot config\n", peer); 1072 return -EINVAL; 1073 } 1074 1075 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1076 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK; 1077 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1078 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1079 } 1080 1081 static int 1082 mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer) 1083 { 1084 struct mwifiex_sta_node *sta_ptr; 1085 struct mwifiex_ds_tdls_oper tdls_oper; 1086 1087 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1088 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1089 1090 if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) { 1091 mwifiex_dbg(priv->adapter, WARN, 1092 "Setup already in progress for peer %pM\n", peer); 1093 return 0; 1094 } 1095 1096 sta_ptr = mwifiex_add_sta_entry(priv, peer); 1097 if (!sta_ptr) 1098 return -ENOMEM; 1099 1100 sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS; 1101 mwifiex_hold_tdls_packets(priv, peer); 1102 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1103 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK; 1104 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1105 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1106 } 1107 1108 static int 1109 mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer) 1110 { 1111 struct mwifiex_sta_node *sta_ptr; 1112 struct mwifiex_ds_tdls_oper tdls_oper; 1113 1114 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1115 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1116 1117 if (sta_ptr) { 1118 if (sta_ptr->is_11n_enabled) { 1119 mwifiex_11n_cleanup_reorder_tbl(priv); 1120 spin_lock_bh(&priv->wmm.ra_list_spinlock); 1121 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1122 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 1123 } 1124 mwifiex_del_sta_entry(priv, peer); 1125 } 1126 1127 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 1128 mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP); 1129 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1130 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1131 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1132 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1133 } 1134 1135 static int 1136 mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) 1137 { 1138 struct mwifiex_sta_node *sta_ptr; 1139 struct ieee80211_mcs_info mcs; 1140 int i; 1141 1142 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1143 1144 if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) { 1145 mwifiex_dbg(priv->adapter, MSG, 1146 "tdls: enable link %pM success\n", peer); 1147 1148 sta_ptr->tdls_status = TDLS_SETUP_COMPLETE; 1149 1150 mcs = sta_ptr->tdls_cap.ht_capb.mcs; 1151 if (mcs.rx_mask[0] != 0xff) 1152 sta_ptr->is_11n_enabled = true; 1153 if (sta_ptr->is_11n_enabled) { 1154 if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) & 1155 IEEE80211_HT_CAP_MAX_AMSDU) 1156 sta_ptr->max_amsdu = 1157 MWIFIEX_TX_DATA_BUF_SIZE_8K; 1158 else 1159 sta_ptr->max_amsdu = 1160 MWIFIEX_TX_DATA_BUF_SIZE_4K; 1161 1162 for (i = 0; i < MAX_NUM_TID; i++) 1163 sta_ptr->ampdu_sta[i] = 1164 priv->aggr_prio_tbl[i].ampdu_user; 1165 } else { 1166 for (i = 0; i < MAX_NUM_TID; i++) 1167 sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED; 1168 } 1169 if (sta_ptr->tdls_cap.extcap.ext_capab[3] & 1170 WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) { 1171 mwifiex_config_tdls_enable(priv); 1172 mwifiex_config_tdls_cs_params(priv); 1173 } 1174 1175 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq)); 1176 mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE); 1177 mwifiex_auto_tdls_update_peer_status(priv, peer, 1178 TDLS_SETUP_COMPLETE); 1179 } else { 1180 mwifiex_dbg(priv->adapter, ERROR, 1181 "tdls: enable link %pM failed\n", peer); 1182 if (sta_ptr) { 1183 mwifiex_11n_cleanup_reorder_tbl(priv); 1184 spin_lock_bh(&priv->wmm.ra_list_spinlock); 1185 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1186 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 1187 mwifiex_del_sta_entry(priv, peer); 1188 } 1189 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 1190 mwifiex_auto_tdls_update_peer_status(priv, peer, 1191 TDLS_NOT_SETUP); 1192 1193 return -1; 1194 } 1195 1196 return 0; 1197 } 1198 1199 int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action) 1200 { 1201 switch (action) { 1202 case MWIFIEX_TDLS_ENABLE_LINK: 1203 return mwifiex_tdls_process_enable_link(priv, peer); 1204 case MWIFIEX_TDLS_DISABLE_LINK: 1205 return mwifiex_tdls_process_disable_link(priv, peer); 1206 case MWIFIEX_TDLS_CREATE_LINK: 1207 return mwifiex_tdls_process_create_link(priv, peer); 1208 case MWIFIEX_TDLS_CONFIG_LINK: 1209 return mwifiex_tdls_process_config_link(priv, peer); 1210 } 1211 return 0; 1212 } 1213 1214 int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac) 1215 { 1216 struct mwifiex_sta_node *sta_ptr; 1217 1218 sta_ptr = mwifiex_get_sta_entry(priv, mac); 1219 if (sta_ptr) 1220 return sta_ptr->tdls_status; 1221 1222 return TDLS_NOT_SETUP; 1223 } 1224 1225 int mwifiex_get_tdls_list(struct mwifiex_private *priv, 1226 struct tdls_peer_info *buf) 1227 { 1228 struct mwifiex_sta_node *sta_ptr; 1229 struct tdls_peer_info *peer = buf; 1230 int count = 0; 1231 1232 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) 1233 return 0; 1234 1235 /* make sure we are in station mode and connected */ 1236 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) 1237 return 0; 1238 1239 spin_lock_bh(&priv->sta_list_spinlock); 1240 list_for_each_entry(sta_ptr, &priv->sta_list, list) { 1241 if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) { 1242 ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr); 1243 peer++; 1244 count++; 1245 if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED) 1246 break; 1247 } 1248 } 1249 spin_unlock_bh(&priv->sta_list_spinlock); 1250 1251 return count; 1252 } 1253 1254 void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv) 1255 { 1256 struct mwifiex_sta_node *sta_ptr; 1257 struct mwifiex_ds_tdls_oper tdls_oper; 1258 1259 if (list_empty(&priv->sta_list)) 1260 return; 1261 1262 list_for_each_entry(sta_ptr, &priv->sta_list, list) { 1263 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1264 1265 if (sta_ptr->is_11n_enabled) { 1266 mwifiex_11n_cleanup_reorder_tbl(priv); 1267 spin_lock_bh(&priv->wmm.ra_list_spinlock); 1268 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1269 spin_unlock_bh(&priv->wmm.ra_list_spinlock); 1270 } 1271 1272 mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr, 1273 TDLS_LINK_TEARDOWN); 1274 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN); 1275 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1276 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1277 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false)) 1278 mwifiex_dbg(priv->adapter, ERROR, 1279 "Disable link failed for TDLS peer %pM", 1280 sta_ptr->mac_addr); 1281 } 1282 1283 mwifiex_del_all_sta_list(priv); 1284 } 1285 1286 int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb) 1287 { 1288 struct mwifiex_auto_tdls_peer *peer; 1289 u8 mac[ETH_ALEN]; 1290 1291 ether_addr_copy(mac, skb->data); 1292 1293 spin_lock_bh(&priv->auto_tdls_lock); 1294 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1295 if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) { 1296 if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && 1297 peer->tdls_status == TDLS_NOT_SETUP && 1298 (peer->failure_count < 1299 MWIFIEX_TDLS_MAX_FAIL_COUNT)) { 1300 peer->tdls_status = TDLS_SETUP_INPROGRESS; 1301 mwifiex_dbg(priv->adapter, INFO, 1302 "setup TDLS link, peer=%pM rssi=%d\n", 1303 peer->mac_addr, peer->rssi); 1304 1305 cfg80211_tdls_oper_request(priv->netdev, 1306 peer->mac_addr, 1307 NL80211_TDLS_SETUP, 1308 0, GFP_ATOMIC); 1309 priv->check_tdls_tx = false; 1310 } else if (peer->failure_count < 1311 MWIFIEX_TDLS_MAX_FAIL_COUNT && 1312 peer->do_discover) { 1313 mwifiex_send_tdls_data_frame(priv, 1314 peer->mac_addr, 1315 WLAN_TDLS_DISCOVERY_REQUEST, 1316 1, 0, NULL, 0); 1317 peer->do_discover = false; 1318 } 1319 } 1320 } 1321 spin_unlock_bh(&priv->auto_tdls_lock); 1322 1323 return 0; 1324 } 1325 1326 void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv) 1327 { 1328 struct mwifiex_auto_tdls_peer *peer, *tmp_node; 1329 1330 spin_lock_bh(&priv->auto_tdls_lock); 1331 list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) { 1332 list_del(&peer->list); 1333 kfree(peer); 1334 } 1335 1336 INIT_LIST_HEAD(&priv->auto_tdls_list); 1337 spin_unlock_bh(&priv->auto_tdls_lock); 1338 priv->check_tdls_tx = false; 1339 } 1340 1341 void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac) 1342 { 1343 struct mwifiex_auto_tdls_peer *tdls_peer; 1344 1345 if (!priv->adapter->auto_tdls) 1346 return; 1347 1348 spin_lock_bh(&priv->auto_tdls_lock); 1349 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { 1350 if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) { 1351 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; 1352 tdls_peer->rssi_jiffies = jiffies; 1353 spin_unlock_bh(&priv->auto_tdls_lock); 1354 return; 1355 } 1356 } 1357 1358 /* create new TDLS peer */ 1359 tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC); 1360 if (tdls_peer) { 1361 ether_addr_copy(tdls_peer->mac_addr, mac); 1362 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; 1363 tdls_peer->rssi_jiffies = jiffies; 1364 INIT_LIST_HEAD(&tdls_peer->list); 1365 list_add_tail(&tdls_peer->list, &priv->auto_tdls_list); 1366 mwifiex_dbg(priv->adapter, INFO, 1367 "Add auto TDLS peer= %pM to list\n", mac); 1368 } 1369 1370 spin_unlock_bh(&priv->auto_tdls_lock); 1371 } 1372 1373 void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, 1374 const u8 *mac, u8 link_status) 1375 { 1376 struct mwifiex_auto_tdls_peer *peer; 1377 1378 if (!priv->adapter->auto_tdls) 1379 return; 1380 1381 spin_lock_bh(&priv->auto_tdls_lock); 1382 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1383 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { 1384 if ((link_status == TDLS_NOT_SETUP) && 1385 (peer->tdls_status == TDLS_SETUP_INPROGRESS)) 1386 peer->failure_count++; 1387 else if (mwifiex_is_tdls_link_setup(link_status)) 1388 peer->failure_count = 0; 1389 1390 peer->tdls_status = link_status; 1391 break; 1392 } 1393 } 1394 spin_unlock_bh(&priv->auto_tdls_lock); 1395 } 1396 1397 void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv, 1398 u8 *mac, s8 snr, s8 nflr) 1399 { 1400 struct mwifiex_auto_tdls_peer *peer; 1401 1402 if (!priv->adapter->auto_tdls) 1403 return; 1404 1405 spin_lock_bh(&priv->auto_tdls_lock); 1406 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1407 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { 1408 peer->rssi = nflr - snr; 1409 peer->rssi_jiffies = jiffies; 1410 break; 1411 } 1412 } 1413 spin_unlock_bh(&priv->auto_tdls_lock); 1414 } 1415 1416 void mwifiex_check_auto_tdls(struct timer_list *t) 1417 { 1418 struct mwifiex_private *priv = from_timer(priv, t, auto_tdls_timer); 1419 struct mwifiex_auto_tdls_peer *tdls_peer; 1420 u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; 1421 1422 if (WARN_ON_ONCE(!priv || !priv->adapter)) { 1423 pr_err("mwifiex: %s: adapter or private structure is NULL\n", 1424 __func__); 1425 return; 1426 } 1427 1428 if (unlikely(!priv->adapter->auto_tdls)) 1429 return; 1430 1431 if (!priv->auto_tdls_timer_active) { 1432 mwifiex_dbg(priv->adapter, INFO, 1433 "auto TDLS timer inactive; return"); 1434 return; 1435 } 1436 1437 priv->check_tdls_tx = false; 1438 1439 spin_lock_bh(&priv->auto_tdls_lock); 1440 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { 1441 if (time_after(jiffies, tdls_peer->rssi_jiffies + 1442 MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) { 1443 tdls_peer->rssi = 0; 1444 tdls_peer->do_discover = true; 1445 priv->check_tdls_tx = true; 1446 } 1447 1448 if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) || 1449 !tdls_peer->rssi) && 1450 mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) { 1451 tdls_peer->tdls_status = TDLS_LINK_TEARDOWN; 1452 mwifiex_dbg(priv->adapter, MSG, 1453 "teardown TDLS link,peer=%pM rssi=%d\n", 1454 tdls_peer->mac_addr, -tdls_peer->rssi); 1455 tdls_peer->do_discover = true; 1456 priv->check_tdls_tx = true; 1457 cfg80211_tdls_oper_request(priv->netdev, 1458 tdls_peer->mac_addr, 1459 NL80211_TDLS_TEARDOWN, 1460 reason, GFP_ATOMIC); 1461 } else if (tdls_peer->rssi && 1462 tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && 1463 tdls_peer->tdls_status == TDLS_NOT_SETUP && 1464 tdls_peer->failure_count < 1465 MWIFIEX_TDLS_MAX_FAIL_COUNT) { 1466 priv->check_tdls_tx = true; 1467 mwifiex_dbg(priv->adapter, INFO, 1468 "check TDLS with peer=%pM\t" 1469 "rssi=%d\n", tdls_peer->mac_addr, 1470 tdls_peer->rssi); 1471 } 1472 } 1473 spin_unlock_bh(&priv->auto_tdls_lock); 1474 1475 mod_timer(&priv->auto_tdls_timer, 1476 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1477 } 1478 1479 void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv) 1480 { 1481 timer_setup(&priv->auto_tdls_timer, mwifiex_check_auto_tdls, 0); 1482 priv->auto_tdls_timer_active = true; 1483 mod_timer(&priv->auto_tdls_timer, 1484 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1485 } 1486 1487 void mwifiex_clean_auto_tdls(struct mwifiex_private *priv) 1488 { 1489 if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && 1490 priv->adapter->auto_tdls && 1491 priv->bss_type == MWIFIEX_BSS_TYPE_STA) { 1492 priv->auto_tdls_timer_active = false; 1493 del_timer(&priv->auto_tdls_timer); 1494 mwifiex_flush_auto_tdls_list(priv); 1495 } 1496 } 1497 1498 static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable) 1499 { 1500 struct mwifiex_tdls_config config; 1501 1502 config.enable = cpu_to_le16(enable); 1503 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1504 ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true); 1505 } 1506 1507 int mwifiex_config_tdls_enable(struct mwifiex_private *priv) 1508 { 1509 return mwifiex_config_tdls(priv, true); 1510 } 1511 1512 int mwifiex_config_tdls_disable(struct mwifiex_private *priv) 1513 { 1514 return mwifiex_config_tdls(priv, false); 1515 } 1516 1517 int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv) 1518 { 1519 struct mwifiex_tdls_config_cs_params config_tdls_cs_params; 1520 1521 config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME; 1522 config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK; 1523 config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK; 1524 1525 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1526 ACT_TDLS_CS_PARAMS, 0, 1527 &config_tdls_cs_params, true); 1528 } 1529 1530 int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac) 1531 { 1532 struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params; 1533 1534 ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac); 1535 1536 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1537 ACT_TDLS_CS_STOP, 0, 1538 &stop_tdls_cs_params, true); 1539 } 1540 1541 int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac, 1542 u8 primary_chan, u8 second_chan_offset, u8 band) 1543 { 1544 struct mwifiex_tdls_init_cs_params start_tdls_cs_params; 1545 1546 ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac); 1547 start_tdls_cs_params.primary_chan = primary_chan; 1548 start_tdls_cs_params.second_chan_offset = second_chan_offset; 1549 start_tdls_cs_params.band = band; 1550 1551 start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME); 1552 start_tdls_cs_params.switch_timeout = 1553 cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT); 1554 start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS; 1555 start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY; 1556 1557 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1558 ACT_TDLS_CS_INIT, 0, 1559 &start_tdls_cs_params, true); 1560 } 1561