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
,
366 u8 result
, struct sk_buff
*skb
)
368 struct nci_conn_info
*conn_info
;
371 conn_info
= ndev
->hci_dev
->conn_info
;
373 status
= NCI_STATUS_REJECTED
;
377 conn_info
->rx_skb
= skb
;
380 nci_req_complete(ndev
, NCI_STATUS_OK
);
383 /* Receive hcp message for pipe, with type and cmd.
384 * skb contains optional message data only.
386 static void nci_hci_hcp_message_rx(struct nci_dev
*ndev
, u8 pipe
,
387 u8 type
, u8 instruction
, struct sk_buff
*skb
)
390 case NCI_HCI_HCP_RESPONSE
:
391 nci_hci_resp_received(ndev
, pipe
, instruction
, skb
);
393 case NCI_HCI_HCP_COMMAND
:
394 nci_hci_cmd_received(ndev
, pipe
, instruction
, skb
);
396 case NCI_HCI_HCP_EVENT
:
397 nci_hci_event_received(ndev
, pipe
, instruction
, skb
);
400 pr_err("UNKNOWN MSG Type %d, instruction=%d\n",
406 nci_req_complete(ndev
, NCI_STATUS_OK
);
409 static void nci_hci_msg_rx_work(struct work_struct
*work
)
411 struct nci_hci_dev
*hdev
=
412 container_of(work
, struct nci_hci_dev
, msg_rx_work
);
414 struct nci_hcp_message
*message
;
415 u8 pipe
, type
, instruction
;
417 while ((skb
= skb_dequeue(&hdev
->msg_rx_queue
)) != NULL
) {
418 pipe
= NCI_HCP_MSG_GET_PIPE(skb
->data
[0]);
419 skb_pull(skb
, NCI_HCI_HCP_PACKET_HEADER_LEN
);
420 message
= (struct nci_hcp_message
*)skb
->data
;
421 type
= NCI_HCP_MSG_GET_TYPE(message
->header
);
422 instruction
= NCI_HCP_MSG_GET_CMD(message
->header
);
423 skb_pull(skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
425 nci_hci_hcp_message_rx(hdev
->ndev
, pipe
,
426 type
, instruction
, skb
);
430 void nci_hci_data_received_cb(void *context
,
431 struct sk_buff
*skb
, int err
)
433 struct nci_dev
*ndev
= (struct nci_dev
*)context
;
434 struct nci_hcp_packet
*packet
;
436 struct sk_buff
*hcp_skb
;
437 struct sk_buff
*frag_skb
;
443 nci_req_complete(ndev
, err
);
447 packet
= (struct nci_hcp_packet
*)skb
->data
;
448 if ((packet
->header
& ~NCI_HCI_FRAGMENT
) == 0) {
449 skb_queue_tail(&ndev
->hci_dev
->rx_hcp_frags
, skb
);
453 /* it's the last fragment. Does it need re-aggregation? */
454 if (skb_queue_len(&ndev
->hci_dev
->rx_hcp_frags
)) {
455 pipe
= NCI_HCP_MSG_GET_PIPE(packet
->header
);
456 skb_queue_tail(&ndev
->hci_dev
->rx_hcp_frags
, skb
);
459 skb_queue_walk(&ndev
->hci_dev
->rx_hcp_frags
, frag_skb
) {
460 msg_len
+= (frag_skb
->len
-
461 NCI_HCI_HCP_PACKET_HEADER_LEN
);
464 hcp_skb
= nfc_alloc_recv_skb(NCI_HCI_HCP_PACKET_HEADER_LEN
+
465 msg_len
, GFP_KERNEL
);
467 nci_req_complete(ndev
, -ENOMEM
);
471 skb_put_u8(hcp_skb
, pipe
);
473 skb_queue_walk(&ndev
->hci_dev
->rx_hcp_frags
, frag_skb
) {
474 msg_len
= frag_skb
->len
- NCI_HCI_HCP_PACKET_HEADER_LEN
;
475 skb_put_data(hcp_skb
,
476 frag_skb
->data
+ NCI_HCI_HCP_PACKET_HEADER_LEN
,
480 skb_queue_purge(&ndev
->hci_dev
->rx_hcp_frags
);
482 packet
->header
&= NCI_HCI_FRAGMENT
;
486 /* if this is a response, dispatch immediately to
487 * unblock waiting cmd context. Otherwise, enqueue to dispatch
488 * in separate context where handler can also execute command.
490 packet
= (struct nci_hcp_packet
*)hcp_skb
->data
;
491 type
= NCI_HCP_MSG_GET_TYPE(packet
->message
.header
);
492 if (type
== NCI_HCI_HCP_RESPONSE
) {
493 pipe
= NCI_HCP_MSG_GET_PIPE(packet
->header
);
494 skb_pull(hcp_skb
, NCI_HCI_HCP_PACKET_HEADER_LEN
);
495 nci_hci_hcp_message_rx(ndev
, pipe
, type
,
496 NCI_STATUS_OK
, hcp_skb
);
498 skb_queue_tail(&ndev
->hci_dev
->msg_rx_queue
, hcp_skb
);
499 schedule_work(&ndev
->hci_dev
->msg_rx_work
);
503 int nci_hci_open_pipe(struct nci_dev
*ndev
, u8 pipe
)
505 struct nci_data data
;
506 struct nci_conn_info
*conn_info
;
508 conn_info
= ndev
->hci_dev
->conn_info
;
512 data
.conn_id
= conn_info
->conn_id
;
514 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
,
515 NCI_HCI_ANY_OPEN_PIPE
);
519 return nci_request(ndev
, nci_hci_send_data_req
,
520 (unsigned long)&data
,
521 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
523 EXPORT_SYMBOL(nci_hci_open_pipe
);
525 static u8
nci_hci_create_pipe(struct nci_dev
*ndev
, u8 dest_host
,
526 u8 dest_gate
, int *result
)
530 struct nci_hci_create_pipe_params params
;
531 struct nci_hci_create_pipe_resp
*resp
;
533 pr_debug("gate=%d\n", dest_gate
);
535 params
.src_gate
= NCI_HCI_ADMIN_GATE
;
536 params
.dest_host
= dest_host
;
537 params
.dest_gate
= dest_gate
;
539 *result
= nci_hci_send_cmd(ndev
, NCI_HCI_ADMIN_GATE
,
540 NCI_HCI_ADM_CREATE_PIPE
,
541 (u8
*)¶ms
, sizeof(params
), &skb
);
543 return NCI_HCI_INVALID_PIPE
;
545 resp
= (struct nci_hci_create_pipe_resp
*)skb
->data
;
549 pr_debug("pipe created=%d\n", pipe
);
554 static int nci_hci_delete_pipe(struct nci_dev
*ndev
, u8 pipe
)
558 return nci_hci_send_cmd(ndev
, NCI_HCI_ADMIN_GATE
,
559 NCI_HCI_ADM_DELETE_PIPE
, &pipe
, 1, NULL
);
562 int nci_hci_set_param(struct nci_dev
*ndev
, u8 gate
, u8 idx
,
563 const u8
*param
, size_t param_len
)
565 struct nci_hcp_message
*message
;
566 struct nci_conn_info
*conn_info
;
567 struct nci_data data
;
570 u8 pipe
= ndev
->hci_dev
->gate2pipe
[gate
];
572 pr_debug("idx=%d to gate %d\n", idx
, gate
);
574 if (pipe
== NCI_HCI_INVALID_PIPE
)
575 return -EADDRNOTAVAIL
;
577 conn_info
= ndev
->hci_dev
->conn_info
;
581 tmp
= kmalloc(1 + param_len
, GFP_KERNEL
);
586 memcpy(tmp
+ 1, param
, param_len
);
588 data
.conn_id
= conn_info
->conn_id
;
590 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
,
591 NCI_HCI_ANY_SET_PARAMETER
);
593 data
.data_len
= param_len
+ 1;
595 r
= nci_request(ndev
, nci_hci_send_data_req
,
596 (unsigned long)&data
,
597 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
598 if (r
== NCI_STATUS_OK
) {
599 message
= (struct nci_hcp_message
*)conn_info
->rx_skb
->data
;
600 r
= nci_hci_result_to_errno(
601 NCI_HCP_MSG_GET_CMD(message
->header
));
602 skb_pull(conn_info
->rx_skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
608 EXPORT_SYMBOL(nci_hci_set_param
);
610 int nci_hci_get_param(struct nci_dev
*ndev
, u8 gate
, u8 idx
,
611 struct sk_buff
**skb
)
613 struct nci_hcp_message
*message
;
614 struct nci_conn_info
*conn_info
;
615 struct nci_data data
;
617 u8 pipe
= ndev
->hci_dev
->gate2pipe
[gate
];
619 pr_debug("idx=%d to gate %d\n", idx
, gate
);
621 if (pipe
== NCI_HCI_INVALID_PIPE
)
622 return -EADDRNOTAVAIL
;
624 conn_info
= ndev
->hci_dev
->conn_info
;
628 data
.conn_id
= conn_info
->conn_id
;
630 data
.cmd
= NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND
,
631 NCI_HCI_ANY_GET_PARAMETER
);
635 r
= nci_request(ndev
, nci_hci_send_data_req
, (unsigned long)&data
,
636 msecs_to_jiffies(NCI_DATA_TIMEOUT
));
638 if (r
== NCI_STATUS_OK
) {
639 message
= (struct nci_hcp_message
*)conn_info
->rx_skb
->data
;
640 r
= nci_hci_result_to_errno(
641 NCI_HCP_MSG_GET_CMD(message
->header
));
642 skb_pull(conn_info
->rx_skb
, NCI_HCI_HCP_MESSAGE_HEADER_LEN
);
645 *skb
= conn_info
->rx_skb
;
650 EXPORT_SYMBOL(nci_hci_get_param
);
652 int nci_hci_connect_gate(struct nci_dev
*ndev
,
653 u8 dest_host
, u8 dest_gate
, u8 pipe
)
655 bool pipe_created
= false;
658 if (pipe
== NCI_HCI_DO_NOT_OPEN_PIPE
)
661 if (ndev
->hci_dev
->gate2pipe
[dest_gate
] != NCI_HCI_INVALID_PIPE
)
664 if (pipe
!= NCI_HCI_INVALID_PIPE
)
668 case NCI_HCI_LINK_MGMT_GATE
:
669 pipe
= NCI_HCI_LINK_MGMT_PIPE
;
671 case NCI_HCI_ADMIN_GATE
:
672 pipe
= NCI_HCI_ADMIN_PIPE
;
675 pipe
= nci_hci_create_pipe(ndev
, dest_host
, dest_gate
, &r
);
676 if (pipe
== NCI_HCI_INVALID_PIPE
)
683 r
= nci_hci_open_pipe(ndev
, pipe
);
686 if (nci_hci_delete_pipe(ndev
, pipe
) < 0) {
687 /* TODO: Cannot clean by deleting pipe...
688 * -> inconsistent state
695 ndev
->hci_dev
->pipes
[pipe
].gate
= dest_gate
;
696 ndev
->hci_dev
->pipes
[pipe
].host
= dest_host
;
697 ndev
->hci_dev
->gate2pipe
[dest_gate
] = pipe
;
701 EXPORT_SYMBOL(nci_hci_connect_gate
);
703 static int nci_hci_dev_connect_gates(struct nci_dev
*ndev
,
705 struct nci_hci_gate
*gates
)
709 while (gate_count
--) {
710 r
= nci_hci_connect_gate(ndev
, gates
->dest_host
,
711 gates
->gate
, gates
->pipe
);
720 int nci_hci_dev_session_init(struct nci_dev
*ndev
)
722 struct nci_conn_info
*conn_info
;
726 ndev
->hci_dev
->count_pipes
= 0;
727 ndev
->hci_dev
->expected_pipes
= 0;
729 conn_info
= ndev
->hci_dev
->conn_info
;
733 conn_info
->data_exchange_cb
= nci_hci_data_received_cb
;
734 conn_info
->data_exchange_cb_context
= ndev
;
736 nci_hci_reset_pipes(ndev
->hci_dev
);
738 if (ndev
->hci_dev
->init_data
.gates
[0].gate
!= NCI_HCI_ADMIN_GATE
)
741 r
= nci_hci_connect_gate(ndev
,
742 ndev
->hci_dev
->init_data
.gates
[0].dest_host
,
743 ndev
->hci_dev
->init_data
.gates
[0].gate
,
744 ndev
->hci_dev
->init_data
.gates
[0].pipe
);
748 r
= nci_hci_get_param(ndev
, NCI_HCI_ADMIN_GATE
,
749 NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY
, &skb
);
754 skb
->len
== strlen(ndev
->hci_dev
->init_data
.session_id
) &&
755 !memcmp(ndev
->hci_dev
->init_data
.session_id
, skb
->data
, skb
->len
) &&
756 ndev
->ops
->hci_load_session
) {
757 /* Restore gate<->pipe table from some proprietary location. */
758 r
= ndev
->ops
->hci_load_session(ndev
);
760 r
= nci_hci_clear_all_pipes(ndev
);
764 r
= nci_hci_dev_connect_gates(ndev
,
765 ndev
->hci_dev
->init_data
.gate_count
,
766 ndev
->hci_dev
->init_data
.gates
);
770 r
= nci_hci_set_param(ndev
, NCI_HCI_ADMIN_GATE
,
771 NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY
,
772 ndev
->hci_dev
->init_data
.session_id
,
773 strlen(ndev
->hci_dev
->init_data
.session_id
));
781 EXPORT_SYMBOL(nci_hci_dev_session_init
);
783 struct nci_hci_dev
*nci_hci_allocate(struct nci_dev
*ndev
)
785 struct nci_hci_dev
*hdev
;
787 hdev
= kzalloc(sizeof(*hdev
), GFP_KERNEL
);
791 skb_queue_head_init(&hdev
->rx_hcp_frags
);
792 INIT_WORK(&hdev
->msg_rx_work
, nci_hci_msg_rx_work
);
793 skb_queue_head_init(&hdev
->msg_rx_queue
);