Skip to content

Commit 1892bf8

Browse files
cricard13Samuel Ortiz
authored andcommitted
NFC: st21nfca: Adding P2P support to st21nfca in Initiator & Target mode
Support for Initiator and Target mode with ISO18092 commands support: - ATR_REQ/ATR_RES - PSL_REQ/PSL_RES - DEP_REQ/DEP_RES Work based on net/nfc/digital_dep.c. st21nfca is using: - Gate reader F for P2P in initiator mode. - Gate card F for P2P in target mode. Felica tag and p2p are differentiated with NFCID2. When starting with 01FE it is acting in p2p mode. On complete_target_discovered on ST21NFCA_RF_READER_F_GATE supported_protocols is set to NFC_PROTO_NFC_DEP_MASK for P2P. Tested against: Nexus S, Galaxy S2, Galaxy S3, Galaxy S3 Mini, Nexus 4 & Nexus 5. Signed-off-by: Christophe Ricard <[email protected]> Signed-off-by: Samuel Ortiz <[email protected]>
1 parent d57d74e commit 1892bf8

File tree

5 files changed

+993
-3
lines changed

5 files changed

+993
-3
lines changed

drivers/nfc/st21nfca/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
st21nfca_i2c-objs = i2c.o
66

7-
obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o
7+
obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o st21nfca_dep.o
88
obj-$(CONFIG_NFC_ST21NFCA_I2C) += st21nfca_i2c.o

drivers/nfc/st21nfca/st21nfca.c

Lines changed: 263 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <net/nfc/llc.h>
2323

2424
#include "st21nfca.h"
25+
#include "st21nfca_dep.h"
2526

2627
#define DRIVER_DESC "HCI NFC driver for ST21NFCA"
2728

@@ -73,6 +74,7 @@ static struct nfc_hci_gate st21nfca_gates[] = {
7374
{ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
7475
{ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE},
7576
{ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
77+
{ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE},
7678
};
7779

7880
struct st21nfca_pipe_info {
@@ -300,6 +302,9 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
300302
u32 im_protocols, u32 tm_protocols)
301303
{
302304
int r;
305+
u32 pol_req;
306+
u8 param[19];
307+
struct sk_buff *datarate_skb;
303308

304309
pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n",
305310
__func__, im_protocols, tm_protocols);
@@ -332,6 +337,31 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
332337
ST21NFCA_RF_READER_F_GATE);
333338
if (r < 0)
334339
return r;
340+
} else {
341+
hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
342+
&hdev->gb_len);
343+
344+
if (hdev->gb == NULL || hdev->gb_len == 0) {
345+
im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
346+
tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
347+
}
348+
349+
param[0] = ST21NFCA_RF_READER_F_DATARATE_106 |
350+
ST21NFCA_RF_READER_F_DATARATE_212 |
351+
ST21NFCA_RF_READER_F_DATARATE_424;
352+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
353+
ST21NFCA_RF_READER_F_DATARATE,
354+
param, 1);
355+
if (r < 0)
356+
return r;
357+
358+
pol_req =
359+
be32_to_cpu(ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
360+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
361+
ST21NFCA_RF_READER_F_POL_REQ,
362+
(u8 *) &pol_req, 4);
363+
if (r < 0)
364+
return r;
335365
}
336366

337367
if ((ST21NFCA_RF_READER_14443_3_A_GATE & im_protocols) == 0) {
@@ -354,6 +384,95 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
354384
nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
355385
NFC_HCI_EVT_END_OPERATION, NULL, 0);
356386
}
387+
388+
if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
389+
r = nfc_hci_get_param(hdev, ST21NFCA_RF_CARD_F_GATE,
390+
ST21NFCA_RF_CARD_F_DATARATE,
391+
&datarate_skb);
392+
if (r < 0)
393+
return r;
394+
395+
/* Configure the maximum supported datarate to 424Kbps */
396+
if (datarate_skb->len > 0 &&
397+
datarate_skb->data[0] !=
398+
ST21NFCA_RF_CARD_F_DATARATE_212_424) {
399+
param[0] = ST21NFCA_RF_CARD_F_DATARATE_212_424;
400+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
401+
ST21NFCA_RF_CARD_F_DATARATE,
402+
param, 1);
403+
if (r < 0)
404+
return r;
405+
}
406+
407+
/*
408+
* Configure sens_res
409+
*
410+
* NFC Forum Digital Spec Table 7:
411+
* NFCID1 size: triple (10 bytes)
412+
*/
413+
param[0] = 0x00;
414+
param[1] = 0x08;
415+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
416+
ST21NFCA_RF_CARD_F_SENS_RES, param, 2);
417+
if (r < 0)
418+
return r;
419+
420+
/*
421+
* Configure sel_res
422+
*
423+
* NFC Forum Digistal Spec Table 17:
424+
* b3 set to 0b (value b7-b6):
425+
* - 10b: Configured for NFC-DEP Protocol
426+
*/
427+
param[0] = 0x40;
428+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
429+
ST21NFCA_RF_CARD_F_SEL_RES, param, 1);
430+
if (r < 0)
431+
return r;
432+
433+
/* Configure NFCID1 Random uid */
434+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
435+
ST21NFCA_RF_CARD_F_NFCID1, NULL, 0);
436+
if (r < 0)
437+
return r;
438+
439+
/* Configure NFCID2_LIST */
440+
/* System Code */
441+
param[0] = 0x00;
442+
param[1] = 0x00;
443+
/* NFCID2 */
444+
param[2] = 0x01;
445+
param[3] = 0xfe;
446+
param[4] = 'S';
447+
param[5] = 'T';
448+
param[6] = 'M';
449+
param[7] = 'i';
450+
param[8] = 'c';
451+
param[9] = 'r';
452+
/* 8 byte Pad bytes used for polling respone frame */
453+
454+
/*
455+
* Configuration byte:
456+
* - bit 0: define the default NFCID2 entry used when the
457+
* system code is equal to 'FFFF'
458+
* - bit 1: use a random value for lowest 6 bytes of
459+
* NFCID2 value
460+
* - bit 2: ignore polling request frame if request code
461+
* is equal to '01'
462+
* - Other bits are RFU
463+
*/
464+
param[18] = 0x01;
465+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
466+
ST21NFCA_RF_CARD_F_NFCID2_LIST, param,
467+
19);
468+
if (r < 0)
469+
return r;
470+
471+
param[0] = 0x02;
472+
r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
473+
ST21NFCA_RF_CARD_F_MODE, param, 1);
474+
}
475+
357476
return r;
358477
}
359478

@@ -458,6 +577,26 @@ static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev,
458577
return r;
459578
}
460579

580+
static int st21nfca_hci_dep_link_up(struct nfc_hci_dev *hdev,
581+
struct nfc_target *target, u8 comm_mode,
582+
u8 *gb, size_t gb_len)
583+
{
584+
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
585+
586+
info->dep_info.idx = target->idx;
587+
return st21nfca_im_send_atr_req(hdev, gb, gb_len);
588+
}
589+
590+
static int st21nfca_hci_dep_link_down(struct nfc_hci_dev *hdev)
591+
{
592+
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
593+
594+
info->state = ST21NFCA_ST_READY;
595+
596+
return nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
597+
ST21NFCA_DM_DISCONNECT, NULL, 0, NULL);
598+
}
599+
461600
static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
462601
struct nfc_target *target)
463602
{
@@ -512,6 +651,69 @@ static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
512651
return 0;
513652
}
514653

654+
static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev,
655+
u8 gate,
656+
struct nfc_target *target)
657+
{
658+
int r;
659+
struct sk_buff *nfcid2_skb = NULL, *nfcid1_skb;
660+
661+
if (gate == ST21NFCA_RF_READER_F_GATE) {
662+
r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
663+
ST21NFCA_RF_READER_F_NFCID2, &nfcid2_skb);
664+
if (r < 0)
665+
goto exit;
666+
667+
if (nfcid2_skb->len > NFC_SENSF_RES_MAXSIZE) {
668+
r = -EPROTO;
669+
goto exit;
670+
}
671+
672+
/*
673+
* - After the recepton of polling response for type F frame
674+
* at 212 or 424 Kbit/s, NFCID2 registry parameters will be
675+
* updated.
676+
* - After the reception of SEL_RES with NFCIP-1 compliant bit
677+
* set for type A frame NFCID1 will be updated
678+
*/
679+
if (nfcid2_skb->len > 0) {
680+
/* P2P in type F */
681+
memcpy(target->sensf_res, nfcid2_skb->data,
682+
nfcid2_skb->len);
683+
target->sensf_res_len = nfcid2_skb->len;
684+
/* NFC Forum Digital Protocol Table 44 */
685+
if (target->sensf_res[0] == 0x01 &&
686+
target->sensf_res[1] == 0xfe)
687+
target->supported_protocols =
688+
NFC_PROTO_NFC_DEP_MASK;
689+
else
690+
target->supported_protocols =
691+
NFC_PROTO_FELICA_MASK;
692+
} else {
693+
/* P2P in type A */
694+
r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
695+
ST21NFCA_RF_READER_F_NFCID1,
696+
&nfcid1_skb);
697+
if (r < 0)
698+
goto exit;
699+
700+
if (nfcid1_skb->len > NFC_NFCID1_MAXSIZE) {
701+
r = -EPROTO;
702+
goto exit;
703+
}
704+
memcpy(target->sensf_res, nfcid1_skb->data,
705+
nfcid1_skb->len);
706+
target->sensf_res_len = nfcid1_skb->len;
707+
target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
708+
}
709+
target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE;
710+
}
711+
r = 1;
712+
exit:
713+
kfree_skb(nfcid2_skb);
714+
return r;
715+
}
716+
515717
#define ST21NFCA_CB_TYPE_READER_ISO15693 1
516718
static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb,
517719
int err)
@@ -548,6 +750,9 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
548750

549751
switch (target->hci_reader_gate) {
550752
case ST21NFCA_RF_READER_F_GATE:
753+
if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK)
754+
return st21nfca_im_send_dep_req(hdev, skb);
755+
551756
*skb_push(skb, 1) = 0x1a;
552757
return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
553758
ST21NFCA_WR_XCHG_DATA, skb->data,
@@ -576,6 +781,11 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
576781
}
577782
}
578783

784+
static int st21nfca_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
785+
{
786+
return st21nfca_tm_send_dep_res(hdev, skb);
787+
}
788+
579789
static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
580790
struct nfc_target *target)
581791
{
@@ -601,6 +811,50 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
601811
}
602812
}
603813

814+
/*
815+
* Returns:
816+
* <= 0: driver handled the event, skb consumed
817+
* 1: driver does not handle the event, please do standard processing
818+
*/
819+
static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate,
820+
u8 event, struct sk_buff *skb)
821+
{
822+
int r;
823+
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
824+
825+
pr_debug("hci event: %d\n", event);
826+
827+
switch (event) {
828+
case ST21NFCA_EVT_CARD_ACTIVATED:
829+
if (gate == ST21NFCA_RF_CARD_F_GATE)
830+
info->dep_info.curr_nfc_dep_pni = 0;
831+
break;
832+
case ST21NFCA_EVT_CARD_DEACTIVATED:
833+
break;
834+
case ST21NFCA_EVT_FIELD_ON:
835+
break;
836+
case ST21NFCA_EVT_FIELD_OFF:
837+
break;
838+
case ST21NFCA_EVT_SEND_DATA:
839+
if (gate == ST21NFCA_RF_CARD_F_GATE) {
840+
r = st21nfca_tm_event_send_data(hdev, skb, gate);
841+
if (r < 0)
842+
goto exit;
843+
return 0;
844+
} else {
845+
info->dep_info.curr_nfc_dep_pni = 0;
846+
return 1;
847+
}
848+
break;
849+
default:
850+
return 1;
851+
}
852+
kfree_skb(skb);
853+
return 0;
854+
exit:
855+
return r;
856+
}
857+
604858
static struct nfc_hci_ops st21nfca_hci_ops = {
605859
.open = st21nfca_hci_open,
606860
.close = st21nfca_hci_close,
@@ -609,9 +863,14 @@ static struct nfc_hci_ops st21nfca_hci_ops = {
609863
.xmit = st21nfca_hci_xmit,
610864
.start_poll = st21nfca_hci_start_poll,
611865
.stop_poll = st21nfca_hci_stop_poll,
866+
.dep_link_up = st21nfca_hci_dep_link_up,
867+
.dep_link_down = st21nfca_hci_dep_link_down,
612868
.target_from_gate = st21nfca_hci_target_from_gate,
869+
.complete_target_discovered = st21nfca_hci_complete_target_discovered,
613870
.im_transceive = st21nfca_hci_im_transceive,
871+
.tm_send = st21nfca_hci_tm_send,
614872
.check_presence = st21nfca_hci_check_presence,
873+
.event_received = st21nfca_hci_event_received,
615874
};
616875

617876
int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
@@ -656,7 +915,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
656915
NFC_PROTO_FELICA_MASK |
657916
NFC_PROTO_ISO14443_MASK |
658917
NFC_PROTO_ISO14443_B_MASK |
659-
NFC_PROTO_ISO15693_MASK;
918+
NFC_PROTO_ISO15693_MASK |
919+
NFC_PROTO_NFC_DEP_MASK;
660920

661921
set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);
662922

@@ -679,6 +939,7 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
679939
goto err_regdev;
680940

681941
*hdev = info->hdev;
942+
st21nfca_dep_init(info->hdev);
682943

683944
return 0;
684945

@@ -696,6 +957,7 @@ void st21nfca_hci_remove(struct nfc_hci_dev *hdev)
696957
{
697958
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
698959

960+
st21nfca_dep_deinit(hdev);
699961
nfc_hci_unregister_device(hdev);
700962
nfc_hci_free_device(hdev);
701963
kfree(info);

0 commit comments

Comments
 (0)