command.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2012 Intel Corporation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "hci: %s: " fmt, __func__
  6. #include <linux/init.h>
  7. #include <linux/kernel.h>
  8. #include <linux/sched.h>
  9. #include <linux/module.h>
  10. #include <net/nfc/hci.h>
  11. #include "hci.h"
  12. #define MAX_FWI 4949
  13. static int nfc_hci_execute_cmd_async(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
  14. const u8 *param, size_t param_len,
  15. data_exchange_cb_t cb, void *cb_context)
  16. {
  17. pr_debug("exec cmd async through pipe=%d, cmd=%d, plen=%zd\n", pipe,
  18. cmd, param_len);
  19. /* TODO: Define hci cmd execution delay. Should it be the same
  20. * for all commands?
  21. */
  22. return nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_COMMAND, cmd,
  23. param, param_len, cb, cb_context, MAX_FWI);
  24. }
  25. /*
  26. * HCI command execution completion callback.
  27. * err will be a standard linux error (may be converted from HCI response)
  28. * skb contains the response data and must be disposed, or may be NULL if
  29. * an error occurred
  30. */
  31. static void nfc_hci_execute_cb(void *context, struct sk_buff *skb, int err)
  32. {
  33. struct hcp_exec_waiter *hcp_ew = (struct hcp_exec_waiter *)context;
  34. pr_debug("HCI Cmd completed with result=%d\n", err);
  35. hcp_ew->exec_result = err;
  36. if (hcp_ew->exec_result == 0)
  37. hcp_ew->result_skb = skb;
  38. else
  39. kfree_skb(skb);
  40. hcp_ew->exec_complete = true;
  41. wake_up(hcp_ew->wq);
  42. }
  43. static int nfc_hci_execute_cmd(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
  44. const u8 *param, size_t param_len,
  45. struct sk_buff **skb)
  46. {
  47. DECLARE_WAIT_QUEUE_HEAD_ONSTACK(ew_wq);
  48. struct hcp_exec_waiter hcp_ew;
  49. hcp_ew.wq = &ew_wq;
  50. hcp_ew.exec_complete = false;
  51. hcp_ew.result_skb = NULL;
  52. pr_debug("exec cmd sync through pipe=%d, cmd=%d, plen=%zd\n", pipe,
  53. cmd, param_len);
  54. /* TODO: Define hci cmd execution delay. Should it be the same
  55. * for all commands?
  56. */
  57. hcp_ew.exec_result = nfc_hci_hcp_message_tx(hdev, pipe,
  58. NFC_HCI_HCP_COMMAND, cmd,
  59. param, param_len,
  60. nfc_hci_execute_cb, &hcp_ew,
  61. MAX_FWI);
  62. if (hcp_ew.exec_result < 0)
  63. return hcp_ew.exec_result;
  64. wait_event(ew_wq, hcp_ew.exec_complete == true);
  65. if (hcp_ew.exec_result == 0) {
  66. if (skb)
  67. *skb = hcp_ew.result_skb;
  68. else
  69. kfree_skb(hcp_ew.result_skb);
  70. }
  71. return hcp_ew.exec_result;
  72. }
  73. int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event,
  74. const u8 *param, size_t param_len)
  75. {
  76. u8 pipe;
  77. pr_debug("%d to gate %d\n", event, gate);
  78. pipe = hdev->gate2pipe[gate];
  79. if (pipe == NFC_HCI_INVALID_PIPE)
  80. return -EADDRNOTAVAIL;
  81. return nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_EVENT, event,
  82. param, param_len, NULL, NULL, 0);
  83. }
  84. EXPORT_SYMBOL(nfc_hci_send_event);
  85. /*
  86. * Execute an hci command sent to gate.
  87. * skb will contain response data if success. skb can be NULL if you are not
  88. * interested by the response.
  89. */
  90. int nfc_hci_send_cmd(struct nfc_hci_dev *hdev, u8 gate, u8 cmd,
  91. const u8 *param, size_t param_len, struct sk_buff **skb)
  92. {
  93. u8 pipe;
  94. pipe = hdev->gate2pipe[gate];
  95. if (pipe == NFC_HCI_INVALID_PIPE)
  96. return -EADDRNOTAVAIL;
  97. return nfc_hci_execute_cmd(hdev, pipe, cmd, param, param_len, skb);
  98. }
  99. EXPORT_SYMBOL(nfc_hci_send_cmd);
  100. int nfc_hci_send_cmd_async(struct nfc_hci_dev *hdev, u8 gate, u8 cmd,
  101. const u8 *param, size_t param_len,
  102. data_exchange_cb_t cb, void *cb_context)
  103. {
  104. u8 pipe;
  105. pipe = hdev->gate2pipe[gate];
  106. if (pipe == NFC_HCI_INVALID_PIPE)
  107. return -EADDRNOTAVAIL;
  108. return nfc_hci_execute_cmd_async(hdev, pipe, cmd, param, param_len,
  109. cb, cb_context);
  110. }
  111. EXPORT_SYMBOL(nfc_hci_send_cmd_async);
  112. int nfc_hci_set_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx,
  113. const u8 *param, size_t param_len)
  114. {
  115. int r;
  116. u8 *tmp;
  117. /* TODO ELa: reg idx must be inserted before param, but we don't want
  118. * to ask the caller to do it to keep a simpler API.
  119. * For now, just create a new temporary param buffer. This is far from
  120. * optimal though, and the plan is to modify APIs to pass idx down to
  121. * nfc_hci_hcp_message_tx where the frame is actually built, thereby
  122. * eliminating the need for the temp allocation-copy here.
  123. */
  124. pr_debug("idx=%d to gate %d\n", idx, gate);
  125. tmp = kmalloc(1 + param_len, GFP_KERNEL);
  126. if (tmp == NULL)
  127. return -ENOMEM;
  128. *tmp = idx;
  129. memcpy(tmp + 1, param, param_len);
  130. r = nfc_hci_send_cmd(hdev, gate, NFC_HCI_ANY_SET_PARAMETER,
  131. tmp, param_len + 1, NULL);
  132. kfree(tmp);
  133. return r;
  134. }
  135. EXPORT_SYMBOL(nfc_hci_set_param);
  136. int nfc_hci_get_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx,
  137. struct sk_buff **skb)
  138. {
  139. pr_debug("gate=%d regidx=%d\n", gate, idx);
  140. return nfc_hci_send_cmd(hdev, gate, NFC_HCI_ANY_GET_PARAMETER,
  141. &idx, 1, skb);
  142. }
  143. EXPORT_SYMBOL(nfc_hci_get_param);
  144. static int nfc_hci_open_pipe(struct nfc_hci_dev *hdev, u8 pipe)
  145. {
  146. struct sk_buff *skb;
  147. int r;
  148. pr_debug("pipe=%d\n", pipe);
  149. r = nfc_hci_execute_cmd(hdev, pipe, NFC_HCI_ANY_OPEN_PIPE,
  150. NULL, 0, &skb);
  151. if (r == 0) {
  152. /* dest host other than host controller will send
  153. * number of pipes already open on this gate before
  154. * execution. The number can be found in skb->data[0]
  155. */
  156. kfree_skb(skb);
  157. }
  158. return r;
  159. }
  160. static int nfc_hci_close_pipe(struct nfc_hci_dev *hdev, u8 pipe)
  161. {
  162. return nfc_hci_execute_cmd(hdev, pipe, NFC_HCI_ANY_CLOSE_PIPE,
  163. NULL, 0, NULL);
  164. }
  165. static u8 nfc_hci_create_pipe(struct nfc_hci_dev *hdev, u8 dest_host,
  166. u8 dest_gate, int *result)
  167. {
  168. struct sk_buff *skb;
  169. struct hci_create_pipe_params params;
  170. struct hci_create_pipe_resp *resp;
  171. u8 pipe;
  172. pr_debug("gate=%d\n", dest_gate);
  173. params.src_gate = NFC_HCI_ADMIN_GATE;
  174. params.dest_host = dest_host;
  175. params.dest_gate = dest_gate;
  176. *result = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE,
  177. NFC_HCI_ADM_CREATE_PIPE,
  178. (u8 *) &params, sizeof(params), &skb);
  179. if (*result < 0)
  180. return NFC_HCI_INVALID_PIPE;
  181. resp = (struct hci_create_pipe_resp *)skb->data;
  182. pipe = resp->pipe;
  183. kfree_skb(skb);
  184. pr_debug("pipe created=%d\n", pipe);
  185. return pipe;
  186. }
  187. static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe)
  188. {
  189. return nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE,
  190. NFC_HCI_ADM_DELETE_PIPE, &pipe, 1, NULL);
  191. }
  192. static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev)
  193. {
  194. u8 param[2];
  195. size_t param_len = 2;
  196. /* TODO: Find out what the identity reference data is
  197. * and fill param with it. HCI spec 6.1.3.5 */
  198. if (test_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &hdev->quirks))
  199. param_len = 0;
  200. return nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE,
  201. NFC_HCI_ADM_CLEAR_ALL_PIPE, param, param_len,
  202. NULL);
  203. }
  204. int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate)
  205. {
  206. int r;
  207. u8 pipe = hdev->gate2pipe[gate];
  208. if (pipe == NFC_HCI_INVALID_PIPE)
  209. return -EADDRNOTAVAIL;
  210. r = nfc_hci_close_pipe(hdev, pipe);
  211. if (r < 0)
  212. return r;
  213. if (pipe != NFC_HCI_LINK_MGMT_PIPE && pipe != NFC_HCI_ADMIN_PIPE) {
  214. r = nfc_hci_delete_pipe(hdev, pipe);
  215. if (r < 0)
  216. return r;
  217. }
  218. hdev->gate2pipe[gate] = NFC_HCI_INVALID_PIPE;
  219. return 0;
  220. }
  221. EXPORT_SYMBOL(nfc_hci_disconnect_gate);
  222. int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev)
  223. {
  224. int r;
  225. r = nfc_hci_clear_all_pipes(hdev);
  226. if (r < 0)
  227. return r;
  228. nfc_hci_reset_pipes(hdev);
  229. return 0;
  230. }
  231. EXPORT_SYMBOL(nfc_hci_disconnect_all_gates);
  232. int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
  233. u8 pipe)
  234. {
  235. bool pipe_created = false;
  236. int r;
  237. if (pipe == NFC_HCI_DO_NOT_CREATE_PIPE)
  238. return 0;
  239. if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE)
  240. return -EADDRINUSE;
  241. if (pipe != NFC_HCI_INVALID_PIPE)
  242. goto open_pipe;
  243. switch (dest_gate) {
  244. case NFC_HCI_LINK_MGMT_GATE:
  245. pipe = NFC_HCI_LINK_MGMT_PIPE;
  246. break;
  247. case NFC_HCI_ADMIN_GATE:
  248. pipe = NFC_HCI_ADMIN_PIPE;
  249. break;
  250. default:
  251. pipe = nfc_hci_create_pipe(hdev, dest_host, dest_gate, &r);
  252. if (pipe == NFC_HCI_INVALID_PIPE)
  253. return r;
  254. pipe_created = true;
  255. break;
  256. }
  257. open_pipe:
  258. r = nfc_hci_open_pipe(hdev, pipe);
  259. if (r < 0) {
  260. if (pipe_created)
  261. if (nfc_hci_delete_pipe(hdev, pipe) < 0) {
  262. /* TODO: Cannot clean by deleting pipe...
  263. * -> inconsistent state */
  264. }
  265. return r;
  266. }
  267. hdev->pipes[pipe].gate = dest_gate;
  268. hdev->pipes[pipe].dest_host = dest_host;
  269. hdev->gate2pipe[dest_gate] = pipe;
  270. return 0;
  271. }
  272. EXPORT_SYMBOL(nfc_hci_connect_gate);