os_if_nan.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580
  1. /*
  2. * Copyright (c) 2016-2017 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 nan component os interface APIs
  20. */
  21. #include "qdf_types.h"
  22. #include "qdf_trace.h"
  23. #include "os_if_nan.h"
  24. #include "wlan_nan_api.h"
  25. #include "nan_ucfg_api.h"
  26. #include "nan_public_structs.h"
  27. #include "wlan_osif_priv.h"
  28. #include <net/cfg80211.h>
  29. #include "wlan_cfg80211.h"
  30. #include "wlan_objmgr_psoc_obj.h"
  31. #include "wlan_objmgr_pdev_obj.h"
  32. #include "wlan_objmgr_vdev_obj.h"
  33. #include "wlan_utility.h"
  34. /* NLA policy */
  35. static const struct nla_policy
  36. vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
  37. [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = { .type = NLA_U32 },
  38. [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 },
  39. [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_NUL_STRING,
  40. .len = IFNAMSIZ - 1 },
  41. [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 },
  42. [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 },
  43. [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = {
  44. .type = NLA_BINARY,
  45. .len = QDF_MAC_ADDR_SIZE },
  46. [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 },
  47. [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY,
  48. .len = NDP_QOS_INFO_LEN },
  49. [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY,
  50. .len = NDP_APP_INFO_LEN },
  51. [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 },
  52. [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 },
  53. [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY,
  54. .len = QDF_MAC_ADDR_SIZE },
  55. [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
  56. .len = NDP_NUM_INSTANCE_ID },
  57. [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = { .type = NLA_U32 },
  58. [QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE] = { .type = NLA_U32 },
  59. [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = { .type = NLA_BINARY,
  60. .len = NDP_PMK_LEN },
  61. [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = { .type = NLA_BINARY,
  62. .len = NDP_SCID_BUF_LEN },
  63. [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = { .type =
  64. NLA_U32 },
  65. [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = { .type = NLA_U32 },
  66. [QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = { .type = NLA_BINARY,
  67. .len = NAN_PASSPHRASE_MAX_LEN },
  68. [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = { .type = NLA_BINARY,
  69. .len = NAN_MAX_SERVICE_NAME_LEN },
  70. };
  71. static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
  72. struct nlattr **tb)
  73. {
  74. char *iface_name;
  75. QDF_STATUS status;
  76. uint16_t transaction_id;
  77. struct wlan_objmgr_vdev *nan_vdev;
  78. struct nan_callbacks cb_obj;
  79. cfg80211_debug("enter");
  80. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
  81. cfg80211_err("Interface name string is unavailable");
  82. return -EINVAL;
  83. }
  84. iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
  85. nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
  86. if (nan_vdev) {
  87. cfg80211_err("NAN data interface %s is already present",
  88. iface_name);
  89. wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
  90. return -EEXIST;
  91. }
  92. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
  93. cfg80211_err("transaction id is unavailable");
  94. return -EINVAL;
  95. }
  96. transaction_id =
  97. nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
  98. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  99. if (QDF_IS_STATUS_ERROR(status)) {
  100. cfg80211_err("Couldn't get ballback object");
  101. return -EINVAL;
  102. }
  103. nan_vdev = cb_obj.ndi_open(iface_name);
  104. if (!nan_vdev) {
  105. cfg80211_err("ndi_open failed");
  106. return -EINVAL;
  107. }
  108. /*
  109. * Create transaction id is required to be saved since the firmware
  110. * does not honor the transaction id for create request
  111. */
  112. ucfg_nan_set_ndp_create_transaction_id(nan_vdev, transaction_id);
  113. ucfg_nan_set_ndi_state(nan_vdev, NAN_DATA_NDI_CREATING_STATE);
  114. return cb_obj.ndi_start(wlan_vdev_get_id(nan_vdev));
  115. }
  116. static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
  117. struct nlattr **tb)
  118. {
  119. uint8_t vdev_id;
  120. char *iface_name;
  121. QDF_STATUS status;
  122. uint32_t num_peers;
  123. uint16_t transaction_id;
  124. struct nan_callbacks cb_obj;
  125. struct wlan_objmgr_vdev *nan_vdev = NULL;
  126. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
  127. cfg80211_err("Interface name string is unavailable");
  128. return -EINVAL;
  129. }
  130. iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
  131. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
  132. cfg80211_err("Transaction id is unavailable");
  133. return -EINVAL;
  134. }
  135. nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
  136. if (!nan_vdev) {
  137. cfg80211_err("Nan datapath interface is not present");
  138. return -EINVAL;
  139. }
  140. transaction_id =
  141. nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
  142. vdev_id = wlan_vdev_get_id(nan_vdev);
  143. num_peers = ucfg_nan_get_active_peers(nan_vdev);
  144. /*
  145. * wlan_util_get_vdev_by_ifname increments ref count
  146. * decrement here since vdev returned by that api is not used any more
  147. */
  148. wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
  149. /* check if there are active peers on the adapter */
  150. if (num_peers) {
  151. cfg80211_err("NDP peers active: %d, cannot delete NDI",
  152. num_peers);
  153. return -EINVAL;
  154. }
  155. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  156. if (QDF_IS_STATUS_ERROR(status)) {
  157. cfg80211_err("Couldn't get ballback object");
  158. return -EINVAL;
  159. }
  160. return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id);
  161. }
  162. /**
  163. * os_if_nan_parse_security_params() - parse vendor attributes for security
  164. * params.
  165. * @tb: parsed NL attribute list
  166. * @ncs_sk_type: out parameter to populate ncs_sk_type
  167. * @pmk: out parameter to populate pmk
  168. * @passphrase: out parameter to populate passphrase
  169. * @service_name: out parameter to populate service_name
  170. *
  171. * Return: 0 on success or error code on failure
  172. */
  173. static int os_if_nan_parse_security_params(struct nlattr **tb,
  174. uint32_t *ncs_sk_type, struct nan_datapath_pmk *pmk,
  175. struct ndp_passphrase *passphrase,
  176. struct ndp_service_name *service_name)
  177. {
  178. if (!ncs_sk_type || !pmk || !passphrase || !service_name) {
  179. cfg80211_err("out buffers for one ore more parameters is null");
  180. return -EINVAL;
  181. }
  182. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]) {
  183. *ncs_sk_type =
  184. nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE]);
  185. }
  186. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
  187. pmk->pmk_len =
  188. nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
  189. pmk->pmk =
  190. nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
  191. cfg80211_err("pmk len: %d", pmk->pmk_len);
  192. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
  193. pmk->pmk, pmk->pmk_len);
  194. }
  195. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]) {
  196. passphrase->passphrase_len =
  197. nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]);
  198. passphrase->passphrase =
  199. nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]);
  200. cfg80211_err("passphrase len: %d", passphrase->passphrase_len);
  201. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
  202. passphrase->passphrase, passphrase->passphrase_len);
  203. }
  204. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) {
  205. service_name->service_name_len =
  206. nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]);
  207. service_name->service_name =
  208. nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]);
  209. cfg80211_err("service_name len: %d",
  210. service_name->service_name_len);
  211. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
  212. service_name->service_name,
  213. service_name->service_name_len);
  214. }
  215. return 0;
  216. }
  217. /**
  218. * os_if_nan_process_ndp_initiator_req() - NDP initiator request handler
  219. * @ctx: hdd context
  220. * @tb: parsed NL attribute list
  221. *
  222. * tb will contain following vendor attributes:
  223. * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
  224. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
  225. * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
  226. * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG
  227. * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
  228. * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
  229. * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
  230. * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
  231. * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
  232. * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
  233. * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional
  234. * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional
  235. *
  236. * Return: 0 on success or error code on failure
  237. */
  238. static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
  239. struct nlattr **tb)
  240. {
  241. int ret = 0;
  242. char *iface_name;
  243. QDF_STATUS status;
  244. uint32_t ndp_qos_cfg;
  245. enum nan_datapath_state state;
  246. struct wlan_objmgr_vdev *nan_vdev;
  247. struct nan_datapath_initiator_req req = {0};
  248. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
  249. cfg80211_err("Interface name string is unavailable");
  250. return -EINVAL;
  251. }
  252. iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
  253. nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
  254. if (!nan_vdev) {
  255. cfg80211_err("NAN data interface %s not available", iface_name);
  256. return -EINVAL;
  257. }
  258. if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) {
  259. cfg80211_err("Interface found is not NDI");
  260. return -EINVAL;
  261. }
  262. state = ucfg_nan_get_ndi_state(nan_vdev);
  263. if (state == NAN_DATA_NDI_DELETED_STATE ||
  264. state == NAN_DATA_NDI_DELETING_STATE ||
  265. state == NAN_DATA_NDI_CREATING_STATE) {
  266. cfg80211_err("Data request not allowed in NDI current state: %d",
  267. state);
  268. ret = -EINVAL;
  269. goto initiator_req_failed;
  270. }
  271. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
  272. cfg80211_err("Transaction ID is unavailable");
  273. ret = -EINVAL;
  274. goto initiator_req_failed;
  275. }
  276. req.transaction_id =
  277. nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
  278. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
  279. req.channel = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
  280. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) {
  281. req.channel_cfg = nla_get_u32(
  282. tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
  283. } else {
  284. cfg80211_err("Channel config is unavailable");
  285. ret = -EINVAL;
  286. goto initiator_req_failed;
  287. }
  288. }
  289. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
  290. cfg80211_err("NDP service instance ID is unavailable");
  291. ret = -EINVAL;
  292. goto initiator_req_failed;
  293. }
  294. req.service_instance_id =
  295. nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
  296. qdf_mem_copy(req.self_ndi_mac_addr.bytes,
  297. wlan_vdev_mlme_get_macaddr(nan_vdev), QDF_MAC_ADDR_SIZE);
  298. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
  299. cfg80211_err("NDI peer discovery mac addr is unavailable");
  300. ret = -EINVAL;
  301. goto initiator_req_failed;
  302. }
  303. qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
  304. nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
  305. QDF_MAC_ADDR_SIZE);
  306. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
  307. req.ndp_info.ndp_app_info_len =
  308. nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
  309. req.ndp_info.ndp_app_info =
  310. nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
  311. }
  312. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
  313. /* at present ndp config stores 4 bytes QOS info only */
  314. req.ndp_config.ndp_cfg_len = 4;
  315. req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
  316. ndp_qos_cfg =
  317. nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
  318. }
  319. if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk,
  320. &req.passphrase, &req.service_name)) {
  321. cfg80211_err("inconsistent security params in request.");
  322. ret = -EINVAL;
  323. goto initiator_req_failed;
  324. }
  325. cfg80211_debug("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, csid: %d, peer_discovery_mac_addr: %pM",
  326. wlan_vdev_get_id(nan_vdev), req.transaction_id, req.channel,
  327. req.service_instance_id, req.ndp_info.ndp_app_info_len,
  328. req.ncs_sk_type, req.peer_discovery_mac_addr.bytes);
  329. status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ);
  330. ret = qdf_status_to_os_return(status);
  331. initiator_req_failed:
  332. wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
  333. return ret;
  334. }
  335. /**
  336. * os_if_nan_process_ndp_responder_req() - NDP responder request handler
  337. * @nan_ctx: hdd context
  338. * @tb: parsed NL attribute list
  339. *
  340. * tb includes following vendor attributes:
  341. * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
  342. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
  343. * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
  344. * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
  345. * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
  346. * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
  347. * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
  348. * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE - optional
  349. * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional
  350. * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional
  351. *
  352. * Return: 0 on success or error code on failure
  353. */
  354. static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
  355. struct nlattr **tb)
  356. {
  357. int ret = 0;
  358. char *iface_name;
  359. QDF_STATUS status;
  360. uint32_t ndp_qos_cfg;
  361. enum nan_datapath_state state;
  362. struct wlan_objmgr_vdev *nan_vdev;
  363. struct nan_datapath_responder_req req = {0};
  364. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
  365. cfg80211_err("Interface name string is unavailable");
  366. return -EINVAL;
  367. }
  368. iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
  369. /* Check if there is already an existing NAN interface */
  370. nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
  371. if (!nan_vdev) {
  372. cfg80211_err("NAN data interface %s not available", iface_name);
  373. return -EINVAL;
  374. }
  375. if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) {
  376. cfg80211_err("Interface found is not NDI");
  377. return -EINVAL;
  378. }
  379. state = ucfg_nan_get_ndi_state(nan_vdev);
  380. if (state == NAN_DATA_NDI_DELETED_STATE ||
  381. state == NAN_DATA_NDI_DELETING_STATE ||
  382. state == NAN_DATA_NDI_CREATING_STATE) {
  383. cfg80211_err("Data request not allowed in current NDI state:%d",
  384. state);
  385. ret = -EAGAIN;
  386. goto responder_req_failed;
  387. }
  388. req.vdev = nan_vdev;
  389. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
  390. cfg80211_err("Transaction ID is unavailable");
  391. ret = -EINVAL;
  392. goto responder_req_failed;
  393. }
  394. req.transaction_id =
  395. nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
  396. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
  397. cfg80211_err("Instance ID is unavailable");
  398. ret = -EINVAL;
  399. goto responder_req_failed;
  400. }
  401. req.ndp_instance_id =
  402. nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
  403. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
  404. cfg80211_err("ndp_rsp is unavailable");
  405. ret = -EINVAL;
  406. goto responder_req_failed;
  407. }
  408. req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
  409. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
  410. req.ndp_info.ndp_app_info_len =
  411. nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
  412. if (req.ndp_info.ndp_app_info_len) {
  413. req.ndp_info.ndp_app_info =
  414. nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
  415. }
  416. } else {
  417. cfg80211_debug("NDP app info is unavailable");
  418. }
  419. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
  420. /* at present ndp config stores 4 bytes QOS info only */
  421. req.ndp_config.ndp_cfg_len = 4;
  422. ndp_qos_cfg =
  423. nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
  424. req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg;
  425. } else {
  426. cfg80211_debug("NDP config data is unavailable");
  427. }
  428. if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk,
  429. &req.passphrase, &req.service_name)) {
  430. cfg80211_err("inconsistent security params in request.");
  431. ret = -EINVAL;
  432. goto responder_req_failed;
  433. }
  434. cfg80211_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d",
  435. wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp,
  436. req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
  437. req.ncs_sk_type);
  438. status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ);
  439. ret = qdf_status_to_os_return(status);
  440. responder_req_failed:
  441. wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
  442. return ret;
  443. }
  444. /**
  445. * os_if_nan_process_ndp_end_req() - NDP end request handler
  446. * @psoc: pointer to psoc object
  447. *
  448. * @tb: parsed NL attribute list
  449. * tb includes following vendor attributes:
  450. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
  451. *
  452. * Return: 0 on success or error code on failure
  453. */
  454. static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
  455. struct nlattr **tb)
  456. {
  457. int ret = 0;
  458. QDF_STATUS status;
  459. struct wlan_objmgr_vdev *nan_vdev;
  460. struct nan_datapath_end_req req = {0};
  461. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
  462. cfg80211_err("Transaction ID is unavailable");
  463. return -EINVAL;
  464. }
  465. req.transaction_id =
  466. nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
  467. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
  468. cfg80211_err("NDP instance ID array is unavailable");
  469. return -EINVAL;
  470. }
  471. req.num_ndp_instances =
  472. nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
  473. sizeof(uint32_t);
  474. if (0 >= req.num_ndp_instances) {
  475. cfg80211_err("Num NDP instances is 0");
  476. return -EINVAL;
  477. }
  478. req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
  479. cfg80211_debug("sending ndp_end_req to SME, transaction_id: %d",
  480. req.transaction_id);
  481. nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE,
  482. WLAN_NAN_ID);
  483. if (!nan_vdev) {
  484. cfg80211_err("NAN data interface is not available");
  485. return -EINVAL;
  486. }
  487. status = ucfg_nan_req_processor(nan_vdev, &req, NDP_END_REQ);
  488. ret = qdf_status_to_os_return(status);
  489. wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
  490. return ret;
  491. }
  492. int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
  493. const void *data, int data_len)
  494. {
  495. uint32_t ndp_cmd_type;
  496. uint16_t transaction_id;
  497. struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
  498. char *iface_name;
  499. if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
  500. data, data_len, vendor_attr_policy)) {
  501. cfg80211_err("Invalid NDP vendor command attributes");
  502. return -EINVAL;
  503. }
  504. /* Parse and fetch NDP Command Type*/
  505. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
  506. cfg80211_err("NAN datapath cmd type failed");
  507. return -EINVAL;
  508. }
  509. ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
  510. if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
  511. cfg80211_err("attr transaction id failed");
  512. return -EINVAL;
  513. }
  514. transaction_id = nla_get_u16(
  515. tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
  516. if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
  517. iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
  518. cfg80211_err("Transaction Id: %d NDPCmd: %d iface_name: %s",
  519. transaction_id, ndp_cmd_type, iface_name);
  520. } else {
  521. cfg80211_err("Transaction Id: %d NDPCmd: %d iface_name: unspecified",
  522. transaction_id, ndp_cmd_type);
  523. }
  524. cfg80211_debug("Received NDP cmd: %d", ndp_cmd_type);
  525. switch (ndp_cmd_type) {
  526. case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
  527. return os_if_nan_process_ndi_create(psoc, tb);
  528. case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
  529. return os_if_nan_process_ndi_delete(psoc, tb);
  530. case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
  531. return os_if_nan_process_ndp_initiator_req(psoc, tb);
  532. case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
  533. return os_if_nan_process_ndp_responder_req(psoc, tb);
  534. case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
  535. return os_if_nan_process_ndp_end_req(psoc, tb);
  536. default:
  537. cfg80211_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
  538. return -EINVAL;
  539. }
  540. return -EINVAL;
  541. }
  542. /**
  543. * os_if_ndp_initiator_rsp_handler() - NDP initiator response handler
  544. * @vdev: pointer to vdev object
  545. * @rsp_params: response parameters
  546. *
  547. * Following vendor event is sent to cfg80211:
  548. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  549. * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
  550. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
  551. * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
  552. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
  553. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
  554. *
  555. * Return: none
  556. */
  557. static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev,
  558. struct nan_datapath_initiator_rsp *rsp)
  559. {
  560. uint32_t data_len;
  561. struct sk_buff *vendor_event;
  562. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  563. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  564. if (!rsp) {
  565. cfg80211_err("Invalid NDP Initator response");
  566. return;
  567. }
  568. data_len = (4 * sizeof(uint32_t)) + (1 * sizeof(uint16_t)) +
  569. NLMSG_HDRLEN + (5 * NLA_HDRLEN);
  570. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
  571. data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  572. GFP_ATOMIC);
  573. if (!vendor_event) {
  574. cfg80211_err("cfg80211_vendor_event_alloc failed");
  575. return;
  576. }
  577. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  578. QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
  579. goto ndp_initiator_rsp_nla_failed;
  580. if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
  581. rsp->transaction_id))
  582. goto ndp_initiator_rsp_nla_failed;
  583. if (nla_put_u32(vendor_event,
  584. QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
  585. rsp->ndp_instance_id))
  586. goto ndp_initiator_rsp_nla_failed;
  587. if (nla_put_u32(vendor_event,
  588. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  589. rsp->status))
  590. goto ndp_initiator_rsp_nla_failed;
  591. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  592. rsp->reason))
  593. goto ndp_initiator_rsp_nla_failed;
  594. cfg80211_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
  595. rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
  596. rsp->reason);
  597. cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
  598. return;
  599. ndp_initiator_rsp_nla_failed:
  600. cfg80211_err("nla_put api failed");
  601. kfree_skb(vendor_event);
  602. }
  603. /*
  604. * os_if_ndp_responder_rsp_handler() - NDP responder response handler
  605. * @vdev: pointer to vdev object
  606. * @rsp: response parameters
  607. *
  608. * Following vendor event is sent to cfg80211:
  609. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  610. * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
  611. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
  612. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
  613. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
  614. *
  615. * Return: none
  616. */
  617. static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev,
  618. struct nan_datapath_responder_rsp *rsp)
  619. {
  620. uint16_t data_len;
  621. struct sk_buff *vendor_event;
  622. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  623. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  624. if (!rsp) {
  625. cfg80211_err("Invalid NDP Responder response");
  626. return;
  627. }
  628. cfg80211_debug("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d",
  629. wlan_vdev_get_id(rsp->vdev), rsp->transaction_id,
  630. rsp->status, rsp->reason);
  631. data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) +
  632. 4 * NLA_HDRLEN + NLMSG_HDRLEN;
  633. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
  634. data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  635. GFP_ATOMIC);
  636. if (!vendor_event) {
  637. cfg80211_err("cfg80211_vendor_event_alloc failed");
  638. return;
  639. }
  640. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  641. QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
  642. goto ndp_responder_rsp_nla_failed;
  643. if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
  644. rsp->transaction_id))
  645. goto ndp_responder_rsp_nla_failed;
  646. if (nla_put_u32(vendor_event,
  647. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  648. rsp->status))
  649. goto ndp_responder_rsp_nla_failed;
  650. if (nla_put_u32(vendor_event,
  651. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  652. rsp->reason))
  653. goto ndp_responder_rsp_nla_failed;
  654. cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
  655. return;
  656. ndp_responder_rsp_nla_failed:
  657. cfg80211_err("nla_put api failed");
  658. kfree_skb(vendor_event);
  659. }
  660. /**
  661. * os_if_ndp_indication_handler() - NDP indication handler
  662. * @vdev: pointer to vdev object
  663. * @ind_params: indication parameters
  664. *
  665. * Following vendor event is sent to cfg80211:
  666. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  667. * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
  668. * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
  669. * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
  670. * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
  671. * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
  672. * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
  673. * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
  674. * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
  675. * QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE(4 bytes)
  676. * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
  677. *
  678. * Return: none
  679. */
  680. static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev,
  681. struct nan_datapath_indication_event *event)
  682. {
  683. uint16_t data_len;
  684. uint32_t ndp_qos_config;
  685. struct sk_buff *vendor_event;
  686. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  687. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  688. enum nan_datapath_state state;
  689. if (!event) {
  690. cfg80211_err("Invalid NDP Indication");
  691. return;
  692. }
  693. cfg80211_debug("NDP Indication, policy: %d", event->policy);
  694. state = ucfg_nan_get_ndi_state(vdev);
  695. /* check if we are in middle of deleting/creating the interface */
  696. if (state == NAN_DATA_NDI_DELETED_STATE ||
  697. state == NAN_DATA_NDI_DELETING_STATE ||
  698. state == NAN_DATA_NDI_CREATING_STATE) {
  699. cfg80211_err("Data request not allowed in current NDI state: %d",
  700. state);
  701. return;
  702. }
  703. data_len = (5 * sizeof(uint32_t)) + (2 * QDF_MAC_ADDR_SIZE) + IFNAMSIZ +
  704. event->ndp_info.ndp_app_info_len + event->scid.scid_len +
  705. (10 * NLA_HDRLEN) + NLMSG_HDRLEN;
  706. /* notify response to the upper layer */
  707. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy,
  708. NULL, data_len,
  709. QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  710. GFP_ATOMIC);
  711. if (!vendor_event) {
  712. cfg80211_err("cfg80211_vendor_event_alloc failed");
  713. return;
  714. }
  715. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  716. QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
  717. goto ndp_indication_nla_failed;
  718. if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
  719. IFNAMSIZ, "nan0"/* adapter->dev->name - fetch dev name */))
  720. goto ndp_indication_nla_failed;
  721. if (nla_put_u32(vendor_event,
  722. QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
  723. event->service_instance_id))
  724. goto ndp_indication_nla_failed;
  725. if (nla_put(vendor_event,
  726. QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
  727. QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
  728. goto ndp_indication_nla_failed;
  729. if (nla_put(vendor_event,
  730. QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
  731. QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
  732. goto ndp_indication_nla_failed;
  733. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
  734. event->ndp_instance_id))
  735. goto ndp_indication_nla_failed;
  736. if (event->ndp_info.ndp_app_info_len)
  737. if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
  738. event->ndp_info.ndp_app_info_len,
  739. event->ndp_info.ndp_app_info))
  740. goto ndp_indication_nla_failed;
  741. if (event->ndp_config.ndp_cfg_len) {
  742. ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
  743. /* at present ndp config stores 4 bytes QOS info only */
  744. if (nla_put_u32(vendor_event,
  745. QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
  746. ndp_qos_config))
  747. goto ndp_indication_nla_failed;
  748. }
  749. if (event->scid.scid_len) {
  750. if (nla_put_u32(vendor_event,
  751. QCA_WLAN_VENDOR_ATTR_NDP_NCS_SK_TYPE,
  752. event->ncs_sk_type))
  753. goto ndp_indication_nla_failed;
  754. if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
  755. event->scid.scid_len,
  756. event->scid.scid))
  757. goto ndp_indication_nla_failed;
  758. cfg80211_debug("csid: %d, scid_len: %d",
  759. event->ncs_sk_type, event->scid.scid_len);
  760. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
  761. event->scid.scid, event->scid.scid_len);
  762. }
  763. cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
  764. return;
  765. ndp_indication_nla_failed:
  766. cfg80211_err("nla_put api failed");
  767. kfree_skb(vendor_event);
  768. }
  769. /**
  770. * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler
  771. * @vdev: pointer to vdev object
  772. * @ind_params: indication parameters
  773. *
  774. * Following vendor event is sent to cfg80211:
  775. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  776. * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
  777. * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
  778. * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
  779. * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
  780. * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
  781. * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
  782. * QCA_WLAN_VENDOR_ATTR_NDP_RETURN_VALUE (4 bytes)
  783. *
  784. * Return: none
  785. */
  786. static void os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev,
  787. struct nan_datapath_confirm_event *ndp_confirm)
  788. {
  789. int idx = 0;
  790. uint32_t data_len;
  791. QDF_STATUS status;
  792. uint32_t ndp_qos_config = 0;
  793. struct sk_buff *vendor_event;
  794. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  795. struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
  796. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  797. struct nan_callbacks cb_obj;
  798. if (!ndp_confirm) {
  799. cfg80211_err("Invalid NDP Initator response");
  800. return;
  801. }
  802. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  803. if (QDF_IS_STATUS_ERROR(status)) {
  804. cfg80211_err("couldn't get callbacks");
  805. return;
  806. }
  807. /* ndp_confirm is called each time user generated ndp req succeeds */
  808. idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev),
  809. &ndp_confirm->peer_ndi_mac_addr);
  810. if (idx < 0)
  811. cfg80211_err("can't find addr: %pM in vdev_id: %d, peer table.",
  812. &ndp_confirm->peer_ndi_mac_addr,
  813. wlan_vdev_get_id(vdev));
  814. else if (ndp_confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT) {
  815. uint32_t active_sessions =
  816. ucfg_nan_get_active_ndp_sessions(vdev, idx);
  817. ucfg_nan_set_active_ndp_sessions(vdev, active_sessions + 1,
  818. idx);
  819. }
  820. data_len = (4 * sizeof(uint32_t)) + QDF_MAC_ADDR_SIZE + IFNAMSIZ +
  821. + NLMSG_HDRLEN + (7 * NLA_HDRLEN) +
  822. ndp_confirm->ndp_info.ndp_app_info_len;
  823. if (ndp_confirm->ndp_info.ndp_app_info_len)
  824. data_len += NLA_HDRLEN + ndp_confirm->ndp_info.ndp_app_info_len;
  825. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
  826. data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  827. GFP_ATOMIC);
  828. if (!vendor_event) {
  829. cfg80211_err("cfg80211_vendor_event_alloc failed");
  830. return;
  831. }
  832. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  833. QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
  834. goto ndp_confirm_nla_failed;
  835. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
  836. ndp_confirm->ndp_instance_id))
  837. goto ndp_confirm_nla_failed;
  838. if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
  839. QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
  840. goto ndp_confirm_nla_failed;
  841. if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
  842. IFNAMSIZ, "nan0" /* TBD adapter->dev->name - fetch name */))
  843. goto ndp_confirm_nla_failed;
  844. if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event,
  845. QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
  846. ndp_confirm->ndp_info.ndp_app_info_len,
  847. ndp_confirm->ndp_info.ndp_app_info))
  848. goto ndp_confirm_nla_failed;
  849. if (nla_put_u32(vendor_event,
  850. QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
  851. ndp_confirm->rsp_code))
  852. goto ndp_confirm_nla_failed;
  853. if (nla_put_u32(vendor_event,
  854. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  855. ndp_confirm->reason_code))
  856. goto ndp_confirm_nla_failed;
  857. cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
  858. cfg80211_debug("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d, reason_code: %d",
  859. ndp_confirm->ndp_instance_id,
  860. ndp_confirm->peer_ndi_mac_addr.bytes,
  861. ndp_qos_config, ndp_confirm->rsp_code,
  862. ndp_confirm->reason_code);
  863. cfg80211_debug("NDP confim, ndp app info dump");
  864. QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
  865. ndp_confirm->ndp_info.ndp_app_info,
  866. ndp_confirm->ndp_info.ndp_app_info_len);
  867. return;
  868. ndp_confirm_nla_failed:
  869. cfg80211_err("nla_put api failed");
  870. kfree_skb(vendor_event);
  871. }
  872. /**
  873. * os_if_ndp_end_rsp_handler() - NDP end response handler
  874. * @vdev: pointer to vdev object
  875. * @rsp_params: response parameters
  876. *
  877. * Following vendor event is sent to cfg80211:
  878. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  879. * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
  880. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
  881. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
  882. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
  883. *
  884. * Return: none
  885. */
  886. static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev,
  887. struct nan_datapath_end_rsp_event *rsp)
  888. {
  889. uint32_t data_len;
  890. struct sk_buff *vendor_event;
  891. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  892. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  893. if (!rsp) {
  894. cfg80211_err("Invalid ndp end response");
  895. return;
  896. }
  897. data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
  898. sizeof(uint16_t);
  899. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
  900. data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  901. GFP_ATOMIC);
  902. if (!vendor_event) {
  903. cfg80211_err("cfg80211_vendor_event_alloc failed");
  904. return;
  905. }
  906. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  907. QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
  908. goto ndp_end_rsp_nla_failed;
  909. if (nla_put_u32(vendor_event,
  910. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  911. rsp->status))
  912. goto ndp_end_rsp_nla_failed;
  913. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  914. rsp->reason))
  915. goto ndp_end_rsp_nla_failed;
  916. if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
  917. rsp->transaction_id))
  918. goto ndp_end_rsp_nla_failed;
  919. cfg80211_debug("NDP End rsp sent, transaction id: %d, status: %d, reason: %d",
  920. rsp->transaction_id, rsp->status, rsp->reason);
  921. cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
  922. return;
  923. ndp_end_rsp_nla_failed:
  924. cfg80211_err("nla_put api failed");
  925. kfree_skb(vendor_event);
  926. }
  927. /**
  928. * os_if_ndp_end_ind_handler() - NDP end indication handler
  929. * @vdev: pointer to vdev object
  930. * @ind_params: indication parameters
  931. *
  932. * Following vendor event is sent to cfg80211:
  933. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  934. * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
  935. * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
  936. *
  937. * Return: none
  938. */
  939. static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev,
  940. struct nan_datapath_end_indication_event *end_ind)
  941. {
  942. QDF_STATUS status;
  943. uint32_t data_len, i;
  944. struct nan_callbacks cb_obj;
  945. uint32_t *ndp_instance_array;
  946. struct sk_buff *vendor_event;
  947. struct wlan_objmgr_vdev *vdev_itr;
  948. struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
  949. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  950. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  951. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  952. if (QDF_IS_STATUS_ERROR(status)) {
  953. cfg80211_err("failed to get callbacks");
  954. return;
  955. }
  956. if (!end_ind) {
  957. cfg80211_err("Invalid ndp end indication");
  958. return;
  959. }
  960. ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
  961. sizeof(*ndp_instance_array));
  962. if (!ndp_instance_array) {
  963. cfg80211_err("Failed to allocate ndp_instance_array");
  964. return;
  965. }
  966. for (i = 0; i < end_ind->num_ndp_ids; i++) {
  967. int idx = 0;
  968. ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
  969. vdev_itr = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
  970. end_ind->ndp_map[i].vdev_id, WLAN_NAN_ID);
  971. if (vdev_itr == NULL) {
  972. cfg80211_err("vdev not found for vdev_id: %d",
  973. end_ind->ndp_map[i].vdev_id);
  974. continue;
  975. }
  976. idx = cb_obj.get_peer_idx(wlan_vdev_get_id(vdev),
  977. &end_ind->ndp_map[i].peer_ndi_mac_addr);
  978. if (idx < 0) {
  979. cfg80211_err("can't find addr: %pM in sta_ctx.",
  980. &end_ind->ndp_map[i].peer_ndi_mac_addr);
  981. continue;
  982. }
  983. /* save the value of active sessions on each peer */
  984. ucfg_nan_set_active_ndp_sessions(vdev,
  985. end_ind->ndp_map[i].num_active_ndp_sessions,
  986. idx);
  987. }
  988. data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
  989. end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
  990. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
  991. data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  992. GFP_ATOMIC);
  993. if (!vendor_event) {
  994. cfg80211_err("cfg80211_vendor_event_alloc failed");
  995. return;
  996. }
  997. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  998. QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
  999. goto ndp_end_ind_nla_failed;
  1000. if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
  1001. end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
  1002. ndp_instance_array))
  1003. goto ndp_end_ind_nla_failed;
  1004. cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
  1005. qdf_mem_free(ndp_instance_array);
  1006. return;
  1007. ndp_end_ind_nla_failed:
  1008. cfg80211_err("nla_put api failed");
  1009. kfree_skb(vendor_event);
  1010. qdf_mem_free(ndp_instance_array);
  1011. }
  1012. /**
  1013. * os_if_new_peer_ind_handler() - NDP new peer indication handler
  1014. * @adapter: pointer to adapter context
  1015. * @ind_params: indication parameters
  1016. *
  1017. * Return: none
  1018. */
  1019. static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev,
  1020. struct nan_datapath_peer_ind *peer_ind)
  1021. {
  1022. int ret;
  1023. QDF_STATUS status;
  1024. uint8_t vdev_id = wlan_vdev_get_id(vdev);
  1025. struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
  1026. uint32_t active_peers = ucfg_nan_get_active_peers(vdev);
  1027. struct nan_callbacks cb_obj;
  1028. if (NULL == peer_ind) {
  1029. cfg80211_err("Invalid new NDP peer params");
  1030. return;
  1031. }
  1032. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  1033. if (QDF_IS_STATUS_ERROR(status)) {
  1034. cfg80211_err("failed to get callbacks");
  1035. return;
  1036. }
  1037. cfg80211_debug("session_id: %d, peer_mac: %pM, sta_id: %d",
  1038. peer_ind->session_id, peer_ind->peer_mac_addr.bytes,
  1039. peer_ind->sta_id);
  1040. ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id,
  1041. &peer_ind->peer_mac_addr,
  1042. (active_peers == 0 ? true : false));
  1043. if (ret) {
  1044. cfg80211_err("new peer handling at HDD failed %d", ret);
  1045. return;
  1046. }
  1047. active_peers++;
  1048. ucfg_nan_set_active_peers(vdev, active_peers);
  1049. cfg80211_debug("vdev_id: %d, num_peers: %d", vdev_id, active_peers);
  1050. }
  1051. /**
  1052. * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication
  1053. * @adapter: pointer to adapter context
  1054. * @ind_params: indication parameters
  1055. *
  1056. * Return: none
  1057. */
  1058. static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev,
  1059. struct nan_datapath_peer_ind *peer_ind)
  1060. {
  1061. QDF_STATUS status;
  1062. struct nan_callbacks cb_obj;
  1063. uint8_t vdev_id = wlan_vdev_get_id(vdev);
  1064. struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
  1065. uint32_t active_peers = ucfg_nan_get_active_peers(vdev);
  1066. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  1067. if (QDF_IS_STATUS_ERROR(status)) {
  1068. cfg80211_err("failed to get callbacks");
  1069. return;
  1070. }
  1071. if (NULL == peer_ind) {
  1072. cfg80211_err("Invalid new NDP peer params");
  1073. return;
  1074. }
  1075. cfg80211_debug("session_id: %d, peer_mac: %pM, sta_id: %d",
  1076. peer_ind->session_id, peer_ind->peer_mac_addr.bytes,
  1077. peer_ind->sta_id);
  1078. active_peers--;
  1079. ucfg_nan_set_active_peers(vdev, active_peers);
  1080. cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id,
  1081. &peer_ind->peer_mac_addr,
  1082. (active_peers == 0 ? true : false));
  1083. }
  1084. /**
  1085. * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler
  1086. * @adapter: pointer to adapter context
  1087. * @rsp_params: response parameters
  1088. *
  1089. * The function is expected to send a response back to the user space
  1090. * even if the creation of BSS has failed
  1091. *
  1092. * Following vendor event is sent to cfg80211:
  1093. * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
  1094. * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
  1095. * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
  1096. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
  1097. * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
  1098. *
  1099. * Return: none
  1100. */
  1101. static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc,
  1102. struct wlan_objmgr_vdev *vdev,
  1103. void *rsp_params)
  1104. {
  1105. QDF_STATUS status;
  1106. bool create_fail = false;
  1107. struct nan_callbacks cb_obj;
  1108. struct sk_buff *vendor_event;
  1109. uint8_t create_transaction_id;
  1110. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  1111. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  1112. uint32_t create_status = NAN_DATAPATH_RSP_STATUS_ERROR;
  1113. uint32_t create_reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
  1114. struct nan_datapath_inf_create_rsp *ndi_rsp =
  1115. (struct nan_datapath_inf_create_rsp *)rsp_params;
  1116. uint32_t data_len = (3 * sizeof(uint32_t)) + sizeof(uint16_t) +
  1117. NLMSG_HDRLEN + (4 * NLA_HDRLEN);
  1118. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  1119. if (QDF_IS_STATUS_ERROR(status)) {
  1120. cfg80211_err("Couldn't get ballback object");
  1121. return;
  1122. }
  1123. if (ndi_rsp) {
  1124. create_status = ndi_rsp->status;
  1125. create_reason = ndi_rsp->reason;
  1126. } else {
  1127. cfg80211_err("Invalid ndi create response");
  1128. create_fail = true;
  1129. }
  1130. create_transaction_id = ucfg_nan_get_ndp_create_transaction_id(vdev);
  1131. /* notify response to the upper layer */
  1132. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy,
  1133. NULL,
  1134. data_len,
  1135. QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  1136. GFP_KERNEL);
  1137. if (!vendor_event) {
  1138. cfg80211_err("cfg80211_vendor_event_alloc failed");
  1139. create_fail = true;
  1140. goto close_ndi;
  1141. }
  1142. /* Sub vendor command */
  1143. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  1144. QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
  1145. cfg80211_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
  1146. goto nla_put_failure;
  1147. }
  1148. /* Transaction id */
  1149. if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
  1150. create_transaction_id)) {
  1151. cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
  1152. goto nla_put_failure;
  1153. }
  1154. /* Status code */
  1155. if (nla_put_u32(vendor_event,
  1156. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  1157. create_status)) {
  1158. cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
  1159. goto nla_put_failure;
  1160. }
  1161. /* Status return value */
  1162. if (nla_put_u32(vendor_event,
  1163. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  1164. create_reason)) {
  1165. cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
  1166. goto nla_put_failure;
  1167. }
  1168. cfg80211_debug("sub command: %d, value: %d",
  1169. QCA_NL80211_VENDOR_SUBCMD_NDP,
  1170. QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE);
  1171. cfg80211_debug("create transaction id: %d, value: %d",
  1172. QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, create_transaction_id);
  1173. cfg80211_debug("status code: %d, value: %d",
  1174. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  1175. create_status);
  1176. cfg80211_debug("Return value: %d, value: %d",
  1177. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, create_reason);
  1178. cfg80211_vendor_event(vendor_event, GFP_KERNEL);
  1179. if (!create_fail) {
  1180. /* update txrx queues and register self sta */
  1181. cb_obj.drv_ndi_create_rsp_handler(wlan_vdev_get_id(vdev),
  1182. ndi_rsp);
  1183. } else {
  1184. cfg80211_err("NDI interface creation failed with reason %d",
  1185. ndi_rsp->reason);
  1186. goto close_ndi;
  1187. }
  1188. return;
  1189. nla_put_failure:
  1190. kfree_skb(vendor_event);
  1191. close_ndi:
  1192. cb_obj.ndi_close(wlan_vdev_get_id(vdev));
  1193. return;
  1194. }
  1195. /**
  1196. * os_if_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
  1197. * @adapter: pointer to adapter context
  1198. * @rsp_params: response parameters
  1199. *
  1200. * Return: none
  1201. */
  1202. static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc,
  1203. struct wlan_objmgr_vdev *vdev,
  1204. void *rsp_params)
  1205. {
  1206. QDF_STATUS status;
  1207. uint8_t vdev_id = wlan_vdev_get_id(vdev);
  1208. struct nan_datapath_inf_delete_rsp *ndi_rsp = rsp_params;
  1209. struct nan_callbacks cb_obj;
  1210. if (!ndi_rsp) {
  1211. cfg80211_err("Invalid ndi delete response");
  1212. return;
  1213. }
  1214. status = ucfg_nan_get_callbacks(psoc, &cb_obj);
  1215. if (QDF_IS_STATUS_ERROR(status)) {
  1216. cfg80211_err("Couldn't get ballback object");
  1217. return;
  1218. }
  1219. if (ndi_rsp->status == NAN_DATAPATH_RSP_STATUS_SUCCESS)
  1220. cfg80211_debug("NDI BSS successfully stopped");
  1221. else
  1222. cfg80211_debug("NDI BSS stop failed with reason %d",
  1223. ndi_rsp->reason);
  1224. ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason);
  1225. ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status);
  1226. cb_obj.drv_ndi_delete_rsp_handler(vdev_id);
  1227. }
  1228. void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc,
  1229. struct wlan_objmgr_vdev *vdev,
  1230. uint32_t type, void *msg)
  1231. {
  1232. switch (type) {
  1233. case NAN_DATAPATH_INF_CREATE_RSP:
  1234. os_if_ndp_iface_create_rsp_handler(psoc, vdev, msg);
  1235. break;
  1236. case NAN_DATAPATH_INF_DELETE_RSP:
  1237. os_if_ndp_iface_delete_rsp_handler(psoc, vdev, msg);
  1238. break;
  1239. case NDP_CONFIRM:
  1240. os_if_ndp_confirm_ind_handler(vdev, msg);
  1241. break;
  1242. case NDP_INITIATOR_RSP:
  1243. os_if_ndp_initiator_rsp_handler(vdev, msg);
  1244. break;
  1245. case NDP_INDICATION:
  1246. os_if_ndp_indication_handler(vdev, msg);
  1247. break;
  1248. case NDP_NEW_PEER:
  1249. os_if_new_peer_ind_handler(vdev, msg);
  1250. break;
  1251. case NDP_RESPONDER_RSP:
  1252. os_if_ndp_responder_rsp_handler(vdev, msg);
  1253. break;
  1254. case NDP_END_RSP:
  1255. os_if_ndp_end_rsp_handler(vdev, msg);
  1256. break;
  1257. case NDP_END_IND:
  1258. os_if_ndp_end_ind_handler(vdev, msg);
  1259. break;
  1260. case NDP_PEER_DEPARTED:
  1261. os_if_peer_departed_ind_handler(vdev, msg);
  1262. break;
  1263. default:
  1264. break;
  1265. }
  1266. }
  1267. int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
  1268. struct nan_callbacks *cb_obj)
  1269. {
  1270. return ucfg_nan_register_hdd_callbacks(psoc, cb_obj,
  1271. os_if_nan_event_handler);
  1272. }
  1273. int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
  1274. struct nan_callbacks *cb_obj)
  1275. {
  1276. return ucfg_nan_register_lim_callbacks(psoc, cb_obj);
  1277. }
  1278. void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc,
  1279. uint8_t vdev_id, bool success)
  1280. {
  1281. struct nan_datapath_inf_create_rsp rsp = {0};
  1282. struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
  1283. psoc, vdev_id, WLAN_NAN_ID);
  1284. if (success) {
  1285. rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
  1286. rsp.reason = 0;
  1287. os_if_nan_event_handler(psoc, vdev,
  1288. NAN_DATAPATH_INF_CREATE_RSP, &rsp);
  1289. } else {
  1290. rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
  1291. rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
  1292. os_if_nan_event_handler(psoc, vdev,
  1293. NAN_DATAPATH_INF_CREATE_RSP, &rsp);
  1294. }
  1295. wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
  1296. }
  1297. void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc,
  1298. uint8_t vdev_id, bool success)
  1299. {
  1300. struct nan_datapath_inf_delete_rsp rsp = {0};
  1301. struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
  1302. psoc, vdev_id, WLAN_NAN_ID);
  1303. if (success) {
  1304. rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
  1305. rsp.reason = 0;
  1306. os_if_nan_event_handler(psoc, vdev,
  1307. NAN_DATAPATH_INF_DELETE_RSP, &rsp);
  1308. } else {
  1309. rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
  1310. rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_DELETE_FAILED;
  1311. os_if_nan_event_handler(psoc, vdev,
  1312. NAN_DATAPATH_INF_DELETE_RSP, &rsp);
  1313. }
  1314. wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
  1315. }
  1316. void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev)
  1317. {
  1318. struct sk_buff *vendor_event;
  1319. struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
  1320. struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
  1321. uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
  1322. (NLA_HDRLEN * 4) + NLMSG_HDRLEN;
  1323. /*
  1324. * The virtual adapters are stopped and closed even during
  1325. * driver unload or stop, the service layer is not required
  1326. * to be informed in that case (response is not expected)
  1327. */
  1328. if (NAN_DATA_NDI_DELETING_STATE != ucfg_nan_get_ndi_state(vdev)) {
  1329. cfg80211_err("NDI interface deleted");
  1330. return;
  1331. }
  1332. /* notify response to the upper layer */
  1333. vendor_event = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
  1334. data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
  1335. GFP_KERNEL);
  1336. if (!vendor_event) {
  1337. cfg80211_err("cfg80211_vendor_event_alloc failed");
  1338. return;
  1339. }
  1340. /* Sub vendor command goes first */
  1341. if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  1342. QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
  1343. cfg80211_err("VENDOR_ATTR_NDP_SUBCMD put fail");
  1344. goto failure;
  1345. }
  1346. /* Transaction id */
  1347. if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
  1348. ucfg_nan_get_ndp_delete_transaction_id(vdev))) {
  1349. cfg80211_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
  1350. goto failure;
  1351. }
  1352. /* Status code */
  1353. if (nla_put_u32(vendor_event,
  1354. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  1355. ucfg_nan_get_ndi_delete_rsp_status(vdev))) {
  1356. cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
  1357. goto failure;
  1358. }
  1359. /* Status return value */
  1360. if (nla_put_u32(vendor_event,
  1361. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  1362. ucfg_nan_get_ndi_delete_rsp_reason(vdev))) {
  1363. cfg80211_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
  1364. goto failure;
  1365. }
  1366. cfg80211_debug("sub command: %d, value: %d",
  1367. QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
  1368. QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
  1369. cfg80211_debug("delete transaction id: %d, value: %d",
  1370. QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
  1371. ucfg_nan_get_ndp_delete_transaction_id(vdev));
  1372. cfg80211_debug("status code: %d, value: %d",
  1373. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
  1374. ucfg_nan_get_ndi_delete_rsp_status(vdev));
  1375. cfg80211_debug("Return value: %d, value: %d",
  1376. QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
  1377. ucfg_nan_get_ndi_delete_rsp_reason(vdev));
  1378. ucfg_nan_set_ndp_delete_transaction_id(vdev, 0);
  1379. ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE);
  1380. cfg80211_vendor_event(vendor_event, GFP_KERNEL);
  1381. return;
  1382. failure:
  1383. kfree_skb(vendor_event);
  1384. }