aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-11-28 17:49:16 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-28 17:49:16 -0500
commit83a9d197c7ecd1913e84aaa982a7215666b656f2 (patch)
treed38c07e2ad8e01abfc73f1234d3db9ed754128ec /net/nfc
parent9e3262e2533f62b9a63e98fc0b17e47c9e298b3d (diff)
parent79d38f7d6cf545ff838dd5227869f3916d1d100d (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== This pull request is intended for the 3.8 stream. It is a bit large -- I guess Thanksgiving got me off track! At least the code got to spend some time in linux-next... :-) This includes the usual batch of pulls for Bluetooth, NFC, and mac80211 as well as iwlwifi. Also here is an ath6kl pull, and a new driver in the rtlwifi family. The brcmfmac, brcmsmac, ath9k, and mwl8k get their usual levels of attention, and a handful of other updates tag along as well. For more detail on the pulls, please see below... On Bluetooth, Gustavo says: "Another set of patches for integration in wireless-next. There are two big set of changes in it: Andrei Emeltchenko and Mat Martineau added more patches towards a full Bluetooth High Speed support and Johan Hedberg improve the single mode support for Bluetooth dongles. Apart from that we have small fixes and improvements." ...and: "A few patches to 3.8. The majority of the work here is from Andrei on the High Speed support. Other than that Johan added support for setting LE advertising data. The rest are fixes and clean ups and small improvements like support for a new broadcom hardware." On mac80211, Johannes says: "This is for mac80211, for -next (3.8). Plenty of changes, as you can see below. Some fixes for previous changes like the export.h include, the beacon listener fix from Ben Greear, etc. Overall, no exciting new features, though hwsim does gain channel context support for people to try it out and look at." ...and...: "This one contains the mac80211-next material. Apart from a few small new features and cleanups I have two fixes for the channel context code. The RX_END timestamp support will probably be reworked again as Simon Barber noted the calculations weren't really valid, but the discussions there are still going on and it's better than what we had before." ...and: "Please pull (see below) to get the following changes: * a fix & a debug aid in IBSS from Antonio, * mesh cleanups from Marco, * a few bugfixes for some of my previous patches from Arend and myself, * and the big initial VHT support patchset" And on iwlwifi, Johannes says: "In addition to the previous four patches that I'm not resending, we have a number of cleanups, message reduction, firmware error handling improvements (yes yes... we need to fix them instead) and various other small things all over." ...and: "In his quest to try to understand the current iwlwifi problems (like stuck queues etc.) Emmanuel has first cleaned up the PCIe code, I'm including his changes in this pull request. Other than that I only have a small cleanup from Sachin Kamat to remove a duplicate include and a bugfix to turn off MFP if software crypto is enabled, but this isn't really interesting as MFP isn't supported right now anyway." On NFC, Samuel says: "With this one we have: - A few HCI improvements in preparation for an upcoming HCI chipset support. - A pn544 code cleanup after the old driver was removed. - An LLCP improvement for notifying user space when one peer stops ACKing I frames." On ath6kl, Kalle says: "Major changes this time are firmware recover support to gracefully handle if firmware crashes, support for changing regulatory domain and support for new ar6004 hardware revision 1.4. Otherwise there are just smaller fixes or cleanups from different people." Thats about it... :-) Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
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}