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