]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - net/nfc/nci/hci.c
xfrm: dst_entries_init() per-net dst_ops
[karo-tx-linux.git] / net / nfc / nci / hci.c
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 && skb)
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 }