xref: /kernel/linux/linux-5.10/net/nfc/nci/rsp.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 *  The NFC Controller Interface is the communication protocol between an
4 *  NFC Controller (NFCC) and a Device Host (DH).
5 *
6 *  Copyright (C) 2011 Texas Instruments, Inc.
7 *
8 *  Written by Ilan Elias <ilane@ti.com>
9 *
10 *  Acknowledgements:
11 *  This file is based on hci_event.c, which was written
12 *  by Maxim Krasnyansky.
13 */
14
15#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
16
17#include <linux/types.h>
18#include <linux/interrupt.h>
19#include <linux/bitops.h>
20#include <linux/skbuff.h>
21
22#include "../nfc.h"
23#include <net/nfc/nci.h>
24#include <net/nfc/nci_core.h>
25
26/* Handle NCI Response packets */
27
28static void nci_core_reset_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
29{
30	struct nci_core_reset_rsp *rsp = (void *) skb->data;
31
32	pr_debug("status 0x%x\n", rsp->status);
33
34	if (rsp->status == NCI_STATUS_OK) {
35		ndev->nci_ver = rsp->nci_ver;
36		pr_debug("nci_ver 0x%x, config_status 0x%x\n",
37			 rsp->nci_ver, rsp->config_status);
38	}
39
40	nci_req_complete(ndev, rsp->status);
41}
42
43static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
44{
45	struct nci_core_init_rsp_1 *rsp_1 = (void *) skb->data;
46	struct nci_core_init_rsp_2 *rsp_2;
47
48	pr_debug("status 0x%x\n", rsp_1->status);
49
50	if (rsp_1->status != NCI_STATUS_OK)
51		goto exit;
52
53	ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features);
54	ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces;
55
56	if (ndev->num_supported_rf_interfaces >
57	    NCI_MAX_SUPPORTED_RF_INTERFACES) {
58		ndev->num_supported_rf_interfaces =
59			NCI_MAX_SUPPORTED_RF_INTERFACES;
60	}
61
62	memcpy(ndev->supported_rf_interfaces,
63	       rsp_1->supported_rf_interfaces,
64	       ndev->num_supported_rf_interfaces);
65
66	rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces);
67
68	ndev->max_logical_connections = rsp_2->max_logical_connections;
69	ndev->max_routing_table_size =
70		__le16_to_cpu(rsp_2->max_routing_table_size);
71	ndev->max_ctrl_pkt_payload_len =
72		rsp_2->max_ctrl_pkt_payload_len;
73	ndev->max_size_for_large_params =
74		__le16_to_cpu(rsp_2->max_size_for_large_params);
75	ndev->manufact_id =
76		rsp_2->manufact_id;
77	ndev->manufact_specific_info =
78		__le32_to_cpu(rsp_2->manufact_specific_info);
79
80	pr_debug("nfcc_features 0x%x\n",
81		 ndev->nfcc_features);
82	pr_debug("num_supported_rf_interfaces %d\n",
83		 ndev->num_supported_rf_interfaces);
84	pr_debug("supported_rf_interfaces[0] 0x%x\n",
85		 ndev->supported_rf_interfaces[0]);
86	pr_debug("supported_rf_interfaces[1] 0x%x\n",
87		 ndev->supported_rf_interfaces[1]);
88	pr_debug("supported_rf_interfaces[2] 0x%x\n",
89		 ndev->supported_rf_interfaces[2]);
90	pr_debug("supported_rf_interfaces[3] 0x%x\n",
91		 ndev->supported_rf_interfaces[3]);
92	pr_debug("max_logical_connections %d\n",
93		 ndev->max_logical_connections);
94	pr_debug("max_routing_table_size %d\n",
95		 ndev->max_routing_table_size);
96	pr_debug("max_ctrl_pkt_payload_len %d\n",
97		 ndev->max_ctrl_pkt_payload_len);
98	pr_debug("max_size_for_large_params %d\n",
99		 ndev->max_size_for_large_params);
100	pr_debug("manufact_id 0x%x\n",
101		 ndev->manufact_id);
102	pr_debug("manufact_specific_info 0x%x\n",
103		 ndev->manufact_specific_info);
104
105exit:
106	nci_req_complete(ndev, rsp_1->status);
107}
108
109static void nci_core_set_config_rsp_packet(struct nci_dev *ndev,
110					   struct sk_buff *skb)
111{
112	struct nci_core_set_config_rsp *rsp = (void *) skb->data;
113
114	pr_debug("status 0x%x\n", rsp->status);
115
116	nci_req_complete(ndev, rsp->status);
117}
118
119static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev,
120				       struct sk_buff *skb)
121{
122	__u8 status = skb->data[0];
123
124	pr_debug("status 0x%x\n", status);
125
126	nci_req_complete(ndev, status);
127}
128
129static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
130{
131	struct nci_conn_info    *conn_info;
132	__u8 status = skb->data[0];
133
134	pr_debug("status 0x%x\n", status);
135
136	if (status == NCI_STATUS_OK) {
137		atomic_set(&ndev->state, NCI_DISCOVERY);
138
139		conn_info = ndev->rf_conn_info;
140		if (!conn_info) {
141			conn_info = devm_kzalloc(&ndev->nfc_dev->dev,
142						 sizeof(struct nci_conn_info),
143						 GFP_KERNEL);
144			if (!conn_info) {
145				status = NCI_STATUS_REJECTED;
146				goto exit;
147			}
148			conn_info->conn_id = NCI_STATIC_RF_CONN_ID;
149			INIT_LIST_HEAD(&conn_info->list);
150			list_add(&conn_info->list, &ndev->conn_info_list);
151			ndev->rf_conn_info = conn_info;
152		}
153	}
154
155exit:
156	nci_req_complete(ndev, status);
157}
158
159static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev,
160					  struct sk_buff *skb)
161{
162	__u8 status = skb->data[0];
163
164	pr_debug("status 0x%x\n", status);
165
166	/* Complete the request on intf_activated_ntf or generic_error_ntf */
167	if (status != NCI_STATUS_OK)
168		nci_req_complete(ndev, status);
169}
170
171static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
172					 struct sk_buff *skb)
173{
174	__u8 status = skb->data[0];
175
176	pr_debug("status 0x%x\n", status);
177
178	/* If target was active, complete the request only in deactivate_ntf */
179	if ((status != NCI_STATUS_OK) ||
180	    (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
181		nci_clear_target_list(ndev);
182		atomic_set(&ndev->state, NCI_IDLE);
183		nci_req_complete(ndev, status);
184	}
185}
186
187static void nci_nfcee_discover_rsp_packet(struct nci_dev *ndev,
188					  struct sk_buff *skb)
189{
190	struct nci_nfcee_discover_rsp *discover_rsp;
191
192	if (skb->len != 2) {
193		nci_req_complete(ndev, NCI_STATUS_NFCEE_PROTOCOL_ERROR);
194		return;
195	}
196
197	discover_rsp = (struct nci_nfcee_discover_rsp *)skb->data;
198
199	if (discover_rsp->status != NCI_STATUS_OK ||
200	    discover_rsp->num_nfcee == 0)
201		nci_req_complete(ndev, discover_rsp->status);
202}
203
204static void nci_nfcee_mode_set_rsp_packet(struct nci_dev *ndev,
205					  struct sk_buff *skb)
206{
207	__u8 status = skb->data[0];
208
209	pr_debug("status 0x%x\n", status);
210	nci_req_complete(ndev, status);
211}
212
213static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev,
214					    struct sk_buff *skb)
215{
216	__u8 status = skb->data[0];
217	struct nci_conn_info *conn_info = NULL;
218	struct nci_core_conn_create_rsp *rsp;
219
220	pr_debug("status 0x%x\n", status);
221
222	if (status == NCI_STATUS_OK) {
223		rsp = (struct nci_core_conn_create_rsp *)skb->data;
224
225		conn_info = devm_kzalloc(&ndev->nfc_dev->dev,
226					 sizeof(*conn_info), GFP_KERNEL);
227		if (!conn_info) {
228			status = NCI_STATUS_REJECTED;
229			goto exit;
230		}
231
232		conn_info->dest_params = devm_kzalloc(&ndev->nfc_dev->dev,
233						sizeof(struct dest_spec_params),
234						GFP_KERNEL);
235		if (!conn_info->dest_params) {
236			status = NCI_STATUS_REJECTED;
237			goto free_conn_info;
238		}
239
240		conn_info->dest_type = ndev->cur_dest_type;
241		conn_info->dest_params->id = ndev->cur_params.id;
242		conn_info->dest_params->protocol = ndev->cur_params.protocol;
243		conn_info->conn_id = rsp->conn_id;
244
245		/* Note: data_exchange_cb and data_exchange_cb_context need to
246		 * be specify out of nci_core_conn_create_rsp_packet
247		 */
248
249		INIT_LIST_HEAD(&conn_info->list);
250		list_add(&conn_info->list, &ndev->conn_info_list);
251
252		if (ndev->cur_params.id == ndev->hci_dev->nfcee_id)
253			ndev->hci_dev->conn_info = conn_info;
254
255		conn_info->conn_id = rsp->conn_id;
256		conn_info->max_pkt_payload_len = rsp->max_ctrl_pkt_payload_len;
257		atomic_set(&conn_info->credits_cnt, rsp->credits_cnt);
258	}
259
260free_conn_info:
261	if (status == NCI_STATUS_REJECTED)
262		devm_kfree(&ndev->nfc_dev->dev, conn_info);
263exit:
264
265	nci_req_complete(ndev, status);
266}
267
268static void nci_core_conn_close_rsp_packet(struct nci_dev *ndev,
269					   struct sk_buff *skb)
270{
271	struct nci_conn_info *conn_info;
272	__u8 status = skb->data[0];
273
274	pr_debug("status 0x%x\n", status);
275	if (status == NCI_STATUS_OK) {
276		conn_info = nci_get_conn_info_by_conn_id(ndev,
277							 ndev->cur_conn_id);
278		if (conn_info) {
279			list_del(&conn_info->list);
280			if (conn_info == ndev->rf_conn_info)
281				ndev->rf_conn_info = NULL;
282			devm_kfree(&ndev->nfc_dev->dev, conn_info);
283		}
284	}
285	nci_req_complete(ndev, status);
286}
287
288void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
289{
290	__u16 rsp_opcode = nci_opcode(skb->data);
291
292	/* we got a rsp, stop the cmd timer */
293	del_timer(&ndev->cmd_timer);
294
295	pr_debug("NCI RX: MT=rsp, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
296		 nci_pbf(skb->data),
297		 nci_opcode_gid(rsp_opcode),
298		 nci_opcode_oid(rsp_opcode),
299		 nci_plen(skb->data));
300
301	/* strip the nci control header */
302	skb_pull(skb, NCI_CTRL_HDR_SIZE);
303
304	if (nci_opcode_gid(rsp_opcode) == NCI_GID_PROPRIETARY) {
305		if (nci_prop_rsp_packet(ndev, rsp_opcode, skb) == -ENOTSUPP) {
306			pr_err("unsupported rsp opcode 0x%x\n",
307			       rsp_opcode);
308		}
309
310		goto end;
311	}
312
313	switch (rsp_opcode) {
314	case NCI_OP_CORE_RESET_RSP:
315		nci_core_reset_rsp_packet(ndev, skb);
316		break;
317
318	case NCI_OP_CORE_INIT_RSP:
319		nci_core_init_rsp_packet(ndev, skb);
320		break;
321
322	case NCI_OP_CORE_SET_CONFIG_RSP:
323		nci_core_set_config_rsp_packet(ndev, skb);
324		break;
325
326	case NCI_OP_CORE_CONN_CREATE_RSP:
327		nci_core_conn_create_rsp_packet(ndev, skb);
328		break;
329
330	case NCI_OP_CORE_CONN_CLOSE_RSP:
331		nci_core_conn_close_rsp_packet(ndev, skb);
332		break;
333
334	case NCI_OP_RF_DISCOVER_MAP_RSP:
335		nci_rf_disc_map_rsp_packet(ndev, skb);
336		break;
337
338	case NCI_OP_RF_DISCOVER_RSP:
339		nci_rf_disc_rsp_packet(ndev, skb);
340		break;
341
342	case NCI_OP_RF_DISCOVER_SELECT_RSP:
343		nci_rf_disc_select_rsp_packet(ndev, skb);
344		break;
345
346	case NCI_OP_RF_DEACTIVATE_RSP:
347		nci_rf_deactivate_rsp_packet(ndev, skb);
348		break;
349
350	case NCI_OP_NFCEE_DISCOVER_RSP:
351		nci_nfcee_discover_rsp_packet(ndev, skb);
352		break;
353
354	case NCI_OP_NFCEE_MODE_SET_RSP:
355		nci_nfcee_mode_set_rsp_packet(ndev, skb);
356		break;
357
358	default:
359		pr_err("unknown rsp opcode 0x%x\n", rsp_opcode);
360		break;
361	}
362
363	nci_core_rsp_packet(ndev, rsp_opcode, skb);
364end:
365	kfree_skb(skb);
366
367	/* trigger the next cmd */
368	atomic_set(&ndev->cmd_cnt, 1);
369	if (!skb_queue_empty(&ndev->cmd_q))
370		queue_work(ndev->cmd_wq, &ndev->cmd_work);
371}
372