tdls.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508
  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. #include "main.h"
  18. #include "wmm.h"
  19. #include "11n.h"
  20. #include "11n_rxreorder.h"
  21. #include "11ac.h"
  22. #define TDLS_REQ_FIX_LEN 6
  23. #define TDLS_RESP_FIX_LEN 8
  24. #define TDLS_CONFIRM_FIX_LEN 6
  25. #define MWIFIEX_TDLS_WMM_INFO_SIZE 7
  26. static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv,
  27. const u8 *mac, u8 status)
  28. {
  29. struct mwifiex_ra_list_tbl *ra_list;
  30. struct list_head *tid_list;
  31. struct sk_buff *skb, *tmp;
  32. struct mwifiex_txinfo *tx_info;
  33. unsigned long flags;
  34. u32 tid;
  35. u8 tid_down;
  36. mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac);
  37. spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
  38. skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) {
  39. if (!ether_addr_equal(mac, skb->data))
  40. continue;
  41. __skb_unlink(skb, &priv->tdls_txq);
  42. tx_info = MWIFIEX_SKB_TXCB(skb);
  43. tid = skb->priority;
  44. tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
  45. if (mwifiex_is_tdls_link_setup(status)) {
  46. ra_list = mwifiex_wmm_get_queue_raptr(priv, tid, mac);
  47. ra_list->tdls_link = true;
  48. tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
  49. } else {
  50. tid_list = &priv->wmm.tid_tbl_ptr[tid_down].ra_list;
  51. if (!list_empty(tid_list))
  52. ra_list = list_first_entry(tid_list,
  53. struct mwifiex_ra_list_tbl, list);
  54. else
  55. ra_list = NULL;
  56. tx_info->flags &= ~MWIFIEX_BUF_FLAG_TDLS_PKT;
  57. }
  58. if (!ra_list) {
  59. mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
  60. continue;
  61. }
  62. skb_queue_tail(&ra_list->skb_head, skb);
  63. ra_list->ba_pkt_count++;
  64. ra_list->total_pkt_count++;
  65. if (atomic_read(&priv->wmm.highest_queued_prio) <
  66. tos_to_tid_inv[tid_down])
  67. atomic_set(&priv->wmm.highest_queued_prio,
  68. tos_to_tid_inv[tid_down]);
  69. atomic_inc(&priv->wmm.tx_pkts_queued);
  70. }
  71. spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
  72. return;
  73. }
  74. static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv,
  75. const u8 *mac)
  76. {
  77. struct mwifiex_ra_list_tbl *ra_list;
  78. struct list_head *ra_list_head;
  79. struct sk_buff *skb, *tmp;
  80. unsigned long flags;
  81. int i;
  82. mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac);
  83. spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
  84. for (i = 0; i < MAX_NUM_TID; i++) {
  85. if (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) {
  86. ra_list_head = &priv->wmm.tid_tbl_ptr[i].ra_list;
  87. list_for_each_entry(ra_list, ra_list_head, list) {
  88. skb_queue_walk_safe(&ra_list->skb_head, skb,
  89. tmp) {
  90. if (!ether_addr_equal(mac, skb->data))
  91. continue;
  92. __skb_unlink(skb, &ra_list->skb_head);
  93. atomic_dec(&priv->wmm.tx_pkts_queued);
  94. ra_list->total_pkt_count--;
  95. skb_queue_tail(&priv->tdls_txq, skb);
  96. }
  97. }
  98. }
  99. }
  100. spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
  101. return;
  102. }
  103. /* This function appends rate TLV to scan config command. */
  104. static int
  105. mwifiex_tdls_append_rates_ie(struct mwifiex_private *priv,
  106. struct sk_buff *skb)
  107. {
  108. u8 rates[MWIFIEX_SUPPORTED_RATES], *pos;
  109. u16 rates_size, supp_rates_size, ext_rates_size;
  110. memset(rates, 0, sizeof(rates));
  111. rates_size = mwifiex_get_supported_rates(priv, rates);
  112. supp_rates_size = min_t(u16, rates_size, MWIFIEX_TDLS_SUPPORTED_RATES);
  113. if (skb_tailroom(skb) < rates_size + 4) {
  114. mwifiex_dbg(priv->adapter, ERROR,
  115. "Insuffient space while adding rates\n");
  116. return -ENOMEM;
  117. }
  118. pos = skb_put(skb, supp_rates_size + 2);
  119. *pos++ = WLAN_EID_SUPP_RATES;
  120. *pos++ = supp_rates_size;
  121. memcpy(pos, rates, supp_rates_size);
  122. if (rates_size > MWIFIEX_TDLS_SUPPORTED_RATES) {
  123. ext_rates_size = rates_size - MWIFIEX_TDLS_SUPPORTED_RATES;
  124. pos = skb_put(skb, ext_rates_size + 2);
  125. *pos++ = WLAN_EID_EXT_SUPP_RATES;
  126. *pos++ = ext_rates_size;
  127. memcpy(pos, rates + MWIFIEX_TDLS_SUPPORTED_RATES,
  128. ext_rates_size);
  129. }
  130. return 0;
  131. }
  132. static void mwifiex_tdls_add_aid(struct mwifiex_private *priv,
  133. struct sk_buff *skb)
  134. {
  135. struct ieee_types_assoc_rsp *assoc_rsp;
  136. u8 *pos;
  137. assoc_rsp = (struct ieee_types_assoc_rsp *)&priv->assoc_rsp_buf;
  138. pos = (void *)skb_put(skb, 4);
  139. *pos++ = WLAN_EID_AID;
  140. *pos++ = 2;
  141. memcpy(pos, &assoc_rsp->a_id, sizeof(assoc_rsp->a_id));
  142. return;
  143. }
  144. static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
  145. struct sk_buff *skb)
  146. {
  147. struct ieee80211_vht_cap vht_cap;
  148. u8 *pos;
  149. pos = (void *)skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
  150. *pos++ = WLAN_EID_VHT_CAPABILITY;
  151. *pos++ = sizeof(struct ieee80211_vht_cap);
  152. memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap));
  153. mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band);
  154. memcpy(pos, &vht_cap, sizeof(vht_cap));
  155. return 0;
  156. }
  157. static int
  158. mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, const u8 *mac,
  159. u8 vht_enabled, struct sk_buff *skb)
  160. {
  161. struct ieee80211_ht_operation *ht_oper;
  162. struct mwifiex_sta_node *sta_ptr;
  163. struct mwifiex_bssdescriptor *bss_desc =
  164. &priv->curr_bss_params.bss_descriptor;
  165. u8 *pos;
  166. sta_ptr = mwifiex_get_sta_entry(priv, mac);
  167. if (unlikely(!sta_ptr)) {
  168. mwifiex_dbg(priv->adapter, ERROR,
  169. "TDLS peer station not found in list\n");
  170. return -1;
  171. }
  172. if (!(le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info))) {
  173. mwifiex_dbg(priv->adapter, WARN,
  174. "TDLS peer doesn't support ht capabilities\n");
  175. return 0;
  176. }
  177. pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
  178. *pos++ = WLAN_EID_HT_OPERATION;
  179. *pos++ = sizeof(struct ieee80211_ht_operation);
  180. ht_oper = (void *)pos;
  181. ht_oper->primary_chan = bss_desc->channel;
  182. /* follow AP's channel bandwidth */
  183. if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) &&
  184. bss_desc->bcn_ht_cap &&
  185. ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param))
  186. ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param;
  187. if (vht_enabled) {
  188. ht_oper->ht_param =
  189. mwifiex_get_sec_chan_offset(bss_desc->channel);
  190. ht_oper->ht_param |= BIT(2);
  191. }
  192. memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper,
  193. sizeof(struct ieee80211_ht_operation));
  194. return 0;
  195. }
  196. static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
  197. const u8 *mac, struct sk_buff *skb)
  198. {
  199. struct mwifiex_bssdescriptor *bss_desc;
  200. struct ieee80211_vht_operation *vht_oper;
  201. struct ieee80211_vht_cap *vht_cap, *ap_vht_cap = NULL;
  202. struct mwifiex_sta_node *sta_ptr;
  203. struct mwifiex_adapter *adapter = priv->adapter;
  204. u8 supp_chwd_set, peer_supp_chwd_set;
  205. u8 *pos, ap_supp_chwd_set, chan_bw;
  206. u16 mcs_map_user, mcs_map_resp, mcs_map_result;
  207. u16 mcs_user, mcs_resp, nss;
  208. u32 usr_vht_cap_info;
  209. bss_desc = &priv->curr_bss_params.bss_descriptor;
  210. sta_ptr = mwifiex_get_sta_entry(priv, mac);
  211. if (unlikely(!sta_ptr)) {
  212. mwifiex_dbg(adapter, ERROR,
  213. "TDLS peer station not found in list\n");
  214. return -1;
  215. }
  216. if (!(le32_to_cpu(sta_ptr->tdls_cap.vhtcap.vht_cap_info))) {
  217. mwifiex_dbg(adapter, WARN,
  218. "TDLS peer doesn't support vht capabilities\n");
  219. return 0;
  220. }
  221. if (!mwifiex_is_bss_in_11ac_mode(priv)) {
  222. if (sta_ptr->tdls_cap.extcap.ext_capab[7] &
  223. WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
  224. mwifiex_dbg(adapter, WARN,
  225. "TDLS peer doesn't support wider bandwidth\n");
  226. return 0;
  227. }
  228. } else {
  229. ap_vht_cap = bss_desc->bcn_vht_cap;
  230. }
  231. pos = (void *)skb_put(skb, sizeof(struct ieee80211_vht_operation) + 2);
  232. *pos++ = WLAN_EID_VHT_OPERATION;
  233. *pos++ = sizeof(struct ieee80211_vht_operation);
  234. vht_oper = (struct ieee80211_vht_operation *)pos;
  235. if (bss_desc->bss_band & BAND_A)
  236. usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
  237. else
  238. usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
  239. /* find the minimum bandwidth between AP/TDLS peers */
  240. vht_cap = &sta_ptr->tdls_cap.vhtcap;
  241. supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
  242. peer_supp_chwd_set =
  243. GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap->vht_cap_info));
  244. supp_chwd_set = min_t(u8, supp_chwd_set, peer_supp_chwd_set);
  245. /* We need check AP's bandwidth when TDLS_WIDER_BANDWIDTH is off */
  246. if (ap_vht_cap && sta_ptr->tdls_cap.extcap.ext_capab[7] &
  247. WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
  248. ap_supp_chwd_set =
  249. GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap->vht_cap_info));
  250. supp_chwd_set = min_t(u8, supp_chwd_set, ap_supp_chwd_set);
  251. }
  252. switch (supp_chwd_set) {
  253. case IEEE80211_VHT_CHANWIDTH_80MHZ:
  254. vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
  255. break;
  256. case IEEE80211_VHT_CHANWIDTH_160MHZ:
  257. vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
  258. break;
  259. case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
  260. vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
  261. break;
  262. default:
  263. vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
  264. break;
  265. }
  266. mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
  267. mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
  268. mcs_map_result = 0;
  269. for (nss = 1; nss <= 8; nss++) {
  270. mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
  271. mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
  272. if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
  273. (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
  274. SET_VHTNSSMCS(mcs_map_result, nss,
  275. IEEE80211_VHT_MCS_NOT_SUPPORTED);
  276. else
  277. SET_VHTNSSMCS(mcs_map_result, nss,
  278. min_t(u16, mcs_user, mcs_resp));
  279. }
  280. vht_oper->basic_mcs_set = cpu_to_le16(mcs_map_result);
  281. switch (vht_oper->chan_width) {
  282. case IEEE80211_VHT_CHANWIDTH_80MHZ:
  283. chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
  284. break;
  285. case IEEE80211_VHT_CHANWIDTH_160MHZ:
  286. chan_bw = IEEE80211_VHT_CHANWIDTH_160MHZ;
  287. break;
  288. case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
  289. chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
  290. break;
  291. default:
  292. chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
  293. break;
  294. }
  295. vht_oper->center_freq_seg1_idx =
  296. mwifiex_get_center_freq_index(priv, BAND_AAC,
  297. bss_desc->channel,
  298. chan_bw);
  299. return 0;
  300. }
  301. static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv,
  302. struct sk_buff *skb)
  303. {
  304. struct ieee_types_extcap *extcap;
  305. extcap = (void *)skb_put(skb, sizeof(struct ieee_types_extcap));
  306. extcap->ieee_hdr.element_id = WLAN_EID_EXT_CAPABILITY;
  307. extcap->ieee_hdr.len = 8;
  308. memset(extcap->ext_capab, 0, 8);
  309. extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED;
  310. extcap->ext_capab[3] |= WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH;
  311. if (priv->adapter->is_hw_11ac_capable)
  312. extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED;
  313. }
  314. static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb)
  315. {
  316. u8 *pos = (void *)skb_put(skb, 3);
  317. *pos++ = WLAN_EID_QOS_CAPA;
  318. *pos++ = 1;
  319. *pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB;
  320. }
  321. static void
  322. mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private *priv, struct sk_buff *skb)
  323. {
  324. struct ieee80211_wmm_param_ie *wmm;
  325. u8 ac_vi[] = {0x42, 0x43, 0x5e, 0x00};
  326. u8 ac_vo[] = {0x62, 0x32, 0x2f, 0x00};
  327. u8 ac_be[] = {0x03, 0xa4, 0x00, 0x00};
  328. u8 ac_bk[] = {0x27, 0xa4, 0x00, 0x00};
  329. wmm = (void *)skb_put(skb, sizeof(*wmm));
  330. memset(wmm, 0, sizeof(*wmm));
  331. wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
  332. wmm->len = sizeof(*wmm) - 2;
  333. wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
  334. wmm->oui[1] = 0x50;
  335. wmm->oui[2] = 0xf2;
  336. wmm->oui_type = 2; /* WME */
  337. wmm->oui_subtype = 1; /* WME param */
  338. wmm->version = 1; /* WME ver */
  339. wmm->qos_info = 0; /* U-APSD not in use */
  340. /* use default WMM AC parameters for TDLS link*/
  341. memcpy(&wmm->ac[0], ac_be, sizeof(ac_be));
  342. memcpy(&wmm->ac[1], ac_bk, sizeof(ac_bk));
  343. memcpy(&wmm->ac[2], ac_vi, sizeof(ac_vi));
  344. memcpy(&wmm->ac[3], ac_vo, sizeof(ac_vo));
  345. }
  346. static void
  347. mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb,
  348. u8 qosinfo)
  349. {
  350. u8 *buf;
  351. buf = (void *)skb_put(skb, MWIFIEX_TDLS_WMM_INFO_SIZE +
  352. sizeof(struct ieee_types_header));
  353. *buf++ = WLAN_EID_VENDOR_SPECIFIC;
  354. *buf++ = 7; /* len */
  355. *buf++ = 0x00; /* Microsoft OUI 00:50:F2 */
  356. *buf++ = 0x50;
  357. *buf++ = 0xf2;
  358. *buf++ = 2; /* WME */
  359. *buf++ = 0; /* WME info */
  360. *buf++ = 1; /* WME ver */
  361. *buf++ = qosinfo; /* U-APSD no in use */
  362. }
  363. static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
  364. const u8 *peer, u8 action_code,
  365. u8 dialog_token,
  366. u16 status_code, struct sk_buff *skb)
  367. {
  368. struct ieee80211_tdls_data *tf;
  369. int ret;
  370. u16 capab;
  371. struct ieee80211_ht_cap *ht_cap;
  372. u8 radio, *pos;
  373. capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
  374. tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
  375. memcpy(tf->da, peer, ETH_ALEN);
  376. memcpy(tf->sa, priv->curr_addr, ETH_ALEN);
  377. tf->ether_type = cpu_to_be16(ETH_P_TDLS);
  378. tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
  379. switch (action_code) {
  380. case WLAN_TDLS_SETUP_REQUEST:
  381. tf->category = WLAN_CATEGORY_TDLS;
  382. tf->action_code = WLAN_TDLS_SETUP_REQUEST;
  383. skb_put(skb, sizeof(tf->u.setup_req));
  384. tf->u.setup_req.dialog_token = dialog_token;
  385. tf->u.setup_req.capability = cpu_to_le16(capab);
  386. ret = mwifiex_tdls_append_rates_ie(priv, skb);
  387. if (ret) {
  388. dev_kfree_skb_any(skb);
  389. return ret;
  390. }
  391. pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
  392. *pos++ = WLAN_EID_HT_CAPABILITY;
  393. *pos++ = sizeof(struct ieee80211_ht_cap);
  394. ht_cap = (void *)pos;
  395. radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
  396. ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
  397. if (ret) {
  398. dev_kfree_skb_any(skb);
  399. return ret;
  400. }
  401. if (priv->adapter->is_hw_11ac_capable) {
  402. ret = mwifiex_tdls_add_vht_capab(priv, skb);
  403. if (ret) {
  404. dev_kfree_skb_any(skb);
  405. return ret;
  406. }
  407. mwifiex_tdls_add_aid(priv, skb);
  408. }
  409. mwifiex_tdls_add_ext_capab(priv, skb);
  410. mwifiex_tdls_add_qos_capab(skb);
  411. mwifiex_add_wmm_info_ie(priv, skb, 0);
  412. break;
  413. case WLAN_TDLS_SETUP_RESPONSE:
  414. tf->category = WLAN_CATEGORY_TDLS;
  415. tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
  416. skb_put(skb, sizeof(tf->u.setup_resp));
  417. tf->u.setup_resp.status_code = cpu_to_le16(status_code);
  418. tf->u.setup_resp.dialog_token = dialog_token;
  419. tf->u.setup_resp.capability = cpu_to_le16(capab);
  420. ret = mwifiex_tdls_append_rates_ie(priv, skb);
  421. if (ret) {
  422. dev_kfree_skb_any(skb);
  423. return ret;
  424. }
  425. pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
  426. *pos++ = WLAN_EID_HT_CAPABILITY;
  427. *pos++ = sizeof(struct ieee80211_ht_cap);
  428. ht_cap = (void *)pos;
  429. radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
  430. ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
  431. if (ret) {
  432. dev_kfree_skb_any(skb);
  433. return ret;
  434. }
  435. if (priv->adapter->is_hw_11ac_capable) {
  436. ret = mwifiex_tdls_add_vht_capab(priv, skb);
  437. if (ret) {
  438. dev_kfree_skb_any(skb);
  439. return ret;
  440. }
  441. mwifiex_tdls_add_aid(priv, skb);
  442. }
  443. mwifiex_tdls_add_ext_capab(priv, skb);
  444. mwifiex_tdls_add_qos_capab(skb);
  445. mwifiex_add_wmm_info_ie(priv, skb, 0);
  446. break;
  447. case WLAN_TDLS_SETUP_CONFIRM:
  448. tf->category = WLAN_CATEGORY_TDLS;
  449. tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
  450. skb_put(skb, sizeof(tf->u.setup_cfm));
  451. tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
  452. tf->u.setup_cfm.dialog_token = dialog_token;
  453. mwifiex_tdls_add_wmm_param_ie(priv, skb);
  454. if (priv->adapter->is_hw_11ac_capable) {
  455. ret = mwifiex_tdls_add_vht_oper(priv, peer, skb);
  456. if (ret) {
  457. dev_kfree_skb_any(skb);
  458. return ret;
  459. }
  460. ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb);
  461. if (ret) {
  462. dev_kfree_skb_any(skb);
  463. return ret;
  464. }
  465. } else {
  466. ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb);
  467. if (ret) {
  468. dev_kfree_skb_any(skb);
  469. return ret;
  470. }
  471. }
  472. break;
  473. case WLAN_TDLS_TEARDOWN:
  474. tf->category = WLAN_CATEGORY_TDLS;
  475. tf->action_code = WLAN_TDLS_TEARDOWN;
  476. skb_put(skb, sizeof(tf->u.teardown));
  477. tf->u.teardown.reason_code = cpu_to_le16(status_code);
  478. break;
  479. case WLAN_TDLS_DISCOVERY_REQUEST:
  480. tf->category = WLAN_CATEGORY_TDLS;
  481. tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
  482. skb_put(skb, sizeof(tf->u.discover_req));
  483. tf->u.discover_req.dialog_token = dialog_token;
  484. break;
  485. default:
  486. mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
  487. return -EINVAL;
  488. }
  489. return 0;
  490. }
  491. static void
  492. mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr,
  493. const u8 *peer, const u8 *bssid)
  494. {
  495. struct ieee80211_tdls_lnkie *lnkid;
  496. lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
  497. lnkid->ie_type = WLAN_EID_LINK_ID;
  498. lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) -
  499. sizeof(struct ieee_types_header);
  500. memcpy(lnkid->bssid, bssid, ETH_ALEN);
  501. memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
  502. memcpy(lnkid->resp_sta, peer, ETH_ALEN);
  503. }
  504. int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
  505. u8 action_code, u8 dialog_token,
  506. u16 status_code, const u8 *extra_ies,
  507. size_t extra_ies_len)
  508. {
  509. struct sk_buff *skb;
  510. struct mwifiex_txinfo *tx_info;
  511. int ret;
  512. u16 skb_len;
  513. skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
  514. max(sizeof(struct ieee80211_mgmt),
  515. sizeof(struct ieee80211_tdls_data)) +
  516. MWIFIEX_MGMT_FRAME_HEADER_SIZE +
  517. MWIFIEX_SUPPORTED_RATES +
  518. 3 + /* Qos Info */
  519. sizeof(struct ieee_types_extcap) +
  520. sizeof(struct ieee80211_ht_cap) +
  521. sizeof(struct ieee_types_bss_co_2040) +
  522. sizeof(struct ieee80211_ht_operation) +
  523. sizeof(struct ieee80211_tdls_lnkie) +
  524. sizeof(struct ieee80211_wmm_param_ie) +
  525. extra_ies_len;
  526. if (priv->adapter->is_hw_11ac_capable)
  527. skb_len += sizeof(struct ieee_types_vht_cap) +
  528. sizeof(struct ieee_types_vht_oper) +
  529. sizeof(struct ieee_types_aid);
  530. skb = dev_alloc_skb(skb_len);
  531. if (!skb) {
  532. mwifiex_dbg(priv->adapter, ERROR,
  533. "allocate skb failed for management frame\n");
  534. return -ENOMEM;
  535. }
  536. skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
  537. switch (action_code) {
  538. case WLAN_TDLS_SETUP_REQUEST:
  539. case WLAN_TDLS_SETUP_CONFIRM:
  540. case WLAN_TDLS_TEARDOWN:
  541. case WLAN_TDLS_DISCOVERY_REQUEST:
  542. ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
  543. dialog_token, status_code,
  544. skb);
  545. if (ret) {
  546. dev_kfree_skb_any(skb);
  547. return ret;
  548. }
  549. if (extra_ies_len)
  550. memcpy(skb_put(skb, extra_ies_len), extra_ies,
  551. extra_ies_len);
  552. mwifiex_tdls_add_link_ie(skb, priv->curr_addr, peer,
  553. priv->cfg_bssid);
  554. break;
  555. case WLAN_TDLS_SETUP_RESPONSE:
  556. ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
  557. dialog_token, status_code,
  558. skb);
  559. if (ret) {
  560. dev_kfree_skb_any(skb);
  561. return ret;
  562. }
  563. if (extra_ies_len)
  564. memcpy(skb_put(skb, extra_ies_len), extra_ies,
  565. extra_ies_len);
  566. mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
  567. priv->cfg_bssid);
  568. break;
  569. }
  570. switch (action_code) {
  571. case WLAN_TDLS_SETUP_REQUEST:
  572. case WLAN_TDLS_SETUP_RESPONSE:
  573. skb->priority = MWIFIEX_PRIO_BK;
  574. break;
  575. default:
  576. skb->priority = MWIFIEX_PRIO_VI;
  577. break;
  578. }
  579. tx_info = MWIFIEX_SKB_TXCB(skb);
  580. memset(tx_info, 0, sizeof(*tx_info));
  581. tx_info->bss_num = priv->bss_num;
  582. tx_info->bss_type = priv->bss_type;
  583. __net_timestamp(skb);
  584. mwifiex_queue_tx_pkt(priv, skb);
  585. /* Delay 10ms to make sure tdls setup confirm/teardown frame
  586. * is received by peer
  587. */
  588. if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
  589. action_code == WLAN_TDLS_TEARDOWN)
  590. msleep_interruptible(10);
  591. return 0;
  592. }
  593. static int
  594. mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
  595. const u8 *peer,
  596. u8 action_code, u8 dialog_token,
  597. u16 status_code, struct sk_buff *skb)
  598. {
  599. struct ieee80211_mgmt *mgmt;
  600. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  601. int ret;
  602. u16 capab;
  603. struct ieee80211_ht_cap *ht_cap;
  604. u8 radio, *pos;
  605. capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
  606. mgmt = (void *)skb_put(skb, offsetof(struct ieee80211_mgmt, u));
  607. memset(mgmt, 0, 24);
  608. memcpy(mgmt->da, peer, ETH_ALEN);
  609. memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
  610. memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
  611. mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
  612. IEEE80211_STYPE_ACTION);
  613. /* add address 4 */
  614. pos = skb_put(skb, ETH_ALEN);
  615. switch (action_code) {
  616. case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
  617. skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1);
  618. mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
  619. mgmt->u.action.u.tdls_discover_resp.action_code =
  620. WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
  621. mgmt->u.action.u.tdls_discover_resp.dialog_token =
  622. dialog_token;
  623. mgmt->u.action.u.tdls_discover_resp.capability =
  624. cpu_to_le16(capab);
  625. /* move back for addr4 */
  626. memmove(pos + ETH_ALEN, &mgmt->u.action.category,
  627. sizeof(mgmt->u.action.u.tdls_discover_resp));
  628. /* init address 4 */
  629. memcpy(pos, bc_addr, ETH_ALEN);
  630. ret = mwifiex_tdls_append_rates_ie(priv, skb);
  631. if (ret) {
  632. dev_kfree_skb_any(skb);
  633. return ret;
  634. }
  635. pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
  636. *pos++ = WLAN_EID_HT_CAPABILITY;
  637. *pos++ = sizeof(struct ieee80211_ht_cap);
  638. ht_cap = (void *)pos;
  639. radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
  640. ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
  641. if (ret) {
  642. dev_kfree_skb_any(skb);
  643. return ret;
  644. }
  645. if (priv->adapter->is_hw_11ac_capable) {
  646. ret = mwifiex_tdls_add_vht_capab(priv, skb);
  647. if (ret) {
  648. dev_kfree_skb_any(skb);
  649. return ret;
  650. }
  651. mwifiex_tdls_add_aid(priv, skb);
  652. }
  653. mwifiex_tdls_add_ext_capab(priv, skb);
  654. mwifiex_tdls_add_qos_capab(skb);
  655. break;
  656. default:
  657. mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n");
  658. return -EINVAL;
  659. }
  660. return 0;
  661. }
  662. int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
  663. u8 action_code, u8 dialog_token,
  664. u16 status_code, const u8 *extra_ies,
  665. size_t extra_ies_len)
  666. {
  667. struct sk_buff *skb;
  668. struct mwifiex_txinfo *tx_info;
  669. u8 *pos;
  670. u32 pkt_type, tx_control;
  671. u16 pkt_len, skb_len;
  672. skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
  673. max(sizeof(struct ieee80211_mgmt),
  674. sizeof(struct ieee80211_tdls_data)) +
  675. MWIFIEX_MGMT_FRAME_HEADER_SIZE +
  676. MWIFIEX_SUPPORTED_RATES +
  677. sizeof(struct ieee_types_extcap) +
  678. sizeof(struct ieee80211_ht_cap) +
  679. sizeof(struct ieee_types_bss_co_2040) +
  680. sizeof(struct ieee80211_ht_operation) +
  681. sizeof(struct ieee80211_tdls_lnkie) +
  682. extra_ies_len +
  683. 3 + /* Qos Info */
  684. ETH_ALEN; /* Address4 */
  685. if (priv->adapter->is_hw_11ac_capable)
  686. skb_len += sizeof(struct ieee_types_vht_cap) +
  687. sizeof(struct ieee_types_vht_oper) +
  688. sizeof(struct ieee_types_aid);
  689. skb = dev_alloc_skb(skb_len);
  690. if (!skb) {
  691. mwifiex_dbg(priv->adapter, ERROR,
  692. "allocate skb failed for management frame\n");
  693. return -ENOMEM;
  694. }
  695. skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
  696. pkt_type = PKT_TYPE_MGMT;
  697. tx_control = 0;
  698. pos = skb_put(skb, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
  699. memset(pos, 0, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
  700. memcpy(pos, &pkt_type, sizeof(pkt_type));
  701. memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control));
  702. if (mwifiex_construct_tdls_action_frame(priv, peer, action_code,
  703. dialog_token, status_code,
  704. skb)) {
  705. dev_kfree_skb_any(skb);
  706. return -EINVAL;
  707. }
  708. if (extra_ies_len)
  709. memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
  710. /* the TDLS link IE is always added last we are the responder */
  711. mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
  712. priv->cfg_bssid);
  713. skb->priority = MWIFIEX_PRIO_VI;
  714. tx_info = MWIFIEX_SKB_TXCB(skb);
  715. memset(tx_info, 0, sizeof(*tx_info));
  716. tx_info->bss_num = priv->bss_num;
  717. tx_info->bss_type = priv->bss_type;
  718. tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
  719. pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
  720. memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
  721. sizeof(pkt_len));
  722. __net_timestamp(skb);
  723. mwifiex_queue_tx_pkt(priv, skb);
  724. return 0;
  725. }
  726. /* This function process tdls action frame from peer.
  727. * Peer capabilities are stored into station node structure.
  728. */
  729. void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
  730. u8 *buf, int len)
  731. {
  732. struct mwifiex_sta_node *sta_ptr;
  733. u8 *peer, *pos, *end;
  734. u8 i, action, basic;
  735. __le16 cap = 0;
  736. int ie_len = 0;
  737. if (len < (sizeof(struct ethhdr) + 3))
  738. return;
  739. if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
  740. return;
  741. if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
  742. return;
  743. peer = buf + ETH_ALEN;
  744. action = *(buf + sizeof(struct ethhdr) + 2);
  745. mwifiex_dbg(priv->adapter, DATA,
  746. "rx:tdls action: peer=%pM, action=%d\n", peer, action);
  747. switch (action) {
  748. case WLAN_TDLS_SETUP_REQUEST:
  749. if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
  750. return;
  751. pos = buf + sizeof(struct ethhdr) + 4;
  752. /* payload 1+ category 1 + action 1 + dialog 1 */
  753. cap = cpu_to_le16(*(u16 *)pos);
  754. ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
  755. pos += 2;
  756. break;
  757. case WLAN_TDLS_SETUP_RESPONSE:
  758. if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN))
  759. return;
  760. /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
  761. pos = buf + sizeof(struct ethhdr) + 6;
  762. cap = cpu_to_le16(*(u16 *)pos);
  763. ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
  764. pos += 2;
  765. break;
  766. case WLAN_TDLS_SETUP_CONFIRM:
  767. if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN))
  768. return;
  769. pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN;
  770. ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
  771. break;
  772. default:
  773. mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
  774. return;
  775. }
  776. sta_ptr = mwifiex_add_sta_entry(priv, peer);
  777. if (!sta_ptr)
  778. return;
  779. sta_ptr->tdls_cap.capab = cap;
  780. for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
  781. if (pos + 2 + pos[1] > end)
  782. break;
  783. switch (*pos) {
  784. case WLAN_EID_SUPP_RATES:
  785. sta_ptr->tdls_cap.rates_len = pos[1];
  786. for (i = 0; i < pos[1]; i++)
  787. sta_ptr->tdls_cap.rates[i] = pos[i + 2];
  788. break;
  789. case WLAN_EID_EXT_SUPP_RATES:
  790. basic = sta_ptr->tdls_cap.rates_len;
  791. for (i = 0; i < pos[1]; i++)
  792. sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
  793. sta_ptr->tdls_cap.rates_len += pos[1];
  794. break;
  795. case WLAN_EID_HT_CAPABILITY:
  796. memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,
  797. sizeof(struct ieee80211_ht_cap));
  798. sta_ptr->is_11n_enabled = 1;
  799. break;
  800. case WLAN_EID_HT_OPERATION:
  801. memcpy(&sta_ptr->tdls_cap.ht_oper, pos,
  802. sizeof(struct ieee80211_ht_operation));
  803. break;
  804. case WLAN_EID_BSS_COEX_2040:
  805. sta_ptr->tdls_cap.coex_2040 = pos[2];
  806. break;
  807. case WLAN_EID_EXT_CAPABILITY:
  808. memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
  809. sizeof(struct ieee_types_header) +
  810. min_t(u8, pos[1], 8));
  811. break;
  812. case WLAN_EID_RSN:
  813. memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
  814. sizeof(struct ieee_types_header) +
  815. min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
  816. sizeof(struct ieee_types_header)));
  817. break;
  818. case WLAN_EID_QOS_CAPA:
  819. sta_ptr->tdls_cap.qos_info = pos[2];
  820. break;
  821. case WLAN_EID_VHT_OPERATION:
  822. if (priv->adapter->is_hw_11ac_capable)
  823. memcpy(&sta_ptr->tdls_cap.vhtoper, pos,
  824. sizeof(struct ieee80211_vht_operation));
  825. break;
  826. case WLAN_EID_VHT_CAPABILITY:
  827. if (priv->adapter->is_hw_11ac_capable) {
  828. memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos,
  829. sizeof(struct ieee80211_vht_cap));
  830. sta_ptr->is_11ac_enabled = 1;
  831. }
  832. break;
  833. case WLAN_EID_AID:
  834. if (priv->adapter->is_hw_11ac_capable)
  835. sta_ptr->tdls_cap.aid =
  836. le16_to_cpu(*(__le16 *)(pos + 2));
  837. default:
  838. break;
  839. }
  840. }
  841. return;
  842. }
  843. static int
  844. mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer)
  845. {
  846. struct mwifiex_sta_node *sta_ptr;
  847. struct mwifiex_ds_tdls_oper tdls_oper;
  848. memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
  849. sta_ptr = mwifiex_get_sta_entry(priv, peer);
  850. if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) {
  851. mwifiex_dbg(priv->adapter, ERROR,
  852. "link absent for peer %pM; cannot config\n", peer);
  853. return -EINVAL;
  854. }
  855. memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
  856. tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK;
  857. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
  858. HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
  859. }
  860. static int
  861. mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer)
  862. {
  863. struct mwifiex_sta_node *sta_ptr;
  864. struct mwifiex_ds_tdls_oper tdls_oper;
  865. memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
  866. sta_ptr = mwifiex_get_sta_entry(priv, peer);
  867. if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) {
  868. mwifiex_dbg(priv->adapter, WARN,
  869. "Setup already in progress for peer %pM\n", peer);
  870. return 0;
  871. }
  872. sta_ptr = mwifiex_add_sta_entry(priv, peer);
  873. if (!sta_ptr)
  874. return -ENOMEM;
  875. sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS;
  876. mwifiex_hold_tdls_packets(priv, peer);
  877. memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
  878. tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
  879. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
  880. HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
  881. }
  882. static int
  883. mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer)
  884. {
  885. struct mwifiex_sta_node *sta_ptr;
  886. struct mwifiex_ds_tdls_oper tdls_oper;
  887. unsigned long flags;
  888. memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
  889. sta_ptr = mwifiex_get_sta_entry(priv, peer);
  890. if (sta_ptr) {
  891. if (sta_ptr->is_11n_enabled) {
  892. mwifiex_11n_cleanup_reorder_tbl(priv);
  893. spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
  894. flags);
  895. mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
  896. spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
  897. flags);
  898. }
  899. mwifiex_del_sta_entry(priv, peer);
  900. }
  901. mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
  902. mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP);
  903. memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
  904. tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
  905. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
  906. HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
  907. }
  908. static int
  909. mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer)
  910. {
  911. struct mwifiex_sta_node *sta_ptr;
  912. struct ieee80211_mcs_info mcs;
  913. unsigned long flags;
  914. int i;
  915. sta_ptr = mwifiex_get_sta_entry(priv, peer);
  916. if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) {
  917. mwifiex_dbg(priv->adapter, MSG,
  918. "tdls: enable link %pM success\n", peer);
  919. sta_ptr->tdls_status = TDLS_SETUP_COMPLETE;
  920. mcs = sta_ptr->tdls_cap.ht_capb.mcs;
  921. if (mcs.rx_mask[0] != 0xff)
  922. sta_ptr->is_11n_enabled = true;
  923. if (sta_ptr->is_11n_enabled) {
  924. if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) &
  925. IEEE80211_HT_CAP_MAX_AMSDU)
  926. sta_ptr->max_amsdu =
  927. MWIFIEX_TX_DATA_BUF_SIZE_8K;
  928. else
  929. sta_ptr->max_amsdu =
  930. MWIFIEX_TX_DATA_BUF_SIZE_4K;
  931. for (i = 0; i < MAX_NUM_TID; i++)
  932. sta_ptr->ampdu_sta[i] =
  933. priv->aggr_prio_tbl[i].ampdu_user;
  934. } else {
  935. for (i = 0; i < MAX_NUM_TID; i++)
  936. sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
  937. }
  938. if (sta_ptr->tdls_cap.extcap.ext_capab[3] &
  939. WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) {
  940. mwifiex_config_tdls_enable(priv);
  941. mwifiex_config_tdls_cs_params(priv);
  942. }
  943. memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
  944. mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE);
  945. mwifiex_auto_tdls_update_peer_status(priv, peer,
  946. TDLS_SETUP_COMPLETE);
  947. } else {
  948. mwifiex_dbg(priv->adapter, ERROR,
  949. "tdls: enable link %pM failed\n", peer);
  950. if (sta_ptr) {
  951. mwifiex_11n_cleanup_reorder_tbl(priv);
  952. spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
  953. flags);
  954. mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
  955. spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
  956. flags);
  957. mwifiex_del_sta_entry(priv, peer);
  958. }
  959. mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
  960. mwifiex_auto_tdls_update_peer_status(priv, peer,
  961. TDLS_NOT_SETUP);
  962. return -1;
  963. }
  964. return 0;
  965. }
  966. int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action)
  967. {
  968. switch (action) {
  969. case MWIFIEX_TDLS_ENABLE_LINK:
  970. return mwifiex_tdls_process_enable_link(priv, peer);
  971. case MWIFIEX_TDLS_DISABLE_LINK:
  972. return mwifiex_tdls_process_disable_link(priv, peer);
  973. case MWIFIEX_TDLS_CREATE_LINK:
  974. return mwifiex_tdls_process_create_link(priv, peer);
  975. case MWIFIEX_TDLS_CONFIG_LINK:
  976. return mwifiex_tdls_process_config_link(priv, peer);
  977. }
  978. return 0;
  979. }
  980. int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac)
  981. {
  982. struct mwifiex_sta_node *sta_ptr;
  983. sta_ptr = mwifiex_get_sta_entry(priv, mac);
  984. if (sta_ptr)
  985. return sta_ptr->tdls_status;
  986. return TDLS_NOT_SETUP;
  987. }
  988. int mwifiex_get_tdls_list(struct mwifiex_private *priv,
  989. struct tdls_peer_info *buf)
  990. {
  991. struct mwifiex_sta_node *sta_ptr;
  992. struct tdls_peer_info *peer = buf;
  993. int count = 0;
  994. unsigned long flags;
  995. if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
  996. return 0;
  997. /* make sure we are in station mode and connected */
  998. if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
  999. return 0;
  1000. spin_lock_irqsave(&priv->sta_list_spinlock, flags);
  1001. list_for_each_entry(sta_ptr, &priv->sta_list, list) {
  1002. if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) {
  1003. ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr);
  1004. peer++;
  1005. count++;
  1006. if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED)
  1007. break;
  1008. }
  1009. }
  1010. spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
  1011. return count;
  1012. }
  1013. void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
  1014. {
  1015. struct mwifiex_sta_node *sta_ptr;
  1016. struct mwifiex_ds_tdls_oper tdls_oper;
  1017. unsigned long flags;
  1018. if (list_empty(&priv->sta_list))
  1019. return;
  1020. list_for_each_entry(sta_ptr, &priv->sta_list, list) {
  1021. memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
  1022. if (sta_ptr->is_11n_enabled) {
  1023. mwifiex_11n_cleanup_reorder_tbl(priv);
  1024. spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
  1025. flags);
  1026. mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
  1027. spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
  1028. flags);
  1029. }
  1030. mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr,
  1031. TDLS_LINK_TEARDOWN);
  1032. memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN);
  1033. tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
  1034. if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
  1035. HostCmd_ACT_GEN_SET, 0, &tdls_oper, false))
  1036. mwifiex_dbg(priv->adapter, ERROR,
  1037. "Disable link failed for TDLS peer %pM",
  1038. sta_ptr->mac_addr);
  1039. }
  1040. mwifiex_del_all_sta_list(priv);
  1041. }
  1042. int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb)
  1043. {
  1044. struct mwifiex_auto_tdls_peer *peer;
  1045. unsigned long flags;
  1046. u8 mac[ETH_ALEN];
  1047. ether_addr_copy(mac, skb->data);
  1048. spin_lock_irqsave(&priv->auto_tdls_lock, flags);
  1049. list_for_each_entry(peer, &priv->auto_tdls_list, list) {
  1050. if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) {
  1051. if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
  1052. peer->tdls_status == TDLS_NOT_SETUP &&
  1053. (peer->failure_count <
  1054. MWIFIEX_TDLS_MAX_FAIL_COUNT)) {
  1055. peer->tdls_status = TDLS_SETUP_INPROGRESS;
  1056. mwifiex_dbg(priv->adapter, INFO,
  1057. "setup TDLS link, peer=%pM rssi=%d\n",
  1058. peer->mac_addr, peer->rssi);
  1059. cfg80211_tdls_oper_request(priv->netdev,
  1060. peer->mac_addr,
  1061. NL80211_TDLS_SETUP,
  1062. 0, GFP_ATOMIC);
  1063. peer->do_setup = false;
  1064. priv->check_tdls_tx = false;
  1065. } else if (peer->failure_count <
  1066. MWIFIEX_TDLS_MAX_FAIL_COUNT &&
  1067. peer->do_discover) {
  1068. mwifiex_send_tdls_data_frame(priv,
  1069. peer->mac_addr,
  1070. WLAN_TDLS_DISCOVERY_REQUEST,
  1071. 1, 0, NULL, 0);
  1072. peer->do_discover = false;
  1073. }
  1074. }
  1075. }
  1076. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1077. return 0;
  1078. }
  1079. void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv)
  1080. {
  1081. struct mwifiex_auto_tdls_peer *peer, *tmp_node;
  1082. unsigned long flags;
  1083. spin_lock_irqsave(&priv->auto_tdls_lock, flags);
  1084. list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) {
  1085. list_del(&peer->list);
  1086. kfree(peer);
  1087. }
  1088. INIT_LIST_HEAD(&priv->auto_tdls_list);
  1089. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1090. priv->check_tdls_tx = false;
  1091. }
  1092. void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac)
  1093. {
  1094. struct mwifiex_auto_tdls_peer *tdls_peer;
  1095. unsigned long flags;
  1096. if (!priv->adapter->auto_tdls)
  1097. return;
  1098. spin_lock_irqsave(&priv->auto_tdls_lock, flags);
  1099. list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
  1100. if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) {
  1101. tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
  1102. tdls_peer->rssi_jiffies = jiffies;
  1103. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1104. return;
  1105. }
  1106. }
  1107. /* create new TDLS peer */
  1108. tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC);
  1109. if (tdls_peer) {
  1110. ether_addr_copy(tdls_peer->mac_addr, mac);
  1111. tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
  1112. tdls_peer->rssi_jiffies = jiffies;
  1113. INIT_LIST_HEAD(&tdls_peer->list);
  1114. list_add_tail(&tdls_peer->list, &priv->auto_tdls_list);
  1115. mwifiex_dbg(priv->adapter, INFO,
  1116. "Add auto TDLS peer= %pM to list\n", mac);
  1117. }
  1118. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1119. }
  1120. void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv,
  1121. const u8 *mac, u8 link_status)
  1122. {
  1123. struct mwifiex_auto_tdls_peer *peer;
  1124. unsigned long flags;
  1125. if (!priv->adapter->auto_tdls)
  1126. return;
  1127. spin_lock_irqsave(&priv->auto_tdls_lock, flags);
  1128. list_for_each_entry(peer, &priv->auto_tdls_list, list) {
  1129. if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
  1130. if ((link_status == TDLS_NOT_SETUP) &&
  1131. (peer->tdls_status == TDLS_SETUP_INPROGRESS))
  1132. peer->failure_count++;
  1133. else if (mwifiex_is_tdls_link_setup(link_status))
  1134. peer->failure_count = 0;
  1135. peer->tdls_status = link_status;
  1136. break;
  1137. }
  1138. }
  1139. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1140. }
  1141. void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv,
  1142. u8 *mac, s8 snr, s8 nflr)
  1143. {
  1144. struct mwifiex_auto_tdls_peer *peer;
  1145. unsigned long flags;
  1146. if (!priv->adapter->auto_tdls)
  1147. return;
  1148. spin_lock_irqsave(&priv->auto_tdls_lock, flags);
  1149. list_for_each_entry(peer, &priv->auto_tdls_list, list) {
  1150. if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
  1151. peer->rssi = nflr - snr;
  1152. peer->rssi_jiffies = jiffies;
  1153. break;
  1154. }
  1155. }
  1156. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1157. }
  1158. void mwifiex_check_auto_tdls(unsigned long context)
  1159. {
  1160. struct mwifiex_private *priv = (struct mwifiex_private *)context;
  1161. struct mwifiex_auto_tdls_peer *tdls_peer;
  1162. unsigned long flags;
  1163. u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
  1164. if (WARN_ON_ONCE(!priv || !priv->adapter)) {
  1165. pr_err("mwifiex: %s: adapter or private structure is NULL\n",
  1166. __func__);
  1167. return;
  1168. }
  1169. if (unlikely(!priv->adapter->auto_tdls))
  1170. return;
  1171. if (!priv->auto_tdls_timer_active) {
  1172. mwifiex_dbg(priv->adapter, INFO,
  1173. "auto TDLS timer inactive; return");
  1174. return;
  1175. }
  1176. priv->check_tdls_tx = false;
  1177. if (list_empty(&priv->auto_tdls_list)) {
  1178. mod_timer(&priv->auto_tdls_timer,
  1179. jiffies +
  1180. msecs_to_jiffies(MWIFIEX_TIMER_10S));
  1181. return;
  1182. }
  1183. spin_lock_irqsave(&priv->auto_tdls_lock, flags);
  1184. list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
  1185. if ((jiffies - tdls_peer->rssi_jiffies) >
  1186. (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) {
  1187. tdls_peer->rssi = 0;
  1188. tdls_peer->do_discover = true;
  1189. priv->check_tdls_tx = true;
  1190. }
  1191. if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) ||
  1192. !tdls_peer->rssi) &&
  1193. mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) {
  1194. tdls_peer->tdls_status = TDLS_LINK_TEARDOWN;
  1195. mwifiex_dbg(priv->adapter, MSG,
  1196. "teardown TDLS link,peer=%pM rssi=%d\n",
  1197. tdls_peer->mac_addr, -tdls_peer->rssi);
  1198. tdls_peer->do_discover = true;
  1199. priv->check_tdls_tx = true;
  1200. cfg80211_tdls_oper_request(priv->netdev,
  1201. tdls_peer->mac_addr,
  1202. NL80211_TDLS_TEARDOWN,
  1203. reason, GFP_ATOMIC);
  1204. } else if (tdls_peer->rssi &&
  1205. tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
  1206. tdls_peer->tdls_status == TDLS_NOT_SETUP &&
  1207. tdls_peer->failure_count <
  1208. MWIFIEX_TDLS_MAX_FAIL_COUNT) {
  1209. priv->check_tdls_tx = true;
  1210. tdls_peer->do_setup = true;
  1211. mwifiex_dbg(priv->adapter, INFO,
  1212. "check TDLS with peer=%pM\t"
  1213. "rssi=%d\n", tdls_peer->mac_addr,
  1214. tdls_peer->rssi);
  1215. }
  1216. }
  1217. spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
  1218. mod_timer(&priv->auto_tdls_timer,
  1219. jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
  1220. }
  1221. void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv)
  1222. {
  1223. setup_timer(&priv->auto_tdls_timer, mwifiex_check_auto_tdls,
  1224. (unsigned long)priv);
  1225. priv->auto_tdls_timer_active = true;
  1226. mod_timer(&priv->auto_tdls_timer,
  1227. jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
  1228. }
  1229. void mwifiex_clean_auto_tdls(struct mwifiex_private *priv)
  1230. {
  1231. if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
  1232. priv->adapter->auto_tdls &&
  1233. priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
  1234. priv->auto_tdls_timer_active = false;
  1235. del_timer(&priv->auto_tdls_timer);
  1236. mwifiex_flush_auto_tdls_list(priv);
  1237. }
  1238. }
  1239. static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable)
  1240. {
  1241. struct mwifiex_tdls_config config;
  1242. config.enable = cpu_to_le16(enable);
  1243. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
  1244. ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true);
  1245. }
  1246. int mwifiex_config_tdls_enable(struct mwifiex_private *priv)
  1247. {
  1248. return mwifiex_config_tdls(priv, true);
  1249. }
  1250. int mwifiex_config_tdls_disable(struct mwifiex_private *priv)
  1251. {
  1252. return mwifiex_config_tdls(priv, false);
  1253. }
  1254. int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv)
  1255. {
  1256. struct mwifiex_tdls_config_cs_params config_tdls_cs_params;
  1257. config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME;
  1258. config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK;
  1259. config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK;
  1260. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
  1261. ACT_TDLS_CS_PARAMS, 0,
  1262. &config_tdls_cs_params, true);
  1263. }
  1264. int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac)
  1265. {
  1266. struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params;
  1267. ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac);
  1268. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
  1269. ACT_TDLS_CS_STOP, 0,
  1270. &stop_tdls_cs_params, true);
  1271. }
  1272. int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac,
  1273. u8 primary_chan, u8 second_chan_offset, u8 band)
  1274. {
  1275. struct mwifiex_tdls_init_cs_params start_tdls_cs_params;
  1276. ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac);
  1277. start_tdls_cs_params.primary_chan = primary_chan;
  1278. start_tdls_cs_params.second_chan_offset = second_chan_offset;
  1279. start_tdls_cs_params.band = band;
  1280. start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME);
  1281. start_tdls_cs_params.switch_timeout =
  1282. cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT);
  1283. start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS;
  1284. start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY;
  1285. return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
  1286. ACT_TDLS_CS_INIT, 0,
  1287. &start_tdls_cs_params, true);
  1288. }