aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp/llcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/llcp/llcp.c')
-rw-r--r--net/nfc/llcp/llcp.c131
1 files changed, 70 insertions, 61 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 82f0f7588b46..c12c5ef3d036 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -56,7 +56,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
56 sk_for_each_safe(sk, node, tmp, &local->sockets.head) { 56 sk_for_each_safe(sk, node, tmp, &local->sockets.head) {
57 llcp_sock = nfc_llcp_sock(sk); 57 llcp_sock = nfc_llcp_sock(sk);
58 58
59 lock_sock(sk); 59 bh_lock_sock(sk);
60 60
61 if (sk->sk_state == LLCP_CONNECTED) 61 if (sk->sk_state == LLCP_CONNECTED)
62 nfc_put_device(llcp_sock->dev); 62 nfc_put_device(llcp_sock->dev);
@@ -68,26 +68,26 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
68 list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, 68 list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
69 accept_queue) { 69 accept_queue) {
70 accept_sk = &lsk->sk; 70 accept_sk = &lsk->sk;
71 lock_sock(accept_sk); 71 bh_lock_sock(accept_sk);
72 72
73 nfc_llcp_accept_unlink(accept_sk); 73 nfc_llcp_accept_unlink(accept_sk);
74 74
75 accept_sk->sk_state = LLCP_CLOSED; 75 accept_sk->sk_state = LLCP_CLOSED;
76 76
77 release_sock(accept_sk); 77 bh_unlock_sock(accept_sk);
78 78
79 sock_orphan(accept_sk); 79 sock_orphan(accept_sk);
80 } 80 }
81 81
82 if (listen == true) { 82 if (listen == true) {
83 release_sock(sk); 83 bh_unlock_sock(sk);
84 continue; 84 continue;
85 } 85 }
86 } 86 }
87 87
88 sk->sk_state = LLCP_CLOSED; 88 sk->sk_state = LLCP_CLOSED;
89 89
90 release_sock(sk); 90 bh_unlock_sock(sk);
91 91
92 sock_orphan(sk); 92 sock_orphan(sk);
93 93
@@ -114,9 +114,9 @@ static void local_release(struct kref *ref)
114 nfc_llcp_socket_release(local, false); 114 nfc_llcp_socket_release(local, false);
115 del_timer_sync(&local->link_timer); 115 del_timer_sync(&local->link_timer);
116 skb_queue_purge(&local->tx_queue); 116 skb_queue_purge(&local->tx_queue);
117 destroy_workqueue(local->tx_wq); 117 cancel_work_sync(&local->tx_work);
118 destroy_workqueue(local->rx_wq); 118 cancel_work_sync(&local->rx_work);
119 destroy_workqueue(local->timeout_wq); 119 cancel_work_sync(&local->timeout_work);
120 kfree_skb(local->rx_pending); 120 kfree_skb(local->rx_pending);
121 kfree(local); 121 kfree(local);
122} 122}
@@ -181,7 +181,7 @@ static void nfc_llcp_symm_timer(unsigned long data)
181 181
182 pr_err("SYMM timeout\n"); 182 pr_err("SYMM timeout\n");
183 183
184 queue_work(local->timeout_wq, &local->timeout_work); 184 queue_work(system_nrt_wq, &local->timeout_work);
185} 185}
186 186
187struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) 187struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
@@ -426,6 +426,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
426 u8 *miux_tlv, miux_length; 426 u8 *miux_tlv, miux_length;
427 __be16 miux; 427 __be16 miux;
428 u8 gb_len = 0; 428 u8 gb_len = 0;
429 int ret = 0;
429 430
430 version = LLCP_VERSION_11; 431 version = LLCP_VERSION_11;
431 version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version, 432 version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version,
@@ -450,8 +451,8 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
450 gb_len += ARRAY_SIZE(llcp_magic); 451 gb_len += ARRAY_SIZE(llcp_magic);
451 452
452 if (gb_len > NFC_MAX_GT_LEN) { 453 if (gb_len > NFC_MAX_GT_LEN) {
453 kfree(version_tlv); 454 ret = -EINVAL;
454 return -EINVAL; 455 goto out;
455 } 456 }
456 457
457 gb_cur = local->gb; 458 gb_cur = local->gb;
@@ -471,12 +472,15 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
471 memcpy(gb_cur, miux_tlv, miux_length); 472 memcpy(gb_cur, miux_tlv, miux_length);
472 gb_cur += miux_length; 473 gb_cur += miux_length;
473 474
475 local->gb_len = gb_len;
476
477out:
474 kfree(version_tlv); 478 kfree(version_tlv);
475 kfree(lto_tlv); 479 kfree(lto_tlv);
480 kfree(wks_tlv);
481 kfree(miux_tlv);
476 482
477 local->gb_len = gb_len; 483 return ret;
478
479 return 0;
480} 484}
481 485
482u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len) 486u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
@@ -554,6 +558,46 @@ static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu)
554 sock->recv_ack_n = (sock->recv_n - 1) % 16; 558 sock->recv_ack_n = (sock->recv_n - 1) % 16;
555} 559}
556 560
561void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
562 struct sk_buff *skb, u8 direction)
563{
564 struct hlist_node *node;
565 struct sk_buff *skb_copy = NULL, *nskb;
566 struct sock *sk;
567 u8 *data;
568
569 read_lock(&local->raw_sockets.lock);
570
571 sk_for_each(sk, node, &local->raw_sockets.head) {
572 if (sk->sk_state != LLCP_BOUND)
573 continue;
574
575 if (skb_copy == NULL) {
576 skb_copy = __pskb_copy(skb, NFC_LLCP_RAW_HEADER_SIZE,
577 GFP_ATOMIC);
578
579 if (skb_copy == NULL)
580 continue;
581
582 data = skb_push(skb_copy, NFC_LLCP_RAW_HEADER_SIZE);
583
584 data[0] = local->dev ? local->dev->idx : 0xFF;
585 data[1] = direction;
586 }
587
588 nskb = skb_clone(skb_copy, GFP_ATOMIC);
589 if (!nskb)
590 continue;
591
592 if (sock_queue_rcv_skb(sk, nskb))
593 kfree_skb(nskb);
594 }
595
596 read_unlock(&local->raw_sockets.lock);
597
598 kfree_skb(skb_copy);
599}
600
557static void nfc_llcp_tx_work(struct work_struct *work) 601static void nfc_llcp_tx_work(struct work_struct *work)
558{ 602{
559 struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, 603 struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
@@ -574,6 +618,9 @@ static void nfc_llcp_tx_work(struct work_struct *work)
574 DUMP_PREFIX_OFFSET, 16, 1, 618 DUMP_PREFIX_OFFSET, 16, 1,
575 skb->data, skb->len, true); 619 skb->data, skb->len, true);
576 620
621 nfc_llcp_send_to_raw_sock(local, skb,
622 NFC_LLCP_DIRECTION_TX);
623
577 ret = nfc_data_exchange(local->dev, local->target_idx, 624 ret = nfc_data_exchange(local->dev, local->target_idx,
578 skb, nfc_llcp_recv, local); 625 skb, nfc_llcp_recv, local);
579 626
@@ -1018,6 +1065,8 @@ static void nfc_llcp_rx_work(struct work_struct *work)
1018 print_hex_dump(KERN_DEBUG, "LLCP Rx: ", DUMP_PREFIX_OFFSET, 1065 print_hex_dump(KERN_DEBUG, "LLCP Rx: ", DUMP_PREFIX_OFFSET,
1019 16, 1, skb->data, skb->len, true); 1066 16, 1, skb->data, skb->len, true);
1020 1067
1068 nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_RX);
1069
1021 switch (ptype) { 1070 switch (ptype) {
1022 case LLCP_PDU_SYMM: 1071 case LLCP_PDU_SYMM:
1023 pr_debug("SYMM\n"); 1072 pr_debug("SYMM\n");
@@ -1052,7 +1101,7 @@ static void nfc_llcp_rx_work(struct work_struct *work)
1052 1101
1053 } 1102 }
1054 1103
1055 queue_work(local->tx_wq, &local->tx_work); 1104 queue_work(system_nrt_wq, &local->tx_work);
1056 kfree_skb(local->rx_pending); 1105 kfree_skb(local->rx_pending);
1057 local->rx_pending = NULL; 1106 local->rx_pending = NULL;
1058 1107
@@ -1071,7 +1120,7 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err)
1071 1120
1072 local->rx_pending = skb_get(skb); 1121 local->rx_pending = skb_get(skb);
1073 del_timer(&local->link_timer); 1122 del_timer(&local->link_timer);
1074 queue_work(local->rx_wq, &local->rx_work); 1123 queue_work(system_nrt_wq, &local->rx_work);
1075 1124
1076 return; 1125 return;
1077} 1126}
@@ -1086,7 +1135,7 @@ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
1086 1135
1087 local->rx_pending = skb_get(skb); 1136 local->rx_pending = skb_get(skb);
1088 del_timer(&local->link_timer); 1137 del_timer(&local->link_timer);
1089 queue_work(local->rx_wq, &local->rx_work); 1138 queue_work(system_nrt_wq, &local->rx_work);
1090 1139
1091 return 0; 1140 return 0;
1092} 1141}
@@ -1121,7 +1170,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
1121 if (rf_mode == NFC_RF_INITIATOR) { 1170 if (rf_mode == NFC_RF_INITIATOR) {
1122 pr_debug("Queueing Tx work\n"); 1171 pr_debug("Queueing Tx work\n");
1123 1172
1124 queue_work(local->tx_wq, &local->tx_work); 1173 queue_work(system_nrt_wq, &local->tx_work);
1125 } else { 1174 } else {
1126 mod_timer(&local->link_timer, 1175 mod_timer(&local->link_timer,
1127 jiffies + msecs_to_jiffies(local->remote_lto)); 1176 jiffies + msecs_to_jiffies(local->remote_lto));
@@ -1130,10 +1179,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
1130 1179
1131int nfc_llcp_register_device(struct nfc_dev *ndev) 1180int nfc_llcp_register_device(struct nfc_dev *ndev)
1132{ 1181{
1133 struct device *dev = &ndev->dev;
1134 struct nfc_llcp_local *local; 1182 struct nfc_llcp_local *local;
1135 char name[32];
1136 int err;
1137 1183
1138 local = kzalloc(sizeof(struct nfc_llcp_local), GFP_KERNEL); 1184 local = kzalloc(sizeof(struct nfc_llcp_local), GFP_KERNEL);
1139 if (local == NULL) 1185 if (local == NULL)
@@ -1149,41 +1195,15 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
1149 1195
1150 skb_queue_head_init(&local->tx_queue); 1196 skb_queue_head_init(&local->tx_queue);
1151 INIT_WORK(&local->tx_work, nfc_llcp_tx_work); 1197 INIT_WORK(&local->tx_work, nfc_llcp_tx_work);
1152 snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev));
1153 local->tx_wq =
1154 alloc_workqueue(name,
1155 WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
1156 1);
1157 if (local->tx_wq == NULL) {
1158 err = -ENOMEM;
1159 goto err_local;
1160 }
1161 1198
1162 local->rx_pending = NULL; 1199 local->rx_pending = NULL;
1163 INIT_WORK(&local->rx_work, nfc_llcp_rx_work); 1200 INIT_WORK(&local->rx_work, nfc_llcp_rx_work);
1164 snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev));
1165 local->rx_wq =
1166 alloc_workqueue(name,
1167 WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
1168 1);
1169 if (local->rx_wq == NULL) {
1170 err = -ENOMEM;
1171 goto err_tx_wq;
1172 }
1173 1201
1174 INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work); 1202 INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
1175 snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev));
1176 local->timeout_wq =
1177 alloc_workqueue(name,
1178 WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
1179 1);
1180 if (local->timeout_wq == NULL) {
1181 err = -ENOMEM;
1182 goto err_rx_wq;
1183 }
1184 1203
1185 local->sockets.lock = __RW_LOCK_UNLOCKED(local->sockets.lock); 1204 rwlock_init(&local->sockets.lock);
1186 local->connecting_sockets.lock = __RW_LOCK_UNLOCKED(local->connecting_sockets.lock); 1205 rwlock_init(&local->connecting_sockets.lock);
1206 rwlock_init(&local->raw_sockets.lock);
1187 1207
1188 nfc_llcp_build_gb(local); 1208 nfc_llcp_build_gb(local);
1189 1209
@@ -1193,17 +1213,6 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
1193 list_add(&llcp_devices, &local->list); 1213 list_add(&llcp_devices, &local->list);
1194 1214
1195 return 0; 1215 return 0;
1196
1197err_rx_wq:
1198 destroy_workqueue(local->rx_wq);
1199
1200err_tx_wq:
1201 destroy_workqueue(local->tx_wq);
1202
1203err_local:
1204 kfree(local);
1205
1206 return 0;
1207} 1216}
1208 1217
1209void nfc_llcp_unregister_device(struct nfc_dev *dev) 1218void nfc_llcp_unregister_device(struct nfc_dev *dev)