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