1 // SPDX-License-Identifier: GPL-2.0-only
3 * The NFC Controller Interface is the communication protocol between an
4 * NFC Controller (NFCC) and a Device Host (DH).
5 * This is the HCI over NCI implementation, as specified in the 10.2
6 * section of the NCI 1.1 specification.
8 * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved.
11 #include <linux/skbuff.h>
14 #include <net/nfc/nci.h>
15 #include <net/nfc/nci_core.h>
16 #include <linux/nfc.h>
26 struct nci_hci_create_pipe_params
{
32 struct nci_hci_create_pipe_resp
{
40 struct nci_hci_delete_pipe_noti
{
44 struct nci_hci_all_pipe_cleared_noti
{
48 struct nci_hcp_message
{
49 u8 header
; /* type -cmd,evt,rsp- + instruction */
53 struct nci_hcp_packet
{
54 u8 header
; /* cbit+pipe */
55 struct nci_hcp_message message
;
58 #define NCI_HCI_ANY_SET_PARAMETER 0x01
59 #define NCI_HCI_ANY_GET_PARAMETER 0x02
60 #define NCI_HCI_ANY_CLOSE_PIPE 0x04
61 #define NCI_HCI_ADM_CLEAR_ALL_PIPE 0x14
63 #define NCI_HFP_NO_CHAINING 0x80
65 #define NCI_NFCEE_ID_HCI 0x80
67 #define NCI_EVT_HOT_PLUG 0x03
69 #define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY 0x01
70 #define NCI_HCI_ADM_CREATE_PIPE 0x10
71 #define NCI_HCI_ADM_DELETE_PIPE 0x11
74 #define NCI_HCI_HCP_PACKET_HEADER_LEN 1
75 #define NCI_HCI_HCP_MESSAGE_HEADER_LEN 1
76 #define NCI_HCI_HCP_HEADER_LEN 2
79 #define NCI_HCI_HCP_COMMAND 0x00
80 #define NCI_HCI_HCP_EVENT 0x01
81 #define NCI_HCI_HCP_RESPONSE 0x02
83 #define NCI_HCI_ADM_NOTIFY_PIPE_CREATED 0x12
84 #define NCI_HCI_ADM_NOTIFY_PIPE_DELETED 0x13
85 #define NCI_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
87 #define NCI_HCI_FRAGMENT 0x7f
88 #define NCI_HCP_HEADER(type, instr) ((((type) & 0x03) << 6) |\
91 #define NCI_HCP_MSG_GET_TYPE(header) ((header & 0xc0) >> 6)
92 #define NCI_HCP_MSG_GET_CMD(header) (header & 0x3f)
93 #define NCI_HCP_MSG_GET_PIPE(header) (header & 0x7f)
95 static int nci_hci_result_to_errno(u8 result
)
100 case NCI_HCI_ANY_E_REG_PAR_UNKNOWN
:
102 case NCI_HCI_ANY_E_TIMEOUT
:
110 static void nci_hci_reset_pipes(struct nci_hci_dev
*hdev
)
114 for (i
= 0; i
< NCI_HCI_MAX_PIPES
; i
++) {
115 hdev
->pipes
[i
].gate
= NCI_HCI_INVALID_GATE
;
116 hdev
->pipes
[i
].host
= NCI_HCI_INVALID_HOST
;
118 memset(hdev
->gate2pipe
, NCI_HCI_INVALID_PIPE
, sizeof(hdev
->gate2pipe
));
121 static void nci_hci_reset_pipes_per_host(struct nci_dev
*ndev
, u8 host
)
125 for (i
= 0; i
< NCI_HCI_MAX_PIPES
; i
++) {
126 if (ndev
->hci_dev
->pipes
[i
].host
== host
) {
127 ndev
->hci_dev
->pipes
[i
].gate
= NCI_HCI_INVALID_GATE
;
128 ndev
->hci_dev
->pipes
[i
].host
= NCI_HCI_INVALID_HOST
;
133 /* Fragment HCI data over NCI packet.
134 * NFC Forum NCI 10.2.2 Data Exchange:
135 * The payload of the Data Packets sent on the Logical Connection SHALL be
136 * valid HCP packets, as defined within [ETSI_102622]. Each Data Packet SHALL
137 * contain a single HCP packet. NCI Segmentation and Reassembly SHALL NOT be
138 * applied to Data Messages in either direction. The HCI fragmentation mechanism
139 * is used if required.
141 static int nci_hci_send_data(struct nci_dev
*ndev
, u8 pipe
,
142 const u8 data_type
, const u8
*data
,
145 struct nci_conn_info
*conn_info
;
150 conn_info
= ndev
->hci_dev
->conn_info
;
155 skb
= nci_skb_alloc(ndev
, conn_info
->max_pkt_payload_len
+
156 NCI_DATA_HDR_SIZE
, GFP_KERNEL
);
160 skb_reserve(skb
, NCI_DATA_HDR_SIZE
+ 2);
161 *(u8
*)skb_push(skb
, 1) = data_type
;
164 len
= conn_info
->max_pkt_payload_len
;
166 /* If last packet add NCI_HFP_NO_CHAINING */
167 if (i
+ conn_info
->max_pkt_payload_len
-
168 (skb
->len
+ 1) >= data_len
) {
169 cb
|= NCI_HFP_NO_CHAINING
;
172 len
= conn_info
->max_pkt_payload_len
- skb
->len
- 1;
175 *(u8
*)skb_push(skb
, 1) = cb
;
178 skb_put_data(skb
, data
+ i
, len
);
180 r
= nci_send_data(ndev
, conn_info
->conn_id
, skb
);
187 skb
= nci_skb_alloc(ndev
,
188 conn_info
->max_pkt_payload_len
+
189 NCI_DATA_HDR_SIZE
, GFP_KERNEL
);
193 skb_reserve(skb
, NCI_DATA_HDR_SIZE
+ 1);
195 } while (i
< data_len
);
200 static void nci_hci_send_data_req(struct nci_dev
*ndev
, unsigned long opt
)
202 struct nci_data
*data
= (struct nci_data
*)opt
;
204 nci_hci_send_data(ndev
, data
->pipe
, data
->cmd
,
205 data
->data
, data
->data_len
);
208 int nci_hci_send_event(struct nci_dev
*ndev
, u8 gate
, u8 event
,
209 const u8
*param
, size_t param_len
)
211 u8 pipe
= ndev
->hci_dev
->gate2pipe
[gate
];
213 if (pipe
== NCI_HCI_INVALID_PIPE
)
214 return -EADDRNOTAVAIL
;
216 return nci_hci_send_data(ndev
, pipe
,
217 NCI_HCP_HEADER(NCI_HCI_HCP_EVENT
, event
),
220 EXPORT_SYMBOL(nci_hci_send_event
);
222 int nci_hci_send_cmd(struct nci_dev
*ndev
, u8 gate
, u8 cmd
,
223 const u8
*param
, size_t param_len
,
224 struct sk_buff
**skb
)
226 struct nci_hcp_message
*message
;
227 struct nci_conn_info
*conn_info
;
228 struct nci_data data
;
230 u8 pipe
= ndev
->hci_dev
->gate2pipe
[gate
];
232 if (pipe
== NCI_HCI_INVALID_PIPE
)
233 return -EADDRNOTAVAIL
;
235 conn_info
= ndev
->hci_dev
->conn_info
;
239 data
.conn_id
= conn_info
->conn_id
;
241 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
, cmd
);
243 data
.data_len
= param_len
;
245 r
= nci_request(ndev
, nci_hci_send_data_req
, (unsigned long)&data
,
246 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
247 if (r
== NCI_STATUS_OK
) {
248 message
= (struct nci_hcp_message
*)conn_info
->rx_skb
->data
;
249 r
= nci_hci_result_to_errno(
250 NCI_HCP_MSG_GET_CMD(message
->header
));
251 skb_pull(conn_info
->rx_skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
254 *skb
= conn_info
->rx_skb
;
259 EXPORT_SYMBOL(nci_hci_send_cmd
);
261 int nci_hci_clear_all_pipes(struct nci_dev
*ndev
)
265 r
= nci_hci_send_cmd(ndev
, NCI_HCI_ADMIN_GATE
,
266 NCI_HCI_ADM_CLEAR_ALL_PIPE
, NULL
, 0, NULL
);
270 nci_hci_reset_pipes(ndev
->hci_dev
);
273 EXPORT_SYMBOL(nci_hci_clear_all_pipes
);
275 static void nci_hci_event_received(struct nci_dev
*ndev
, u8 pipe
,
276 u8 event
, struct sk_buff
*skb
)
278 if (ndev
->ops
->hci_event_received
)
279 ndev
->ops
->hci_event_received(ndev
, pipe
, event
, skb
);
282 static void nci_hci_cmd_received(struct nci_dev
*ndev
, u8 pipe
,
283 u8 cmd
, struct sk_buff
*skb
)
285 u8 gate
= ndev
->hci_dev
->pipes
[pipe
].gate
;
286 u8 status
= NCI_HCI_ANY_OK
| ~NCI_HCI_FRAGMENT
;
287 u8 dest_gate
, new_pipe
;
288 struct nci_hci_create_pipe_resp
*create_info
;
289 struct nci_hci_delete_pipe_noti
*delete_info
;
290 struct nci_hci_all_pipe_cleared_noti
*cleared_info
;
292 pr_debug("from gate %x pipe %x cmd %x\n", gate
, pipe
, cmd
);
295 case NCI_HCI_ADM_NOTIFY_PIPE_CREATED
:
297 status
= NCI_HCI_ANY_E_NOK
;
300 create_info
= (struct nci_hci_create_pipe_resp
*)skb
->data
;
301 dest_gate
= create_info
->dest_gate
;
302 new_pipe
= create_info
->pipe
;
303 if (new_pipe
>= NCI_HCI_MAX_PIPES
) {
304 status
= NCI_HCI_ANY_E_NOK
;
308 /* Save the new created pipe and bind with local gate,
309 * the description for skb->data[3] is destination gate id
310 * but since we received this cmd from host controller, we
311 * are the destination and it is our local gate
313 ndev
->hci_dev
->gate2pipe
[dest_gate
] = new_pipe
;
314 ndev
->hci_dev
->pipes
[new_pipe
].gate
= dest_gate
;
315 ndev
->hci_dev
->pipes
[new_pipe
].host
=
316 create_info
->src_host
;
318 case NCI_HCI_ANY_OPEN_PIPE
:
319 /* If the pipe is not created report an error */
320 if (gate
== NCI_HCI_INVALID_GATE
) {
321 status
= NCI_HCI_ANY_E_NOK
;
325 case NCI_HCI_ADM_NOTIFY_PIPE_DELETED
:
327 status
= NCI_HCI_ANY_E_NOK
;
330 delete_info
= (struct nci_hci_delete_pipe_noti
*)skb
->data
;
331 if (delete_info
->pipe
>= NCI_HCI_MAX_PIPES
) {
332 status
= NCI_HCI_ANY_E_NOK
;
336 ndev
->hci_dev
->pipes
[delete_info
->pipe
].gate
=
337 NCI_HCI_INVALID_GATE
;
338 ndev
->hci_dev
->pipes
[delete_info
->pipe
].host
=
339 NCI_HCI_INVALID_HOST
;
341 case NCI_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED
:
343 status
= NCI_HCI_ANY_E_NOK
;
348 (struct nci_hci_all_pipe_cleared_noti
*)skb
->data
;
349 nci_hci_reset_pipes_per_host(ndev
, cleared_info
->host
);
352 pr_debug("Discarded unknown cmd %x to gate %x\n", cmd
, gate
);
356 if (ndev
->ops
->hci_cmd_received
)
357 ndev
->ops
->hci_cmd_received(ndev
, pipe
, cmd
, skb
);
360 nci_hci_send_data(ndev
, pipe
, status
, NULL
, 0);
365 static void nci_hci_resp_received(struct nci_dev
*ndev
, u8 pipe
,
368 struct nci_conn_info
*conn_info
;
370 conn_info
= ndev
->hci_dev
->conn_info
;
374 conn_info
->rx_skb
= skb
;
377 nci_req_complete(ndev
, NCI_STATUS_OK
);
380 /* Receive hcp message for pipe, with type and cmd.
381 * skb contains optional message data only.
383 static void nci_hci_hcp_message_rx(struct nci_dev
*ndev
, u8 pipe
,
384 u8 type
, u8 instruction
, struct sk_buff
*skb
)
387 case NCI_HCI_HCP_RESPONSE
:
388 nci_hci_resp_received(ndev
, pipe
, skb
);
390 case NCI_HCI_HCP_COMMAND
:
391 nci_hci_cmd_received(ndev
, pipe
, instruction
, skb
);
393 case NCI_HCI_HCP_EVENT
:
394 nci_hci_event_received(ndev
, pipe
, instruction
, skb
);
397 pr_err("UNKNOWN MSG Type %d, instruction=%d\n",
403 nci_req_complete(ndev
, NCI_STATUS_OK
);
406 static void nci_hci_msg_rx_work(struct work_struct
*work
)
408 struct nci_hci_dev
*hdev
=
409 container_of(work
, struct nci_hci_dev
, msg_rx_work
);
411 struct nci_hcp_message
*message
;
412 u8 pipe
, type
, instruction
;
414 while ((skb
= skb_dequeue(&hdev
->msg_rx_queue
)) != NULL
) {
415 pipe
= NCI_HCP_MSG_GET_PIPE(skb
->data
[0]);
416 skb_pull(skb
, NCI_HCI_HCP_PACKET_HEADER_LEN
);
417 message
= (struct nci_hcp_message
*)skb
->data
;
418 type
= NCI_HCP_MSG_GET_TYPE(message
->header
);
419 instruction
= NCI_HCP_MSG_GET_CMD(message
->header
);
420 skb_pull(skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
422 nci_hci_hcp_message_rx(hdev
->ndev
, pipe
,
423 type
, instruction
, skb
);
427 void nci_hci_data_received_cb(void *context
,
428 struct sk_buff
*skb
, int err
)
430 struct nci_dev
*ndev
= (struct nci_dev
*)context
;
431 struct nci_hcp_packet
*packet
;
433 struct sk_buff
*hcp_skb
;
434 struct sk_buff
*frag_skb
;
440 nci_req_complete(ndev
, err
);
444 packet
= (struct nci_hcp_packet
*)skb
->data
;
445 if ((packet
->header
& ~NCI_HCI_FRAGMENT
) == 0) {
446 skb_queue_tail(&ndev
->hci_dev
->rx_hcp_frags
, skb
);
450 /* it's the last fragment. Does it need re-aggregation? */
451 if (skb_queue_len(&ndev
->hci_dev
->rx_hcp_frags
)) {
452 pipe
= NCI_HCP_MSG_GET_PIPE(packet
->header
);
453 skb_queue_tail(&ndev
->hci_dev
->rx_hcp_frags
, skb
);
456 skb_queue_walk(&ndev
->hci_dev
->rx_hcp_frags
, frag_skb
) {
457 msg_len
+= (frag_skb
->len
-
458 NCI_HCI_HCP_PACKET_HEADER_LEN
);
461 hcp_skb
= nfc_alloc_recv_skb(NCI_HCI_HCP_PACKET_HEADER_LEN
+
462 msg_len
, GFP_KERNEL
);
464 nci_req_complete(ndev
, -ENOMEM
);
468 skb_put_u8(hcp_skb
, pipe
);
470 skb_queue_walk(&ndev
->hci_dev
->rx_hcp_frags
, frag_skb
) {
471 msg_len
= frag_skb
->len
- NCI_HCI_HCP_PACKET_HEADER_LEN
;
472 skb_put_data(hcp_skb
,
473 frag_skb
->data
+ NCI_HCI_HCP_PACKET_HEADER_LEN
,
477 skb_queue_purge(&ndev
->hci_dev
->rx_hcp_frags
);
479 packet
->header
&= NCI_HCI_FRAGMENT
;
483 /* if this is a response, dispatch immediately to
484 * unblock waiting cmd context. Otherwise, enqueue to dispatch
485 * in separate context where handler can also execute command.
487 packet
= (struct nci_hcp_packet
*)hcp_skb
->data
;
488 type
= NCI_HCP_MSG_GET_TYPE(packet
->message
.header
);
489 if (type
== NCI_HCI_HCP_RESPONSE
) {
490 pipe
= NCI_HCP_MSG_GET_PIPE(packet
->header
);
491 skb_pull(hcp_skb
, NCI_HCI_HCP_PACKET_HEADER_LEN
);
492 nci_hci_hcp_message_rx(ndev
, pipe
, type
,
493 NCI_STATUS_OK
, hcp_skb
);
495 skb_queue_tail(&ndev
->hci_dev
->msg_rx_queue
, hcp_skb
);
496 schedule_work(&ndev
->hci_dev
->msg_rx_work
);
500 int nci_hci_open_pipe(struct nci_dev
*ndev
, u8 pipe
)
502 struct nci_data data
;
503 struct nci_conn_info
*conn_info
;
505 conn_info
= ndev
->hci_dev
->conn_info
;
509 data
.conn_id
= conn_info
->conn_id
;
511 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
,
512 NCI_HCI_ANY_OPEN_PIPE
);
516 return nci_request(ndev
, nci_hci_send_data_req
,
517 (unsigned long)&data
,
518 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
520 EXPORT_SYMBOL(nci_hci_open_pipe
);
522 static u8
nci_hci_create_pipe(struct nci_dev
*ndev
, u8 dest_host
,
523 u8 dest_gate
, int *result
)
527 struct nci_hci_create_pipe_params params
;
528 struct nci_hci_create_pipe_resp
*resp
;
530 pr_debug("gate=%d\n", dest_gate
);
532 params
.src_gate
= NCI_HCI_ADMIN_GATE
;
533 params
.dest_host
= dest_host
;
534 params
.dest_gate
= dest_gate
;
536 *result
= nci_hci_send_cmd(ndev
, NCI_HCI_ADMIN_GATE
,
537 NCI_HCI_ADM_CREATE_PIPE
,
538 (u8
*)¶ms
, sizeof(params
), &skb
);
540 return NCI_HCI_INVALID_PIPE
;
542 resp
= (struct nci_hci_create_pipe_resp
*)skb
->data
;
546 pr_debug("pipe created=%d\n", pipe
);
551 static int nci_hci_delete_pipe(struct nci_dev
*ndev
, u8 pipe
)
555 return nci_hci_send_cmd(ndev
, NCI_HCI_ADMIN_GATE
,
556 NCI_HCI_ADM_DELETE_PIPE
, &pipe
, 1, NULL
);
559 int nci_hci_set_param(struct nci_dev
*ndev
, u8 gate
, u8 idx
,
560 const u8
*param
, size_t param_len
)
562 struct nci_hcp_message
*message
;
563 struct nci_conn_info
*conn_info
;
564 struct nci_data data
;
567 u8 pipe
= ndev
->hci_dev
->gate2pipe
[gate
];
569 pr_debug("idx=%d to gate %d\n", idx
, gate
);
571 if (pipe
== NCI_HCI_INVALID_PIPE
)
572 return -EADDRNOTAVAIL
;
574 conn_info
= ndev
->hci_dev
->conn_info
;
578 tmp
= kmalloc(1 + param_len
, GFP_KERNEL
);
583 memcpy(tmp
+ 1, param
, param_len
);
585 data
.conn_id
= conn_info
->conn_id
;
587 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
,
588 NCI_HCI_ANY_SET_PARAMETER
);
590 data
.data_len
= param_len
+ 1;
592 r
= nci_request(ndev
, nci_hci_send_data_req
,
593 (unsigned long)&data
,
594 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
595 if (r
== NCI_STATUS_OK
) {
596 message
= (struct nci_hcp_message
*)conn_info
->rx_skb
->data
;
597 r
= nci_hci_result_to_errno(
598 NCI_HCP_MSG_GET_CMD(message
->header
));
599 skb_pull(conn_info
->rx_skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
605 EXPORT_SYMBOL(nci_hci_set_param
);
607 int nci_hci_get_param(struct nci_dev
*ndev
, u8 gate
, u8 idx
,
608 struct sk_buff
**skb
)
610 struct nci_hcp_message
*message
;
611 struct nci_conn_info
*conn_info
;
612 struct nci_data data
;
614 u8 pipe
= ndev
->hci_dev
->gate2pipe
[gate
];
616 pr_debug("idx=%d to gate %d\n", idx
, gate
);
618 if (pipe
== NCI_HCI_INVALID_PIPE
)
619 return -EADDRNOTAVAIL
;
621 conn_info
= ndev
->hci_dev
->conn_info
;
625 data
.conn_id
= conn_info
->conn_id
;
627 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
,
628 NCI_HCI_ANY_GET_PARAMETER
);
632 r
= nci_request(ndev
, nci_hci_send_data_req
, (unsigned long)&data
,
633 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
635 if (r
== NCI_STATUS_OK
) {
636 message
= (struct nci_hcp_message
*)conn_info
->rx_skb
->data
;
637 r
= nci_hci_result_to_errno(
638 NCI_HCP_MSG_GET_CMD(message
->header
));
639 skb_pull(conn_info
->rx_skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
642 *skb
= conn_info
->rx_skb
;
647 EXPORT_SYMBOL(nci_hci_get_param
);
649 int nci_hci_connect_gate(struct nci_dev
*ndev
,
650 u8 dest_host
, u8 dest_gate
, u8 pipe
)
652 bool pipe_created
= false;
655 if (pipe
== NCI_HCI_DO_NOT_OPEN_PIPE
)
658 if (ndev
->hci_dev
->gate2pipe
[dest_gate
] != NCI_HCI_INVALID_PIPE
)
661 if (pipe
!= NCI_HCI_INVALID_PIPE
)
665 case NCI_HCI_LINK_MGMT_GATE
:
666 pipe
= NCI_HCI_LINK_MGMT_PIPE
;
668 case NCI_HCI_ADMIN_GATE
:
669 pipe
= NCI_HCI_ADMIN_PIPE
;
672 pipe
= nci_hci_create_pipe(ndev
, dest_host
, dest_gate
, &r
);
673 if (pipe
== NCI_HCI_INVALID_PIPE
)
680 r
= nci_hci_open_pipe(ndev
, pipe
);
683 if (nci_hci_delete_pipe(ndev
, pipe
) < 0) {
684 /* TODO: Cannot clean by deleting pipe...
685 * -> inconsistent state
692 ndev
->hci_dev
->pipes
[pipe
].gate
= dest_gate
;
693 ndev
->hci_dev
->pipes
[pipe
].host
= dest_host
;
694 ndev
->hci_dev
->gate2pipe
[dest_gate
] = pipe
;
698 EXPORT_SYMBOL(nci_hci_connect_gate
);
700 static int nci_hci_dev_connect_gates(struct nci_dev
*ndev
,
702 struct nci_hci_gate
*gates
)
706 while (gate_count
--) {
707 r
= nci_hci_connect_gate(ndev
, gates
->dest_host
,
708 gates
->gate
, gates
->pipe
);
717 int nci_hci_dev_session_init(struct nci_dev
*ndev
)
719 struct nci_conn_info
*conn_info
;
723 ndev
->hci_dev
->count_pipes
= 0;
724 ndev
->hci_dev
->expected_pipes
= 0;
726 conn_info
= ndev
->hci_dev
->conn_info
;
730 conn_info
->data_exchange_cb
= nci_hci_data_received_cb
;
731 conn_info
->data_exchange_cb_context
= ndev
;
733 nci_hci_reset_pipes(ndev
->hci_dev
);
735 if (ndev
->hci_dev
->init_data
.gates
[0].gate
!= NCI_HCI_ADMIN_GATE
)
738 r
= nci_hci_connect_gate(ndev
,
739 ndev
->hci_dev
->init_data
.gates
[0].dest_host
,
740 ndev
->hci_dev
->init_data
.gates
[0].gate
,
741 ndev
->hci_dev
->init_data
.gates
[0].pipe
);
745 r
= nci_hci_get_param(ndev
, NCI_HCI_ADMIN_GATE
,
746 NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY
, &skb
);
751 skb
->len
== strlen(ndev
->hci_dev
->init_data
.session_id
) &&
752 !memcmp(ndev
->hci_dev
->init_data
.session_id
, skb
->data
, skb
->len
) &&
753 ndev
->ops
->hci_load_session
) {
754 /* Restore gate<->pipe table from some proprietary location. */
755 r
= ndev
->ops
->hci_load_session(ndev
);
757 r
= nci_hci_clear_all_pipes(ndev
);
761 r
= nci_hci_dev_connect_gates(ndev
,
762 ndev
->hci_dev
->init_data
.gate_count
,
763 ndev
->hci_dev
->init_data
.gates
);
767 r
= nci_hci_set_param(ndev
, NCI_HCI_ADMIN_GATE
,
768 NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY
,
769 ndev
->hci_dev
->init_data
.session_id
,
770 strlen(ndev
->hci_dev
->init_data
.session_id
));
778 EXPORT_SYMBOL(nci_hci_dev_session_init
);
780 struct nci_hci_dev
*nci_hci_allocate(struct nci_dev
*ndev
)
782 struct nci_hci_dev
*hdev
;
784 hdev
= kzalloc(sizeof(*hdev
), GFP_KERNEL
);
788 skb_queue_head_init(&hdev
->rx_hcp_frags
);
789 INIT_WORK(&hdev
->msg_rx_work
, nci_hci_msg_rx_work
);
790 skb_queue_head_init(&hdev
->msg_rx_queue
);