wlan_cfg80211_tdls.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. /*
  2. * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /**
  19. * DOC: defines driver functions interfacing with linux kernel
  20. */
  21. #include <qdf_list.h>
  22. #include <qdf_status.h>
  23. #include <linux/wireless.h>
  24. #include <linux/netdevice.h>
  25. #include <net/cfg80211.h>
  26. #include <wlan_cfg80211.h>
  27. #include <wlan_cfg80211_tdls.h>
  28. #include <wlan_osif_priv.h>
  29. #include <wlan_tdls_public_structs.h>
  30. #include <wlan_tdls_ucfg_api.h>
  31. #include <qdf_mem.h>
  32. #include <wlan_utility.h>
  33. #include <wlan_reg_services_api.h>
  34. #include "wlan_cfg80211_mc_cp_stats.h"
  35. #include "sir_api.h"
  36. #include "wlan_tdls_ucfg_api.h"
  37. #define TDLS_MAX_NO_OF_2_4_CHANNELS 14
  38. static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac)
  39. {
  40. static const uint8_t temp_mac[QDF_MAC_ADDR_SIZE] = {0};
  41. if (!qdf_mem_cmp(mac, temp_mac, QDF_MAC_ADDR_SIZE)) {
  42. osif_debug("Invalid Mac address " QDF_MAC_ADDR_FMT
  43. " cmd declined.",
  44. QDF_MAC_ADDR_REF(mac));
  45. return -EINVAL;
  46. }
  47. return 0;
  48. }
  49. QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev)
  50. {
  51. struct osif_tdls_vdev *tdls_priv;
  52. struct vdev_osif_priv *osif_priv;
  53. osif_priv = wlan_vdev_get_ospriv(vdev);
  54. if (!osif_priv) {
  55. osif_err("osif_priv is NULL!");
  56. return QDF_STATUS_E_FAULT;
  57. }
  58. osif_debug("initialize tdls os if layer private structure");
  59. tdls_priv = qdf_mem_malloc(sizeof(*tdls_priv));
  60. if (!tdls_priv)
  61. return QDF_STATUS_E_NOMEM;
  62. init_completion(&tdls_priv->tdls_add_peer_comp);
  63. init_completion(&tdls_priv->tdls_del_peer_comp);
  64. init_completion(&tdls_priv->tdls_mgmt_comp);
  65. init_completion(&tdls_priv->tdls_link_establish_req_comp);
  66. init_completion(&tdls_priv->tdls_teardown_comp);
  67. init_completion(&tdls_priv->tdls_user_cmd_comp);
  68. init_completion(&tdls_priv->tdls_antenna_switch_comp);
  69. osif_priv->osif_tdls = tdls_priv;
  70. return QDF_STATUS_SUCCESS;
  71. }
  72. void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev)
  73. {
  74. struct vdev_osif_priv *osif_priv;
  75. osif_priv = wlan_vdev_get_ospriv(vdev);
  76. if (!osif_priv) {
  77. osif_err("osif_priv is NULL!");
  78. return;
  79. }
  80. osif_debug("deinitialize tdls os if layer private structure");
  81. if (osif_priv->osif_tdls)
  82. qdf_mem_free(osif_priv->osif_tdls);
  83. osif_priv->osif_tdls = NULL;
  84. }
  85. void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev)
  86. {
  87. ucfg_tdls_notify_reset_adapter(vdev);
  88. }
  89. int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
  90. const uint8_t *mac)
  91. {
  92. struct tdls_add_peer_params *add_peer_req;
  93. int status;
  94. struct vdev_osif_priv *osif_priv;
  95. struct osif_tdls_vdev *tdls_priv;
  96. unsigned long rc;
  97. status = wlan_cfg80211_tdls_validate_mac_addr(mac);
  98. if (status)
  99. return status;
  100. osif_debug("Add TDLS peer " QDF_MAC_ADDR_FMT,
  101. QDF_MAC_ADDR_REF(mac));
  102. add_peer_req = qdf_mem_malloc(sizeof(*add_peer_req));
  103. if (!add_peer_req)
  104. return -EINVAL;
  105. osif_priv = wlan_vdev_get_ospriv(vdev);
  106. if (!osif_priv || !osif_priv->osif_tdls) {
  107. osif_err("osif_tdls_vdev or osif_priv is NULL for the current vdev");
  108. status = -EINVAL;
  109. goto error;
  110. }
  111. tdls_priv = osif_priv->osif_tdls;
  112. add_peer_req->vdev_id = wlan_vdev_get_id(vdev);
  113. qdf_mem_copy(add_peer_req->peer_addr, mac, QDF_MAC_ADDR_SIZE);
  114. reinit_completion(&tdls_priv->tdls_add_peer_comp);
  115. status = ucfg_tdls_add_peer(vdev, add_peer_req);
  116. if (QDF_IS_STATUS_ERROR(status)) {
  117. osif_err("ucfg_tdls_add_peer returned err %d", status);
  118. status = -EIO;
  119. goto error;
  120. }
  121. rc = wait_for_completion_timeout(
  122. &tdls_priv->tdls_add_peer_comp,
  123. msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
  124. if (!rc) {
  125. osif_err("timeout for tdls add peer indication %ld", rc);
  126. status = -EPERM;
  127. goto error;
  128. }
  129. if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) {
  130. osif_err("tdls add peer failed, status:%d",
  131. tdls_priv->tdls_add_peer_status);
  132. status = -EPERM;
  133. }
  134. error:
  135. qdf_mem_free(add_peer_req);
  136. return status;
  137. }
  138. static bool
  139. is_duplicate_channel(uint8_t *arr, int index, uint8_t match)
  140. {
  141. int i;
  142. for (i = 0; i < index; i++) {
  143. if (arr[i] == match)
  144. return true;
  145. }
  146. return false;
  147. }
  148. static void
  149. tdls_calc_channels_from_staparams(struct tdls_update_peer_params *req_info,
  150. struct station_parameters *params)
  151. {
  152. int i = 0, j = 0, k = 0, no_of_channels = 0;
  153. int num_unique_channels;
  154. int next;
  155. uint8_t *dest_chans;
  156. const uint8_t *src_chans;
  157. dest_chans = req_info->supported_channels;
  158. src_chans = params->supported_channels;
  159. /* Convert (first channel , number of channels) tuple to
  160. * the total list of channels. This goes with the assumption
  161. * that if the first channel is < 14, then the next channels
  162. * are an incremental of 1 else an incremental of 4 till the number
  163. * of channels.
  164. */
  165. for (i = 0; i < params->supported_channels_len &&
  166. j < WLAN_MAC_MAX_SUPP_CHANNELS; i += 2) {
  167. int wifi_chan_index;
  168. if (!is_duplicate_channel(dest_chans, j, src_chans[i]))
  169. dest_chans[j] = src_chans[i];
  170. else
  171. continue;
  172. wifi_chan_index = ((dest_chans[j] <= WLAN_CHANNEL_14) ? 1 : 4);
  173. no_of_channels = src_chans[i + 1];
  174. osif_debug("i:%d,j:%d,k:%d,[%d]:%d,index:%d,chans_num: %d",
  175. i, j, k, j,
  176. dest_chans[j],
  177. wifi_chan_index,
  178. no_of_channels);
  179. for (k = 1; k <= no_of_channels &&
  180. j < WLAN_MAC_MAX_SUPP_CHANNELS - 1; k++) {
  181. next = dest_chans[j] + wifi_chan_index;
  182. if (!is_duplicate_channel(dest_chans, j + 1, next))
  183. dest_chans[j + 1] = next;
  184. else
  185. continue;
  186. osif_debug("i: %d, j: %d, k: %d, [%d]: %d",
  187. i, j, k, j + 1, dest_chans[j + 1]);
  188. j += 1;
  189. }
  190. }
  191. num_unique_channels = j + 1;
  192. osif_debug("Unique Channel List: supported_channels ");
  193. for (i = 0; i < num_unique_channels; i++)
  194. osif_debug("[%d]: %d,", i, dest_chans[i]);
  195. if (num_unique_channels > NUM_CHANNELS)
  196. num_unique_channels = NUM_CHANNELS;
  197. req_info->supported_channels_len = num_unique_channels;
  198. osif_debug("After removing duplcates supported_channels_len: %d",
  199. req_info->supported_channels_len);
  200. }
  201. #ifdef WLAN_FEATURE_11AX
  202. static void
  203. wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params *req_info,
  204. struct station_parameters *params)
  205. {
  206. if (params->he_capa_len < MIN_TDLS_HE_CAP_LEN) {
  207. osif_debug("he_capa_len %d less than MIN_TDLS_HE_CAP_LEN",
  208. params->he_capa_len);
  209. return;
  210. }
  211. if (!params->he_capa) {
  212. osif_debug("he_capa not present");
  213. return;
  214. }
  215. req_info->he_cap_len = params->he_capa_len;
  216. if (req_info->he_cap_len > MAX_TDLS_HE_CAP_LEN)
  217. req_info->he_cap_len = MAX_TDLS_HE_CAP_LEN;
  218. qdf_mem_copy(&req_info->he_cap, params->he_capa,
  219. req_info->he_cap_len);
  220. return;
  221. }
  222. #else
  223. static void
  224. wlan_cfg80211_tdls_extract_he_params(struct tdls_update_peer_params *req_info,
  225. struct station_parameters *params)
  226. {
  227. }
  228. #endif
  229. static void
  230. wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info,
  231. struct station_parameters *params,
  232. bool tdls_11ax_support)
  233. {
  234. int i;
  235. osif_debug("sta cap %d, uapsd_queue %d, max_sp %d",
  236. params->capability,
  237. params->uapsd_queues, params->max_sp);
  238. if (!req_info) {
  239. osif_err("reg_info is NULL");
  240. return;
  241. }
  242. req_info->capability = params->capability;
  243. req_info->uapsd_queues = params->uapsd_queues;
  244. req_info->max_sp = params->max_sp;
  245. if (params->supported_channels_len)
  246. tdls_calc_channels_from_staparams(req_info, params);
  247. if (params->supported_oper_classes_len > WLAN_MAX_SUPP_OPER_CLASSES) {
  248. osif_debug("received oper classes:%d, resetting it to max supported: %d",
  249. params->supported_oper_classes_len,
  250. WLAN_MAX_SUPP_OPER_CLASSES);
  251. params->supported_oper_classes_len = WLAN_MAX_SUPP_OPER_CLASSES;
  252. }
  253. qdf_mem_copy(req_info->supported_oper_classes,
  254. params->supported_oper_classes,
  255. params->supported_oper_classes_len);
  256. req_info->supported_oper_classes_len =
  257. params->supported_oper_classes_len;
  258. if (params->ext_capab_len)
  259. qdf_mem_copy(req_info->extn_capability, params->ext_capab,
  260. sizeof(req_info->extn_capability));
  261. if (params->ht_capa) {
  262. req_info->htcap_present = 1;
  263. qdf_mem_copy(&req_info->ht_cap, params->ht_capa,
  264. sizeof(struct htcap_cmn_ie));
  265. }
  266. req_info->supported_rates_len = params->supported_rates_len;
  267. /* Note : The Maximum sizeof supported_rates sent by the Supplicant is
  268. * 32. The supported_rates array , for all the structures propogating
  269. * till Add Sta to the firmware has to be modified , if the supplicant
  270. * (ieee80211) is modified to send more rates.
  271. */
  272. /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
  273. */
  274. if (req_info->supported_rates_len > WLAN_MAC_MAX_SUPP_RATES)
  275. req_info->supported_rates_len = WLAN_MAC_MAX_SUPP_RATES;
  276. if (req_info->supported_rates_len) {
  277. qdf_mem_copy(req_info->supported_rates,
  278. params->supported_rates,
  279. req_info->supported_rates_len);
  280. osif_debug("Supported Rates with Length %d",
  281. req_info->supported_rates_len);
  282. for (i = 0; i < req_info->supported_rates_len; i++)
  283. osif_debug("[%d]: %0x", i,
  284. req_info->supported_rates[i]);
  285. }
  286. if (params->vht_capa) {
  287. req_info->vhtcap_present = 1;
  288. qdf_mem_copy(&req_info->vht_cap, params->vht_capa,
  289. sizeof(struct vhtcap));
  290. }
  291. if (params->ht_capa || params->vht_capa ||
  292. (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
  293. req_info->is_qos_wmm_sta = true;
  294. if (params->sta_flags_set & BIT(NL80211_STA_FLAG_MFP)) {
  295. osif_debug("TDLS peer pmf capable");
  296. req_info->is_pmf = 1;
  297. }
  298. if (tdls_11ax_support)
  299. wlan_cfg80211_tdls_extract_he_params(req_info, params);
  300. else
  301. osif_debug("tdls ax disabled");
  302. }
  303. int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
  304. const uint8_t *mac,
  305. struct station_parameters *params)
  306. {
  307. struct tdls_update_peer_params *req_info;
  308. int status;
  309. struct vdev_osif_priv *osif_priv;
  310. struct osif_tdls_vdev *tdls_priv;
  311. unsigned long rc;
  312. struct wlan_objmgr_psoc *psoc;
  313. bool tdls_11ax_support = false;
  314. status = wlan_cfg80211_tdls_validate_mac_addr(mac);
  315. if (status)
  316. return status;
  317. osif_debug("Update TDLS peer " QDF_MAC_ADDR_FMT,
  318. QDF_MAC_ADDR_REF(mac));
  319. req_info = qdf_mem_malloc(sizeof(*req_info));
  320. if (!req_info)
  321. return -EINVAL;
  322. psoc = wlan_vdev_get_psoc(vdev);
  323. if (!psoc) {
  324. osif_err_rl("Invalid psoc");
  325. return -EINVAL;
  326. }
  327. tdls_11ax_support = ucfg_tdls_is_fw_11ax_capable(psoc);
  328. wlan_cfg80211_tdls_extract_params(req_info, params, tdls_11ax_support);
  329. osif_priv = wlan_vdev_get_ospriv(vdev);
  330. if (!osif_priv || !osif_priv->osif_tdls) {
  331. osif_err("osif priv or tdls priv is NULL");
  332. status = -EINVAL;
  333. goto error;
  334. }
  335. tdls_priv = osif_priv->osif_tdls;
  336. req_info->vdev_id = wlan_vdev_get_id(vdev);
  337. qdf_mem_copy(req_info->peer_addr, mac, QDF_MAC_ADDR_SIZE);
  338. reinit_completion(&tdls_priv->tdls_add_peer_comp);
  339. status = ucfg_tdls_update_peer(vdev, req_info);
  340. if (QDF_IS_STATUS_ERROR(status)) {
  341. osif_err("ucfg_tdls_update_peer returned err %d", status);
  342. status = -EIO;
  343. goto error;
  344. }
  345. rc = wait_for_completion_timeout(
  346. &tdls_priv->tdls_add_peer_comp,
  347. msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
  348. if (!rc) {
  349. osif_err("timeout for tdls update peer indication %ld", rc);
  350. status = -EPERM;
  351. goto error;
  352. }
  353. if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) {
  354. osif_err("tdls update peer failed, status:%d",
  355. tdls_priv->tdls_add_peer_status);
  356. status = -EPERM;
  357. }
  358. error:
  359. qdf_mem_free(req_info);
  360. return status;
  361. }
  362. static char *tdls_oper_to_str(enum nl80211_tdls_operation oper)
  363. {
  364. switch (oper) {
  365. case NL80211_TDLS_ENABLE_LINK:
  366. return "TDLS_ENABLE_LINK";
  367. case NL80211_TDLS_DISABLE_LINK:
  368. return "TDLS_DISABLE_LINK";
  369. case NL80211_TDLS_TEARDOWN:
  370. return "TDLS_TEARDOWN";
  371. case NL80211_TDLS_SETUP:
  372. return "TDLS_SETUP";
  373. default:
  374. return "UNKNOWN:ERR";
  375. }
  376. }
  377. static enum tdls_command_type tdls_oper_to_cmd(enum nl80211_tdls_operation oper)
  378. {
  379. if (oper == NL80211_TDLS_ENABLE_LINK)
  380. return TDLS_CMD_ENABLE_LINK;
  381. else if (oper == NL80211_TDLS_DISABLE_LINK)
  382. return TDLS_CMD_DISABLE_LINK;
  383. else if (oper == NL80211_TDLS_TEARDOWN)
  384. return TDLS_CMD_REMOVE_FORCE_PEER;
  385. else if (oper == NL80211_TDLS_SETUP)
  386. return TDLS_CMD_CONFIG_FORCE_PEER;
  387. else
  388. return 0;
  389. }
  390. int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev,
  391. uint32_t trigger_mode)
  392. {
  393. enum tdls_feature_mode tdls_mode;
  394. struct tdls_set_mode_params set_mode_params;
  395. int status;
  396. if (!vdev)
  397. return -EINVAL;
  398. switch (trigger_mode) {
  399. case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT:
  400. tdls_mode = TDLS_SUPPORT_EXP_TRIG_ONLY;
  401. return 0;
  402. case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL:
  403. tdls_mode = TDLS_SUPPORT_EXT_CONTROL;
  404. break;
  405. case WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT:
  406. tdls_mode = TDLS_SUPPORT_IMP_MODE;
  407. return 0;
  408. default:
  409. osif_err("Invalid TDLS trigger mode");
  410. return -EINVAL;
  411. }
  412. osif_notice("cfg80211 tdls trigger mode %d", trigger_mode);
  413. set_mode_params.source = TDLS_SET_MODE_SOURCE_USER;
  414. set_mode_params.tdls_mode = tdls_mode;
  415. set_mode_params.update_last = false;
  416. set_mode_params.vdev = vdev;
  417. status = ucfg_tdls_set_operating_mode(&set_mode_params);
  418. return status;
  419. }
  420. int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
  421. const uint8_t *peer,
  422. enum nl80211_tdls_operation oper)
  423. {
  424. struct vdev_osif_priv *osif_priv;
  425. struct osif_tdls_vdev *tdls_priv;
  426. int status;
  427. unsigned long rc;
  428. enum tdls_command_type cmd;
  429. status = wlan_cfg80211_tdls_validate_mac_addr(peer);
  430. if (status)
  431. return status;
  432. if (NL80211_TDLS_DISCOVERY_REQ == oper) {
  433. osif_warn(
  434. "We don't support in-driver setup/teardown/discovery");
  435. return -ENOTSUPP;
  436. }
  437. osif_debug("%s start", tdls_oper_to_str(oper));
  438. cmd = tdls_oper_to_cmd(oper);
  439. switch (oper) {
  440. case NL80211_TDLS_ENABLE_LINK:
  441. case NL80211_TDLS_TEARDOWN:
  442. case NL80211_TDLS_SETUP:
  443. status = ucfg_tdls_oper(vdev, peer, cmd);
  444. if (QDF_IS_STATUS_ERROR(status)) {
  445. osif_err("%s fail %d",
  446. tdls_oper_to_str(oper), status);
  447. status = -EIO;
  448. goto error;
  449. }
  450. break;
  451. case NL80211_TDLS_DISABLE_LINK:
  452. osif_priv = wlan_vdev_get_ospriv(vdev);
  453. if (!osif_priv || !osif_priv->osif_tdls) {
  454. osif_err("osif priv or tdls priv is NULL");
  455. status = -EINVAL;
  456. goto error;
  457. }
  458. tdls_priv = osif_priv->osif_tdls;
  459. reinit_completion(&tdls_priv->tdls_del_peer_comp);
  460. status = ucfg_tdls_oper(vdev, peer, cmd);
  461. if (QDF_IS_STATUS_ERROR(status)) {
  462. osif_err("ucfg_tdls_disable_link fail %d", status);
  463. status = -EIO;
  464. goto error;
  465. }
  466. rc = wait_for_completion_timeout(
  467. &tdls_priv->tdls_del_peer_comp,
  468. msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
  469. if (!rc) {
  470. osif_err("timeout for tdls disable link %ld", rc);
  471. status = -EPERM;
  472. }
  473. break;
  474. default:
  475. osif_err("unsupported event %d", oper);
  476. status = -ENOTSUPP;
  477. }
  478. error:
  479. return status;
  480. }
  481. void wlan_cfg80211_tdls_rx_callback(void *user_data,
  482. struct tdls_rx_mgmt_frame *rx_frame)
  483. {
  484. struct wlan_objmgr_psoc *psoc;
  485. struct wlan_objmgr_vdev *vdev;
  486. struct vdev_osif_priv *osif_priv;
  487. struct wireless_dev *wdev;
  488. psoc = user_data;
  489. if (!psoc) {
  490. osif_err("psoc is null");
  491. return;
  492. }
  493. vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
  494. rx_frame->vdev_id, WLAN_TDLS_NB_ID);
  495. if (!vdev) {
  496. osif_err("vdev is null");
  497. return;
  498. }
  499. osif_priv = wlan_vdev_get_ospriv(vdev);
  500. if (!osif_priv) {
  501. osif_err("osif_priv is null");
  502. goto fail;
  503. }
  504. wdev = osif_priv->wdev;
  505. if (!wdev) {
  506. osif_err("wdev is null");
  507. goto fail;
  508. }
  509. osif_notice("Indicate frame over nl80211, vdev id:%d, idx:%d",
  510. rx_frame->vdev_id, wdev->netdev->ifindex);
  511. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
  512. cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100,
  513. rx_frame->buf, rx_frame->frame_len,
  514. NL80211_RXMGMT_FLAG_ANSWERED);
  515. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
  516. cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100,
  517. rx_frame->buf, rx_frame->frame_len,
  518. NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC);
  519. #else
  520. cfg80211_rx_mgmt(wdev, rx_frame->rx_freq, rx_frame->rx_rssi * 100,
  521. rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC);
  522. #endif /* LINUX_VERSION_CODE */
  523. fail:
  524. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  525. }
  526. static void wlan_cfg80211_update_tdls_peers_rssi(struct wlan_objmgr_vdev *vdev)
  527. {
  528. int ret = 0, i;
  529. struct stats_event *rssi_info;
  530. struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
  531. rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(
  532. vdev, bcast_mac.bytes,
  533. &ret);
  534. if (ret || !rssi_info) {
  535. osif_err("get peer rssi fail");
  536. wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
  537. return;
  538. }
  539. for (i = 0; i < rssi_info->num_peer_stats; i++)
  540. ucfg_tdls_set_rssi(vdev, rssi_info->peer_stats[i].peer_macaddr,
  541. rssi_info->peer_stats[i].peer_rssi);
  542. wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
  543. }
  544. int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
  545. char *buf, int buflen)
  546. {
  547. struct vdev_osif_priv *osif_priv;
  548. struct osif_tdls_vdev *tdls_priv;
  549. int32_t len;
  550. QDF_STATUS status;
  551. unsigned long rc;
  552. osif_priv = wlan_vdev_get_ospriv(vdev);
  553. if (!osif_priv || !osif_priv->osif_tdls) {
  554. osif_err("osif_tdls_vdev or osif_priv is NULL for the current vdev");
  555. return -EINVAL;
  556. }
  557. tdls_priv = osif_priv->osif_tdls;
  558. wlan_cfg80211_update_tdls_peers_rssi(vdev);
  559. reinit_completion(&tdls_priv->tdls_user_cmd_comp);
  560. status = ucfg_tdls_get_all_peers(vdev, buf, buflen);
  561. if (QDF_IS_STATUS_ERROR(status)) {
  562. osif_err("ucfg_tdls_get_all_peers failed err %d", status);
  563. len = scnprintf(buf, buflen,
  564. "\nucfg_tdls_send_mgmt failed\n");
  565. goto error_get_tdls_peers;
  566. }
  567. osif_debug("Wait for tdls_user_cmd_comp. Timeout %u ms",
  568. WAIT_TIME_FOR_TDLS_USER_CMD);
  569. rc = wait_for_completion_timeout(
  570. &tdls_priv->tdls_user_cmd_comp,
  571. msecs_to_jiffies(WAIT_TIME_FOR_TDLS_USER_CMD));
  572. if (0 == rc) {
  573. osif_err("TDLS user cmd get all peers timed out rc %ld",
  574. rc);
  575. len = scnprintf(buf, buflen,
  576. "\nTDLS user cmd get all peers timed out\n");
  577. goto error_get_tdls_peers;
  578. }
  579. len = tdls_priv->tdls_user_cmd_len;
  580. error_get_tdls_peers:
  581. return len;
  582. }
  583. int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
  584. const uint8_t *peer_mac,
  585. uint8_t action_code, uint8_t dialog_token,
  586. uint16_t status_code, uint32_t peer_capability,
  587. const uint8_t *buf, size_t len)
  588. {
  589. struct tdls_action_frame_request mgmt_req;
  590. struct vdev_osif_priv *osif_priv;
  591. struct osif_tdls_vdev *tdls_priv;
  592. int status;
  593. unsigned long rc;
  594. struct tdls_set_responder_req set_responder;
  595. status = wlan_cfg80211_tdls_validate_mac_addr(peer_mac);
  596. if (status)
  597. return status;
  598. osif_priv = wlan_vdev_get_ospriv(vdev);
  599. if (!osif_priv || !osif_priv->osif_tdls) {
  600. osif_err("osif priv or tdls priv is NULL");
  601. return -EINVAL;
  602. }
  603. tdls_priv = osif_priv->osif_tdls;
  604. /* make sure doesn't call send_mgmt() while it is pending */
  605. if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) {
  606. osif_err(QDF_MAC_ADDR_FMT " action %d couldn't sent, as one is pending. return EBUSY",
  607. QDF_MAC_ADDR_REF(peer_mac), action_code);
  608. return -EBUSY;
  609. }
  610. /* Reset TDLS VDEV magic */
  611. tdls_priv->mgmt_tx_completion_status = TDLS_VDEV_MAGIC;
  612. /*prepare the request */
  613. /* Validate the management Request */
  614. mgmt_req.chk_frame.action_code = action_code;
  615. qdf_mem_copy(mgmt_req.chk_frame.peer_mac, peer_mac, QDF_MAC_ADDR_SIZE);
  616. mgmt_req.chk_frame.dialog_token = dialog_token;
  617. mgmt_req.chk_frame.action_code = action_code;
  618. mgmt_req.chk_frame.status_code = status_code;
  619. mgmt_req.chk_frame.len = len;
  620. mgmt_req.vdev = vdev;
  621. mgmt_req.vdev_id = wlan_vdev_get_id(vdev);
  622. mgmt_req.session_id = mgmt_req.vdev_id;
  623. /* populate management req params */
  624. qdf_mem_copy(mgmt_req.tdls_mgmt.peer_mac.bytes,
  625. peer_mac, QDF_MAC_ADDR_SIZE);
  626. mgmt_req.tdls_mgmt.dialog = dialog_token;
  627. mgmt_req.tdls_mgmt.frame_type = action_code;
  628. mgmt_req.tdls_mgmt.len = len;
  629. mgmt_req.tdls_mgmt.peer_capability = peer_capability;
  630. mgmt_req.tdls_mgmt.status_code = mgmt_req.chk_frame.status_code;
  631. /*populate the additional IE's */
  632. mgmt_req.cmd_buf = buf;
  633. mgmt_req.len = len;
  634. reinit_completion(&tdls_priv->tdls_mgmt_comp);
  635. status = ucfg_tdls_send_mgmt_frame(&mgmt_req);
  636. if (QDF_IS_STATUS_ERROR(status)) {
  637. osif_err("ucfg_tdls_send_mgmt failed err %d", status);
  638. status = -EIO;
  639. tdls_priv->mgmt_tx_completion_status = false;
  640. goto error_mgmt_req;
  641. }
  642. osif_debug("Wait for tdls_mgmt_comp. Timeout %u ms",
  643. WAIT_TIME_FOR_TDLS_MGMT);
  644. rc = wait_for_completion_timeout(
  645. &tdls_priv->tdls_mgmt_comp,
  646. msecs_to_jiffies(WAIT_TIME_FOR_TDLS_MGMT));
  647. if ((0 == rc) || (QDF_STATUS_SUCCESS !=
  648. tdls_priv->mgmt_tx_completion_status)) {
  649. osif_err("%s rc %ld mgmtTxCompletionStatus %u",
  650. !rc ? "Mgmt Tx Completion timed out" :
  651. "Mgmt Tx Completion failed",
  652. rc, tdls_priv->mgmt_tx_completion_status);
  653. tdls_priv->mgmt_tx_completion_status = false;
  654. status = -EINVAL;
  655. goto error_mgmt_req;
  656. }
  657. osif_debug("Mgmt Tx Completion status %ld TxCompletion %u",
  658. rc, tdls_priv->mgmt_tx_completion_status);
  659. if (TDLS_SETUP_RESPONSE == action_code ||
  660. TDLS_SETUP_CONFIRM == action_code) {
  661. qdf_mem_copy(set_responder.peer_mac, peer_mac,
  662. QDF_MAC_ADDR_SIZE);
  663. set_responder.vdev = vdev;
  664. if (TDLS_SETUP_RESPONSE == action_code)
  665. set_responder.responder = false;
  666. if (TDLS_SETUP_CONFIRM == action_code)
  667. set_responder.responder = true;
  668. ucfg_tdls_responder(&set_responder);
  669. }
  670. error_mgmt_req:
  671. return status;
  672. }
  673. int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode)
  674. {
  675. struct vdev_osif_priv *osif_priv;
  676. struct osif_tdls_vdev *tdls_priv;
  677. int ret;
  678. unsigned long rc;
  679. if (!vdev) {
  680. osif_err("vdev is NULL");
  681. return -EAGAIN;
  682. }
  683. osif_priv = wlan_vdev_get_ospriv(vdev);
  684. if (!osif_priv || !osif_priv->osif_tdls) {
  685. osif_err("osif priv or tdls priv is NULL");
  686. ret = -EINVAL;
  687. goto error;
  688. }
  689. tdls_priv = osif_priv->osif_tdls;
  690. reinit_completion(&tdls_priv->tdls_antenna_switch_comp);
  691. ret = ucfg_tdls_antenna_switch(vdev, mode);
  692. if (QDF_IS_STATUS_ERROR(ret)) {
  693. osif_err("ucfg_tdls_antenna_switch failed err %d", ret);
  694. ret = -EAGAIN;
  695. goto error;
  696. }
  697. rc = wait_for_completion_timeout(
  698. &tdls_priv->tdls_antenna_switch_comp,
  699. msecs_to_jiffies(WAIT_TIME_FOR_TDLS_ANTENNA_SWITCH));
  700. if (!rc) {
  701. osif_err("timeout for tdls antenna switch %ld", rc);
  702. ret = -EAGAIN;
  703. goto error;
  704. }
  705. ret = tdls_priv->tdls_antenna_switch_status;
  706. osif_debug("tdls antenna switch status:%d", ret);
  707. error:
  708. return ret;
  709. }
  710. static void
  711. wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind)
  712. {
  713. struct vdev_osif_priv *osif_vdev;
  714. osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
  715. cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
  716. ind->peer_mac, NL80211_TDLS_DISCOVERY_REQ,
  717. false, GFP_KERNEL);
  718. }
  719. static void
  720. wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind)
  721. {
  722. struct vdev_osif_priv *osif_vdev;
  723. osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
  724. osif_debug("Indication to request TDLS setup");
  725. cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
  726. ind->peer_mac, NL80211_TDLS_SETUP, false,
  727. GFP_KERNEL);
  728. }
  729. static void
  730. wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind)
  731. {
  732. struct vdev_osif_priv *osif_vdev;
  733. osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
  734. osif_debug("Teardown reason %d", ind->reason);
  735. cfg80211_tdls_oper_request(osif_vdev->wdev->netdev,
  736. ind->peer_mac, NL80211_TDLS_TEARDOWN,
  737. ind->reason, GFP_KERNEL);
  738. }
  739. void wlan_cfg80211_tdls_event_callback(void *user_data,
  740. enum tdls_event_type type,
  741. struct tdls_osif_indication *ind)
  742. {
  743. struct vdev_osif_priv *osif_vdev;
  744. struct osif_tdls_vdev *tdls_priv;
  745. if (!ind || !ind->vdev) {
  746. osif_err("ind: %pK", ind);
  747. return;
  748. }
  749. osif_vdev = wlan_vdev_get_ospriv(ind->vdev);
  750. if (!osif_vdev || !osif_vdev->osif_tdls) {
  751. osif_err("osif priv or tdls priv is NULL");
  752. return;
  753. }
  754. tdls_priv = osif_vdev->osif_tdls;
  755. switch (type) {
  756. case TDLS_EVENT_MGMT_TX_ACK_CNF:
  757. tdls_priv->mgmt_tx_completion_status = ind->status;
  758. complete(&tdls_priv->tdls_mgmt_comp);
  759. break;
  760. case TDLS_EVENT_ADD_PEER:
  761. tdls_priv->tdls_add_peer_status = ind->status;
  762. complete(&tdls_priv->tdls_add_peer_comp);
  763. break;
  764. case TDLS_EVENT_DEL_PEER:
  765. complete(&tdls_priv->tdls_del_peer_comp);
  766. break;
  767. case TDLS_EVENT_DISCOVERY_REQ:
  768. wlan_cfg80211_tdls_indicate_discovery(ind);
  769. break;
  770. case TDLS_EVENT_TEARDOWN_REQ:
  771. wlan_cfg80211_tdls_indicate_teardown(ind);
  772. break;
  773. case TDLS_EVENT_SETUP_REQ:
  774. wlan_cfg80211_tdls_indicate_setup(ind);
  775. break;
  776. case TDLS_EVENT_USER_CMD:
  777. tdls_priv->tdls_user_cmd_len = ind->status;
  778. complete(&tdls_priv->tdls_user_cmd_comp);
  779. break;
  780. case TDLS_EVENT_ANTENNA_SWITCH:
  781. tdls_priv->tdls_antenna_switch_status = ind->status;
  782. complete(&tdls_priv->tdls_antenna_switch_comp);
  783. default:
  784. break;
  785. }
  786. }