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_seg0_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 void mwifiex_tdls_add_bss_co_2040(struct sk_buff *skb) 435 { 436 struct ieee_types_bss_co_2040 *bssco; 437 438 bssco = (void *)skb_put(skb, sizeof(struct ieee_types_bss_co_2040)); 439 bssco->ieee_hdr.element_id = WLAN_EID_BSS_COEX_2040; 440 bssco->ieee_hdr.len = sizeof(struct ieee_types_bss_co_2040) - 441 sizeof(struct ieee_types_header); 442 bssco->bss_2040co = 0x01; 443 } 444 445 static void mwifiex_tdls_add_supported_chan(struct sk_buff *skb) 446 { 447 struct ieee_types_generic *supp_chan; 448 u8 chan_supp[] = {1, 11}; 449 450 supp_chan = (void *)skb_put(skb, (sizeof(struct ieee_types_header) + 451 sizeof(chan_supp))); 452 supp_chan->ieee_hdr.element_id = WLAN_EID_SUPPORTED_CHANNELS; 453 supp_chan->ieee_hdr.len = sizeof(chan_supp); 454 memcpy(supp_chan->data, chan_supp, sizeof(chan_supp)); 455 } 456 457 static void mwifiex_tdls_add_oper_class(struct sk_buff *skb) 458 { 459 struct ieee_types_generic *reg_class; 460 u8 rc_list[] = {1, 461 1, 2, 3, 4, 12, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33}; 462 reg_class = (void *)skb_put(skb, (sizeof(struct ieee_types_header) + 463 sizeof(rc_list))); 464 reg_class->ieee_hdr.element_id = WLAN_EID_SUPPORTED_REGULATORY_CLASSES; 465 reg_class->ieee_hdr.len = sizeof(rc_list); 466 memcpy(reg_class->data, rc_list, sizeof(rc_list)); 467 } 468 469 static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, 470 const u8 *peer, u8 action_code, 471 u8 dialog_token, 472 u16 status_code, struct sk_buff *skb) 473 { 474 struct ieee80211_tdls_data *tf; 475 int ret; 476 u16 capab; 477 struct ieee80211_ht_cap *ht_cap; 478 u8 radio, *pos; 479 480 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; 481 482 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); 483 memcpy(tf->da, peer, ETH_ALEN); 484 memcpy(tf->sa, priv->curr_addr, ETH_ALEN); 485 tf->ether_type = cpu_to_be16(ETH_P_TDLS); 486 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; 487 488 switch (action_code) { 489 case WLAN_TDLS_SETUP_REQUEST: 490 tf->category = WLAN_CATEGORY_TDLS; 491 tf->action_code = WLAN_TDLS_SETUP_REQUEST; 492 skb_put(skb, sizeof(tf->u.setup_req)); 493 tf->u.setup_req.dialog_token = dialog_token; 494 tf->u.setup_req.capability = cpu_to_le16(capab); 495 ret = mwifiex_tdls_append_rates_ie(priv, skb); 496 if (ret) { 497 dev_kfree_skb_any(skb); 498 return ret; 499 } 500 501 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 502 *pos++ = WLAN_EID_HT_CAPABILITY; 503 *pos++ = sizeof(struct ieee80211_ht_cap); 504 ht_cap = (void *)pos; 505 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 506 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 507 if (ret) { 508 dev_kfree_skb_any(skb); 509 return ret; 510 } 511 512 if (priv->adapter->is_hw_11ac_capable) { 513 ret = mwifiex_tdls_add_vht_capab(priv, skb); 514 if (ret) { 515 dev_kfree_skb_any(skb); 516 return ret; 517 } 518 mwifiex_tdls_add_aid(priv, skb); 519 } 520 521 mwifiex_tdls_add_ext_capab(priv, skb); 522 mwifiex_tdls_add_bss_co_2040(skb); 523 mwifiex_tdls_add_supported_chan(skb); 524 mwifiex_tdls_add_oper_class(skb); 525 mwifiex_add_wmm_info_ie(priv, skb, 0); 526 break; 527 528 case WLAN_TDLS_SETUP_RESPONSE: 529 tf->category = WLAN_CATEGORY_TDLS; 530 tf->action_code = WLAN_TDLS_SETUP_RESPONSE; 531 skb_put(skb, sizeof(tf->u.setup_resp)); 532 tf->u.setup_resp.status_code = cpu_to_le16(status_code); 533 tf->u.setup_resp.dialog_token = dialog_token; 534 tf->u.setup_resp.capability = cpu_to_le16(capab); 535 ret = mwifiex_tdls_append_rates_ie(priv, skb); 536 if (ret) { 537 dev_kfree_skb_any(skb); 538 return ret; 539 } 540 541 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 542 *pos++ = WLAN_EID_HT_CAPABILITY; 543 *pos++ = sizeof(struct ieee80211_ht_cap); 544 ht_cap = (void *)pos; 545 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 546 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 547 if (ret) { 548 dev_kfree_skb_any(skb); 549 return ret; 550 } 551 552 if (priv->adapter->is_hw_11ac_capable) { 553 ret = mwifiex_tdls_add_vht_capab(priv, skb); 554 if (ret) { 555 dev_kfree_skb_any(skb); 556 return ret; 557 } 558 mwifiex_tdls_add_aid(priv, skb); 559 } 560 561 mwifiex_tdls_add_ext_capab(priv, skb); 562 mwifiex_tdls_add_bss_co_2040(skb); 563 mwifiex_tdls_add_supported_chan(skb); 564 mwifiex_tdls_add_oper_class(skb); 565 mwifiex_add_wmm_info_ie(priv, skb, 0); 566 break; 567 568 case WLAN_TDLS_SETUP_CONFIRM: 569 tf->category = WLAN_CATEGORY_TDLS; 570 tf->action_code = WLAN_TDLS_SETUP_CONFIRM; 571 skb_put(skb, sizeof(tf->u.setup_cfm)); 572 tf->u.setup_cfm.status_code = cpu_to_le16(status_code); 573 tf->u.setup_cfm.dialog_token = dialog_token; 574 575 mwifiex_tdls_add_wmm_param_ie(priv, skb); 576 if (priv->adapter->is_hw_11ac_capable) { 577 ret = mwifiex_tdls_add_vht_oper(priv, peer, skb); 578 if (ret) { 579 dev_kfree_skb_any(skb); 580 return ret; 581 } 582 ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb); 583 if (ret) { 584 dev_kfree_skb_any(skb); 585 return ret; 586 } 587 } else { 588 ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb); 589 if (ret) { 590 dev_kfree_skb_any(skb); 591 return ret; 592 } 593 } 594 break; 595 596 case WLAN_TDLS_TEARDOWN: 597 tf->category = WLAN_CATEGORY_TDLS; 598 tf->action_code = WLAN_TDLS_TEARDOWN; 599 skb_put(skb, sizeof(tf->u.teardown)); 600 tf->u.teardown.reason_code = cpu_to_le16(status_code); 601 break; 602 603 case WLAN_TDLS_DISCOVERY_REQUEST: 604 tf->category = WLAN_CATEGORY_TDLS; 605 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; 606 skb_put(skb, sizeof(tf->u.discover_req)); 607 tf->u.discover_req.dialog_token = dialog_token; 608 break; 609 default: 610 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); 611 return -EINVAL; 612 } 613 614 return 0; 615 } 616 617 static void 618 mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, 619 const u8 *peer, const u8 *bssid) 620 { 621 struct ieee80211_tdls_lnkie *lnkid; 622 623 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); 624 lnkid->ie_type = WLAN_EID_LINK_ID; 625 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 626 sizeof(struct ieee_types_header); 627 628 memcpy(lnkid->bssid, bssid, ETH_ALEN); 629 memcpy(lnkid->init_sta, src_addr, ETH_ALEN); 630 memcpy(lnkid->resp_sta, peer, ETH_ALEN); 631 } 632 633 int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, 634 u8 action_code, u8 dialog_token, 635 u16 status_code, const u8 *extra_ies, 636 size_t extra_ies_len) 637 { 638 struct sk_buff *skb; 639 struct mwifiex_txinfo *tx_info; 640 int ret; 641 u16 skb_len; 642 643 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN + 644 max(sizeof(struct ieee80211_mgmt), 645 sizeof(struct ieee80211_tdls_data)) + 646 MWIFIEX_MGMT_FRAME_HEADER_SIZE + 647 MWIFIEX_SUPPORTED_RATES + 648 3 + /* Qos Info */ 649 sizeof(struct ieee_types_extcap) + 650 sizeof(struct ieee80211_ht_cap) + 651 sizeof(struct ieee_types_bss_co_2040) + 652 sizeof(struct ieee80211_ht_operation) + 653 sizeof(struct ieee80211_tdls_lnkie) + 654 (2 * (sizeof(struct ieee_types_header))) + 655 MWIFIEX_SUPPORTED_CHANNELS + 656 MWIFIEX_OPERATING_CLASSES + 657 sizeof(struct ieee80211_wmm_param_ie) + 658 extra_ies_len; 659 660 if (priv->adapter->is_hw_11ac_capable) 661 skb_len += sizeof(struct ieee_types_vht_cap) + 662 sizeof(struct ieee_types_vht_oper) + 663 sizeof(struct ieee_types_aid); 664 665 skb = dev_alloc_skb(skb_len); 666 if (!skb) { 667 mwifiex_dbg(priv->adapter, ERROR, 668 "allocate skb failed for management frame\n"); 669 return -ENOMEM; 670 } 671 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN); 672 673 switch (action_code) { 674 case WLAN_TDLS_SETUP_REQUEST: 675 case WLAN_TDLS_SETUP_CONFIRM: 676 case WLAN_TDLS_TEARDOWN: 677 case WLAN_TDLS_DISCOVERY_REQUEST: 678 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code, 679 dialog_token, status_code, 680 skb); 681 if (ret) { 682 dev_kfree_skb_any(skb); 683 return ret; 684 } 685 if (extra_ies_len) 686 memcpy(skb_put(skb, extra_ies_len), extra_ies, 687 extra_ies_len); 688 mwifiex_tdls_add_link_ie(skb, priv->curr_addr, peer, 689 priv->cfg_bssid); 690 break; 691 case WLAN_TDLS_SETUP_RESPONSE: 692 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code, 693 dialog_token, status_code, 694 skb); 695 if (ret) { 696 dev_kfree_skb_any(skb); 697 return ret; 698 } 699 if (extra_ies_len) 700 memcpy(skb_put(skb, extra_ies_len), extra_ies, 701 extra_ies_len); 702 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr, 703 priv->cfg_bssid); 704 break; 705 } 706 707 switch (action_code) { 708 case WLAN_TDLS_SETUP_REQUEST: 709 case WLAN_TDLS_SETUP_RESPONSE: 710 skb->priority = MWIFIEX_PRIO_BK; 711 break; 712 default: 713 skb->priority = MWIFIEX_PRIO_VI; 714 break; 715 } 716 717 tx_info = MWIFIEX_SKB_TXCB(skb); 718 memset(tx_info, 0, sizeof(*tx_info)); 719 tx_info->bss_num = priv->bss_num; 720 tx_info->bss_type = priv->bss_type; 721 722 __net_timestamp(skb); 723 mwifiex_queue_tx_pkt(priv, skb); 724 725 /* Delay 10ms to make sure tdls setup confirm/teardown frame 726 * is received by peer 727 */ 728 if (action_code == WLAN_TDLS_SETUP_CONFIRM || 729 action_code == WLAN_TDLS_TEARDOWN) 730 msleep_interruptible(10); 731 732 return 0; 733 } 734 735 static int 736 mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, 737 const u8 *peer, 738 u8 action_code, u8 dialog_token, 739 u16 status_code, struct sk_buff *skb) 740 { 741 struct ieee80211_mgmt *mgmt; 742 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 743 int ret; 744 u16 capab; 745 struct ieee80211_ht_cap *ht_cap; 746 u8 radio, *pos; 747 748 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; 749 750 mgmt = (void *)skb_put(skb, offsetof(struct ieee80211_mgmt, u)); 751 752 memset(mgmt, 0, 24); 753 memcpy(mgmt->da, peer, ETH_ALEN); 754 memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN); 755 memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN); 756 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 757 IEEE80211_STYPE_ACTION); 758 759 /* add address 4 */ 760 pos = skb_put(skb, ETH_ALEN); 761 762 switch (action_code) { 763 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 764 skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); 765 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 766 mgmt->u.action.u.tdls_discover_resp.action_code = 767 WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 768 mgmt->u.action.u.tdls_discover_resp.dialog_token = 769 dialog_token; 770 mgmt->u.action.u.tdls_discover_resp.capability = 771 cpu_to_le16(capab); 772 /* move back for addr4 */ 773 memmove(pos + ETH_ALEN, &mgmt->u.action.category, 774 sizeof(mgmt->u.action.u.tdls_discover_resp)); 775 /* init address 4 */ 776 memcpy(pos, bc_addr, ETH_ALEN); 777 778 ret = mwifiex_tdls_append_rates_ie(priv, skb); 779 if (ret) { 780 dev_kfree_skb_any(skb); 781 return ret; 782 } 783 784 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); 785 *pos++ = WLAN_EID_HT_CAPABILITY; 786 *pos++ = sizeof(struct ieee80211_ht_cap); 787 ht_cap = (void *)pos; 788 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 789 ret = mwifiex_fill_cap_info(priv, radio, ht_cap); 790 if (ret) { 791 dev_kfree_skb_any(skb); 792 return ret; 793 } 794 795 if (priv->adapter->is_hw_11ac_capable) { 796 ret = mwifiex_tdls_add_vht_capab(priv, skb); 797 if (ret) { 798 dev_kfree_skb_any(skb); 799 return ret; 800 } 801 mwifiex_tdls_add_aid(priv, skb); 802 } 803 804 mwifiex_tdls_add_ext_capab(priv, skb); 805 mwifiex_tdls_add_bss_co_2040(skb); 806 mwifiex_tdls_add_supported_chan(skb); 807 mwifiex_tdls_add_qos_capab(skb); 808 mwifiex_tdls_add_oper_class(skb); 809 break; 810 default: 811 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n"); 812 return -EINVAL; 813 } 814 815 return 0; 816 } 817 818 int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, 819 u8 action_code, u8 dialog_token, 820 u16 status_code, const u8 *extra_ies, 821 size_t extra_ies_len) 822 { 823 struct sk_buff *skb; 824 struct mwifiex_txinfo *tx_info; 825 u8 *pos; 826 u32 pkt_type, tx_control; 827 u16 pkt_len, skb_len; 828 829 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN + 830 max(sizeof(struct ieee80211_mgmt), 831 sizeof(struct ieee80211_tdls_data)) + 832 MWIFIEX_MGMT_FRAME_HEADER_SIZE + 833 MWIFIEX_SUPPORTED_RATES + 834 sizeof(struct ieee_types_extcap) + 835 sizeof(struct ieee80211_ht_cap) + 836 sizeof(struct ieee_types_bss_co_2040) + 837 sizeof(struct ieee80211_ht_operation) + 838 sizeof(struct ieee80211_tdls_lnkie) + 839 extra_ies_len + 840 3 + /* Qos Info */ 841 ETH_ALEN; /* Address4 */ 842 843 if (priv->adapter->is_hw_11ac_capable) 844 skb_len += sizeof(struct ieee_types_vht_cap) + 845 sizeof(struct ieee_types_vht_oper) + 846 sizeof(struct ieee_types_aid); 847 848 skb = dev_alloc_skb(skb_len); 849 if (!skb) { 850 mwifiex_dbg(priv->adapter, ERROR, 851 "allocate skb failed for management frame\n"); 852 return -ENOMEM; 853 } 854 855 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN); 856 857 pkt_type = PKT_TYPE_MGMT; 858 tx_control = 0; 859 pos = skb_put(skb, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len)); 860 memset(pos, 0, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len)); 861 memcpy(pos, &pkt_type, sizeof(pkt_type)); 862 memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control)); 863 864 if (mwifiex_construct_tdls_action_frame(priv, peer, action_code, 865 dialog_token, status_code, 866 skb)) { 867 dev_kfree_skb_any(skb); 868 return -EINVAL; 869 } 870 871 if (extra_ies_len) 872 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); 873 874 /* the TDLS link IE is always added last we are the responder */ 875 876 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr, 877 priv->cfg_bssid); 878 879 skb->priority = MWIFIEX_PRIO_VI; 880 881 tx_info = MWIFIEX_SKB_TXCB(skb); 882 memset(tx_info, 0, sizeof(*tx_info)); 883 tx_info->bss_num = priv->bss_num; 884 tx_info->bss_type = priv->bss_type; 885 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 886 887 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len); 888 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len, 889 sizeof(pkt_len)); 890 __net_timestamp(skb); 891 mwifiex_queue_tx_pkt(priv, skb); 892 893 return 0; 894 } 895 896 /* This function process tdls action frame from peer. 897 * Peer capabilities are stored into station node structure. 898 */ 899 void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, 900 u8 *buf, int len) 901 { 902 struct mwifiex_sta_node *sta_ptr; 903 u8 *peer, *pos, *end; 904 u8 i, action, basic; 905 u16 cap = 0; 906 int ie_len = 0; 907 908 if (len < (sizeof(struct ethhdr) + 3)) 909 return; 910 if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE) 911 return; 912 if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS) 913 return; 914 915 peer = buf + ETH_ALEN; 916 action = *(buf + sizeof(struct ethhdr) + 2); 917 mwifiex_dbg(priv->adapter, DATA, 918 "rx:tdls action: peer=%pM, action=%d\n", peer, action); 919 920 switch (action) { 921 case WLAN_TDLS_SETUP_REQUEST: 922 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN)) 923 return; 924 925 pos = buf + sizeof(struct ethhdr) + 4; 926 /* payload 1+ category 1 + action 1 + dialog 1 */ 927 cap = get_unaligned_le16(pos); 928 ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; 929 pos += 2; 930 break; 931 932 case WLAN_TDLS_SETUP_RESPONSE: 933 if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN)) 934 return; 935 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ 936 pos = buf + sizeof(struct ethhdr) + 6; 937 cap = get_unaligned_le16(pos); 938 ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; 939 pos += 2; 940 break; 941 942 case WLAN_TDLS_SETUP_CONFIRM: 943 if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN)) 944 return; 945 pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN; 946 ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; 947 break; 948 default: 949 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); 950 return; 951 } 952 953 sta_ptr = mwifiex_add_sta_entry(priv, peer); 954 if (!sta_ptr) 955 return; 956 957 sta_ptr->tdls_cap.capab = cpu_to_le16(cap); 958 959 for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) { 960 if (pos + 2 + pos[1] > end) 961 break; 962 963 switch (*pos) { 964 case WLAN_EID_SUPP_RATES: 965 sta_ptr->tdls_cap.rates_len = pos[1]; 966 for (i = 0; i < pos[1]; i++) 967 sta_ptr->tdls_cap.rates[i] = pos[i + 2]; 968 break; 969 970 case WLAN_EID_EXT_SUPP_RATES: 971 basic = sta_ptr->tdls_cap.rates_len; 972 for (i = 0; i < pos[1]; i++) 973 sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; 974 sta_ptr->tdls_cap.rates_len += pos[1]; 975 break; 976 case WLAN_EID_HT_CAPABILITY: 977 memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos, 978 sizeof(struct ieee80211_ht_cap)); 979 sta_ptr->is_11n_enabled = 1; 980 break; 981 case WLAN_EID_HT_OPERATION: 982 memcpy(&sta_ptr->tdls_cap.ht_oper, pos, 983 sizeof(struct ieee80211_ht_operation)); 984 break; 985 case WLAN_EID_BSS_COEX_2040: 986 sta_ptr->tdls_cap.coex_2040 = pos[2]; 987 break; 988 case WLAN_EID_EXT_CAPABILITY: 989 memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, 990 sizeof(struct ieee_types_header) + 991 min_t(u8, pos[1], 8)); 992 break; 993 case WLAN_EID_RSN: 994 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, 995 sizeof(struct ieee_types_header) + 996 min_t(u8, pos[1], IEEE_MAX_IE_SIZE - 997 sizeof(struct ieee_types_header))); 998 break; 999 case WLAN_EID_QOS_CAPA: 1000 sta_ptr->tdls_cap.qos_info = pos[2]; 1001 break; 1002 case WLAN_EID_VHT_OPERATION: 1003 if (priv->adapter->is_hw_11ac_capable) 1004 memcpy(&sta_ptr->tdls_cap.vhtoper, pos, 1005 sizeof(struct ieee80211_vht_operation)); 1006 break; 1007 case WLAN_EID_VHT_CAPABILITY: 1008 if (priv->adapter->is_hw_11ac_capable) { 1009 memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos, 1010 sizeof(struct ieee80211_vht_cap)); 1011 sta_ptr->is_11ac_enabled = 1; 1012 } 1013 break; 1014 case WLAN_EID_AID: 1015 if (priv->adapter->is_hw_11ac_capable) 1016 sta_ptr->tdls_cap.aid = 1017 get_unaligned_le16((pos + 2)); 1018 default: 1019 break; 1020 } 1021 } 1022 1023 return; 1024 } 1025 1026 static int 1027 mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer) 1028 { 1029 struct mwifiex_sta_node *sta_ptr; 1030 struct mwifiex_ds_tdls_oper tdls_oper; 1031 1032 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1033 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1034 1035 if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) { 1036 mwifiex_dbg(priv->adapter, ERROR, 1037 "link absent for peer %pM; cannot config\n", peer); 1038 return -EINVAL; 1039 } 1040 1041 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1042 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK; 1043 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1044 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1045 } 1046 1047 static int 1048 mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer) 1049 { 1050 struct mwifiex_sta_node *sta_ptr; 1051 struct mwifiex_ds_tdls_oper tdls_oper; 1052 1053 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1054 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1055 1056 if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) { 1057 mwifiex_dbg(priv->adapter, WARN, 1058 "Setup already in progress for peer %pM\n", peer); 1059 return 0; 1060 } 1061 1062 sta_ptr = mwifiex_add_sta_entry(priv, peer); 1063 if (!sta_ptr) 1064 return -ENOMEM; 1065 1066 sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS; 1067 mwifiex_hold_tdls_packets(priv, peer); 1068 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1069 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK; 1070 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1071 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1072 } 1073 1074 static int 1075 mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer) 1076 { 1077 struct mwifiex_sta_node *sta_ptr; 1078 struct mwifiex_ds_tdls_oper tdls_oper; 1079 unsigned long flags; 1080 1081 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1082 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1083 1084 if (sta_ptr) { 1085 if (sta_ptr->is_11n_enabled) { 1086 mwifiex_11n_cleanup_reorder_tbl(priv); 1087 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, 1088 flags); 1089 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1090 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1091 flags); 1092 } 1093 mwifiex_del_sta_entry(priv, peer); 1094 } 1095 1096 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 1097 mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP); 1098 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); 1099 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1100 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1101 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true); 1102 } 1103 1104 static int 1105 mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) 1106 { 1107 struct mwifiex_sta_node *sta_ptr; 1108 struct ieee80211_mcs_info mcs; 1109 unsigned long flags; 1110 int i; 1111 1112 sta_ptr = mwifiex_get_sta_entry(priv, peer); 1113 1114 if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) { 1115 mwifiex_dbg(priv->adapter, MSG, 1116 "tdls: enable link %pM success\n", peer); 1117 1118 sta_ptr->tdls_status = TDLS_SETUP_COMPLETE; 1119 1120 mcs = sta_ptr->tdls_cap.ht_capb.mcs; 1121 if (mcs.rx_mask[0] != 0xff) 1122 sta_ptr->is_11n_enabled = true; 1123 if (sta_ptr->is_11n_enabled) { 1124 if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) & 1125 IEEE80211_HT_CAP_MAX_AMSDU) 1126 sta_ptr->max_amsdu = 1127 MWIFIEX_TX_DATA_BUF_SIZE_8K; 1128 else 1129 sta_ptr->max_amsdu = 1130 MWIFIEX_TX_DATA_BUF_SIZE_4K; 1131 1132 for (i = 0; i < MAX_NUM_TID; i++) 1133 sta_ptr->ampdu_sta[i] = 1134 priv->aggr_prio_tbl[i].ampdu_user; 1135 } else { 1136 for (i = 0; i < MAX_NUM_TID; i++) 1137 sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED; 1138 } 1139 if (sta_ptr->tdls_cap.extcap.ext_capab[3] & 1140 WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) { 1141 mwifiex_config_tdls_enable(priv); 1142 mwifiex_config_tdls_cs_params(priv); 1143 } 1144 1145 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq)); 1146 mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE); 1147 mwifiex_auto_tdls_update_peer_status(priv, peer, 1148 TDLS_SETUP_COMPLETE); 1149 } else { 1150 mwifiex_dbg(priv->adapter, ERROR, 1151 "tdls: enable link %pM failed\n", peer); 1152 if (sta_ptr) { 1153 mwifiex_11n_cleanup_reorder_tbl(priv); 1154 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, 1155 flags); 1156 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1157 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1158 flags); 1159 mwifiex_del_sta_entry(priv, peer); 1160 } 1161 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); 1162 mwifiex_auto_tdls_update_peer_status(priv, peer, 1163 TDLS_NOT_SETUP); 1164 1165 return -1; 1166 } 1167 1168 return 0; 1169 } 1170 1171 int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action) 1172 { 1173 switch (action) { 1174 case MWIFIEX_TDLS_ENABLE_LINK: 1175 return mwifiex_tdls_process_enable_link(priv, peer); 1176 case MWIFIEX_TDLS_DISABLE_LINK: 1177 return mwifiex_tdls_process_disable_link(priv, peer); 1178 case MWIFIEX_TDLS_CREATE_LINK: 1179 return mwifiex_tdls_process_create_link(priv, peer); 1180 case MWIFIEX_TDLS_CONFIG_LINK: 1181 return mwifiex_tdls_process_config_link(priv, peer); 1182 } 1183 return 0; 1184 } 1185 1186 int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac) 1187 { 1188 struct mwifiex_sta_node *sta_ptr; 1189 1190 sta_ptr = mwifiex_get_sta_entry(priv, mac); 1191 if (sta_ptr) 1192 return sta_ptr->tdls_status; 1193 1194 return TDLS_NOT_SETUP; 1195 } 1196 1197 int mwifiex_get_tdls_list(struct mwifiex_private *priv, 1198 struct tdls_peer_info *buf) 1199 { 1200 struct mwifiex_sta_node *sta_ptr; 1201 struct tdls_peer_info *peer = buf; 1202 int count = 0; 1203 unsigned long flags; 1204 1205 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) 1206 return 0; 1207 1208 /* make sure we are in station mode and connected */ 1209 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected)) 1210 return 0; 1211 1212 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 1213 list_for_each_entry(sta_ptr, &priv->sta_list, list) { 1214 if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) { 1215 ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr); 1216 peer++; 1217 count++; 1218 if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED) 1219 break; 1220 } 1221 } 1222 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 1223 1224 return count; 1225 } 1226 1227 void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv) 1228 { 1229 struct mwifiex_sta_node *sta_ptr; 1230 struct mwifiex_ds_tdls_oper tdls_oper; 1231 unsigned long flags; 1232 1233 if (list_empty(&priv->sta_list)) 1234 return; 1235 1236 list_for_each_entry(sta_ptr, &priv->sta_list, list) { 1237 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); 1238 1239 if (sta_ptr->is_11n_enabled) { 1240 mwifiex_11n_cleanup_reorder_tbl(priv); 1241 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, 1242 flags); 1243 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); 1244 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1245 flags); 1246 } 1247 1248 mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr, 1249 TDLS_LINK_TEARDOWN); 1250 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN); 1251 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; 1252 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, 1253 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false)) 1254 mwifiex_dbg(priv->adapter, ERROR, 1255 "Disable link failed for TDLS peer %pM", 1256 sta_ptr->mac_addr); 1257 } 1258 1259 mwifiex_del_all_sta_list(priv); 1260 } 1261 1262 int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb) 1263 { 1264 struct mwifiex_auto_tdls_peer *peer; 1265 unsigned long flags; 1266 u8 mac[ETH_ALEN]; 1267 1268 ether_addr_copy(mac, skb->data); 1269 1270 spin_lock_irqsave(&priv->auto_tdls_lock, flags); 1271 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1272 if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) { 1273 if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && 1274 peer->tdls_status == TDLS_NOT_SETUP && 1275 (peer->failure_count < 1276 MWIFIEX_TDLS_MAX_FAIL_COUNT)) { 1277 peer->tdls_status = TDLS_SETUP_INPROGRESS; 1278 mwifiex_dbg(priv->adapter, INFO, 1279 "setup TDLS link, peer=%pM rssi=%d\n", 1280 peer->mac_addr, peer->rssi); 1281 1282 cfg80211_tdls_oper_request(priv->netdev, 1283 peer->mac_addr, 1284 NL80211_TDLS_SETUP, 1285 0, GFP_ATOMIC); 1286 peer->do_setup = false; 1287 priv->check_tdls_tx = false; 1288 } else if (peer->failure_count < 1289 MWIFIEX_TDLS_MAX_FAIL_COUNT && 1290 peer->do_discover) { 1291 mwifiex_send_tdls_data_frame(priv, 1292 peer->mac_addr, 1293 WLAN_TDLS_DISCOVERY_REQUEST, 1294 1, 0, NULL, 0); 1295 peer->do_discover = false; 1296 } 1297 } 1298 } 1299 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1300 1301 return 0; 1302 } 1303 1304 void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv) 1305 { 1306 struct mwifiex_auto_tdls_peer *peer, *tmp_node; 1307 unsigned long flags; 1308 1309 spin_lock_irqsave(&priv->auto_tdls_lock, flags); 1310 list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) { 1311 list_del(&peer->list); 1312 kfree(peer); 1313 } 1314 1315 INIT_LIST_HEAD(&priv->auto_tdls_list); 1316 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1317 priv->check_tdls_tx = false; 1318 } 1319 1320 void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac) 1321 { 1322 struct mwifiex_auto_tdls_peer *tdls_peer; 1323 unsigned long flags; 1324 1325 if (!priv->adapter->auto_tdls) 1326 return; 1327 1328 spin_lock_irqsave(&priv->auto_tdls_lock, flags); 1329 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { 1330 if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) { 1331 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; 1332 tdls_peer->rssi_jiffies = jiffies; 1333 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1334 return; 1335 } 1336 } 1337 1338 /* create new TDLS peer */ 1339 tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC); 1340 if (tdls_peer) { 1341 ether_addr_copy(tdls_peer->mac_addr, mac); 1342 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; 1343 tdls_peer->rssi_jiffies = jiffies; 1344 INIT_LIST_HEAD(&tdls_peer->list); 1345 list_add_tail(&tdls_peer->list, &priv->auto_tdls_list); 1346 mwifiex_dbg(priv->adapter, INFO, 1347 "Add auto TDLS peer= %pM to list\n", mac); 1348 } 1349 1350 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1351 } 1352 1353 void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, 1354 const u8 *mac, u8 link_status) 1355 { 1356 struct mwifiex_auto_tdls_peer *peer; 1357 unsigned long flags; 1358 1359 if (!priv->adapter->auto_tdls) 1360 return; 1361 1362 spin_lock_irqsave(&priv->auto_tdls_lock, flags); 1363 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1364 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { 1365 if ((link_status == TDLS_NOT_SETUP) && 1366 (peer->tdls_status == TDLS_SETUP_INPROGRESS)) 1367 peer->failure_count++; 1368 else if (mwifiex_is_tdls_link_setup(link_status)) 1369 peer->failure_count = 0; 1370 1371 peer->tdls_status = link_status; 1372 break; 1373 } 1374 } 1375 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1376 } 1377 1378 void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv, 1379 u8 *mac, s8 snr, s8 nflr) 1380 { 1381 struct mwifiex_auto_tdls_peer *peer; 1382 unsigned long flags; 1383 1384 if (!priv->adapter->auto_tdls) 1385 return; 1386 1387 spin_lock_irqsave(&priv->auto_tdls_lock, flags); 1388 list_for_each_entry(peer, &priv->auto_tdls_list, list) { 1389 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { 1390 peer->rssi = nflr - snr; 1391 peer->rssi_jiffies = jiffies; 1392 break; 1393 } 1394 } 1395 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1396 } 1397 1398 void mwifiex_check_auto_tdls(unsigned long context) 1399 { 1400 struct mwifiex_private *priv = (struct mwifiex_private *)context; 1401 struct mwifiex_auto_tdls_peer *tdls_peer; 1402 unsigned long flags; 1403 u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; 1404 1405 if (WARN_ON_ONCE(!priv || !priv->adapter)) { 1406 pr_err("mwifiex: %s: adapter or private structure is NULL\n", 1407 __func__); 1408 return; 1409 } 1410 1411 if (unlikely(!priv->adapter->auto_tdls)) 1412 return; 1413 1414 if (!priv->auto_tdls_timer_active) { 1415 mwifiex_dbg(priv->adapter, INFO, 1416 "auto TDLS timer inactive; return"); 1417 return; 1418 } 1419 1420 priv->check_tdls_tx = false; 1421 1422 if (list_empty(&priv->auto_tdls_list)) { 1423 mod_timer(&priv->auto_tdls_timer, 1424 jiffies + 1425 msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1426 return; 1427 } 1428 1429 spin_lock_irqsave(&priv->auto_tdls_lock, flags); 1430 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { 1431 if ((jiffies - tdls_peer->rssi_jiffies) > 1432 (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) { 1433 tdls_peer->rssi = 0; 1434 tdls_peer->do_discover = true; 1435 priv->check_tdls_tx = true; 1436 } 1437 1438 if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) || 1439 !tdls_peer->rssi) && 1440 mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) { 1441 tdls_peer->tdls_status = TDLS_LINK_TEARDOWN; 1442 mwifiex_dbg(priv->adapter, MSG, 1443 "teardown TDLS link,peer=%pM rssi=%d\n", 1444 tdls_peer->mac_addr, -tdls_peer->rssi); 1445 tdls_peer->do_discover = true; 1446 priv->check_tdls_tx = true; 1447 cfg80211_tdls_oper_request(priv->netdev, 1448 tdls_peer->mac_addr, 1449 NL80211_TDLS_TEARDOWN, 1450 reason, GFP_ATOMIC); 1451 } else if (tdls_peer->rssi && 1452 tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && 1453 tdls_peer->tdls_status == TDLS_NOT_SETUP && 1454 tdls_peer->failure_count < 1455 MWIFIEX_TDLS_MAX_FAIL_COUNT) { 1456 priv->check_tdls_tx = true; 1457 tdls_peer->do_setup = true; 1458 mwifiex_dbg(priv->adapter, INFO, 1459 "check TDLS with peer=%pM\t" 1460 "rssi=%d\n", tdls_peer->mac_addr, 1461 tdls_peer->rssi); 1462 } 1463 } 1464 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); 1465 1466 mod_timer(&priv->auto_tdls_timer, 1467 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1468 } 1469 1470 void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv) 1471 { 1472 setup_timer(&priv->auto_tdls_timer, mwifiex_check_auto_tdls, 1473 (unsigned long)priv); 1474 priv->auto_tdls_timer_active = true; 1475 mod_timer(&priv->auto_tdls_timer, 1476 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1477 } 1478 1479 void mwifiex_clean_auto_tdls(struct mwifiex_private *priv) 1480 { 1481 if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && 1482 priv->adapter->auto_tdls && 1483 priv->bss_type == MWIFIEX_BSS_TYPE_STA) { 1484 priv->auto_tdls_timer_active = false; 1485 del_timer(&priv->auto_tdls_timer); 1486 mwifiex_flush_auto_tdls_list(priv); 1487 } 1488 } 1489 1490 static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable) 1491 { 1492 struct mwifiex_tdls_config config; 1493 1494 config.enable = cpu_to_le16(enable); 1495 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1496 ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true); 1497 } 1498 1499 int mwifiex_config_tdls_enable(struct mwifiex_private *priv) 1500 { 1501 return mwifiex_config_tdls(priv, true); 1502 } 1503 1504 int mwifiex_config_tdls_disable(struct mwifiex_private *priv) 1505 { 1506 return mwifiex_config_tdls(priv, false); 1507 } 1508 1509 int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv) 1510 { 1511 struct mwifiex_tdls_config_cs_params config_tdls_cs_params; 1512 1513 config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME; 1514 config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK; 1515 config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK; 1516 1517 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1518 ACT_TDLS_CS_PARAMS, 0, 1519 &config_tdls_cs_params, true); 1520 } 1521 1522 int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac) 1523 { 1524 struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params; 1525 1526 ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac); 1527 1528 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1529 ACT_TDLS_CS_STOP, 0, 1530 &stop_tdls_cs_params, true); 1531 } 1532 1533 int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac, 1534 u8 primary_chan, u8 second_chan_offset, u8 band) 1535 { 1536 struct mwifiex_tdls_init_cs_params start_tdls_cs_params; 1537 1538 ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac); 1539 start_tdls_cs_params.primary_chan = primary_chan; 1540 start_tdls_cs_params.second_chan_offset = second_chan_offset; 1541 start_tdls_cs_params.band = band; 1542 1543 start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME); 1544 start_tdls_cs_params.switch_timeout = 1545 cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT); 1546 start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS; 1547 start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY; 1548 1549 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG, 1550 ACT_TDLS_CS_INIT, 0, 1551 &start_tdls_cs_params, true); 1552 } 1553