aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/digital_dep.c180
1 files changed, 174 insertions, 6 deletions
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c
index e613c294e426..35a9edf0e360 100644
--- a/net/nfc/digital_dep.c
+++ b/net/nfc/digital_dep.c
@@ -109,6 +109,8 @@ struct digital_dep_req_res {
109 109
110static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, 110static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
111 struct sk_buff *resp); 111 struct sk_buff *resp);
112static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
113 struct sk_buff *resp);
112 114
113static const u8 digital_payload_bits_map[4] = { 115static const u8 digital_payload_bits_map[4] = {
114 [0] = 64, 116 [0] = 64,
@@ -201,6 +203,72 @@ digital_send_dep_data_prep(struct nfc_digital_dev *ddev, struct sk_buff *skb,
201 return new_skb; 203 return new_skb;
202} 204}
203 205
206static struct sk_buff *
207digital_recv_dep_data_gather(struct nfc_digital_dev *ddev, u8 pfb,
208 struct sk_buff *resp,
209 int (*send_ack)(struct nfc_digital_dev *ddev,
210 struct digital_data_exch
211 *data_exch),
212 struct digital_data_exch *data_exch)
213{
214 struct sk_buff *new_skb;
215 int rc;
216
217 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb) && (!ddev->chaining_skb)) {
218 ddev->chaining_skb =
219 nfc_alloc_recv_skb(8 * ddev->local_payload_max,
220 GFP_KERNEL);
221 if (!ddev->chaining_skb) {
222 rc = -ENOMEM;
223 goto error;
224 }
225 }
226
227 if (ddev->chaining_skb) {
228 if (resp->len > skb_tailroom(ddev->chaining_skb)) {
229 new_skb = skb_copy_expand(ddev->chaining_skb,
230 skb_headroom(
231 ddev->chaining_skb),
232 8 * ddev->local_payload_max,
233 GFP_KERNEL);
234 if (!new_skb) {
235 rc = -ENOMEM;
236 goto error;
237 }
238
239 kfree_skb(ddev->chaining_skb);
240 ddev->chaining_skb = new_skb;
241 }
242
243 memcpy(skb_put(ddev->chaining_skb, resp->len), resp->data,
244 resp->len);
245
246 kfree_skb(resp);
247 resp = NULL;
248
249 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
250 rc = send_ack(ddev, data_exch);
251 if (rc)
252 goto error;
253
254 return NULL;
255 }
256
257 resp = ddev->chaining_skb;
258 ddev->chaining_skb = NULL;
259 }
260
261 return resp;
262
263error:
264 kfree_skb(resp);
265
266 kfree_skb(ddev->chaining_skb);
267 ddev->chaining_skb = NULL;
268
269 return ERR_PTR(rc);
270}
271
204static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg, 272static void digital_in_recv_psl_res(struct nfc_digital_dev *ddev, void *arg,
205 struct sk_buff *resp) 273 struct sk_buff *resp)
206{ 274{
@@ -429,6 +497,38 @@ int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
429 return rc; 497 return rc;
430} 498}
431 499
500static int digital_in_send_ack(struct nfc_digital_dev *ddev,
501 struct digital_data_exch *data_exch)
502{
503 struct digital_dep_req_res *dep_req;
504 struct sk_buff *skb;
505 int rc;
506
507 skb = digital_skb_alloc(ddev, 1);
508 if (!skb)
509 return -ENOMEM;
510
511 skb_push(skb, sizeof(struct digital_dep_req_res));
512
513 dep_req = (struct digital_dep_req_res *)skb->data;
514
515 dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT;
516 dep_req->cmd = DIGITAL_CMD_DEP_REQ;
517 dep_req->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
518 ddev->curr_nfc_dep_pni;
519
520 digital_skb_push_dep_sod(ddev, skb);
521
522 ddev->skb_add_crc(skb);
523
524 rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res,
525 data_exch);
526 if (rc)
527 kfree_skb(skb);
528
529 return rc;
530}
531
432static int digital_in_send_rtox(struct nfc_digital_dev *ddev, 532static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
433 struct digital_data_exch *data_exch, u8 rtox) 533 struct digital_data_exch *data_exch, u8 rtox)
434{ 534{
@@ -534,6 +634,23 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
534 634
535 ddev->curr_nfc_dep_pni = 635 ddev->curr_nfc_dep_pni =
536 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); 636 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
637
638 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
639 digital_in_send_ack,
640 data_exch);
641 if (IS_ERR(resp)) {
642 rc = PTR_ERR(resp);
643 resp = NULL;
644 goto error;
645 }
646
647 /* If resp is NULL then we're still chaining so return and
648 * wait for the next part of the PDU. Else, the PDU is
649 * complete so pass it up.
650 */
651 if (!resp)
652 return;
653
537 rc = 0; 654 rc = 0;
538 break; 655 break;
539 656
@@ -575,12 +692,6 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
575 return; 692 return;
576 } 693 }
577 694
578 if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) {
579 pr_err("MI bit set. Chained PDU not supported\n");
580 rc = -EIO;
581 goto error;
582 }
583
584exit: 695exit:
585 data_exch->cb(data_exch->cb_context, resp, rc); 696 data_exch->cb(data_exch->cb_context, resp, rc);
586 697
@@ -660,6 +771,48 @@ static void digital_tg_set_rf_tech(struct nfc_digital_dev *ddev, u8 rf_tech)
660 } 771 }
661} 772}
662 773
774static int digital_tg_send_ack(struct nfc_digital_dev *ddev,
775 struct digital_data_exch *data_exch)
776{
777 struct digital_dep_req_res *dep_res;
778 struct sk_buff *skb;
779 int rc;
780
781 skb = digital_skb_alloc(ddev, 1);
782 if (!skb)
783 return -ENOMEM;
784
785 skb_push(skb, sizeof(struct digital_dep_req_res));
786
787 dep_res = (struct digital_dep_req_res *)skb->data;
788
789 dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN;
790 dep_res->cmd = DIGITAL_CMD_DEP_RES;
791 dep_res->pfb = DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU |
792 ddev->curr_nfc_dep_pni;
793
794 if (ddev->did) {
795 dep_res->pfb |= DIGITAL_NFC_DEP_PFB_DID_BIT;
796
797 memcpy(skb_put(skb, sizeof(ddev->did)), &ddev->did,
798 sizeof(ddev->did));
799 }
800
801 ddev->curr_nfc_dep_pni =
802 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
803
804 digital_skb_push_dep_sod(ddev, skb);
805
806 ddev->skb_add_crc(skb);
807
808 rc = digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req,
809 data_exch);
810 if (rc)
811 kfree_skb(skb);
812
813 return rc;
814}
815
663static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg, 816static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
664 struct sk_buff *resp) 817 struct sk_buff *resp)
665{ 818{
@@ -736,6 +889,21 @@ static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
736 goto exit; 889 goto exit;
737 } 890 }
738 891
892 resp = digital_recv_dep_data_gather(ddev, pfb, resp,
893 digital_tg_send_ack, NULL);
894 if (IS_ERR(resp)) {
895 rc = PTR_ERR(resp);
896 resp = NULL;
897 goto exit;
898 }
899
900 /* If resp is NULL then we're still chaining so return and
901 * wait for the next part of the PDU. Else, the PDU is
902 * complete so pass it up.
903 */
904 if (!resp)
905 return;
906
739 rc = 0; 907 rc = 0;
740 break; 908 break;
741 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: 909 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: