xref: /linux/net/nfc/nci/hci.c (revision c0e297dc61f8d4453e07afbea1fa8d0e67cd4a34)
1 /*
2  *  The NFC Controller Interface is the communication protocol between an
3  *  NFC Controller (NFCC) and a Device Host (DH).
4  *  This is the HCI over NCI implementation, as specified in the 10.2
5  *  section of the NCI 1.1 specification.
6  *
7  *  Copyright (C) 2014  STMicroelectronics SAS. All rights reserved.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2
11  *  as published by the Free Software Foundation
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <linux/skbuff.h>
24 
25 #include "../nfc.h"
26 #include <net/nfc/nci.h>
27 #include <net/nfc/nci_core.h>
28 #include <linux/nfc.h>
29 
30 struct nci_data {
31 	u8              conn_id;
32 	u8              pipe;
33 	u8              cmd;
34 	const u8        *data;
35 	u32             data_len;
36 } __packed;
37 
38 struct nci_hci_create_pipe_params {
39 	u8 src_gate;
40 	u8 dest_host;
41 	u8 dest_gate;
42 } __packed;
43 
44 struct nci_hci_create_pipe_resp {
45 	u8 src_host;
46 	u8 src_gate;
47 	u8 dest_host;
48 	u8 dest_gate;
49 	u8 pipe;
50 } __packed;
51 
52 struct nci_hci_delete_pipe_noti {
53 	u8 pipe;
54 } __packed;
55 
56 struct nci_hci_all_pipe_cleared_noti {
57 	u8 host;
58 } __packed;
59 
60 struct nci_hcp_message {
61 	u8 header;      /* type -cmd,evt,rsp- + instruction */
62 	u8 data[];
63 } __packed;
64 
65 struct nci_hcp_packet {
66 	u8 header;      /* cbit+pipe */
67 	struct nci_hcp_message message;
68 } __packed;
69 
70 #define NCI_HCI_ANY_SET_PARAMETER  0x01
71 #define NCI_HCI_ANY_GET_PARAMETER  0x02
72 #define NCI_HCI_ANY_CLOSE_PIPE     0x04
73 
74 #define NCI_HFP_NO_CHAINING        0x80
75 
76 #define NCI_NFCEE_ID_HCI                0x80
77 
78 #define NCI_EVT_HOT_PLUG           0x03
79 
80 #define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY       0x01
81 
82 /* HCP headers */
83 #define NCI_HCI_HCP_PACKET_HEADER_LEN      1
84 #define NCI_HCI_HCP_MESSAGE_HEADER_LEN     1
85 #define NCI_HCI_HCP_HEADER_LEN             2
86 
87 /* HCP types */
88 #define NCI_HCI_HCP_COMMAND        0x00
89 #define NCI_HCI_HCP_EVENT          0x01
90 #define NCI_HCI_HCP_RESPONSE       0x02
91 
92 #define NCI_HCI_ADM_NOTIFY_PIPE_CREATED     0x12
93 #define NCI_HCI_ADM_NOTIFY_PIPE_DELETED     0x13
94 #define NCI_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
95 
96 #define NCI_HCI_FRAGMENT           0x7f
97 #define NCI_HCP_HEADER(type, instr) ((((type) & 0x03) << 6) |\
98 				      ((instr) & 0x3f))
99 
100 #define NCI_HCP_MSG_GET_TYPE(header) ((header & 0xc0) >> 6)
101 #define NCI_HCP_MSG_GET_CMD(header)  (header & 0x3f)
102 #define NCI_HCP_MSG_GET_PIPE(header) (header & 0x7f)
103 
104 /* HCI core */
105 static void nci_hci_reset_pipes(struct nci_hci_dev *hdev)
106 {
107 	int i;
108 
109 	for (i = 0; i < NCI_HCI_MAX_PIPES; i++) {
110 		hdev->pipes[i].gate = NCI_HCI_INVALID_GATE;
111 		hdev->pipes[i].host = NCI_HCI_INVALID_HOST;
112 	}
113 	memset(hdev->gate2pipe, NCI_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe));
114 }
115 
116 static void nci_hci_reset_pipes_per_host(struct nci_dev *ndev, u8 host)
117 {
118 	int i;
119 
120 	for (i = 0; i < NCI_HCI_MAX_PIPES; i++) {
121 		if (ndev->hci_dev->pipes[i].host == host) {
122 			ndev->hci_dev->pipes[i].gate = NCI_HCI_INVALID_GATE;
123 			ndev->hci_dev->pipes[i].host = NCI_HCI_INVALID_HOST;
124 		}
125 	}
126 }
127 
128 /* Fragment HCI data over NCI packet.
129  * NFC Forum NCI 10.2.2 Data Exchange:
130  * The payload of the Data Packets sent on the Logical Connection SHALL be
131  * valid HCP packets, as defined within [ETSI_102622]. Each Data Packet SHALL
132  * contain a single HCP packet. NCI Segmentation and Reassembly SHALL NOT be
133  * applied to Data Messages in either direction. The HCI fragmentation mechanism
134  * is used if required.
135  */
136 static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
137 			     const u8 data_type, const u8 *data,
138 			     size_t data_len)
139 {
140 	struct nci_conn_info    *conn_info;
141 	struct sk_buff *skb;
142 	int len, i, r;
143 	u8 cb = pipe;
144 
145 	conn_info = ndev->hci_dev->conn_info;
146 	if (!conn_info)
147 		return -EPROTO;
148 
149 	skb = nci_skb_alloc(ndev, 2 + conn_info->max_pkt_payload_len +
150 			    NCI_DATA_HDR_SIZE, GFP_KERNEL);
151 	if (!skb)
152 		return -ENOMEM;
153 
154 	skb_reserve(skb, 2 + NCI_DATA_HDR_SIZE);
155 	*skb_push(skb, 1) = data_type;
156 
157 	i = 0;
158 	len = conn_info->max_pkt_payload_len;
159 
160 	do {
161 		/* If last packet add NCI_HFP_NO_CHAINING */
162 		if (i + conn_info->max_pkt_payload_len -
163 		    (skb->len + 1) >= data_len) {
164 			cb |= NCI_HFP_NO_CHAINING;
165 			len = data_len - i;
166 		} else {
167 			len = conn_info->max_pkt_payload_len - skb->len - 1;
168 		}
169 
170 		*skb_push(skb, 1) = cb;
171 
172 		if (len > 0)
173 			memcpy(skb_put(skb, len), data + i, len);
174 
175 		r = nci_send_data(ndev, conn_info->conn_id, skb);
176 		if (r < 0)
177 			return r;
178 
179 		i += len;
180 		if (i < data_len) {
181 			skb_trim(skb, 0);
182 			skb_pull(skb, len);
183 		}
184 	} while (i < data_len);
185 
186 	return i;
187 }
188 
189 static void nci_hci_send_data_req(struct nci_dev *ndev, unsigned long opt)
190 {
191 	struct nci_data *data = (struct nci_data *)opt;
192 
193 	nci_hci_send_data(ndev, data->pipe, data->cmd,
194 			  data->data, data->data_len);
195 }
196 
197 int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event,
198 		       const u8 *param, size_t param_len)
199 {
200 	u8 pipe = ndev->hci_dev->gate2pipe[gate];
201 
202 	if (pipe == NCI_HCI_INVALID_PIPE)
203 		return -EADDRNOTAVAIL;
204 
205 	return nci_hci_send_data(ndev, pipe,
206 			NCI_HCP_HEADER(NCI_HCI_HCP_EVENT, event),
207 			param, param_len);
208 }
209 EXPORT_SYMBOL(nci_hci_send_event);
210 
211 int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate, u8 cmd,
212 		     const u8 *param, size_t param_len,
213 		     struct sk_buff **skb)
214 {
215 	struct nci_conn_info    *conn_info;
216 	struct nci_data data;
217 	int r;
218 	u8 pipe = ndev->hci_dev->gate2pipe[gate];
219 
220 	if (pipe == NCI_HCI_INVALID_PIPE)
221 		return -EADDRNOTAVAIL;
222 
223 	conn_info = ndev->hci_dev->conn_info;
224 	if (!conn_info)
225 		return -EPROTO;
226 
227 	data.conn_id = conn_info->conn_id;
228 	data.pipe = pipe;
229 	data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND, cmd);
230 	data.data = param;
231 	data.data_len = param_len;
232 
233 	r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
234 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
235 
236 	if (r == NCI_STATUS_OK)
237 		*skb = conn_info->rx_skb;
238 
239 	return r;
240 }
241 EXPORT_SYMBOL(nci_hci_send_cmd);
242 
243 static void nci_hci_event_received(struct nci_dev *ndev, u8 pipe,
244 				   u8 event, struct sk_buff *skb)
245 {
246 	if (ndev->ops->hci_event_received)
247 		ndev->ops->hci_event_received(ndev, pipe, event, skb);
248 }
249 
250 static void nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe,
251 				 u8 cmd, struct sk_buff *skb)
252 {
253 	u8 gate = ndev->hci_dev->pipes[pipe].gate;
254 	u8 status = NCI_HCI_ANY_OK | ~NCI_HCI_FRAGMENT;
255 	u8 dest_gate, new_pipe;
256 	struct nci_hci_create_pipe_resp *create_info;
257 	struct nci_hci_delete_pipe_noti *delete_info;
258 	struct nci_hci_all_pipe_cleared_noti *cleared_info;
259 
260 	pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd);
261 
262 	switch (cmd) {
263 	case NCI_HCI_ADM_NOTIFY_PIPE_CREATED:
264 		if (skb->len != 5) {
265 			status = NCI_HCI_ANY_E_NOK;
266 			goto exit;
267 		}
268 		create_info = (struct nci_hci_create_pipe_resp *)skb->data;
269 		dest_gate = create_info->dest_gate;
270 		new_pipe = create_info->pipe;
271 
272 		/* Save the new created pipe and bind with local gate,
273 		 * the description for skb->data[3] is destination gate id
274 		 * but since we received this cmd from host controller, we
275 		 * are the destination and it is our local gate
276 		 */
277 		ndev->hci_dev->gate2pipe[dest_gate] = new_pipe;
278 		ndev->hci_dev->pipes[new_pipe].gate = dest_gate;
279 		ndev->hci_dev->pipes[new_pipe].host =
280 						create_info->src_host;
281 		break;
282 	case NCI_HCI_ANY_OPEN_PIPE:
283 		/* If the pipe is not created report an error */
284 		if (gate == NCI_HCI_INVALID_GATE) {
285 			status = NCI_HCI_ANY_E_NOK;
286 			goto exit;
287 		}
288 		break;
289 	case NCI_HCI_ADM_NOTIFY_PIPE_DELETED:
290 		if (skb->len != 1) {
291 			status = NCI_HCI_ANY_E_NOK;
292 			goto exit;
293 		}
294 		delete_info = (struct nci_hci_delete_pipe_noti *)skb->data;
295 
296 		ndev->hci_dev->pipes[delete_info->pipe].gate =
297 						NCI_HCI_INVALID_GATE;
298 		ndev->hci_dev->pipes[delete_info->pipe].host =
299 						NCI_HCI_INVALID_HOST;
300 		break;
301 	case NCI_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
302 		if (skb->len != 1) {
303 			status = NCI_HCI_ANY_E_NOK;
304 			goto exit;
305 		}
306 
307 		cleared_info =
308 			(struct nci_hci_all_pipe_cleared_noti *)skb->data;
309 		nci_hci_reset_pipes_per_host(ndev, cleared_info->host);
310 		break;
311 	default:
312 		pr_debug("Discarded unknown cmd %x to gate %x\n", cmd, gate);
313 		break;
314 	}
315 
316 	if (ndev->ops->hci_cmd_received)
317 		ndev->ops->hci_cmd_received(ndev, pipe, cmd, skb);
318 
319 exit:
320 	nci_hci_send_data(ndev, pipe, status, NULL, 0);
321 
322 	kfree_skb(skb);
323 }
324 
325 static void nci_hci_resp_received(struct nci_dev *ndev, u8 pipe,
326 				  u8 result, struct sk_buff *skb)
327 {
328 	struct nci_conn_info    *conn_info;
329 	u8 status = result;
330 
331 	if (result != NCI_HCI_ANY_OK)
332 		goto exit;
333 
334 	conn_info = ndev->hci_dev->conn_info;
335 	if (!conn_info) {
336 		status = NCI_STATUS_REJECTED;
337 		goto exit;
338 	}
339 
340 	conn_info->rx_skb = skb;
341 
342 exit:
343 	nci_req_complete(ndev, status);
344 }
345 
346 /* Receive hcp message for pipe, with type and cmd.
347  * skb contains optional message data only.
348  */
349 static void nci_hci_hcp_message_rx(struct nci_dev *ndev, u8 pipe,
350 				   u8 type, u8 instruction, struct sk_buff *skb)
351 {
352 	switch (type) {
353 	case NCI_HCI_HCP_RESPONSE:
354 		nci_hci_resp_received(ndev, pipe, instruction, skb);
355 		break;
356 	case NCI_HCI_HCP_COMMAND:
357 		nci_hci_cmd_received(ndev, pipe, instruction, skb);
358 		break;
359 	case NCI_HCI_HCP_EVENT:
360 		nci_hci_event_received(ndev, pipe, instruction, skb);
361 		break;
362 	default:
363 		pr_err("UNKNOWN MSG Type %d, instruction=%d\n",
364 		       type, instruction);
365 		kfree_skb(skb);
366 		break;
367 	}
368 
369 	nci_req_complete(ndev, 0);
370 }
371 
372 static void nci_hci_msg_rx_work(struct work_struct *work)
373 {
374 	struct nci_hci_dev *hdev =
375 		container_of(work, struct nci_hci_dev, msg_rx_work);
376 	struct sk_buff *skb;
377 	struct nci_hcp_message *message;
378 	u8 pipe, type, instruction;
379 
380 	while ((skb = skb_dequeue(&hdev->msg_rx_queue)) != NULL) {
381 		pipe = skb->data[0];
382 		skb_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
383 		message = (struct nci_hcp_message *)skb->data;
384 		type = NCI_HCP_MSG_GET_TYPE(message->header);
385 		instruction = NCI_HCP_MSG_GET_CMD(message->header);
386 		skb_pull(skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
387 
388 		nci_hci_hcp_message_rx(hdev->ndev, pipe,
389 				       type, instruction, skb);
390 	}
391 }
392 
393 void nci_hci_data_received_cb(void *context,
394 			      struct sk_buff *skb, int err)
395 {
396 	struct nci_dev *ndev = (struct nci_dev *)context;
397 	struct nci_hcp_packet *packet;
398 	u8 pipe, type, instruction;
399 	struct sk_buff *hcp_skb;
400 	struct sk_buff *frag_skb;
401 	int msg_len;
402 
403 	pr_debug("\n");
404 
405 	if (err) {
406 		nci_req_complete(ndev, err);
407 		return;
408 	}
409 
410 	packet = (struct nci_hcp_packet *)skb->data;
411 	if ((packet->header & ~NCI_HCI_FRAGMENT) == 0) {
412 		skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
413 		return;
414 	}
415 
416 	/* it's the last fragment. Does it need re-aggregation? */
417 	if (skb_queue_len(&ndev->hci_dev->rx_hcp_frags)) {
418 		pipe = packet->header & NCI_HCI_FRAGMENT;
419 		skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
420 
421 		msg_len = 0;
422 		skb_queue_walk(&ndev->hci_dev->rx_hcp_frags, frag_skb) {
423 			msg_len += (frag_skb->len -
424 				    NCI_HCI_HCP_PACKET_HEADER_LEN);
425 		}
426 
427 		hcp_skb = nfc_alloc_recv_skb(NCI_HCI_HCP_PACKET_HEADER_LEN +
428 					     msg_len, GFP_KERNEL);
429 		if (!hcp_skb) {
430 			nci_req_complete(ndev, -ENOMEM);
431 			return;
432 		}
433 
434 		*skb_put(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN) = pipe;
435 
436 		skb_queue_walk(&ndev->hci_dev->rx_hcp_frags, frag_skb) {
437 		       msg_len = frag_skb->len - NCI_HCI_HCP_PACKET_HEADER_LEN;
438 			memcpy(skb_put(hcp_skb, msg_len), frag_skb->data +
439 			       NCI_HCI_HCP_PACKET_HEADER_LEN, msg_len);
440 		}
441 
442 		skb_queue_purge(&ndev->hci_dev->rx_hcp_frags);
443 	} else {
444 		packet->header &= NCI_HCI_FRAGMENT;
445 		hcp_skb = skb;
446 	}
447 
448 	/* if this is a response, dispatch immediately to
449 	 * unblock waiting cmd context. Otherwise, enqueue to dispatch
450 	 * in separate context where handler can also execute command.
451 	 */
452 	packet = (struct nci_hcp_packet *)hcp_skb->data;
453 	type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
454 	if (type == NCI_HCI_HCP_RESPONSE) {
455 		pipe = packet->header;
456 		instruction = NCI_HCP_MSG_GET_CMD(packet->message.header);
457 		skb_pull(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN +
458 			 NCI_HCI_HCP_MESSAGE_HEADER_LEN);
459 		nci_hci_hcp_message_rx(ndev, pipe, type, instruction, hcp_skb);
460 	} else {
461 		skb_queue_tail(&ndev->hci_dev->msg_rx_queue, hcp_skb);
462 		schedule_work(&ndev->hci_dev->msg_rx_work);
463 	}
464 }
465 
466 int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe)
467 {
468 	struct nci_data data;
469 	struct nci_conn_info    *conn_info;
470 
471 	conn_info = ndev->hci_dev->conn_info;
472 	if (!conn_info)
473 		return -EPROTO;
474 
475 	data.conn_id = conn_info->conn_id;
476 	data.pipe = pipe;
477 	data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
478 				       NCI_HCI_ANY_OPEN_PIPE);
479 	data.data = NULL;
480 	data.data_len = 0;
481 
482 	return nci_request(ndev, nci_hci_send_data_req,
483 			(unsigned long)&data,
484 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
485 }
486 EXPORT_SYMBOL(nci_hci_open_pipe);
487 
488 int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
489 		      const u8 *param, size_t param_len)
490 {
491 	struct nci_conn_info *conn_info;
492 	struct nci_data data;
493 	int r;
494 	u8 *tmp;
495 	u8 pipe = ndev->hci_dev->gate2pipe[gate];
496 
497 	pr_debug("idx=%d to gate %d\n", idx, gate);
498 
499 	if (pipe == NCI_HCI_INVALID_PIPE)
500 		return -EADDRNOTAVAIL;
501 
502 	conn_info = ndev->hci_dev->conn_info;
503 	if (!conn_info)
504 		return -EPROTO;
505 
506 	tmp = kmalloc(1 + param_len, GFP_KERNEL);
507 	if (!tmp)
508 		return -ENOMEM;
509 
510 	*tmp = idx;
511 	memcpy(tmp + 1, param, param_len);
512 
513 	data.conn_id = conn_info->conn_id;
514 	data.pipe = pipe;
515 	data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
516 				       NCI_HCI_ANY_SET_PARAMETER);
517 	data.data = tmp;
518 	data.data_len = param_len + 1;
519 
520 	r = nci_request(ndev, nci_hci_send_data_req,
521 			(unsigned long)&data,
522 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
523 
524 	kfree(tmp);
525 	return r;
526 }
527 EXPORT_SYMBOL(nci_hci_set_param);
528 
529 int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx,
530 		      struct sk_buff **skb)
531 {
532 	struct nci_conn_info    *conn_info;
533 	struct nci_data data;
534 	int r;
535 	u8 pipe = ndev->hci_dev->gate2pipe[gate];
536 
537 	pr_debug("idx=%d to gate %d\n", idx, gate);
538 
539 	if (pipe == NCI_HCI_INVALID_PIPE)
540 		return -EADDRNOTAVAIL;
541 
542 	conn_info = ndev->hci_dev->conn_info;
543 	if (!conn_info)
544 		return -EPROTO;
545 
546 	data.conn_id = conn_info->conn_id;
547 	data.pipe = pipe;
548 	data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
549 				  NCI_HCI_ANY_GET_PARAMETER);
550 	data.data = &idx;
551 	data.data_len = 1;
552 
553 	r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
554 			msecs_to_jiffies(NCI_DATA_TIMEOUT));
555 
556 	if (r == NCI_STATUS_OK)
557 		*skb = conn_info->rx_skb;
558 
559 	return r;
560 }
561 EXPORT_SYMBOL(nci_hci_get_param);
562 
563 int nci_hci_connect_gate(struct nci_dev *ndev,
564 			 u8 dest_host, u8 dest_gate, u8 pipe)
565 {
566 	int r;
567 
568 	if (pipe == NCI_HCI_DO_NOT_OPEN_PIPE)
569 		return 0;
570 
571 	if (ndev->hci_dev->gate2pipe[dest_gate] != NCI_HCI_INVALID_PIPE)
572 		return -EADDRINUSE;
573 
574 	if (pipe != NCI_HCI_INVALID_PIPE)
575 		goto open_pipe;
576 
577 	switch (dest_gate) {
578 	case NCI_HCI_LINK_MGMT_GATE:
579 		pipe = NCI_HCI_LINK_MGMT_PIPE;
580 	break;
581 	case NCI_HCI_ADMIN_GATE:
582 		pipe = NCI_HCI_ADMIN_PIPE;
583 	break;
584 	}
585 
586 open_pipe:
587 	r = nci_hci_open_pipe(ndev, pipe);
588 	if (r < 0)
589 		return r;
590 
591 	ndev->hci_dev->pipes[pipe].gate = dest_gate;
592 	ndev->hci_dev->pipes[pipe].host = dest_host;
593 	ndev->hci_dev->gate2pipe[dest_gate] = pipe;
594 
595 	return 0;
596 }
597 EXPORT_SYMBOL(nci_hci_connect_gate);
598 
599 static int nci_hci_dev_connect_gates(struct nci_dev *ndev,
600 				     u8 gate_count,
601 				     struct nci_hci_gate *gates)
602 {
603 	int r;
604 
605 	while (gate_count--) {
606 		r = nci_hci_connect_gate(ndev, gates->dest_host,
607 					 gates->gate, gates->pipe);
608 		if (r < 0)
609 			return r;
610 		gates++;
611 	}
612 
613 	return 0;
614 }
615 
616 int nci_hci_dev_session_init(struct nci_dev *ndev)
617 {
618 	struct nci_conn_info    *conn_info;
619 	struct sk_buff *skb;
620 	int r;
621 
622 	ndev->hci_dev->count_pipes = 0;
623 	ndev->hci_dev->expected_pipes = 0;
624 
625 	conn_info = ndev->hci_dev->conn_info;
626 	if (!conn_info)
627 		return -EPROTO;
628 
629 	conn_info->data_exchange_cb = nci_hci_data_received_cb;
630 	conn_info->data_exchange_cb_context = ndev;
631 
632 	nci_hci_reset_pipes(ndev->hci_dev);
633 
634 	if (ndev->hci_dev->init_data.gates[0].gate != NCI_HCI_ADMIN_GATE)
635 		return -EPROTO;
636 
637 	r = nci_hci_connect_gate(ndev,
638 				 ndev->hci_dev->init_data.gates[0].dest_host,
639 				 ndev->hci_dev->init_data.gates[0].gate,
640 				 ndev->hci_dev->init_data.gates[0].pipe);
641 	if (r < 0)
642 		return r;
643 
644 	r = nci_hci_get_param(ndev, NCI_HCI_ADMIN_GATE,
645 			      NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY, &skb);
646 	if (r < 0)
647 		return r;
648 
649 	if (skb->len &&
650 	    skb->len == strlen(ndev->hci_dev->init_data.session_id) &&
651 	    !memcmp(ndev->hci_dev->init_data.session_id, skb->data, skb->len) &&
652 	    ndev->ops->hci_load_session) {
653 		/* Restore gate<->pipe table from some proprietary location. */
654 		r = ndev->ops->hci_load_session(ndev);
655 	} else {
656 		r = nci_hci_dev_connect_gates(ndev,
657 					      ndev->hci_dev->init_data.gate_count,
658 					      ndev->hci_dev->init_data.gates);
659 		if (r < 0)
660 			goto exit;
661 
662 		r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE,
663 				      NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY,
664 				      ndev->hci_dev->init_data.session_id,
665 				      strlen(ndev->hci_dev->init_data.session_id));
666 	}
667 
668 exit:
669 	kfree_skb(skb);
670 
671 	return r;
672 }
673 EXPORT_SYMBOL(nci_hci_dev_session_init);
674 
675 struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev)
676 {
677 	struct nci_hci_dev *hdev;
678 
679 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
680 	if (!hdev)
681 		return NULL;
682 
683 	skb_queue_head_init(&hdev->rx_hcp_frags);
684 	INIT_WORK(&hdev->msg_rx_work, nci_hci_msg_rx_work);
685 	skb_queue_head_init(&hdev->msg_rx_queue);
686 	hdev->ndev = ndev;
687 
688 	return hdev;
689 }
690