0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "main.h"
0020 #include "wmm.h"
0021 #include "11n.h"
0022 #include "11n_rxreorder.h"
0023 #include "11ac.h"
0024
0025 #define TDLS_REQ_FIX_LEN 6
0026 #define TDLS_RESP_FIX_LEN 8
0027 #define TDLS_CONFIRM_FIX_LEN 6
0028 #define MWIFIEX_TDLS_WMM_INFO_SIZE 7
0029
0030 static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv,
0031 const u8 *mac, u8 status)
0032 {
0033 struct mwifiex_ra_list_tbl *ra_list;
0034 struct list_head *tid_list;
0035 struct sk_buff *skb, *tmp;
0036 struct mwifiex_txinfo *tx_info;
0037 u32 tid;
0038 u8 tid_down;
0039
0040 mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac);
0041 spin_lock_bh(&priv->wmm.ra_list_spinlock);
0042
0043 skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) {
0044 if (!ether_addr_equal(mac, skb->data))
0045 continue;
0046
0047 __skb_unlink(skb, &priv->tdls_txq);
0048 tx_info = MWIFIEX_SKB_TXCB(skb);
0049 tid = skb->priority;
0050 tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
0051
0052 if (mwifiex_is_tdls_link_setup(status)) {
0053 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid, mac);
0054 ra_list->tdls_link = true;
0055 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
0056 } else {
0057 tid_list = &priv->wmm.tid_tbl_ptr[tid_down].ra_list;
0058 ra_list = list_first_entry_or_null(tid_list,
0059 struct mwifiex_ra_list_tbl, list);
0060 tx_info->flags &= ~MWIFIEX_BUF_FLAG_TDLS_PKT;
0061 }
0062
0063 if (!ra_list) {
0064 mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
0065 continue;
0066 }
0067
0068 skb_queue_tail(&ra_list->skb_head, skb);
0069
0070 ra_list->ba_pkt_count++;
0071 ra_list->total_pkt_count++;
0072
0073 if (atomic_read(&priv->wmm.highest_queued_prio) <
0074 tos_to_tid_inv[tid_down])
0075 atomic_set(&priv->wmm.highest_queued_prio,
0076 tos_to_tid_inv[tid_down]);
0077
0078 atomic_inc(&priv->wmm.tx_pkts_queued);
0079 }
0080
0081 spin_unlock_bh(&priv->wmm.ra_list_spinlock);
0082 return;
0083 }
0084
0085 static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv,
0086 const u8 *mac)
0087 {
0088 struct mwifiex_ra_list_tbl *ra_list;
0089 struct list_head *ra_list_head;
0090 struct sk_buff *skb, *tmp;
0091 int i;
0092
0093 mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac);
0094 spin_lock_bh(&priv->wmm.ra_list_spinlock);
0095
0096 for (i = 0; i < MAX_NUM_TID; i++) {
0097 if (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) {
0098 ra_list_head = &priv->wmm.tid_tbl_ptr[i].ra_list;
0099 list_for_each_entry(ra_list, ra_list_head, list) {
0100 skb_queue_walk_safe(&ra_list->skb_head, skb,
0101 tmp) {
0102 if (!ether_addr_equal(mac, skb->data))
0103 continue;
0104 __skb_unlink(skb, &ra_list->skb_head);
0105 atomic_dec(&priv->wmm.tx_pkts_queued);
0106 ra_list->total_pkt_count--;
0107 skb_queue_tail(&priv->tdls_txq, skb);
0108 }
0109 }
0110 }
0111 }
0112
0113 spin_unlock_bh(&priv->wmm.ra_list_spinlock);
0114 return;
0115 }
0116
0117
0118 static int
0119 mwifiex_tdls_append_rates_ie(struct mwifiex_private *priv,
0120 struct sk_buff *skb)
0121 {
0122 u8 rates[MWIFIEX_SUPPORTED_RATES], *pos;
0123 u16 rates_size, supp_rates_size, ext_rates_size;
0124
0125 memset(rates, 0, sizeof(rates));
0126 rates_size = mwifiex_get_supported_rates(priv, rates);
0127
0128 supp_rates_size = min_t(u16, rates_size, MWIFIEX_TDLS_SUPPORTED_RATES);
0129
0130 if (skb_tailroom(skb) < rates_size + 4) {
0131 mwifiex_dbg(priv->adapter, ERROR,
0132 "Insufficient space while adding rates\n");
0133 return -ENOMEM;
0134 }
0135
0136 pos = skb_put(skb, supp_rates_size + 2);
0137 *pos++ = WLAN_EID_SUPP_RATES;
0138 *pos++ = supp_rates_size;
0139 memcpy(pos, rates, supp_rates_size);
0140
0141 if (rates_size > MWIFIEX_TDLS_SUPPORTED_RATES) {
0142 ext_rates_size = rates_size - MWIFIEX_TDLS_SUPPORTED_RATES;
0143 pos = skb_put(skb, ext_rates_size + 2);
0144 *pos++ = WLAN_EID_EXT_SUPP_RATES;
0145 *pos++ = ext_rates_size;
0146 memcpy(pos, rates + MWIFIEX_TDLS_SUPPORTED_RATES,
0147 ext_rates_size);
0148 }
0149
0150 return 0;
0151 }
0152
0153 static void mwifiex_tdls_add_aid(struct mwifiex_private *priv,
0154 struct sk_buff *skb)
0155 {
0156 struct ieee_types_assoc_rsp *assoc_rsp;
0157 u8 *pos;
0158
0159 assoc_rsp = (struct ieee_types_assoc_rsp *)&priv->assoc_rsp_buf;
0160 pos = skb_put(skb, 4);
0161 *pos++ = WLAN_EID_AID;
0162 *pos++ = 2;
0163 memcpy(pos, &assoc_rsp->a_id, sizeof(assoc_rsp->a_id));
0164
0165 return;
0166 }
0167
0168 static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
0169 struct sk_buff *skb)
0170 {
0171 struct ieee80211_vht_cap vht_cap;
0172 u8 *pos;
0173
0174 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
0175 *pos++ = WLAN_EID_VHT_CAPABILITY;
0176 *pos++ = sizeof(struct ieee80211_vht_cap);
0177
0178 memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap));
0179
0180 mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band);
0181 memcpy(pos, &vht_cap, sizeof(vht_cap));
0182
0183 return 0;
0184 }
0185
0186 static int
0187 mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, const u8 *mac,
0188 u8 vht_enabled, struct sk_buff *skb)
0189 {
0190 struct ieee80211_ht_operation *ht_oper;
0191 struct mwifiex_sta_node *sta_ptr;
0192 struct mwifiex_bssdescriptor *bss_desc =
0193 &priv->curr_bss_params.bss_descriptor;
0194 u8 *pos;
0195
0196 sta_ptr = mwifiex_get_sta_entry(priv, mac);
0197 if (unlikely(!sta_ptr)) {
0198 mwifiex_dbg(priv->adapter, ERROR,
0199 "TDLS peer station not found in list\n");
0200 return -1;
0201 }
0202
0203 if (!(le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info))) {
0204 mwifiex_dbg(priv->adapter, WARN,
0205 "TDLS peer doesn't support ht capabilities\n");
0206 return 0;
0207 }
0208
0209 pos = skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
0210 *pos++ = WLAN_EID_HT_OPERATION;
0211 *pos++ = sizeof(struct ieee80211_ht_operation);
0212 ht_oper = (void *)pos;
0213
0214 ht_oper->primary_chan = bss_desc->channel;
0215
0216
0217 if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) &&
0218 bss_desc->bcn_ht_cap &&
0219 ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param))
0220 ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param;
0221
0222 if (vht_enabled) {
0223 ht_oper->ht_param =
0224 mwifiex_get_sec_chan_offset(bss_desc->channel);
0225 ht_oper->ht_param |= BIT(2);
0226 }
0227
0228 memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper,
0229 sizeof(struct ieee80211_ht_operation));
0230
0231 return 0;
0232 }
0233
0234 static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
0235 const u8 *mac, struct sk_buff *skb)
0236 {
0237 struct mwifiex_bssdescriptor *bss_desc;
0238 struct ieee80211_vht_operation *vht_oper;
0239 struct ieee80211_vht_cap *vht_cap, *ap_vht_cap = NULL;
0240 struct mwifiex_sta_node *sta_ptr;
0241 struct mwifiex_adapter *adapter = priv->adapter;
0242 u8 supp_chwd_set, peer_supp_chwd_set;
0243 u8 *pos, ap_supp_chwd_set, chan_bw;
0244 u16 mcs_map_user, mcs_map_resp, mcs_map_result;
0245 u16 mcs_user, mcs_resp, nss;
0246 u32 usr_vht_cap_info;
0247
0248 bss_desc = &priv->curr_bss_params.bss_descriptor;
0249
0250 sta_ptr = mwifiex_get_sta_entry(priv, mac);
0251 if (unlikely(!sta_ptr)) {
0252 mwifiex_dbg(adapter, ERROR,
0253 "TDLS peer station not found in list\n");
0254 return -1;
0255 }
0256
0257 if (!(le32_to_cpu(sta_ptr->tdls_cap.vhtcap.vht_cap_info))) {
0258 mwifiex_dbg(adapter, WARN,
0259 "TDLS peer doesn't support vht capabilities\n");
0260 return 0;
0261 }
0262
0263 if (!mwifiex_is_bss_in_11ac_mode(priv)) {
0264 if (sta_ptr->tdls_cap.extcap.ext_capab[7] &
0265 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
0266 mwifiex_dbg(adapter, WARN,
0267 "TDLS peer doesn't support wider bandwidth\n");
0268 return 0;
0269 }
0270 } else {
0271 ap_vht_cap = bss_desc->bcn_vht_cap;
0272 }
0273
0274 pos = skb_put(skb, sizeof(struct ieee80211_vht_operation) + 2);
0275 *pos++ = WLAN_EID_VHT_OPERATION;
0276 *pos++ = sizeof(struct ieee80211_vht_operation);
0277 vht_oper = (struct ieee80211_vht_operation *)pos;
0278
0279 if (bss_desc->bss_band & BAND_A)
0280 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
0281 else
0282 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
0283
0284
0285 vht_cap = &sta_ptr->tdls_cap.vhtcap;
0286 supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
0287 peer_supp_chwd_set =
0288 GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap->vht_cap_info));
0289 supp_chwd_set = min_t(u8, supp_chwd_set, peer_supp_chwd_set);
0290
0291
0292
0293 if (ap_vht_cap && sta_ptr->tdls_cap.extcap.ext_capab[7] &
0294 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
0295 ap_supp_chwd_set =
0296 GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap->vht_cap_info));
0297 supp_chwd_set = min_t(u8, supp_chwd_set, ap_supp_chwd_set);
0298 }
0299
0300 switch (supp_chwd_set) {
0301 case IEEE80211_VHT_CHANWIDTH_80MHZ:
0302 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
0303 break;
0304 case IEEE80211_VHT_CHANWIDTH_160MHZ:
0305 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
0306 break;
0307 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
0308 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
0309 break;
0310 default:
0311 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
0312 break;
0313 }
0314
0315 mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
0316 mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
0317 mcs_map_result = 0;
0318
0319 for (nss = 1; nss <= 8; nss++) {
0320 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
0321 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
0322
0323 if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
0324 (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
0325 SET_VHTNSSMCS(mcs_map_result, nss,
0326 IEEE80211_VHT_MCS_NOT_SUPPORTED);
0327 else
0328 SET_VHTNSSMCS(mcs_map_result, nss,
0329 min_t(u16, mcs_user, mcs_resp));
0330 }
0331
0332 vht_oper->basic_mcs_set = cpu_to_le16(mcs_map_result);
0333
0334 switch (vht_oper->chan_width) {
0335 case IEEE80211_VHT_CHANWIDTH_80MHZ:
0336 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
0337 break;
0338 case IEEE80211_VHT_CHANWIDTH_160MHZ:
0339 chan_bw = IEEE80211_VHT_CHANWIDTH_160MHZ;
0340 break;
0341 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
0342 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
0343 break;
0344 default:
0345 chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
0346 break;
0347 }
0348 vht_oper->center_freq_seg0_idx =
0349 mwifiex_get_center_freq_index(priv, BAND_AAC,
0350 bss_desc->channel,
0351 chan_bw);
0352
0353 return 0;
0354 }
0355
0356 static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv,
0357 struct sk_buff *skb)
0358 {
0359 struct ieee_types_extcap *extcap;
0360
0361 extcap = skb_put(skb, sizeof(struct ieee_types_extcap));
0362 extcap->ieee_hdr.element_id = WLAN_EID_EXT_CAPABILITY;
0363 extcap->ieee_hdr.len = 8;
0364 memset(extcap->ext_capab, 0, 8);
0365 extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED;
0366 extcap->ext_capab[3] |= WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH;
0367
0368 if (priv->adapter->is_hw_11ac_capable)
0369 extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED;
0370 }
0371
0372 static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb)
0373 {
0374 u8 *pos = skb_put(skb, 3);
0375
0376 *pos++ = WLAN_EID_QOS_CAPA;
0377 *pos++ = 1;
0378 *pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB;
0379 }
0380
0381 static void
0382 mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private *priv, struct sk_buff *skb)
0383 {
0384 struct ieee80211_wmm_param_ie *wmm;
0385 u8 ac_vi[] = {0x42, 0x43, 0x5e, 0x00};
0386 u8 ac_vo[] = {0x62, 0x32, 0x2f, 0x00};
0387 u8 ac_be[] = {0x03, 0xa4, 0x00, 0x00};
0388 u8 ac_bk[] = {0x27, 0xa4, 0x00, 0x00};
0389
0390 wmm = skb_put_zero(skb, sizeof(*wmm));
0391
0392 wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
0393 wmm->len = sizeof(*wmm) - 2;
0394 wmm->oui[0] = 0x00;
0395 wmm->oui[1] = 0x50;
0396 wmm->oui[2] = 0xf2;
0397 wmm->oui_type = 2;
0398 wmm->oui_subtype = 1;
0399 wmm->version = 1;
0400 wmm->qos_info = 0;
0401
0402
0403 memcpy(&wmm->ac[0], ac_be, sizeof(ac_be));
0404 memcpy(&wmm->ac[1], ac_bk, sizeof(ac_bk));
0405 memcpy(&wmm->ac[2], ac_vi, sizeof(ac_vi));
0406 memcpy(&wmm->ac[3], ac_vo, sizeof(ac_vo));
0407 }
0408
0409 static void
0410 mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb,
0411 u8 qosinfo)
0412 {
0413 u8 *buf;
0414
0415 buf = skb_put(skb,
0416 MWIFIEX_TDLS_WMM_INFO_SIZE + sizeof(struct ieee_types_header));
0417
0418 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
0419 *buf++ = 7;
0420 *buf++ = 0x00;
0421 *buf++ = 0x50;
0422 *buf++ = 0xf2;
0423 *buf++ = 2;
0424 *buf++ = 0;
0425 *buf++ = 1;
0426 *buf++ = qosinfo;
0427 }
0428
0429 static void mwifiex_tdls_add_bss_co_2040(struct sk_buff *skb)
0430 {
0431 struct ieee_types_bss_co_2040 *bssco;
0432
0433 bssco = skb_put(skb, sizeof(struct ieee_types_bss_co_2040));
0434 bssco->ieee_hdr.element_id = WLAN_EID_BSS_COEX_2040;
0435 bssco->ieee_hdr.len = sizeof(struct ieee_types_bss_co_2040) -
0436 sizeof(struct ieee_types_header);
0437 bssco->bss_2040co = 0x01;
0438 }
0439
0440 static void mwifiex_tdls_add_supported_chan(struct sk_buff *skb)
0441 {
0442 struct ieee_types_generic *supp_chan;
0443 u8 chan_supp[] = {1, 11};
0444
0445 supp_chan = skb_put(skb,
0446 (sizeof(struct ieee_types_header) + sizeof(chan_supp)));
0447 supp_chan->ieee_hdr.element_id = WLAN_EID_SUPPORTED_CHANNELS;
0448 supp_chan->ieee_hdr.len = sizeof(chan_supp);
0449 memcpy(supp_chan->data, chan_supp, sizeof(chan_supp));
0450 }
0451
0452 static void mwifiex_tdls_add_oper_class(struct sk_buff *skb)
0453 {
0454 struct ieee_types_generic *reg_class;
0455 u8 rc_list[] = {1,
0456 1, 2, 3, 4, 12, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33};
0457 reg_class = skb_put(skb,
0458 (sizeof(struct ieee_types_header) + sizeof(rc_list)));
0459 reg_class->ieee_hdr.element_id = WLAN_EID_SUPPORTED_REGULATORY_CLASSES;
0460 reg_class->ieee_hdr.len = sizeof(rc_list);
0461 memcpy(reg_class->data, rc_list, sizeof(rc_list));
0462 }
0463
0464 static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
0465 const u8 *peer, u8 action_code,
0466 u8 dialog_token,
0467 u16 status_code, struct sk_buff *skb)
0468 {
0469 struct ieee80211_tdls_data *tf;
0470 int ret;
0471 u16 capab;
0472 struct ieee80211_ht_cap *ht_cap;
0473 u8 radio, *pos;
0474
0475 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
0476
0477 tf = skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
0478 memcpy(tf->da, peer, ETH_ALEN);
0479 memcpy(tf->sa, priv->curr_addr, ETH_ALEN);
0480 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
0481 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
0482
0483 switch (action_code) {
0484 case WLAN_TDLS_SETUP_REQUEST:
0485 tf->category = WLAN_CATEGORY_TDLS;
0486 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
0487 skb_put(skb, sizeof(tf->u.setup_req));
0488 tf->u.setup_req.dialog_token = dialog_token;
0489 tf->u.setup_req.capability = cpu_to_le16(capab);
0490 ret = mwifiex_tdls_append_rates_ie(priv, skb);
0491 if (ret) {
0492 dev_kfree_skb_any(skb);
0493 return ret;
0494 }
0495
0496 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
0497 *pos++ = WLAN_EID_HT_CAPABILITY;
0498 *pos++ = sizeof(struct ieee80211_ht_cap);
0499 ht_cap = (void *)pos;
0500 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
0501 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
0502 if (ret) {
0503 dev_kfree_skb_any(skb);
0504 return ret;
0505 }
0506
0507 if (priv->adapter->is_hw_11ac_capable) {
0508 ret = mwifiex_tdls_add_vht_capab(priv, skb);
0509 if (ret) {
0510 dev_kfree_skb_any(skb);
0511 return ret;
0512 }
0513 mwifiex_tdls_add_aid(priv, skb);
0514 }
0515
0516 mwifiex_tdls_add_ext_capab(priv, skb);
0517 mwifiex_tdls_add_bss_co_2040(skb);
0518 mwifiex_tdls_add_supported_chan(skb);
0519 mwifiex_tdls_add_oper_class(skb);
0520 mwifiex_add_wmm_info_ie(priv, skb, 0);
0521 break;
0522
0523 case WLAN_TDLS_SETUP_RESPONSE:
0524 tf->category = WLAN_CATEGORY_TDLS;
0525 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
0526 skb_put(skb, sizeof(tf->u.setup_resp));
0527 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
0528 tf->u.setup_resp.dialog_token = dialog_token;
0529 tf->u.setup_resp.capability = cpu_to_le16(capab);
0530 ret = mwifiex_tdls_append_rates_ie(priv, skb);
0531 if (ret) {
0532 dev_kfree_skb_any(skb);
0533 return ret;
0534 }
0535
0536 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
0537 *pos++ = WLAN_EID_HT_CAPABILITY;
0538 *pos++ = sizeof(struct ieee80211_ht_cap);
0539 ht_cap = (void *)pos;
0540 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
0541 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
0542 if (ret) {
0543 dev_kfree_skb_any(skb);
0544 return ret;
0545 }
0546
0547 if (priv->adapter->is_hw_11ac_capable) {
0548 ret = mwifiex_tdls_add_vht_capab(priv, skb);
0549 if (ret) {
0550 dev_kfree_skb_any(skb);
0551 return ret;
0552 }
0553 mwifiex_tdls_add_aid(priv, skb);
0554 }
0555
0556 mwifiex_tdls_add_ext_capab(priv, skb);
0557 mwifiex_tdls_add_bss_co_2040(skb);
0558 mwifiex_tdls_add_supported_chan(skb);
0559 mwifiex_tdls_add_oper_class(skb);
0560 mwifiex_add_wmm_info_ie(priv, skb, 0);
0561 break;
0562
0563 case WLAN_TDLS_SETUP_CONFIRM:
0564 tf->category = WLAN_CATEGORY_TDLS;
0565 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
0566 skb_put(skb, sizeof(tf->u.setup_cfm));
0567 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
0568 tf->u.setup_cfm.dialog_token = dialog_token;
0569
0570 mwifiex_tdls_add_wmm_param_ie(priv, skb);
0571 if (priv->adapter->is_hw_11ac_capable) {
0572 ret = mwifiex_tdls_add_vht_oper(priv, peer, skb);
0573 if (ret) {
0574 dev_kfree_skb_any(skb);
0575 return ret;
0576 }
0577 ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb);
0578 if (ret) {
0579 dev_kfree_skb_any(skb);
0580 return ret;
0581 }
0582 } else {
0583 ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb);
0584 if (ret) {
0585 dev_kfree_skb_any(skb);
0586 return ret;
0587 }
0588 }
0589 break;
0590
0591 case WLAN_TDLS_TEARDOWN:
0592 tf->category = WLAN_CATEGORY_TDLS;
0593 tf->action_code = WLAN_TDLS_TEARDOWN;
0594 skb_put(skb, sizeof(tf->u.teardown));
0595 tf->u.teardown.reason_code = cpu_to_le16(status_code);
0596 break;
0597
0598 case WLAN_TDLS_DISCOVERY_REQUEST:
0599 tf->category = WLAN_CATEGORY_TDLS;
0600 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
0601 skb_put(skb, sizeof(tf->u.discover_req));
0602 tf->u.discover_req.dialog_token = dialog_token;
0603 break;
0604 default:
0605 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
0606 return -EINVAL;
0607 }
0608
0609 return 0;
0610 }
0611
0612 static void
0613 mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr,
0614 const u8 *peer, const u8 *bssid)
0615 {
0616 struct ieee80211_tdls_lnkie *lnkid;
0617
0618 lnkid = skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
0619 lnkid->ie_type = WLAN_EID_LINK_ID;
0620 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) -
0621 sizeof(struct ieee_types_header);
0622
0623 memcpy(lnkid->bssid, bssid, ETH_ALEN);
0624 memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
0625 memcpy(lnkid->resp_sta, peer, ETH_ALEN);
0626 }
0627
0628 int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
0629 u8 action_code, u8 dialog_token,
0630 u16 status_code, const u8 *extra_ies,
0631 size_t extra_ies_len)
0632 {
0633 struct sk_buff *skb;
0634 struct mwifiex_txinfo *tx_info;
0635 int ret;
0636 u16 skb_len;
0637
0638 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
0639 max(sizeof(struct ieee80211_mgmt),
0640 sizeof(struct ieee80211_tdls_data)) +
0641 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
0642 MWIFIEX_SUPPORTED_RATES +
0643 3 +
0644 sizeof(struct ieee_types_extcap) +
0645 sizeof(struct ieee80211_ht_cap) +
0646 sizeof(struct ieee_types_bss_co_2040) +
0647 sizeof(struct ieee80211_ht_operation) +
0648 sizeof(struct ieee80211_tdls_lnkie) +
0649 (2 * (sizeof(struct ieee_types_header))) +
0650 MWIFIEX_SUPPORTED_CHANNELS +
0651 MWIFIEX_OPERATING_CLASSES +
0652 sizeof(struct ieee80211_wmm_param_ie) +
0653 extra_ies_len;
0654
0655 if (priv->adapter->is_hw_11ac_capable)
0656 skb_len += sizeof(struct ieee_types_vht_cap) +
0657 sizeof(struct ieee_types_vht_oper) +
0658 sizeof(struct ieee_types_aid);
0659
0660 skb = dev_alloc_skb(skb_len);
0661 if (!skb) {
0662 mwifiex_dbg(priv->adapter, ERROR,
0663 "allocate skb failed for management frame\n");
0664 return -ENOMEM;
0665 }
0666 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
0667
0668 switch (action_code) {
0669 case WLAN_TDLS_SETUP_REQUEST:
0670 case WLAN_TDLS_SETUP_CONFIRM:
0671 case WLAN_TDLS_TEARDOWN:
0672 case WLAN_TDLS_DISCOVERY_REQUEST:
0673 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
0674 dialog_token, status_code,
0675 skb);
0676 if (ret) {
0677 dev_kfree_skb_any(skb);
0678 return ret;
0679 }
0680 if (extra_ies_len)
0681 skb_put_data(skb, extra_ies, extra_ies_len);
0682 mwifiex_tdls_add_link_ie(skb, priv->curr_addr, peer,
0683 priv->cfg_bssid);
0684 break;
0685 case WLAN_TDLS_SETUP_RESPONSE:
0686 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
0687 dialog_token, status_code,
0688 skb);
0689 if (ret) {
0690 dev_kfree_skb_any(skb);
0691 return ret;
0692 }
0693 if (extra_ies_len)
0694 skb_put_data(skb, extra_ies, extra_ies_len);
0695 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
0696 priv->cfg_bssid);
0697 break;
0698 }
0699
0700 switch (action_code) {
0701 case WLAN_TDLS_SETUP_REQUEST:
0702 case WLAN_TDLS_SETUP_RESPONSE:
0703 skb->priority = MWIFIEX_PRIO_BK;
0704 break;
0705 default:
0706 skb->priority = MWIFIEX_PRIO_VI;
0707 break;
0708 }
0709
0710 tx_info = MWIFIEX_SKB_TXCB(skb);
0711 memset(tx_info, 0, sizeof(*tx_info));
0712 tx_info->bss_num = priv->bss_num;
0713 tx_info->bss_type = priv->bss_type;
0714
0715 __net_timestamp(skb);
0716 mwifiex_queue_tx_pkt(priv, skb);
0717
0718
0719
0720
0721 if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
0722 action_code == WLAN_TDLS_TEARDOWN)
0723 msleep_interruptible(10);
0724
0725 return 0;
0726 }
0727
0728 static int
0729 mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
0730 const u8 *peer,
0731 u8 action_code, u8 dialog_token,
0732 u16 status_code, struct sk_buff *skb)
0733 {
0734 struct ieee80211_mgmt *mgmt;
0735 int ret;
0736 u16 capab;
0737 struct ieee80211_ht_cap *ht_cap;
0738 u8 radio, *pos;
0739
0740 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
0741
0742 mgmt = skb_put(skb, offsetof(struct ieee80211_mgmt, u));
0743
0744 memset(mgmt, 0, 24);
0745 memcpy(mgmt->da, peer, ETH_ALEN);
0746 memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
0747 memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
0748 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
0749 IEEE80211_STYPE_ACTION);
0750
0751
0752 pos = skb_put(skb, ETH_ALEN);
0753
0754 switch (action_code) {
0755 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
0756 skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1);
0757 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
0758 mgmt->u.action.u.tdls_discover_resp.action_code =
0759 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
0760 mgmt->u.action.u.tdls_discover_resp.dialog_token =
0761 dialog_token;
0762 mgmt->u.action.u.tdls_discover_resp.capability =
0763 cpu_to_le16(capab);
0764
0765 memmove(pos + ETH_ALEN, &mgmt->u.action.category,
0766 sizeof(mgmt->u.action.u.tdls_discover_resp));
0767
0768 eth_broadcast_addr(pos);
0769
0770 ret = mwifiex_tdls_append_rates_ie(priv, skb);
0771 if (ret) {
0772 dev_kfree_skb_any(skb);
0773 return ret;
0774 }
0775
0776 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
0777 *pos++ = WLAN_EID_HT_CAPABILITY;
0778 *pos++ = sizeof(struct ieee80211_ht_cap);
0779 ht_cap = (void *)pos;
0780 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
0781 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
0782 if (ret) {
0783 dev_kfree_skb_any(skb);
0784 return ret;
0785 }
0786
0787 if (priv->adapter->is_hw_11ac_capable) {
0788 ret = mwifiex_tdls_add_vht_capab(priv, skb);
0789 if (ret) {
0790 dev_kfree_skb_any(skb);
0791 return ret;
0792 }
0793 mwifiex_tdls_add_aid(priv, skb);
0794 }
0795
0796 mwifiex_tdls_add_ext_capab(priv, skb);
0797 mwifiex_tdls_add_bss_co_2040(skb);
0798 mwifiex_tdls_add_supported_chan(skb);
0799 mwifiex_tdls_add_qos_capab(skb);
0800 mwifiex_tdls_add_oper_class(skb);
0801 break;
0802 default:
0803 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n");
0804 return -EINVAL;
0805 }
0806
0807 return 0;
0808 }
0809
0810 int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
0811 u8 action_code, u8 dialog_token,
0812 u16 status_code, const u8 *extra_ies,
0813 size_t extra_ies_len)
0814 {
0815 struct sk_buff *skb;
0816 struct mwifiex_txinfo *tx_info;
0817 u8 *pos;
0818 u32 pkt_type, tx_control;
0819 u16 pkt_len, skb_len;
0820
0821 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
0822 max(sizeof(struct ieee80211_mgmt),
0823 sizeof(struct ieee80211_tdls_data)) +
0824 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
0825 MWIFIEX_SUPPORTED_RATES +
0826 sizeof(struct ieee_types_extcap) +
0827 sizeof(struct ieee80211_ht_cap) +
0828 sizeof(struct ieee_types_bss_co_2040) +
0829 sizeof(struct ieee80211_ht_operation) +
0830 sizeof(struct ieee80211_tdls_lnkie) +
0831 extra_ies_len +
0832 3 +
0833 ETH_ALEN;
0834
0835 if (priv->adapter->is_hw_11ac_capable)
0836 skb_len += sizeof(struct ieee_types_vht_cap) +
0837 sizeof(struct ieee_types_vht_oper) +
0838 sizeof(struct ieee_types_aid);
0839
0840 skb = dev_alloc_skb(skb_len);
0841 if (!skb) {
0842 mwifiex_dbg(priv->adapter, ERROR,
0843 "allocate skb failed for management frame\n");
0844 return -ENOMEM;
0845 }
0846
0847 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
0848
0849 pkt_type = PKT_TYPE_MGMT;
0850 tx_control = 0;
0851 pos = skb_put_zero(skb,
0852 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
0853 memcpy(pos, &pkt_type, sizeof(pkt_type));
0854 memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control));
0855
0856 if (mwifiex_construct_tdls_action_frame(priv, peer, action_code,
0857 dialog_token, status_code,
0858 skb)) {
0859 dev_kfree_skb_any(skb);
0860 return -EINVAL;
0861 }
0862
0863 if (extra_ies_len)
0864 skb_put_data(skb, extra_ies, extra_ies_len);
0865
0866
0867
0868 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
0869 priv->cfg_bssid);
0870
0871 skb->priority = MWIFIEX_PRIO_VI;
0872
0873 tx_info = MWIFIEX_SKB_TXCB(skb);
0874 memset(tx_info, 0, sizeof(*tx_info));
0875 tx_info->bss_num = priv->bss_num;
0876 tx_info->bss_type = priv->bss_type;
0877 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
0878
0879 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
0880 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
0881 sizeof(pkt_len));
0882 __net_timestamp(skb);
0883 mwifiex_queue_tx_pkt(priv, skb);
0884
0885 return 0;
0886 }
0887
0888
0889
0890
0891 void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
0892 u8 *buf, int len)
0893 {
0894 struct mwifiex_sta_node *sta_ptr;
0895 u8 *peer, *pos, *end;
0896 u8 i, action, basic;
0897 u16 cap = 0;
0898 int ies_len = 0;
0899
0900 if (len < (sizeof(struct ethhdr) + 3))
0901 return;
0902 if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
0903 return;
0904 if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
0905 return;
0906
0907 peer = buf + ETH_ALEN;
0908 action = *(buf + sizeof(struct ethhdr) + 2);
0909 mwifiex_dbg(priv->adapter, DATA,
0910 "rx:tdls action: peer=%pM, action=%d\n", peer, action);
0911
0912 switch (action) {
0913 case WLAN_TDLS_SETUP_REQUEST:
0914 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
0915 return;
0916
0917 pos = buf + sizeof(struct ethhdr) + 4;
0918
0919 cap = get_unaligned_le16(pos);
0920 ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
0921 pos += 2;
0922 break;
0923
0924 case WLAN_TDLS_SETUP_RESPONSE:
0925 if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN))
0926 return;
0927
0928 pos = buf + sizeof(struct ethhdr) + 6;
0929 cap = get_unaligned_le16(pos);
0930 ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
0931 pos += 2;
0932 break;
0933
0934 case WLAN_TDLS_SETUP_CONFIRM:
0935 if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN))
0936 return;
0937 pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN;
0938 ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
0939 break;
0940 default:
0941 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
0942 return;
0943 }
0944
0945 sta_ptr = mwifiex_add_sta_entry(priv, peer);
0946 if (!sta_ptr)
0947 return;
0948
0949 sta_ptr->tdls_cap.capab = cpu_to_le16(cap);
0950
0951 for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) {
0952 u8 ie_len = pos[1];
0953
0954 if (pos + 2 + ie_len > end)
0955 break;
0956
0957 switch (*pos) {
0958 case WLAN_EID_SUPP_RATES:
0959 if (ie_len > sizeof(sta_ptr->tdls_cap.rates))
0960 return;
0961 sta_ptr->tdls_cap.rates_len = ie_len;
0962 for (i = 0; i < ie_len; i++)
0963 sta_ptr->tdls_cap.rates[i] = pos[i + 2];
0964 break;
0965
0966 case WLAN_EID_EXT_SUPP_RATES:
0967 if (ie_len > sizeof(sta_ptr->tdls_cap.rates))
0968 return;
0969 basic = sta_ptr->tdls_cap.rates_len;
0970 if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic)
0971 return;
0972 for (i = 0; i < ie_len; i++)
0973 sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
0974 sta_ptr->tdls_cap.rates_len += ie_len;
0975 break;
0976 case WLAN_EID_HT_CAPABILITY:
0977 if (ie_len != sizeof(struct ieee80211_ht_cap))
0978 return;
0979
0980 memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2,
0981 sizeof(struct ieee80211_ht_cap));
0982 sta_ptr->is_11n_enabled = 1;
0983 break;
0984 case WLAN_EID_HT_OPERATION:
0985 if (ie_len != sizeof(struct ieee80211_ht_operation))
0986 return;
0987
0988 memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2,
0989 sizeof(struct ieee80211_ht_operation));
0990 break;
0991 case WLAN_EID_BSS_COEX_2040:
0992 if (ie_len != sizeof(pos[2]))
0993 return;
0994 sta_ptr->tdls_cap.coex_2040 = pos[2];
0995 break;
0996 case WLAN_EID_EXT_CAPABILITY:
0997 if (ie_len < sizeof(struct ieee_types_header))
0998 return;
0999 if (ie_len > 8)
1000 return;
1001 memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
1002 sizeof(struct ieee_types_header) +
1003 min_t(u8, ie_len, 8));
1004 break;
1005 case WLAN_EID_RSN:
1006 if (ie_len < sizeof(struct ieee_types_header))
1007 return;
1008 if (ie_len > IEEE_MAX_IE_SIZE -
1009 sizeof(struct ieee_types_header))
1010 return;
1011 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
1012 sizeof(struct ieee_types_header) +
1013 min_t(u8, ie_len, IEEE_MAX_IE_SIZE -
1014 sizeof(struct ieee_types_header)));
1015 break;
1016 case WLAN_EID_QOS_CAPA:
1017 if (ie_len != sizeof(pos[2]))
1018 return;
1019 sta_ptr->tdls_cap.qos_info = pos[2];
1020 break;
1021 case WLAN_EID_VHT_OPERATION:
1022 if (priv->adapter->is_hw_11ac_capable) {
1023 if (ie_len !=
1024 sizeof(struct ieee80211_vht_operation))
1025 return;
1026
1027 memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2,
1028 sizeof(struct ieee80211_vht_operation));
1029 }
1030 break;
1031 case WLAN_EID_VHT_CAPABILITY:
1032 if (priv->adapter->is_hw_11ac_capable) {
1033 if (ie_len != sizeof(struct ieee80211_vht_cap))
1034 return;
1035
1036 memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2,
1037 sizeof(struct ieee80211_vht_cap));
1038 sta_ptr->is_11ac_enabled = 1;
1039 }
1040 break;
1041 case WLAN_EID_AID:
1042 if (priv->adapter->is_hw_11ac_capable) {
1043 if (ie_len != sizeof(u16))
1044 return;
1045 sta_ptr->tdls_cap.aid =
1046 get_unaligned_le16((pos + 2));
1047 }
1048 break;
1049 default:
1050 break;
1051 }
1052 }
1053
1054 return;
1055 }
1056
1057 static int
1058 mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer)
1059 {
1060 struct mwifiex_sta_node *sta_ptr;
1061 struct mwifiex_ds_tdls_oper tdls_oper;
1062
1063 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1064 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1065
1066 if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) {
1067 mwifiex_dbg(priv->adapter, ERROR,
1068 "link absent for peer %pM; cannot config\n", peer);
1069 return -EINVAL;
1070 }
1071
1072 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1073 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK;
1074 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1075 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1076 }
1077
1078 static int
1079 mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer)
1080 {
1081 struct mwifiex_sta_node *sta_ptr;
1082 struct mwifiex_ds_tdls_oper tdls_oper;
1083
1084 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1085 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1086
1087 if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) {
1088 mwifiex_dbg(priv->adapter, WARN,
1089 "Setup already in progress for peer %pM\n", peer);
1090 return 0;
1091 }
1092
1093 sta_ptr = mwifiex_add_sta_entry(priv, peer);
1094 if (!sta_ptr)
1095 return -ENOMEM;
1096
1097 sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS;
1098 mwifiex_hold_tdls_packets(priv, peer);
1099 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1100 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
1101 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1102 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1103 }
1104
1105 static int
1106 mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer)
1107 {
1108 struct mwifiex_sta_node *sta_ptr;
1109 struct mwifiex_ds_tdls_oper tdls_oper;
1110
1111 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1112 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1113
1114 if (sta_ptr) {
1115 if (sta_ptr->is_11n_enabled) {
1116 mwifiex_11n_cleanup_reorder_tbl(priv);
1117 spin_lock_bh(&priv->wmm.ra_list_spinlock);
1118 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1119 spin_unlock_bh(&priv->wmm.ra_list_spinlock);
1120 }
1121 mwifiex_del_sta_entry(priv, peer);
1122 }
1123
1124 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
1125 mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP);
1126 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1127 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1128 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1129 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1130 }
1131
1132 static int
1133 mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer)
1134 {
1135 struct mwifiex_sta_node *sta_ptr;
1136 struct ieee80211_mcs_info mcs;
1137 int i;
1138
1139 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1140
1141 if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) {
1142 mwifiex_dbg(priv->adapter, MSG,
1143 "tdls: enable link %pM success\n", peer);
1144
1145 sta_ptr->tdls_status = TDLS_SETUP_COMPLETE;
1146
1147 mcs = sta_ptr->tdls_cap.ht_capb.mcs;
1148 if (mcs.rx_mask[0] != 0xff)
1149 sta_ptr->is_11n_enabled = true;
1150 if (sta_ptr->is_11n_enabled) {
1151 if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) &
1152 IEEE80211_HT_CAP_MAX_AMSDU)
1153 sta_ptr->max_amsdu =
1154 MWIFIEX_TX_DATA_BUF_SIZE_8K;
1155 else
1156 sta_ptr->max_amsdu =
1157 MWIFIEX_TX_DATA_BUF_SIZE_4K;
1158
1159 for (i = 0; i < MAX_NUM_TID; i++)
1160 sta_ptr->ampdu_sta[i] =
1161 priv->aggr_prio_tbl[i].ampdu_user;
1162 } else {
1163 for (i = 0; i < MAX_NUM_TID; i++)
1164 sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
1165 }
1166 if (sta_ptr->tdls_cap.extcap.ext_capab[3] &
1167 WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) {
1168 mwifiex_config_tdls_enable(priv);
1169 mwifiex_config_tdls_cs_params(priv);
1170 }
1171
1172 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
1173 mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE);
1174 mwifiex_auto_tdls_update_peer_status(priv, peer,
1175 TDLS_SETUP_COMPLETE);
1176 } else {
1177 mwifiex_dbg(priv->adapter, ERROR,
1178 "tdls: enable link %pM failed\n", peer);
1179 if (sta_ptr) {
1180 mwifiex_11n_cleanup_reorder_tbl(priv);
1181 spin_lock_bh(&priv->wmm.ra_list_spinlock);
1182 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1183 spin_unlock_bh(&priv->wmm.ra_list_spinlock);
1184 mwifiex_del_sta_entry(priv, peer);
1185 }
1186 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
1187 mwifiex_auto_tdls_update_peer_status(priv, peer,
1188 TDLS_NOT_SETUP);
1189
1190 return -1;
1191 }
1192
1193 return 0;
1194 }
1195
1196 int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action)
1197 {
1198 switch (action) {
1199 case MWIFIEX_TDLS_ENABLE_LINK:
1200 return mwifiex_tdls_process_enable_link(priv, peer);
1201 case MWIFIEX_TDLS_DISABLE_LINK:
1202 return mwifiex_tdls_process_disable_link(priv, peer);
1203 case MWIFIEX_TDLS_CREATE_LINK:
1204 return mwifiex_tdls_process_create_link(priv, peer);
1205 case MWIFIEX_TDLS_CONFIG_LINK:
1206 return mwifiex_tdls_process_config_link(priv, peer);
1207 }
1208 return 0;
1209 }
1210
1211 int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac)
1212 {
1213 struct mwifiex_sta_node *sta_ptr;
1214
1215 sta_ptr = mwifiex_get_sta_entry(priv, mac);
1216 if (sta_ptr)
1217 return sta_ptr->tdls_status;
1218
1219 return TDLS_NOT_SETUP;
1220 }
1221
1222 int mwifiex_get_tdls_list(struct mwifiex_private *priv,
1223 struct tdls_peer_info *buf)
1224 {
1225 struct mwifiex_sta_node *sta_ptr;
1226 struct tdls_peer_info *peer = buf;
1227 int count = 0;
1228
1229 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
1230 return 0;
1231
1232
1233 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
1234 return 0;
1235
1236 spin_lock_bh(&priv->sta_list_spinlock);
1237 list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1238 if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) {
1239 ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr);
1240 peer++;
1241 count++;
1242 if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED)
1243 break;
1244 }
1245 }
1246 spin_unlock_bh(&priv->sta_list_spinlock);
1247
1248 return count;
1249 }
1250
1251 void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
1252 {
1253 struct mwifiex_sta_node *sta_ptr;
1254 struct mwifiex_ds_tdls_oper tdls_oper;
1255
1256 if (list_empty(&priv->sta_list))
1257 return;
1258
1259 list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1260 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1261
1262 if (sta_ptr->is_11n_enabled) {
1263 mwifiex_11n_cleanup_reorder_tbl(priv);
1264 spin_lock_bh(&priv->wmm.ra_list_spinlock);
1265 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1266 spin_unlock_bh(&priv->wmm.ra_list_spinlock);
1267 }
1268
1269 mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr,
1270 TDLS_LINK_TEARDOWN);
1271 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN);
1272 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1273 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1274 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false))
1275 mwifiex_dbg(priv->adapter, ERROR,
1276 "Disable link failed for TDLS peer %pM",
1277 sta_ptr->mac_addr);
1278 }
1279
1280 mwifiex_del_all_sta_list(priv);
1281 }
1282
1283 int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb)
1284 {
1285 struct mwifiex_auto_tdls_peer *peer;
1286 u8 mac[ETH_ALEN];
1287
1288 ether_addr_copy(mac, skb->data);
1289
1290 spin_lock_bh(&priv->auto_tdls_lock);
1291 list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1292 if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) {
1293 if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
1294 peer->tdls_status == TDLS_NOT_SETUP &&
1295 (peer->failure_count <
1296 MWIFIEX_TDLS_MAX_FAIL_COUNT)) {
1297 peer->tdls_status = TDLS_SETUP_INPROGRESS;
1298 mwifiex_dbg(priv->adapter, INFO,
1299 "setup TDLS link, peer=%pM rssi=%d\n",
1300 peer->mac_addr, peer->rssi);
1301
1302 cfg80211_tdls_oper_request(priv->netdev,
1303 peer->mac_addr,
1304 NL80211_TDLS_SETUP,
1305 0, GFP_ATOMIC);
1306 peer->do_setup = false;
1307 priv->check_tdls_tx = false;
1308 } else if (peer->failure_count <
1309 MWIFIEX_TDLS_MAX_FAIL_COUNT &&
1310 peer->do_discover) {
1311 mwifiex_send_tdls_data_frame(priv,
1312 peer->mac_addr,
1313 WLAN_TDLS_DISCOVERY_REQUEST,
1314 1, 0, NULL, 0);
1315 peer->do_discover = false;
1316 }
1317 }
1318 }
1319 spin_unlock_bh(&priv->auto_tdls_lock);
1320
1321 return 0;
1322 }
1323
1324 void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv)
1325 {
1326 struct mwifiex_auto_tdls_peer *peer, *tmp_node;
1327
1328 spin_lock_bh(&priv->auto_tdls_lock);
1329 list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) {
1330 list_del(&peer->list);
1331 kfree(peer);
1332 }
1333
1334 INIT_LIST_HEAD(&priv->auto_tdls_list);
1335 spin_unlock_bh(&priv->auto_tdls_lock);
1336 priv->check_tdls_tx = false;
1337 }
1338
1339 void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac)
1340 {
1341 struct mwifiex_auto_tdls_peer *tdls_peer;
1342
1343 if (!priv->adapter->auto_tdls)
1344 return;
1345
1346 spin_lock_bh(&priv->auto_tdls_lock);
1347 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
1348 if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) {
1349 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
1350 tdls_peer->rssi_jiffies = jiffies;
1351 spin_unlock_bh(&priv->auto_tdls_lock);
1352 return;
1353 }
1354 }
1355
1356
1357 tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC);
1358 if (tdls_peer) {
1359 ether_addr_copy(tdls_peer->mac_addr, mac);
1360 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
1361 tdls_peer->rssi_jiffies = jiffies;
1362 INIT_LIST_HEAD(&tdls_peer->list);
1363 list_add_tail(&tdls_peer->list, &priv->auto_tdls_list);
1364 mwifiex_dbg(priv->adapter, INFO,
1365 "Add auto TDLS peer= %pM to list\n", mac);
1366 }
1367
1368 spin_unlock_bh(&priv->auto_tdls_lock);
1369 }
1370
1371 void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv,
1372 const u8 *mac, u8 link_status)
1373 {
1374 struct mwifiex_auto_tdls_peer *peer;
1375
1376 if (!priv->adapter->auto_tdls)
1377 return;
1378
1379 spin_lock_bh(&priv->auto_tdls_lock);
1380 list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1381 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
1382 if ((link_status == TDLS_NOT_SETUP) &&
1383 (peer->tdls_status == TDLS_SETUP_INPROGRESS))
1384 peer->failure_count++;
1385 else if (mwifiex_is_tdls_link_setup(link_status))
1386 peer->failure_count = 0;
1387
1388 peer->tdls_status = link_status;
1389 break;
1390 }
1391 }
1392 spin_unlock_bh(&priv->auto_tdls_lock);
1393 }
1394
1395 void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv,
1396 u8 *mac, s8 snr, s8 nflr)
1397 {
1398 struct mwifiex_auto_tdls_peer *peer;
1399
1400 if (!priv->adapter->auto_tdls)
1401 return;
1402
1403 spin_lock_bh(&priv->auto_tdls_lock);
1404 list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1405 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
1406 peer->rssi = nflr - snr;
1407 peer->rssi_jiffies = jiffies;
1408 break;
1409 }
1410 }
1411 spin_unlock_bh(&priv->auto_tdls_lock);
1412 }
1413
1414 void mwifiex_check_auto_tdls(struct timer_list *t)
1415 {
1416 struct mwifiex_private *priv = from_timer(priv, t, auto_tdls_timer);
1417 struct mwifiex_auto_tdls_peer *tdls_peer;
1418 u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
1419
1420 if (WARN_ON_ONCE(!priv || !priv->adapter)) {
1421 pr_err("mwifiex: %s: adapter or private structure is NULL\n",
1422 __func__);
1423 return;
1424 }
1425
1426 if (unlikely(!priv->adapter->auto_tdls))
1427 return;
1428
1429 if (!priv->auto_tdls_timer_active) {
1430 mwifiex_dbg(priv->adapter, INFO,
1431 "auto TDLS timer inactive; return");
1432 return;
1433 }
1434
1435 priv->check_tdls_tx = false;
1436
1437 spin_lock_bh(&priv->auto_tdls_lock);
1438 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
1439 if ((jiffies - tdls_peer->rssi_jiffies) >
1440 (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) {
1441 tdls_peer->rssi = 0;
1442 tdls_peer->do_discover = true;
1443 priv->check_tdls_tx = true;
1444 }
1445
1446 if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) ||
1447 !tdls_peer->rssi) &&
1448 mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) {
1449 tdls_peer->tdls_status = TDLS_LINK_TEARDOWN;
1450 mwifiex_dbg(priv->adapter, MSG,
1451 "teardown TDLS link,peer=%pM rssi=%d\n",
1452 tdls_peer->mac_addr, -tdls_peer->rssi);
1453 tdls_peer->do_discover = true;
1454 priv->check_tdls_tx = true;
1455 cfg80211_tdls_oper_request(priv->netdev,
1456 tdls_peer->mac_addr,
1457 NL80211_TDLS_TEARDOWN,
1458 reason, GFP_ATOMIC);
1459 } else if (tdls_peer->rssi &&
1460 tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
1461 tdls_peer->tdls_status == TDLS_NOT_SETUP &&
1462 tdls_peer->failure_count <
1463 MWIFIEX_TDLS_MAX_FAIL_COUNT) {
1464 priv->check_tdls_tx = true;
1465 tdls_peer->do_setup = true;
1466 mwifiex_dbg(priv->adapter, INFO,
1467 "check TDLS with peer=%pM\t"
1468 "rssi=%d\n", tdls_peer->mac_addr,
1469 tdls_peer->rssi);
1470 }
1471 }
1472 spin_unlock_bh(&priv->auto_tdls_lock);
1473
1474 mod_timer(&priv->auto_tdls_timer,
1475 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
1476 }
1477
1478 void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv)
1479 {
1480 timer_setup(&priv->auto_tdls_timer, mwifiex_check_auto_tdls, 0);
1481 priv->auto_tdls_timer_active = true;
1482 mod_timer(&priv->auto_tdls_timer,
1483 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
1484 }
1485
1486 void mwifiex_clean_auto_tdls(struct mwifiex_private *priv)
1487 {
1488 if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
1489 priv->adapter->auto_tdls &&
1490 priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1491 priv->auto_tdls_timer_active = false;
1492 del_timer(&priv->auto_tdls_timer);
1493 mwifiex_flush_auto_tdls_list(priv);
1494 }
1495 }
1496
1497 static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable)
1498 {
1499 struct mwifiex_tdls_config config;
1500
1501 config.enable = cpu_to_le16(enable);
1502 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1503 ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true);
1504 }
1505
1506 int mwifiex_config_tdls_enable(struct mwifiex_private *priv)
1507 {
1508 return mwifiex_config_tdls(priv, true);
1509 }
1510
1511 int mwifiex_config_tdls_disable(struct mwifiex_private *priv)
1512 {
1513 return mwifiex_config_tdls(priv, false);
1514 }
1515
1516 int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv)
1517 {
1518 struct mwifiex_tdls_config_cs_params config_tdls_cs_params;
1519
1520 config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME;
1521 config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK;
1522 config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK;
1523
1524 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1525 ACT_TDLS_CS_PARAMS, 0,
1526 &config_tdls_cs_params, true);
1527 }
1528
1529 int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac)
1530 {
1531 struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params;
1532
1533 ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac);
1534
1535 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1536 ACT_TDLS_CS_STOP, 0,
1537 &stop_tdls_cs_params, true);
1538 }
1539
1540 int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac,
1541 u8 primary_chan, u8 second_chan_offset, u8 band)
1542 {
1543 struct mwifiex_tdls_init_cs_params start_tdls_cs_params;
1544
1545 ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac);
1546 start_tdls_cs_params.primary_chan = primary_chan;
1547 start_tdls_cs_params.second_chan_offset = second_chan_offset;
1548 start_tdls_cs_params.band = band;
1549
1550 start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME);
1551 start_tdls_cs_params.switch_timeout =
1552 cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT);
1553 start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS;
1554 start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY;
1555
1556 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1557 ACT_TDLS_CS_INIT, 0,
1558 &start_tdls_cs_params, true);
1559 }