Loading include/net/nfc/digital.h +3 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ enum { NFC_DIGITAL_FRAMING_NFCA_T1T, NFC_DIGITAL_FRAMING_NFCA_T2T, NFC_DIGITAL_FRAMING_NFCA_T4T, NFC_DIGITAL_FRAMING_NFCA_NFC_DEP, NFC_DIGITAL_FRAMING_NFCF, Loading Loading @@ -208,6 +209,8 @@ struct nfc_digital_dev { u8 curr_rf_tech; u8 curr_nfc_dep_pni; u16 target_fsc; int (*skb_check_crc)(struct sk_buff *skb); void (*skb_add_crc)(struct sk_buff *skb); }; Loading net/nfc/digital_core.c +7 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,11 @@ int digital_target_found(struct nfc_digital_dev *ddev, framing = NFC_DIGITAL_FRAMING_ISO15693_TVT; check_crc = digital_skb_check_crc_b; add_crc = digital_skb_add_crc_b; case NFC_PROTO_ISO14443: framing = NFC_DIGITAL_FRAMING_NFCA_T4T; check_crc = digital_skb_check_crc_a; add_crc = digital_skb_add_crc_a; break; default: Loading Loading @@ -714,6 +719,8 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; if (supported_protocols & NFC_PROTO_ISO15693_MASK) ddev->protocols |= NFC_PROTO_ISO15693_MASK; if (supported_protocols & NFC_PROTO_ISO14443_MASK) ddev->protocols |= NFC_PROTO_ISO14443_MASK; ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; Loading net/nfc/digital_technology.c +79 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) #define DIGITAL_SEL_RES_IS_T4T(sel_res) ((sel_res) & 0x20) #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x0C00) == 0x0C00) Loading Loading @@ -60,6 +61,16 @@ #define DIGITAL_ISO15693_RES_IS_VALID(flags) \ (!((flags) & DIGITAL_ISO15693_RES_FLAG_ERROR)) static const u8 digital_ats_fsc[] = { 16, 24, 32, 40, 48, 64, 96, 128, }; #define DIGITAL_ATS_FSCI(t0) ((t0) & 0x0F) #define DIGITAL_ATS_MAX_FSC 256 #define DIGITAL_RATS_BYTE1 0xE0 #define DIGITAL_RATS_PARAM 0x80 struct digital_sdd_res { u8 nfcid1[4]; u8 bcc; Loading Loading @@ -107,6 +118,63 @@ struct digital_iso15693_inv_res { static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, struct nfc_target *target); static void digital_in_recv_ats(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp) { struct nfc_target *target = arg; u8 fsdi; int rc; if (IS_ERR(resp)) { rc = PTR_ERR(resp); resp = NULL; goto exit; } if (resp->len < 2) { rc = -EIO; goto exit; } fsdi = DIGITAL_ATS_FSCI(resp->data[1]); if (fsdi >= 8) ddev->target_fsc = DIGITAL_ATS_MAX_FSC; else ddev->target_fsc = digital_ats_fsc[fsdi]; ddev->curr_nfc_dep_pni = 0; rc = digital_target_found(ddev, target, NFC_PROTO_ISO14443); exit: dev_kfree_skb(resp); kfree(target); if (rc) digital_poll_next_tech(ddev); } static int digital_in_send_rats(struct nfc_digital_dev *ddev, struct nfc_target *target) { int rc; struct sk_buff *skb; skb = digital_skb_alloc(ddev, 2); if (!skb) return -ENOMEM; *skb_put(skb, 1) = DIGITAL_RATS_BYTE1; *skb_put(skb, 1) = DIGITAL_RATS_PARAM; rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_ats, target); if (rc) kfree_skb(skb); return rc; } static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp) { Loading Loading @@ -144,8 +212,19 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, goto exit_free_skb; } target->sel_res = sel_res; if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { nfc_proto = NFC_PROTO_MIFARE; } else if (DIGITAL_SEL_RES_IS_T4T(sel_res)) { rc = digital_in_send_rats(ddev, target); if (rc) goto exit; /* * Skip target_found and don't free it for now. This will be * done when receiving the ATS */ goto exit_free_skb; } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { nfc_proto = NFC_PROTO_NFC_DEP; } else { Loading @@ -153,8 +232,6 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, goto exit; } target->sel_res = sel_res; rc = digital_target_found(ddev, target, nfc_proto); exit: Loading Loading
include/net/nfc/digital.h +3 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ enum { NFC_DIGITAL_FRAMING_NFCA_T1T, NFC_DIGITAL_FRAMING_NFCA_T2T, NFC_DIGITAL_FRAMING_NFCA_T4T, NFC_DIGITAL_FRAMING_NFCA_NFC_DEP, NFC_DIGITAL_FRAMING_NFCF, Loading Loading @@ -208,6 +209,8 @@ struct nfc_digital_dev { u8 curr_rf_tech; u8 curr_nfc_dep_pni; u16 target_fsc; int (*skb_check_crc)(struct sk_buff *skb); void (*skb_add_crc)(struct sk_buff *skb); }; Loading
net/nfc/digital_core.c +7 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,11 @@ int digital_target_found(struct nfc_digital_dev *ddev, framing = NFC_DIGITAL_FRAMING_ISO15693_TVT; check_crc = digital_skb_check_crc_b; add_crc = digital_skb_add_crc_b; case NFC_PROTO_ISO14443: framing = NFC_DIGITAL_FRAMING_NFCA_T4T; check_crc = digital_skb_check_crc_a; add_crc = digital_skb_add_crc_a; break; default: Loading Loading @@ -714,6 +719,8 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; if (supported_protocols & NFC_PROTO_ISO15693_MASK) ddev->protocols |= NFC_PROTO_ISO15693_MASK; if (supported_protocols & NFC_PROTO_ISO14443_MASK) ddev->protocols |= NFC_PROTO_ISO14443_MASK; ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; Loading
net/nfc/digital_technology.c +79 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) #define DIGITAL_SEL_RES_IS_T4T(sel_res) ((sel_res) & 0x20) #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x0C00) == 0x0C00) Loading Loading @@ -60,6 +61,16 @@ #define DIGITAL_ISO15693_RES_IS_VALID(flags) \ (!((flags) & DIGITAL_ISO15693_RES_FLAG_ERROR)) static const u8 digital_ats_fsc[] = { 16, 24, 32, 40, 48, 64, 96, 128, }; #define DIGITAL_ATS_FSCI(t0) ((t0) & 0x0F) #define DIGITAL_ATS_MAX_FSC 256 #define DIGITAL_RATS_BYTE1 0xE0 #define DIGITAL_RATS_PARAM 0x80 struct digital_sdd_res { u8 nfcid1[4]; u8 bcc; Loading Loading @@ -107,6 +118,63 @@ struct digital_iso15693_inv_res { static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, struct nfc_target *target); static void digital_in_recv_ats(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp) { struct nfc_target *target = arg; u8 fsdi; int rc; if (IS_ERR(resp)) { rc = PTR_ERR(resp); resp = NULL; goto exit; } if (resp->len < 2) { rc = -EIO; goto exit; } fsdi = DIGITAL_ATS_FSCI(resp->data[1]); if (fsdi >= 8) ddev->target_fsc = DIGITAL_ATS_MAX_FSC; else ddev->target_fsc = digital_ats_fsc[fsdi]; ddev->curr_nfc_dep_pni = 0; rc = digital_target_found(ddev, target, NFC_PROTO_ISO14443); exit: dev_kfree_skb(resp); kfree(target); if (rc) digital_poll_next_tech(ddev); } static int digital_in_send_rats(struct nfc_digital_dev *ddev, struct nfc_target *target) { int rc; struct sk_buff *skb; skb = digital_skb_alloc(ddev, 2); if (!skb) return -ENOMEM; *skb_put(skb, 1) = DIGITAL_RATS_BYTE1; *skb_put(skb, 1) = DIGITAL_RATS_PARAM; rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_ats, target); if (rc) kfree_skb(skb); return rc; } static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, struct sk_buff *resp) { Loading Loading @@ -144,8 +212,19 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, goto exit_free_skb; } target->sel_res = sel_res; if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { nfc_proto = NFC_PROTO_MIFARE; } else if (DIGITAL_SEL_RES_IS_T4T(sel_res)) { rc = digital_in_send_rats(ddev, target); if (rc) goto exit; /* * Skip target_found and don't free it for now. This will be * done when receiving the ATS */ goto exit_free_skb; } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { nfc_proto = NFC_PROTO_NFC_DEP; } else { Loading @@ -153,8 +232,6 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, goto exit; } target->sel_res = sel_res; rc = digital_target_found(ddev, target, nfc_proto); exit: Loading