aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/hci/command.c4
-rw-r--r--net/nfc/hci/core.c25
-rw-r--r--net/nfc/llcp/commands.c32
-rw-r--r--net/nfc/llcp/llcp.c17
4 files changed, 63 insertions, 15 deletions
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c
index 07659cfd6d7b..7d99410e6c1a 100644
--- a/net/nfc/hci/command.c
+++ b/net/nfc/hci/command.c
@@ -344,7 +344,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
344 return -EADDRINUSE; 344 return -EADDRINUSE;
345 345
346 if (pipe != NFC_HCI_INVALID_PIPE) 346 if (pipe != NFC_HCI_INVALID_PIPE)
347 goto pipe_is_open; 347 goto open_pipe;
348 348
349 switch (dest_gate) { 349 switch (dest_gate) {
350 case NFC_HCI_LINK_MGMT_GATE: 350 case NFC_HCI_LINK_MGMT_GATE:
@@ -361,6 +361,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
361 break; 361 break;
362 } 362 }
363 363
364open_pipe:
364 r = nfc_hci_open_pipe(hdev, pipe); 365 r = nfc_hci_open_pipe(hdev, pipe);
365 if (r < 0) { 366 if (r < 0) {
366 if (pipe_created) 367 if (pipe_created)
@@ -371,7 +372,6 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
371 return r; 372 return r;
372 } 373 }
373 374
374pipe_is_open:
375 hdev->gate2pipe[dest_gate] = pipe; 375 hdev->gate2pipe[dest_gate] = pipe;
376 376
377 return 0; 377 return 0;
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index bc571b0efb92..7bea574d5934 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -33,17 +33,20 @@
33/* Largest headroom needed for outgoing HCI commands */ 33/* Largest headroom needed for outgoing HCI commands */
34#define HCI_CMDS_HEADROOM 1 34#define HCI_CMDS_HEADROOM 1
35 35
36static int nfc_hci_result_to_errno(u8 result) 36int nfc_hci_result_to_errno(u8 result)
37{ 37{
38 switch (result) { 38 switch (result) {
39 case NFC_HCI_ANY_OK: 39 case NFC_HCI_ANY_OK:
40 return 0; 40 return 0;
41 case NFC_HCI_ANY_E_REG_PAR_UNKNOWN:
42 return -EOPNOTSUPP;
41 case NFC_HCI_ANY_E_TIMEOUT: 43 case NFC_HCI_ANY_E_TIMEOUT:
42 return -ETIME; 44 return -ETIME;
43 default: 45 default:
44 return -1; 46 return -1;
45 } 47 }
46} 48}
49EXPORT_SYMBOL(nfc_hci_result_to_errno);
47 50
48static void nfc_hci_msg_tx_work(struct work_struct *work) 51static void nfc_hci_msg_tx_work(struct work_struct *work)
49{ 52{
@@ -167,7 +170,7 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
167 kfree_skb(skb); 170 kfree_skb(skb);
168} 171}
169 172
170static u32 nfc_hci_sak_to_protocol(u8 sak) 173u32 nfc_hci_sak_to_protocol(u8 sak)
171{ 174{
172 switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) { 175 switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) {
173 case NFC_HCI_TYPE_A_SEL_PROT_MIFARE: 176 case NFC_HCI_TYPE_A_SEL_PROT_MIFARE:
@@ -182,6 +185,7 @@ static u32 nfc_hci_sak_to_protocol(u8 sak)
182 return 0xffffffff; 185 return 0xffffffff;
183 } 186 }
184} 187}
188EXPORT_SYMBOL(nfc_hci_sak_to_protocol);
185 189
186int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) 190int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate)
187{ 191{
@@ -284,6 +288,12 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
284 struct sk_buff *skb) 288 struct sk_buff *skb)
285{ 289{
286 int r = 0; 290 int r = 0;
291 u8 gate = nfc_hci_pipe2gate(hdev, pipe);
292
293 if (gate == 0xff) {
294 pr_err("Discarded event %x to unopened pipe %x\n", event, pipe);
295 goto exit;
296 }
287 297
288 switch (event) { 298 switch (event) {
289 case NFC_HCI_EVT_TARGET_DISCOVERED: 299 case NFC_HCI_EVT_TARGET_DISCOVERED:
@@ -307,14 +317,11 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
307 goto exit; 317 goto exit;
308 } 318 }
309 319
310 r = nfc_hci_target_discovered(hdev, 320 r = nfc_hci_target_discovered(hdev, gate);
311 nfc_hci_pipe2gate(hdev, pipe));
312 break; 321 break;
313 default: 322 default:
314 if (hdev->ops->event_received) { 323 if (hdev->ops->event_received) {
315 hdev->ops->event_received(hdev, 324 hdev->ops->event_received(hdev, gate, event, skb);
316 nfc_hci_pipe2gate(hdev, pipe),
317 event, skb);
318 return; 325 return;
319 } 326 }
320 327
@@ -419,6 +426,10 @@ static int hci_dev_version(struct nfc_hci_dev *hdev)
419 426
420 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, 427 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
421 NFC_HCI_ID_MGMT_VERSION_SW, &skb); 428 NFC_HCI_ID_MGMT_VERSION_SW, &skb);
429 if (r == -EOPNOTSUPP) {
430 pr_info("Software/Hardware info not available\n");
431 return 0;
432 }
422 if (r < 0) 433 if (r < 0)
423 return r; 434 return r;
424 435
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c
index ed2d17312d61..df24be48d4da 100644
--- a/net/nfc/llcp/commands.c
+++ b/net/nfc/llcp/commands.c
@@ -528,6 +528,23 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
528 if (local == NULL) 528 if (local == NULL)
529 return -ENODEV; 529 return -ENODEV;
530 530
531 /* Remote is ready but has not acknowledged our frames */
532 if((sock->remote_ready &&
533 skb_queue_len(&sock->tx_pending_queue) >= sock->rw &&
534 skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) {
535 pr_err("Pending queue is full %d frames\n",
536 skb_queue_len(&sock->tx_pending_queue));
537 return -ENOBUFS;
538 }
539
540 /* Remote is not ready and we've been queueing enough frames */
541 if ((!sock->remote_ready &&
542 skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) {
543 pr_err("Tx queue is full %d frames\n",
544 skb_queue_len(&sock->tx_queue));
545 return -ENOBUFS;
546 }
547
531 msg_data = kzalloc(len, GFP_KERNEL); 548 msg_data = kzalloc(len, GFP_KERNEL);
532 if (msg_data == NULL) 549 if (msg_data == NULL)
533 return -ENOMEM; 550 return -ENOMEM;
@@ -579,7 +596,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
579 struct sk_buff *pdu; 596 struct sk_buff *pdu;
580 struct nfc_llcp_local *local; 597 struct nfc_llcp_local *local;
581 size_t frag_len = 0, remaining_len; 598 size_t frag_len = 0, remaining_len;
582 u8 *msg_ptr; 599 u8 *msg_ptr, *msg_data;
583 int err; 600 int err;
584 601
585 pr_debug("Send UI frame len %zd\n", len); 602 pr_debug("Send UI frame len %zd\n", len);
@@ -588,8 +605,17 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
588 if (local == NULL) 605 if (local == NULL)
589 return -ENODEV; 606 return -ENODEV;
590 607
608 msg_data = kzalloc(len, GFP_KERNEL);
609 if (msg_data == NULL)
610 return -ENOMEM;
611
612 if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
613 kfree(msg_data);
614 return -EFAULT;
615 }
616
591 remaining_len = len; 617 remaining_len = len;
592 msg_ptr = (u8 *) msg->msg_iov; 618 msg_ptr = msg_data;
593 619
594 while (remaining_len > 0) { 620 while (remaining_len > 0) {
595 621
@@ -616,6 +642,8 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
616 msg_ptr += frag_len; 642 msg_ptr += frag_len;
617 } 643 }
618 644
645 kfree(msg_data);
646
619 return len; 647 return len;
620} 648}
621 649
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 2e9ddf34c099..2df87056c6df 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -656,6 +656,8 @@ static void nfc_llcp_tx_work(struct work_struct *work)
656 if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) { 656 if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) {
657 nfc_llcp_send_symm(local->dev); 657 nfc_llcp_send_symm(local->dev);
658 } else { 658 } else {
659 struct sk_buff *copy_skb = NULL;
660 u8 ptype = nfc_llcp_ptype(skb);
659 int ret; 661 int ret;
660 662
661 pr_debug("Sending pending skb\n"); 663 pr_debug("Sending pending skb\n");
@@ -663,22 +665,29 @@ static void nfc_llcp_tx_work(struct work_struct *work)
663 DUMP_PREFIX_OFFSET, 16, 1, 665 DUMP_PREFIX_OFFSET, 16, 1,
664 skb->data, skb->len, true); 666 skb->data, skb->len, true);
665 667
668 if (ptype == LLCP_PDU_I)
669 copy_skb = skb_copy(skb, GFP_ATOMIC);
670
666 nfc_llcp_send_to_raw_sock(local, skb, 671 nfc_llcp_send_to_raw_sock(local, skb,
667 NFC_LLCP_DIRECTION_TX); 672 NFC_LLCP_DIRECTION_TX);
668 673
669 ret = nfc_data_exchange(local->dev, local->target_idx, 674 ret = nfc_data_exchange(local->dev, local->target_idx,
670 skb, nfc_llcp_recv, local); 675 skb, nfc_llcp_recv, local);
671 676
672 if (!ret && nfc_llcp_ptype(skb) == LLCP_PDU_I) { 677 if (ret) {
673 skb = skb_get(skb); 678 kfree_skb(copy_skb);
674 skb_queue_tail(&llcp_sock->tx_pending_queue, 679 goto out;
675 skb);
676 } 680 }
681
682 if (ptype == LLCP_PDU_I && copy_skb)
683 skb_queue_tail(&llcp_sock->tx_pending_queue,
684 copy_skb);
677 } 685 }
678 } else { 686 } else {
679 nfc_llcp_send_symm(local->dev); 687 nfc_llcp_send_symm(local->dev);
680 } 688 }
681 689
690out:
682 mod_timer(&local->link_timer, 691 mod_timer(&local->link_timer,
683 jiffies + msecs_to_jiffies(2 * local->remote_lto)); 692 jiffies + msecs_to_jiffies(2 * local->remote_lto));
684} 693}