wlan_tdls_ucfg_api.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. /*
  2. * Copyright (c) 2017-2019 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: wlan_tdls_ucfg_api.c
  20. *
  21. * TDLS north bound interface definitions
  22. */
  23. #include <wlan_tdls_ucfg_api.h>
  24. #include <wlan_tdls_tgt_api.h>
  25. #include "../../core/src/wlan_tdls_main.h"
  26. #include "../../core/src/wlan_tdls_cmds_process.h"
  27. #include "../../core/src/wlan_tdls_ct.h"
  28. #include "../../core/src/wlan_tdls_mgmt.h"
  29. #include <wlan_objmgr_global_obj.h>
  30. #include <wlan_objmgr_cmn.h>
  31. #include "wlan_policy_mgr_api.h"
  32. #include "wlan_scan_ucfg_api.h"
  33. #include "wlan_tdls_cfg.h"
  34. #include "cfg_ucfg_api.h"
  35. QDF_STATUS ucfg_tdls_init(void)
  36. {
  37. QDF_STATUS status;
  38. tdls_notice("tdls module dispatcher init");
  39. status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_TDLS,
  40. tdls_psoc_obj_create_notification, NULL);
  41. if (QDF_IS_STATUS_ERROR(status)) {
  42. tdls_err("Failed to register psoc create handler for tdls");
  43. return status;
  44. }
  45. status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS,
  46. tdls_psoc_obj_destroy_notification, NULL);
  47. if (QDF_IS_STATUS_ERROR(status)) {
  48. tdls_err("Failed to register psoc delete handler for tdls");
  49. goto fail_delete_psoc;
  50. }
  51. status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_TDLS,
  52. tdls_vdev_obj_create_notification, NULL);
  53. if (QDF_IS_STATUS_ERROR(status)) {
  54. tdls_err("Failed to register vdev create handler for tdls");
  55. goto fail_create_vdev;
  56. }
  57. status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_TDLS,
  58. tdls_vdev_obj_destroy_notification, NULL);
  59. if (QDF_IS_STATUS_ERROR(status)) {
  60. tdls_err("Failed to register vdev create handler for tdls");
  61. goto fail_delete_vdev;
  62. }
  63. tdls_notice("tdls module dispatcher init done");
  64. return status;
  65. fail_delete_vdev:
  66. wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_TDLS,
  67. tdls_vdev_obj_create_notification, NULL);
  68. fail_create_vdev:
  69. wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS,
  70. tdls_psoc_obj_destroy_notification, NULL);
  71. fail_delete_psoc:
  72. wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_TDLS,
  73. tdls_psoc_obj_create_notification, NULL);
  74. return status;
  75. }
  76. QDF_STATUS ucfg_tdls_deinit(void)
  77. {
  78. QDF_STATUS ret;
  79. tdls_notice("tdls module dispatcher deinit");
  80. ret = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_TDLS,
  81. tdls_psoc_obj_create_notification, NULL);
  82. if (QDF_IS_STATUS_ERROR(ret))
  83. tdls_err("Failed to unregister psoc create handler");
  84. ret = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS,
  85. tdls_psoc_obj_destroy_notification, NULL);
  86. if (QDF_IS_STATUS_ERROR(ret))
  87. tdls_err("Failed to unregister psoc delete handler");
  88. ret = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_TDLS,
  89. tdls_vdev_obj_create_notification, NULL);
  90. if (QDF_IS_STATUS_ERROR(ret))
  91. tdls_err("Failed to unregister vdev create handler");
  92. ret = wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_TDLS,
  93. tdls_vdev_obj_destroy_notification, NULL);
  94. if (QDF_IS_STATUS_ERROR(ret))
  95. tdls_err("Failed to unregister vdev delete handler");
  96. return ret;
  97. }
  98. /**
  99. * tdls_update_feature_flag() - update tdls feature flag
  100. * @tdls_soc_obj: pointer to tdls psoc object
  101. *
  102. * This function updates tdls feature flag
  103. */
  104. static void
  105. tdls_update_feature_flag(struct tdls_soc_priv_obj *tdls_soc_obj)
  106. {
  107. tdls_soc_obj->tdls_configs.tdls_feature_flags =
  108. ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ?
  109. 1 << TDLS_FEATURE_OFF_CHANNEL : 0) |
  110. (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ?
  111. 1 << TDLS_FEATURE_WMM : 0) |
  112. (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ?
  113. 1 << TDLS_FEATURE_BUFFER_STA : 0) |
  114. (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ?
  115. 1 << TDLS_FEATURE_SLEEP_STA : 0) |
  116. (tdls_soc_obj->tdls_configs.tdls_scan_enable ?
  117. 1 << TDLS_FEATURE_SCAN : 0) |
  118. (tdls_soc_obj->tdls_configs.tdls_support_enable ?
  119. 1 << TDLS_FEATURE_ENABLE : 0) |
  120. (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ?
  121. 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) |
  122. (tdls_soc_obj->tdls_configs.tdls_external_control ?
  123. 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0));
  124. }
  125. /**
  126. * tdls_object_init_params() - init parameters for tdls object
  127. * @tdls_soc_obj: pointer to tdls psoc object
  128. *
  129. * This function init parameters for tdls object
  130. */
  131. static QDF_STATUS tdls_object_init_params(
  132. struct tdls_soc_priv_obj *tdls_soc_obj)
  133. {
  134. struct wlan_objmgr_psoc *psoc;
  135. if (!tdls_soc_obj) {
  136. tdls_err("invalid param");
  137. return QDF_STATUS_E_INVAL;
  138. }
  139. psoc = tdls_soc_obj->soc;
  140. if (!psoc) {
  141. tdls_err("invalid psoc object");
  142. return QDF_STATUS_E_INVAL;
  143. }
  144. tdls_soc_obj->tdls_configs.tdls_tx_states_period =
  145. cfg_get(psoc, CFG_TDLS_TX_STATS_PERIOD);
  146. tdls_soc_obj->tdls_configs.tdls_tx_pkt_threshold =
  147. cfg_get(psoc, CFG_TDLS_TX_PACKET_THRESHOLD);
  148. tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold =
  149. cfg_get(psoc, CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD);
  150. tdls_soc_obj->tdls_configs.tdls_max_discovery_attempt =
  151. cfg_get(psoc, CFG_TDLS_MAX_DISCOVERY_ATTEMPT);
  152. tdls_soc_obj->tdls_configs.tdls_idle_timeout =
  153. cfg_get(psoc, CFG_TDLS_IDLE_TIMEOUT);
  154. tdls_soc_obj->tdls_configs.tdls_idle_pkt_threshold =
  155. cfg_get(psoc, CFG_TDLS_IDLE_PACKET_THRESHOLD);
  156. tdls_soc_obj->tdls_configs.tdls_rssi_trigger_threshold =
  157. cfg_get(psoc, CFG_TDLS_RSSI_TRIGGER_THRESHOLD);
  158. tdls_soc_obj->tdls_configs.tdls_rssi_teardown_threshold =
  159. cfg_get(psoc, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD);
  160. tdls_soc_obj->tdls_configs.tdls_rssi_delta =
  161. cfg_get(psoc, CFG_TDLS_RSSI_DELTA);
  162. tdls_soc_obj->tdls_configs.tdls_uapsd_mask =
  163. cfg_get(psoc, CFG_TDLS_QOS_WMM_UAPSD_MASK);
  164. tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time =
  165. cfg_get(psoc, CFG_TDLS_PUAPSD_INACT_TIME);
  166. tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window =
  167. cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW);
  168. tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout =
  169. cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT);
  170. tdls_soc_obj->tdls_configs.tdls_pre_off_chan_num =
  171. cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM);
  172. tdls_soc_obj->tdls_configs.tdls_pre_off_chan_bw =
  173. cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_BW);
  174. tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold =
  175. cfg_get(psoc, CFG_TDLS_PEER_KICKOUT_THRESHOLD);
  176. tdls_soc_obj->tdls_configs.delayed_trig_framint =
  177. cfg_get(psoc, CFG_TL_DELAYED_TRGR_FRM_INTERVAL);
  178. tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable =
  179. cfg_get(psoc, CFG_TDLS_WMM_MODE_ENABLE);
  180. tdls_soc_obj->tdls_configs.tdls_off_chan_enable =
  181. cfg_get(psoc, CFG_TDLS_OFF_CHANNEL_ENABLED);
  182. tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable =
  183. cfg_get(psoc, CFG_TDLS_BUF_STA_ENABLED);
  184. tdls_soc_obj->tdls_configs.tdls_scan_enable =
  185. cfg_get(psoc, CFG_TDLS_SCAN_ENABLE);
  186. tdls_soc_obj->tdls_configs.tdls_support_enable =
  187. cfg_get(psoc, CFG_TDLS_SUPPORT_ENABLE);
  188. tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable =
  189. cfg_get(psoc, CFG_TDLS_IMPLICIT_TRIGGER);
  190. tdls_soc_obj->tdls_configs.tdls_external_control =
  191. cfg_get(psoc, CFG_TDLS_EXTERNAL_CONTROL);
  192. tdls_update_feature_flag(tdls_soc_obj);
  193. return QDF_STATUS_SUCCESS;
  194. }
  195. static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj)
  196. {
  197. tdls_object_init_params(soc_obj);
  198. soc_obj->connected_peer_count = 0;
  199. soc_obj->tdls_nss_switch_in_progress = false;
  200. soc_obj->tdls_teardown_peers_cnt = 0;
  201. soc_obj->tdls_nss_teardown_complete = false;
  202. soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN;
  203. soc_obj->enable_tdls_connection_tracker = false;
  204. soc_obj->tdls_external_peer_count = 0;
  205. soc_obj->tdls_disable_in_progress = false;
  206. qdf_spinlock_create(&soc_obj->tdls_ct_spinlock);
  207. return QDF_STATUS_SUCCESS;
  208. }
  209. static QDF_STATUS tdls_global_deinit(struct tdls_soc_priv_obj *soc_obj)
  210. {
  211. qdf_spinlock_destroy(&soc_obj->tdls_ct_spinlock);
  212. return QDF_STATUS_SUCCESS;
  213. }
  214. QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc)
  215. {
  216. QDF_STATUS status;
  217. struct tdls_soc_priv_obj *soc_obj;
  218. tdls_debug("tdls psoc open");
  219. soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
  220. WLAN_UMAC_COMP_TDLS);
  221. if (!soc_obj) {
  222. tdls_err("Failed to get tdls psoc component");
  223. return QDF_STATUS_E_FAILURE;
  224. }
  225. status = tdls_global_init(soc_obj);
  226. return status;
  227. }
  228. QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
  229. struct tdls_start_params *req)
  230. {
  231. struct tdls_soc_priv_obj *soc_obj;
  232. uint32_t tdls_feature_flags;
  233. struct policy_mgr_tdls_cbacks tdls_pm_call_backs;
  234. uint8_t sta_idx;
  235. tdls_debug("tdls update config ");
  236. if (!psoc || !req) {
  237. tdls_err("psoc: 0x%pK, req: 0x%pK", psoc, req);
  238. return QDF_STATUS_E_FAILURE;
  239. }
  240. soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
  241. WLAN_UMAC_COMP_TDLS);
  242. if (!soc_obj) {
  243. tdls_err("Failed to get tdls psoc component");
  244. return QDF_STATUS_E_FAILURE;
  245. }
  246. soc_obj->tdls_rx_cb = req->tdls_rx_cb;
  247. soc_obj->tdls_rx_cb_data = req->tdls_rx_cb_data;
  248. soc_obj->tdls_wmm_cb = req->tdls_wmm_cb;
  249. soc_obj->tdls_wmm_cb_data = req->tdls_wmm_cb_data;
  250. soc_obj->tdls_event_cb = req->tdls_event_cb;
  251. soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data;
  252. /* Save callbacks to register/deregister TDLS sta with datapath */
  253. soc_obj->tdls_reg_peer = req->tdls_reg_peer;
  254. soc_obj->tdls_dereg_peer = req->tdls_dereg_peer;
  255. soc_obj->tdls_peer_context = req->tdls_peer_context;
  256. /* Save legacy PE/WMA commands in TDLS soc object */
  257. soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req;
  258. soc_obj->tdls_add_sta_req = req->tdls_add_sta_req;
  259. soc_obj->tdls_del_sta_req = req->tdls_del_sta_req;
  260. soc_obj->tdls_update_peer_state = req->tdls_update_peer_state;
  261. soc_obj->tdls_del_all_peers = req->tdls_del_all_peers;
  262. soc_obj->tdls_update_dp_vdev_flags = req->tdls_update_dp_vdev_flags;
  263. soc_obj->tdls_dp_vdev_update = req->tdls_dp_vdev_update;
  264. tdls_pm_call_backs.tdls_notify_increment_session =
  265. tdls_notify_increment_session;
  266. tdls_pm_call_backs.tdls_notify_decrement_session =
  267. tdls_notify_decrement_session;
  268. if (QDF_STATUS_SUCCESS != policy_mgr_register_tdls_cb(
  269. psoc, &tdls_pm_call_backs)) {
  270. tdls_err("policy manager callback registration failed ");
  271. return QDF_STATUS_E_FAILURE;
  272. }
  273. tdls_update_feature_flag(soc_obj);
  274. tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags;
  275. if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags))
  276. soc_obj->tdls_current_mode = TDLS_SUPPORT_EXP_TRIG_ONLY;
  277. else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags))
  278. soc_obj->tdls_current_mode = TDLS_SUPPORT_EXT_CONTROL;
  279. else
  280. soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE;
  281. soc_obj->tdls_last_mode = soc_obj->tdls_current_mode;
  282. if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags) ||
  283. TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags) ||
  284. TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags))
  285. soc_obj->max_num_tdls_sta =
  286. WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM;
  287. else
  288. soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM;
  289. for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) {
  290. soc_obj->tdls_conn_info[sta_idx].sta_id = INVALID_TDLS_PEER_ID;
  291. soc_obj->tdls_conn_info[sta_idx].index =
  292. INVALID_TDLS_PEER_INDEX;
  293. soc_obj->tdls_conn_info[sta_idx].session_id = 255;
  294. qdf_mem_zero(&soc_obj->tdls_conn_info[sta_idx].peer_mac,
  295. QDF_MAC_ADDR_SIZE);
  296. }
  297. return QDF_STATUS_SUCCESS;
  298. }
  299. QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc)
  300. {
  301. QDF_STATUS status;
  302. tdls_notice("psoc tdls enable: 0x%pK", psoc);
  303. if (!psoc) {
  304. tdls_err("NULL psoc");
  305. return QDF_STATUS_E_FAILURE;
  306. }
  307. status = tgt_tdls_register_ev_handler(psoc);
  308. if (status != QDF_STATUS_SUCCESS)
  309. return status;
  310. status = wlan_serialization_register_comp_info_cb(psoc,
  311. WLAN_UMAC_COMP_TDLS,
  312. WLAN_SER_CMD_SCAN,
  313. tdls_scan_serialization_comp_info_cb);
  314. if (QDF_STATUS_SUCCESS != status) {
  315. tdls_err("Serialize scan cmd register failed ");
  316. return status;
  317. }
  318. /* register callbacks with tx/rx mgmt */
  319. status = tdls_mgmt_rx_ops(psoc, true);
  320. if (status != QDF_STATUS_SUCCESS)
  321. tdls_err("Failed to register mgmt rx callback, status:%d",
  322. status);
  323. return status;
  324. }
  325. QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc)
  326. {
  327. QDF_STATUS status;
  328. struct tdls_soc_priv_obj *soc_obj = NULL;
  329. tdls_notice("psoc tdls disable: 0x%pK", psoc);
  330. if (!psoc) {
  331. tdls_err("NULL psoc");
  332. return QDF_STATUS_E_FAILURE;
  333. }
  334. status = tgt_tdls_unregister_ev_handler(psoc);
  335. if (QDF_IS_STATUS_ERROR(status))
  336. tdls_err("Failed to unregister tdls event handler");
  337. status = tdls_mgmt_rx_ops(psoc, false);
  338. if (QDF_IS_STATUS_ERROR(status))
  339. tdls_err("Failed to unregister mgmt rx callback");
  340. soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
  341. WLAN_UMAC_COMP_TDLS);
  342. if (!soc_obj) {
  343. tdls_err("Failed to get tdls psoc component");
  344. return QDF_STATUS_E_FAILURE;
  345. }
  346. soc_obj->tdls_event_cb = NULL;
  347. soc_obj->tdls_evt_cb_data = NULL;
  348. return status;
  349. }
  350. QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc)
  351. {
  352. QDF_STATUS status = QDF_STATUS_SUCCESS;
  353. struct tdls_soc_priv_obj *tdls_soc;
  354. tdls_notice("tdls psoc close");
  355. tdls_soc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
  356. WLAN_UMAC_COMP_TDLS);
  357. if (!tdls_soc) {
  358. tdls_err("Failed to get tdls psoc component");
  359. return QDF_STATUS_E_FAILURE;
  360. }
  361. status = tdls_global_deinit(tdls_soc);
  362. return status;
  363. }
  364. QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
  365. struct tdls_add_peer_params *add_peer_req)
  366. {
  367. struct scheduler_msg msg = {0, };
  368. struct tdls_add_peer_request *req;
  369. QDF_STATUS status;
  370. if (!vdev || !add_peer_req) {
  371. tdls_err("vdev: %pK, req %pK", vdev, add_peer_req);
  372. return QDF_STATUS_E_NULL_VALUE;
  373. }
  374. tdls_debug("vdevid: %d, peertype: %d",
  375. add_peer_req->vdev_id, add_peer_req->peer_type);
  376. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  377. if (QDF_IS_STATUS_ERROR(status)) {
  378. tdls_err("can't get vdev");
  379. return status;
  380. }
  381. req = qdf_mem_malloc(sizeof(*req));
  382. if (!req) {
  383. tdls_err("mem allocate fail");
  384. status = QDF_STATUS_E_NOMEM;
  385. goto dec_ref;
  386. }
  387. qdf_mem_copy(&req->add_peer_req, add_peer_req, sizeof(*add_peer_req));
  388. req->vdev = vdev;
  389. msg.bodyptr = req;
  390. msg.callback = tdls_process_cmd;
  391. msg.type = TDLS_CMD_ADD_STA;
  392. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  393. QDF_MODULE_ID_TDLS,
  394. QDF_MODULE_ID_OS_IF, &msg);
  395. if (QDF_IS_STATUS_ERROR(status)) {
  396. tdls_err("post add peer msg fail");
  397. qdf_mem_free(req);
  398. goto dec_ref;
  399. }
  400. return status;
  401. dec_ref:
  402. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  403. return status;
  404. }
  405. QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
  406. struct tdls_update_peer_params *update_peer)
  407. {
  408. struct scheduler_msg msg = {0,};
  409. struct tdls_update_peer_request *req;
  410. QDF_STATUS status;
  411. if (!vdev || !update_peer) {
  412. tdls_err("vdev: %pK, update_peer: %pK", vdev, update_peer);
  413. return QDF_STATUS_E_NULL_VALUE;
  414. }
  415. tdls_debug("vdev_id: %d, peertype: %d",
  416. update_peer->vdev_id, update_peer->peer_type);
  417. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  418. if (QDF_IS_STATUS_ERROR(status)) {
  419. tdls_err("can't get vdev");
  420. return status;
  421. }
  422. req = qdf_mem_malloc(sizeof(*req));
  423. if (!req) {
  424. tdls_err("mem allocate fail");
  425. status = QDF_STATUS_E_NOMEM;
  426. goto dec_ref;
  427. }
  428. qdf_mem_copy(&req->update_peer_req, update_peer, sizeof(*update_peer));
  429. req->vdev = vdev;
  430. msg.bodyptr = req;
  431. msg.callback = tdls_process_cmd;
  432. msg.type = TDLS_CMD_CHANGE_STA;
  433. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  434. QDF_MODULE_ID_TDLS,
  435. QDF_MODULE_ID_OS_IF, &msg);
  436. if (QDF_IS_STATUS_ERROR(status)) {
  437. tdls_err("post update peer msg fail");
  438. qdf_mem_free(req);
  439. goto dec_ref;
  440. }
  441. return status;
  442. dec_ref:
  443. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  444. return status;
  445. }
  446. static char *tdls_get_oper_str(enum tdls_command_type cmd_type)
  447. {
  448. switch (cmd_type) {
  449. case TDLS_CMD_ENABLE_LINK:
  450. return "Enable_TDLS_LINK";
  451. case TDLS_CMD_DISABLE_LINK:
  452. return "DISABLE_TDLS_LINK";
  453. case TDLS_CMD_REMOVE_FORCE_PEER:
  454. return "REMOVE_FORCE_PEER";
  455. case TDLS_CMD_CONFIG_FORCE_PEER:
  456. return "CONFIG_FORCE_PEER";
  457. default:
  458. return "ERR:UNKNOWN OPER";
  459. }
  460. }
  461. QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev,
  462. const uint8_t *macaddr, enum tdls_command_type cmd)
  463. {
  464. struct scheduler_msg msg = {0,};
  465. struct tdls_oper_request *req;
  466. QDF_STATUS status;
  467. if (!vdev || !macaddr) {
  468. tdls_err("vdev: %pK, mac %pK", vdev, macaddr);
  469. return QDF_STATUS_E_NULL_VALUE;
  470. }
  471. tdls_debug("%s for peer " QDF_MAC_ADDR_STR,
  472. tdls_get_oper_str(cmd),
  473. QDF_MAC_ADDR_ARRAY(macaddr));
  474. req = qdf_mem_malloc(sizeof(*req));
  475. if (!req) {
  476. tdls_err("%s: mem allocate fail", tdls_get_oper_str(cmd));
  477. return QDF_STATUS_E_NOMEM;
  478. }
  479. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  480. if (QDF_IS_STATUS_ERROR(status)) {
  481. tdls_err("can't get vdev");
  482. goto error;
  483. }
  484. qdf_mem_copy(req->peer_addr, macaddr, QDF_MAC_ADDR_SIZE);
  485. req->vdev = vdev;
  486. msg.bodyptr = req;
  487. msg.callback = tdls_process_cmd;
  488. msg.type = cmd;
  489. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  490. QDF_MODULE_ID_TDLS,
  491. QDF_MODULE_ID_OS_IF, &msg);
  492. if (QDF_IS_STATUS_ERROR(status)) {
  493. tdls_err("post msg for %s fail", tdls_get_oper_str(cmd));
  494. goto dec_ref;
  495. }
  496. return status;
  497. dec_ref:
  498. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  499. error:
  500. qdf_mem_free(req);
  501. return status;
  502. }
  503. QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
  504. char *buf, int buflen)
  505. {
  506. struct scheduler_msg msg = {0, };
  507. struct tdls_get_all_peers *tdls_peers;
  508. QDF_STATUS status;
  509. tdls_peers = qdf_mem_malloc(sizeof(*tdls_peers));
  510. if (!tdls_peers) {
  511. tdls_err("mem allocate fail");
  512. return QDF_STATUS_E_NOMEM;
  513. }
  514. tdls_peers->vdev = vdev;
  515. tdls_peers->buf_len = buflen;
  516. tdls_peers->buf = buf;
  517. msg.bodyptr = tdls_peers;
  518. msg.callback = tdls_process_cmd;
  519. msg.type = TDLS_CMD_GET_ALL_PEERS;
  520. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  521. QDF_MODULE_ID_TDLS,
  522. QDF_MODULE_ID_OS_IF, &msg);
  523. if (status != QDF_STATUS_SUCCESS)
  524. qdf_mem_free(tdls_peers);
  525. return QDF_STATUS_SUCCESS;
  526. }
  527. static QDF_STATUS tdls_send_mgmt_frame_flush_callback(struct scheduler_msg *msg)
  528. {
  529. struct tdls_action_frame_request *req;
  530. if (!msg || !msg->bodyptr) {
  531. tdls_err("msg or msg->bodyptr is NULL");
  532. return QDF_STATUS_E_NULL_VALUE;
  533. }
  534. req = msg->bodyptr;
  535. if (req->vdev)
  536. wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
  537. qdf_mem_free(req);
  538. return QDF_STATUS_SUCCESS;
  539. }
  540. static QDF_STATUS ucfg_tdls_post_msg_flush_cb(struct scheduler_msg *msg)
  541. {
  542. void *ptr = msg->bodyptr;
  543. struct wlan_objmgr_vdev *vdev = NULL;
  544. switch (msg->type) {
  545. case TDLS_CMD_TEARDOWN_LINKS:
  546. case TDLS_NOTIFY_RESET_ADAPTERS:
  547. ptr = NULL;
  548. break;
  549. case TDLS_NOTIFY_STA_CONNECTION:
  550. vdev = ((struct tdls_sta_notify_params *)ptr)->vdev;
  551. break;
  552. case TDLS_NOTIFY_STA_DISCONNECTION:
  553. vdev = ((struct tdls_sta_notify_params *)ptr)->vdev;
  554. break;
  555. case TDLS_CMD_SET_TDLS_MODE:
  556. vdev = ((struct tdls_set_mode_params *)ptr)->vdev;
  557. break;
  558. case TDLS_CMD_TX_ACTION:
  559. case TDLS_CMD_SET_RESPONDER:
  560. break;
  561. }
  562. if (vdev)
  563. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  564. if (ptr)
  565. qdf_mem_free(ptr);
  566. msg->bodyptr = NULL;
  567. return QDF_STATUS_SUCCESS;
  568. }
  569. QDF_STATUS ucfg_tdls_send_mgmt_frame(
  570. struct tdls_action_frame_request *req)
  571. {
  572. struct scheduler_msg msg = {0, };
  573. struct tdls_action_frame_request *mgmt_req;
  574. QDF_STATUS status;
  575. if (!req || !req->vdev) {
  576. tdls_err("Invalid mgmt req params %pK", req);
  577. return QDF_STATUS_E_NULL_VALUE;
  578. }
  579. mgmt_req = qdf_mem_malloc(sizeof(*mgmt_req) +
  580. req->len);
  581. if (!mgmt_req) {
  582. tdls_err("mem allocate fail");
  583. return QDF_STATUS_E_NOMEM;
  584. }
  585. qdf_mem_copy(mgmt_req, req, sizeof(*req));
  586. /*populate the additional IE's */
  587. if ((0 != req->len) && (NULL != req->cmd_buf)) {
  588. qdf_mem_copy(mgmt_req->tdls_mgmt.buf, req->cmd_buf,
  589. req->len);
  590. mgmt_req->tdls_mgmt.len = req->len;
  591. } else {
  592. mgmt_req->tdls_mgmt.len = 0;
  593. }
  594. tdls_debug("vdev id: %d, session id : %d", mgmt_req->vdev_id,
  595. mgmt_req->session_id);
  596. status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_TDLS_NB_ID);
  597. if (QDF_IS_STATUS_ERROR(status)) {
  598. tdls_err("Unable to get vdev reference for tdls module");
  599. goto mem_free;
  600. }
  601. msg.bodyptr = mgmt_req;
  602. msg.callback = tdls_process_cmd;
  603. msg.flush_callback = tdls_send_mgmt_frame_flush_callback;
  604. msg.type = TDLS_CMD_TX_ACTION;
  605. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  606. QDF_MODULE_ID_TDLS,
  607. QDF_MODULE_ID_OS_IF, &msg);
  608. if (QDF_IS_STATUS_ERROR(status))
  609. goto release_ref;
  610. return status;
  611. release_ref:
  612. wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
  613. mem_free:
  614. qdf_mem_free(mgmt_req);
  615. return status;
  616. }
  617. QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req)
  618. {
  619. struct scheduler_msg msg = {0, };
  620. struct tdls_set_responder_req *msg_req;
  621. QDF_STATUS status;
  622. if (!req || !req->vdev) {
  623. tdls_err("invalid input %pK", req);
  624. return QDF_STATUS_E_NULL_VALUE;
  625. }
  626. msg_req = qdf_mem_malloc(sizeof(*msg_req));
  627. if (!msg_req)
  628. return QDF_STATUS_E_NULL_VALUE;
  629. msg_req->responder = req->responder;
  630. msg_req->vdev = req->vdev;
  631. qdf_mem_copy(msg_req->peer_mac, req->peer_mac, QDF_MAC_ADDR_SIZE);
  632. msg.bodyptr = msg_req;
  633. msg.callback = tdls_process_cmd;
  634. msg.flush_callback = ucfg_tdls_post_msg_flush_cb;
  635. msg.type = TDLS_CMD_SET_RESPONDER;
  636. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  637. QDF_MODULE_ID_TDLS,
  638. QDF_MODULE_ID_OS_IF, &msg);
  639. if (QDF_IS_STATUS_ERROR(status))
  640. qdf_mem_free(msg_req);
  641. return status;
  642. }
  643. QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev)
  644. {
  645. QDF_STATUS status;
  646. struct scheduler_msg msg = {0, };
  647. if (!vdev) {
  648. tdls_err("vdev is NULL ");
  649. return QDF_STATUS_E_NULL_VALUE;
  650. }
  651. tdls_debug("Enter ");
  652. msg.bodyptr = vdev;
  653. msg.callback = tdls_process_cmd;
  654. msg.flush_callback = ucfg_tdls_post_msg_flush_cb;
  655. msg.type = TDLS_CMD_TEARDOWN_LINKS;
  656. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  657. QDF_MODULE_ID_TDLS,
  658. QDF_MODULE_ID_OS_IF, &msg);
  659. tdls_debug("Exit ");
  660. return status;
  661. }
  662. QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev)
  663. {
  664. QDF_STATUS status;
  665. struct scheduler_msg msg = {0, };
  666. if (!vdev) {
  667. tdls_err("vdev is NULL ");
  668. return QDF_STATUS_E_NULL_VALUE;
  669. }
  670. tdls_debug("Enter ");
  671. msg.bodyptr = vdev;
  672. msg.callback = tdls_process_cmd;
  673. msg.flush_callback = ucfg_tdls_post_msg_flush_cb;
  674. msg.type = TDLS_NOTIFY_RESET_ADAPTERS;
  675. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  676. QDF_MODULE_ID_TDLS,
  677. QDF_MODULE_ID_OS_IF, &msg);
  678. return status;
  679. }
  680. QDF_STATUS ucfg_tdls_notify_sta_connect(
  681. struct tdls_sta_notify_params *notify_info)
  682. {
  683. struct scheduler_msg msg = {0, };
  684. struct tdls_sta_notify_params *notify;
  685. QDF_STATUS status;
  686. if (!notify_info || !notify_info->vdev) {
  687. tdls_err("notify_info %pK", notify_info);
  688. return QDF_STATUS_E_NULL_VALUE;
  689. }
  690. tdls_debug("Enter ");
  691. notify = qdf_mem_malloc(sizeof(*notify));
  692. if (!notify) {
  693. wlan_objmgr_vdev_release_ref(notify_info->vdev,
  694. WLAN_TDLS_NB_ID);
  695. return QDF_STATUS_E_NULL_VALUE;
  696. }
  697. *notify = *notify_info;
  698. msg.bodyptr = notify;
  699. msg.callback = tdls_process_cmd;
  700. msg.type = TDLS_NOTIFY_STA_CONNECTION;
  701. msg.flush_callback = ucfg_tdls_post_msg_flush_cb;
  702. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  703. QDF_MODULE_ID_TDLS,
  704. QDF_MODULE_ID_TARGET_IF, &msg);
  705. if (QDF_IS_STATUS_ERROR(status)) {
  706. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
  707. qdf_mem_free(notify);
  708. }
  709. tdls_debug("Exit ");
  710. return status;
  711. }
  712. QDF_STATUS ucfg_tdls_notify_sta_disconnect(
  713. struct tdls_sta_notify_params *notify_info)
  714. {
  715. struct scheduler_msg msg = {0, };
  716. struct tdls_sta_notify_params *notify;
  717. QDF_STATUS status;
  718. if (!notify_info || !notify_info->vdev) {
  719. tdls_err("notify_info %pK", notify_info);
  720. return QDF_STATUS_E_NULL_VALUE;
  721. }
  722. tdls_debug("Enter ");
  723. notify = qdf_mem_malloc(sizeof(*notify));
  724. if (!notify)
  725. return QDF_STATUS_E_NULL_VALUE;
  726. *notify = *notify_info;
  727. msg.bodyptr = notify;
  728. msg.callback = tdls_process_cmd;
  729. msg.type = TDLS_NOTIFY_STA_DISCONNECTION;
  730. msg.flush_callback = ucfg_tdls_post_msg_flush_cb;
  731. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  732. QDF_MODULE_ID_TDLS,
  733. QDF_MODULE_ID_TARGET_IF, &msg);
  734. if (QDF_IS_STATUS_ERROR(status)) {
  735. wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
  736. qdf_mem_free(notify);
  737. }
  738. tdls_debug("Exit ");
  739. return QDF_STATUS_SUCCESS;
  740. }
  741. QDF_STATUS ucfg_tdls_set_operating_mode(
  742. struct tdls_set_mode_params *set_mode_params)
  743. {
  744. struct scheduler_msg msg = {0, };
  745. struct tdls_set_mode_params *set_mode;
  746. QDF_STATUS status;
  747. if (!set_mode_params || !set_mode_params->vdev) {
  748. tdls_err("set_mode_params %pK", set_mode_params);
  749. return QDF_STATUS_E_NULL_VALUE;
  750. }
  751. tdls_debug("Enter ");
  752. set_mode = qdf_mem_malloc(sizeof(*set_mode));
  753. if (!set_mode) {
  754. tdls_err("memory allocate fail");
  755. return QDF_STATUS_E_NULL_VALUE;
  756. }
  757. status = wlan_objmgr_vdev_try_get_ref(set_mode->vdev, WLAN_TDLS_NB_ID);
  758. if (QDF_IS_STATUS_ERROR(status)) {
  759. tdls_err("failed to get vdev ref");
  760. qdf_mem_free(set_mode);
  761. return status;
  762. }
  763. set_mode->source = set_mode_params->source;
  764. set_mode->tdls_mode = set_mode_params->tdls_mode;
  765. set_mode->update_last = set_mode_params->update_last;
  766. set_mode->vdev = set_mode_params->vdev;
  767. msg.bodyptr = set_mode;
  768. msg.callback = tdls_process_cmd;
  769. msg.type = TDLS_CMD_SET_TDLS_MODE;
  770. msg.flush_callback = ucfg_tdls_post_msg_flush_cb;
  771. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  772. QDF_MODULE_ID_TDLS,
  773. QDF_MODULE_ID_OS_IF, &msg);
  774. if (QDF_IS_STATUS_ERROR(status)) {
  775. wlan_objmgr_vdev_release_ref(set_mode->vdev, WLAN_TDLS_NB_ID);
  776. qdf_mem_free(set_mode);
  777. }
  778. tdls_debug("Exit ");
  779. return QDF_STATUS_SUCCESS;
  780. }
  781. void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
  782. struct qdf_mac_addr *mac_addr,
  783. struct qdf_mac_addr *dest_mac_addr)
  784. {
  785. QDF_STATUS status;
  786. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  787. if (status != QDF_STATUS_SUCCESS)
  788. return;
  789. tdls_update_rx_pkt_cnt(vdev, mac_addr, dest_mac_addr);
  790. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  791. }
  792. void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
  793. struct qdf_mac_addr *mac_addr)
  794. {
  795. QDF_STATUS status;
  796. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  797. if (status != QDF_STATUS_SUCCESS)
  798. return;
  799. tdls_update_tx_pkt_cnt(vdev, mac_addr);
  800. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  801. }
  802. QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev,
  803. uint32_t mode)
  804. {
  805. QDF_STATUS status;
  806. struct tdls_antenna_switch_request *req;
  807. struct scheduler_msg msg = {0, };
  808. req = qdf_mem_malloc(sizeof(*req));
  809. if (!req) {
  810. tdls_err("mem allocate fail");
  811. return QDF_STATUS_E_NOMEM;
  812. }
  813. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  814. if (QDF_IS_STATUS_ERROR(status)) {
  815. tdls_err("can't get vdev");
  816. goto error;
  817. }
  818. req->vdev = vdev;
  819. req->mode = mode;
  820. msg.bodyptr = req;
  821. msg.callback = tdls_process_cmd;
  822. msg.flush_callback = tdls_antenna_switch_flush_callback;
  823. msg.type = TDLS_CMD_ANTENNA_SWITCH;
  824. status = scheduler_post_message(QDF_MODULE_ID_HDD,
  825. QDF_MODULE_ID_TDLS,
  826. QDF_MODULE_ID_OS_IF, &msg);
  827. if (QDF_IS_STATUS_ERROR(status)) {
  828. tdls_err("post antenna switch msg fail");
  829. goto dec_ref;
  830. }
  831. return status;
  832. dec_ref:
  833. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  834. error:
  835. qdf_mem_free(req);
  836. return status;
  837. }
  838. QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev,
  839. int offchannel)
  840. {
  841. QDF_STATUS status = QDF_STATUS_SUCCESS;
  842. struct scheduler_msg msg = {0, };
  843. struct tdls_set_offchannel *req;
  844. req = qdf_mem_malloc(sizeof(*req));
  845. if (!req) {
  846. tdls_err("mem allocate fail");
  847. return QDF_STATUS_E_NOMEM;
  848. }
  849. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  850. if (QDF_IS_STATUS_ERROR(status)) {
  851. tdls_err("can't get vdev");
  852. goto free;
  853. }
  854. req->offchannel = offchannel;
  855. req->vdev = vdev;
  856. req->callback = wlan_tdls_offchan_parms_callback;
  857. msg.bodyptr = req;
  858. msg.callback = tdls_process_cmd;
  859. msg.type = TDLS_CMD_SET_OFFCHANNEL;
  860. status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS,
  861. QDF_MODULE_ID_OS_IF, &msg);
  862. if (QDF_IS_STATUS_ERROR(status)) {
  863. tdls_err("post set tdls offchannel msg fail");
  864. goto dec_ref;
  865. }
  866. return status;
  867. dec_ref:
  868. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  869. free:
  870. qdf_mem_free(req);
  871. return status;
  872. }
  873. QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev,
  874. int offchanmode)
  875. {
  876. QDF_STATUS status = QDF_STATUS_SUCCESS;
  877. struct scheduler_msg msg = {0, };
  878. struct tdls_set_offchanmode *req;
  879. req = qdf_mem_malloc(sizeof(*req));
  880. if (!req) {
  881. tdls_err("mem allocate fail");
  882. return QDF_STATUS_E_NOMEM;
  883. }
  884. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  885. if (QDF_IS_STATUS_ERROR(status)) {
  886. tdls_err("can't get vdev");
  887. goto free;
  888. }
  889. req->offchan_mode = offchanmode;
  890. req->vdev = vdev;
  891. req->callback = wlan_tdls_offchan_parms_callback;
  892. msg.bodyptr = req;
  893. msg.callback = tdls_process_cmd;
  894. msg.type = TDLS_CMD_SET_OFFCHANMODE;
  895. status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS,
  896. QDF_MODULE_ID_OS_IF, &msg);
  897. if (QDF_IS_STATUS_ERROR(status)) {
  898. tdls_err("post set offchanmode msg fail");
  899. goto dec_ref;
  900. }
  901. return status;
  902. dec_ref:
  903. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  904. free:
  905. qdf_mem_free(req);
  906. return status;
  907. }
  908. QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev,
  909. int offchanoffset)
  910. {
  911. int status = QDF_STATUS_SUCCESS;
  912. struct scheduler_msg msg = {0, };
  913. struct tdls_set_secoffchanneloffset *req;
  914. req = qdf_mem_malloc(sizeof(*req));
  915. if (!req) {
  916. tdls_err("mem allocate fail");
  917. return QDF_STATUS_E_NOMEM;
  918. }
  919. status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
  920. if (QDF_IS_STATUS_ERROR(status)) {
  921. tdls_err("can't get vdev");
  922. goto free;
  923. }
  924. req->offchan_offset = offchanoffset;
  925. req->vdev = vdev;
  926. req->callback = wlan_tdls_offchan_parms_callback;
  927. msg.bodyptr = req;
  928. msg.callback = tdls_process_cmd;
  929. msg.type = TDLS_CMD_SET_SECOFFCHANOFFSET;
  930. status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS,
  931. QDF_MODULE_ID_OS_IF, &msg);
  932. if (QDF_IS_STATUS_ERROR(status)) {
  933. tdls_err("post set secoffchan offset msg fail");
  934. goto dec_ref;
  935. }
  936. return status;
  937. dec_ref:
  938. wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
  939. free:
  940. qdf_mem_free(req);
  941. return status;
  942. }