Commit c5da0e4a35eb1eba0c1593bef4bf2b58d9d50d6b
1 parent
645d5087bd
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
NFC: digital: Remove PR_ERR and PR_DBG macros
They can be replaced by the standard pr_err and pr_debug one after defining the right pr_fmt macro. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Showing 4 changed files with 31 additions and 27 deletions Inline Diff
net/nfc/digital.h
1 | /* | 1 | /* |
2 | * NFC Digital Protocol stack | 2 | * NFC Digital Protocol stack |
3 | * Copyright (c) 2013, Intel Corporation. | 3 | * Copyright (c) 2013, Intel Corporation. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | 9 | * This program is distributed in the hope it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #ifndef __DIGITAL_H | 16 | #ifndef __DIGITAL_H |
17 | #define __DIGITAL_H | 17 | #define __DIGITAL_H |
18 | 18 | ||
19 | #include <net/nfc/nfc.h> | 19 | #include <net/nfc/nfc.h> |
20 | #include <net/nfc/digital.h> | 20 | #include <net/nfc/digital.h> |
21 | 21 | ||
22 | #include <linux/crc-ccitt.h> | 22 | #include <linux/crc-ccitt.h> |
23 | #include <linux/crc-itu-t.h> | 23 | #include <linux/crc-itu-t.h> |
24 | 24 | ||
25 | #define PR_DBG(fmt, ...) pr_debug("%s: " fmt "\n", __func__, ##__VA_ARGS__) | 25 | #define PROTOCOL_ERR(req) pr_err("%d: NFC Digital Protocol error: %s\n", \ |
26 | #define PR_ERR(fmt, ...) pr_err("%s: " fmt "\n", __func__, ##__VA_ARGS__) | 26 | __LINE__, req) |
27 | #define PROTOCOL_ERR(req) pr_err("%s:%d: NFC Digital Protocol error: %s\n", \ | ||
28 | __func__, __LINE__, req) | ||
29 | 27 | ||
30 | #define DIGITAL_CMD_IN_SEND 0 | 28 | #define DIGITAL_CMD_IN_SEND 0 |
31 | #define DIGITAL_CMD_TG_SEND 1 | 29 | #define DIGITAL_CMD_TG_SEND 1 |
32 | #define DIGITAL_CMD_TG_LISTEN 2 | 30 | #define DIGITAL_CMD_TG_LISTEN 2 |
33 | #define DIGITAL_CMD_TG_LISTEN_MDAA 3 | 31 | #define DIGITAL_CMD_TG_LISTEN_MDAA 3 |
34 | 32 | ||
35 | #define DIGITAL_MAX_HEADER_LEN 7 | 33 | #define DIGITAL_MAX_HEADER_LEN 7 |
36 | #define DIGITAL_CRC_LEN 2 | 34 | #define DIGITAL_CRC_LEN 2 |
37 | 35 | ||
38 | #define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01 | 36 | #define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01 |
39 | #define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE | 37 | #define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE |
40 | 38 | ||
41 | #define DIGITAL_SENS_RES_NFC_DEP 0x0100 | 39 | #define DIGITAL_SENS_RES_NFC_DEP 0x0100 |
42 | #define DIGITAL_SEL_RES_NFC_DEP 0x40 | 40 | #define DIGITAL_SEL_RES_NFC_DEP 0x40 |
43 | #define DIGITAL_SENSF_FELICA_SC 0xFFFF | 41 | #define DIGITAL_SENSF_FELICA_SC 0xFFFF |
44 | 42 | ||
45 | #define DIGITAL_DRV_CAPS_IN_CRC(ddev) \ | 43 | #define DIGITAL_DRV_CAPS_IN_CRC(ddev) \ |
46 | ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC) | 44 | ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC) |
47 | #define DIGITAL_DRV_CAPS_TG_CRC(ddev) \ | 45 | #define DIGITAL_DRV_CAPS_TG_CRC(ddev) \ |
48 | ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_TG_CRC) | 46 | ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_TG_CRC) |
49 | 47 | ||
50 | struct digital_data_exch { | 48 | struct digital_data_exch { |
51 | data_exchange_cb_t cb; | 49 | data_exchange_cb_t cb; |
52 | void *cb_context; | 50 | void *cb_context; |
53 | }; | 51 | }; |
54 | 52 | ||
55 | struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev, | 53 | struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev, |
56 | unsigned int len); | 54 | unsigned int len); |
57 | 55 | ||
58 | int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, | 56 | int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, |
59 | struct sk_buff *skb, struct digital_tg_mdaa_params *params, | 57 | struct sk_buff *skb, struct digital_tg_mdaa_params *params, |
60 | u16 timeout, nfc_digital_cmd_complete_t cmd_cb, | 58 | u16 timeout, nfc_digital_cmd_complete_t cmd_cb, |
61 | void *cb_context); | 59 | void *cb_context); |
62 | 60 | ||
63 | int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param); | 61 | int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param); |
64 | static inline int digital_in_send_cmd(struct nfc_digital_dev *ddev, | 62 | static inline int digital_in_send_cmd(struct nfc_digital_dev *ddev, |
65 | struct sk_buff *skb, u16 timeout, | 63 | struct sk_buff *skb, u16 timeout, |
66 | nfc_digital_cmd_complete_t cmd_cb, | 64 | nfc_digital_cmd_complete_t cmd_cb, |
67 | void *cb_context) | 65 | void *cb_context) |
68 | { | 66 | { |
69 | return digital_send_cmd(ddev, DIGITAL_CMD_IN_SEND, skb, NULL, timeout, | 67 | return digital_send_cmd(ddev, DIGITAL_CMD_IN_SEND, skb, NULL, timeout, |
70 | cmd_cb, cb_context); | 68 | cmd_cb, cb_context); |
71 | } | 69 | } |
72 | 70 | ||
73 | void digital_poll_next_tech(struct nfc_digital_dev *ddev); | 71 | void digital_poll_next_tech(struct nfc_digital_dev *ddev); |
74 | 72 | ||
75 | int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech); | 73 | int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech); |
76 | int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech); | 74 | int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech); |
77 | 75 | ||
78 | int digital_target_found(struct nfc_digital_dev *ddev, | 76 | int digital_target_found(struct nfc_digital_dev *ddev, |
79 | struct nfc_target *target, u8 protocol); | 77 | struct nfc_target *target, u8 protocol); |
80 | 78 | ||
81 | int digital_in_recv_mifare_res(struct sk_buff *resp); | 79 | int digital_in_recv_mifare_res(struct sk_buff *resp); |
82 | 80 | ||
83 | int digital_in_send_atr_req(struct nfc_digital_dev *ddev, | 81 | int digital_in_send_atr_req(struct nfc_digital_dev *ddev, |
84 | struct nfc_target *target, __u8 comm_mode, __u8 *gb, | 82 | struct nfc_target *target, __u8 comm_mode, __u8 *gb, |
85 | size_t gb_len); | 83 | size_t gb_len); |
86 | int digital_in_send_dep_req(struct nfc_digital_dev *ddev, | 84 | int digital_in_send_dep_req(struct nfc_digital_dev *ddev, |
87 | struct nfc_target *target, struct sk_buff *skb, | 85 | struct nfc_target *target, struct sk_buff *skb, |
88 | struct digital_data_exch *data_exch); | 86 | struct digital_data_exch *data_exch); |
89 | 87 | ||
90 | int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param); | 88 | int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param); |
91 | static inline int digital_tg_send_cmd(struct nfc_digital_dev *ddev, | 89 | static inline int digital_tg_send_cmd(struct nfc_digital_dev *ddev, |
92 | struct sk_buff *skb, u16 timeout, | 90 | struct sk_buff *skb, u16 timeout, |
93 | nfc_digital_cmd_complete_t cmd_cb, void *cb_context) | 91 | nfc_digital_cmd_complete_t cmd_cb, void *cb_context) |
94 | { | 92 | { |
95 | return digital_send_cmd(ddev, DIGITAL_CMD_TG_SEND, skb, NULL, timeout, | 93 | return digital_send_cmd(ddev, DIGITAL_CMD_TG_SEND, skb, NULL, timeout, |
96 | cmd_cb, cb_context); | 94 | cmd_cb, cb_context); |
97 | } | 95 | } |
98 | 96 | ||
99 | void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg, | 97 | void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg, |
100 | struct sk_buff *resp); | 98 | struct sk_buff *resp); |
101 | 99 | ||
102 | void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg, | 100 | void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg, |
103 | struct sk_buff *resp); | 101 | struct sk_buff *resp); |
104 | 102 | ||
105 | static inline int digital_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, | 103 | static inline int digital_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, |
106 | nfc_digital_cmd_complete_t cb, void *arg) | 104 | nfc_digital_cmd_complete_t cb, void *arg) |
107 | { | 105 | { |
108 | return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN, NULL, NULL, | 106 | return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN, NULL, NULL, |
109 | timeout, cb, arg); | 107 | timeout, cb, arg); |
110 | } | 108 | } |
111 | 109 | ||
112 | void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg, | 110 | void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg, |
113 | struct sk_buff *resp); | 111 | struct sk_buff *resp); |
114 | 112 | ||
115 | int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb); | 113 | int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb); |
116 | 114 | ||
117 | int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech); | 115 | int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech); |
118 | int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech); | 116 | int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech); |
119 | 117 | ||
120 | typedef u16 (*crc_func_t)(u16, const u8 *, size_t); | 118 | typedef u16 (*crc_func_t)(u16, const u8 *, size_t); |
121 | 119 | ||
122 | #define CRC_A_INIT 0x6363 | 120 | #define CRC_A_INIT 0x6363 |
123 | #define CRC_B_INIT 0xFFFF | 121 | #define CRC_B_INIT 0xFFFF |
124 | #define CRC_F_INIT 0x0000 | 122 | #define CRC_F_INIT 0x0000 |
125 | 123 | ||
126 | void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init, | 124 | void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init, |
127 | u8 bitwise_inv, u8 msb_first); | 125 | u8 bitwise_inv, u8 msb_first); |
128 | 126 | ||
129 | static inline void digital_skb_add_crc_a(struct sk_buff *skb) | 127 | static inline void digital_skb_add_crc_a(struct sk_buff *skb) |
130 | { | 128 | { |
131 | digital_skb_add_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0); | 129 | digital_skb_add_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0); |
132 | } | 130 | } |
133 | 131 | ||
134 | static inline void digital_skb_add_crc_b(struct sk_buff *skb) | 132 | static inline void digital_skb_add_crc_b(struct sk_buff *skb) |
135 | { | 133 | { |
136 | digital_skb_add_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0); | 134 | digital_skb_add_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0); |
137 | } | 135 | } |
138 | 136 | ||
139 | static inline void digital_skb_add_crc_f(struct sk_buff *skb) | 137 | static inline void digital_skb_add_crc_f(struct sk_buff *skb) |
140 | { | 138 | { |
141 | digital_skb_add_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1); | 139 | digital_skb_add_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1); |
142 | } | 140 | } |
143 | 141 | ||
144 | static inline void digital_skb_add_crc_none(struct sk_buff *skb) | 142 | static inline void digital_skb_add_crc_none(struct sk_buff *skb) |
145 | { | 143 | { |
146 | return; | 144 | return; |
147 | } | 145 | } |
148 | 146 | ||
149 | int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func, | 147 | int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func, |
150 | u16 crc_init, u8 bitwise_inv, u8 msb_first); | 148 | u16 crc_init, u8 bitwise_inv, u8 msb_first); |
151 | 149 | ||
152 | static inline int digital_skb_check_crc_a(struct sk_buff *skb) | 150 | static inline int digital_skb_check_crc_a(struct sk_buff *skb) |
153 | { | 151 | { |
154 | return digital_skb_check_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0); | 152 | return digital_skb_check_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0); |
155 | } | 153 | } |
156 | 154 | ||
157 | static inline int digital_skb_check_crc_b(struct sk_buff *skb) | 155 | static inline int digital_skb_check_crc_b(struct sk_buff *skb) |
158 | { | 156 | { |
159 | return digital_skb_check_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0); | 157 | return digital_skb_check_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0); |
160 | } | 158 | } |
161 | 159 | ||
162 | static inline int digital_skb_check_crc_f(struct sk_buff *skb) | 160 | static inline int digital_skb_check_crc_f(struct sk_buff *skb) |
163 | { | 161 | { |
164 | return digital_skb_check_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1); | 162 | return digital_skb_check_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1); |
165 | } | 163 | } |
166 | 164 | ||
167 | static inline int digital_skb_check_crc_none(struct sk_buff *skb) | 165 | static inline int digital_skb_check_crc_none(struct sk_buff *skb) |
168 | { | 166 | { |
169 | return 0; | 167 | return 0; |
170 | } | 168 | } |
171 | 169 | ||
172 | #endif /* __DIGITAL_H */ | 170 | #endif /* __DIGITAL_H */ |
173 | 171 |
net/nfc/digital_core.c
1 | /* | 1 | /* |
2 | * NFC Digital Protocol stack | 2 | * NFC Digital Protocol stack |
3 | * Copyright (c) 2013, Intel Corporation. | 3 | * Copyright (c) 2013, Intel Corporation. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | 9 | * This program is distributed in the hope it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) "digital: %s: " fmt, __func__ | ||
17 | |||
16 | #include <linux/module.h> | 18 | #include <linux/module.h> |
17 | 19 | ||
18 | #include "digital.h" | 20 | #include "digital.h" |
19 | 21 | ||
20 | #define DIGITAL_PROTO_NFCA_RF_TECH \ | 22 | #define DIGITAL_PROTO_NFCA_RF_TECH \ |
21 | (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK) | 23 | (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK) |
22 | 24 | ||
23 | #define DIGITAL_PROTO_NFCF_RF_TECH \ | 25 | #define DIGITAL_PROTO_NFCF_RF_TECH \ |
24 | (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) | 26 | (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) |
25 | 27 | ||
26 | struct digital_cmd { | 28 | struct digital_cmd { |
27 | struct list_head queue; | 29 | struct list_head queue; |
28 | 30 | ||
29 | u8 type; | 31 | u8 type; |
30 | u8 pending; | 32 | u8 pending; |
31 | 33 | ||
32 | u16 timeout; | 34 | u16 timeout; |
33 | struct sk_buff *req; | 35 | struct sk_buff *req; |
34 | struct sk_buff *resp; | 36 | struct sk_buff *resp; |
35 | struct digital_tg_mdaa_params *mdaa_params; | 37 | struct digital_tg_mdaa_params *mdaa_params; |
36 | 38 | ||
37 | nfc_digital_cmd_complete_t cmd_cb; | 39 | nfc_digital_cmd_complete_t cmd_cb; |
38 | void *cb_context; | 40 | void *cb_context; |
39 | }; | 41 | }; |
40 | 42 | ||
41 | struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev, | 43 | struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev, |
42 | unsigned int len) | 44 | unsigned int len) |
43 | { | 45 | { |
44 | struct sk_buff *skb; | 46 | struct sk_buff *skb; |
45 | 47 | ||
46 | skb = alloc_skb(len + ddev->tx_headroom + ddev->tx_tailroom, | 48 | skb = alloc_skb(len + ddev->tx_headroom + ddev->tx_tailroom, |
47 | GFP_KERNEL); | 49 | GFP_KERNEL); |
48 | if (skb) | 50 | if (skb) |
49 | skb_reserve(skb, ddev->tx_headroom); | 51 | skb_reserve(skb, ddev->tx_headroom); |
50 | 52 | ||
51 | return skb; | 53 | return skb; |
52 | } | 54 | } |
53 | 55 | ||
54 | void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init, | 56 | void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init, |
55 | u8 bitwise_inv, u8 msb_first) | 57 | u8 bitwise_inv, u8 msb_first) |
56 | { | 58 | { |
57 | u16 crc; | 59 | u16 crc; |
58 | 60 | ||
59 | crc = crc_func(init, skb->data, skb->len); | 61 | crc = crc_func(init, skb->data, skb->len); |
60 | 62 | ||
61 | if (bitwise_inv) | 63 | if (bitwise_inv) |
62 | crc = ~crc; | 64 | crc = ~crc; |
63 | 65 | ||
64 | if (msb_first) | 66 | if (msb_first) |
65 | crc = __fswab16(crc); | 67 | crc = __fswab16(crc); |
66 | 68 | ||
67 | *skb_put(skb, 1) = crc & 0xFF; | 69 | *skb_put(skb, 1) = crc & 0xFF; |
68 | *skb_put(skb, 1) = (crc >> 8) & 0xFF; | 70 | *skb_put(skb, 1) = (crc >> 8) & 0xFF; |
69 | } | 71 | } |
70 | 72 | ||
71 | int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func, | 73 | int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func, |
72 | u16 crc_init, u8 bitwise_inv, u8 msb_first) | 74 | u16 crc_init, u8 bitwise_inv, u8 msb_first) |
73 | { | 75 | { |
74 | int rc; | 76 | int rc; |
75 | u16 crc; | 77 | u16 crc; |
76 | 78 | ||
77 | if (skb->len <= 2) | 79 | if (skb->len <= 2) |
78 | return -EIO; | 80 | return -EIO; |
79 | 81 | ||
80 | crc = crc_func(crc_init, skb->data, skb->len - 2); | 82 | crc = crc_func(crc_init, skb->data, skb->len - 2); |
81 | 83 | ||
82 | if (bitwise_inv) | 84 | if (bitwise_inv) |
83 | crc = ~crc; | 85 | crc = ~crc; |
84 | 86 | ||
85 | if (msb_first) | 87 | if (msb_first) |
86 | crc = __swab16(crc); | 88 | crc = __swab16(crc); |
87 | 89 | ||
88 | rc = (skb->data[skb->len - 2] - (crc & 0xFF)) + | 90 | rc = (skb->data[skb->len - 2] - (crc & 0xFF)) + |
89 | (skb->data[skb->len - 1] - ((crc >> 8) & 0xFF)); | 91 | (skb->data[skb->len - 1] - ((crc >> 8) & 0xFF)); |
90 | 92 | ||
91 | if (rc) | 93 | if (rc) |
92 | return -EIO; | 94 | return -EIO; |
93 | 95 | ||
94 | skb_trim(skb, skb->len - 2); | 96 | skb_trim(skb, skb->len - 2); |
95 | 97 | ||
96 | return 0; | 98 | return 0; |
97 | } | 99 | } |
98 | 100 | ||
99 | static inline void digital_switch_rf(struct nfc_digital_dev *ddev, bool on) | 101 | static inline void digital_switch_rf(struct nfc_digital_dev *ddev, bool on) |
100 | { | 102 | { |
101 | ddev->ops->switch_rf(ddev, on); | 103 | ddev->ops->switch_rf(ddev, on); |
102 | } | 104 | } |
103 | 105 | ||
104 | static inline void digital_abort_cmd(struct nfc_digital_dev *ddev) | 106 | static inline void digital_abort_cmd(struct nfc_digital_dev *ddev) |
105 | { | 107 | { |
106 | ddev->ops->abort_cmd(ddev); | 108 | ddev->ops->abort_cmd(ddev); |
107 | } | 109 | } |
108 | 110 | ||
109 | static void digital_wq_cmd_complete(struct work_struct *work) | 111 | static void digital_wq_cmd_complete(struct work_struct *work) |
110 | { | 112 | { |
111 | struct digital_cmd *cmd; | 113 | struct digital_cmd *cmd; |
112 | struct nfc_digital_dev *ddev = container_of(work, | 114 | struct nfc_digital_dev *ddev = container_of(work, |
113 | struct nfc_digital_dev, | 115 | struct nfc_digital_dev, |
114 | cmd_complete_work); | 116 | cmd_complete_work); |
115 | 117 | ||
116 | mutex_lock(&ddev->cmd_lock); | 118 | mutex_lock(&ddev->cmd_lock); |
117 | 119 | ||
118 | cmd = list_first_entry_or_null(&ddev->cmd_queue, struct digital_cmd, | 120 | cmd = list_first_entry_or_null(&ddev->cmd_queue, struct digital_cmd, |
119 | queue); | 121 | queue); |
120 | if (!cmd) { | 122 | if (!cmd) { |
121 | mutex_unlock(&ddev->cmd_lock); | 123 | mutex_unlock(&ddev->cmd_lock); |
122 | return; | 124 | return; |
123 | } | 125 | } |
124 | 126 | ||
125 | list_del(&cmd->queue); | 127 | list_del(&cmd->queue); |
126 | 128 | ||
127 | mutex_unlock(&ddev->cmd_lock); | 129 | mutex_unlock(&ddev->cmd_lock); |
128 | 130 | ||
129 | if (!IS_ERR(cmd->resp)) | 131 | if (!IS_ERR(cmd->resp)) |
130 | print_hex_dump_debug("DIGITAL RX: ", DUMP_PREFIX_NONE, 16, 1, | 132 | print_hex_dump_debug("DIGITAL RX: ", DUMP_PREFIX_NONE, 16, 1, |
131 | cmd->resp->data, cmd->resp->len, false); | 133 | cmd->resp->data, cmd->resp->len, false); |
132 | 134 | ||
133 | cmd->cmd_cb(ddev, cmd->cb_context, cmd->resp); | 135 | cmd->cmd_cb(ddev, cmd->cb_context, cmd->resp); |
134 | 136 | ||
135 | kfree(cmd->mdaa_params); | 137 | kfree(cmd->mdaa_params); |
136 | kfree(cmd); | 138 | kfree(cmd); |
137 | 139 | ||
138 | schedule_work(&ddev->cmd_work); | 140 | schedule_work(&ddev->cmd_work); |
139 | } | 141 | } |
140 | 142 | ||
141 | static void digital_send_cmd_complete(struct nfc_digital_dev *ddev, | 143 | static void digital_send_cmd_complete(struct nfc_digital_dev *ddev, |
142 | void *arg, struct sk_buff *resp) | 144 | void *arg, struct sk_buff *resp) |
143 | { | 145 | { |
144 | struct digital_cmd *cmd = arg; | 146 | struct digital_cmd *cmd = arg; |
145 | 147 | ||
146 | cmd->resp = resp; | 148 | cmd->resp = resp; |
147 | 149 | ||
148 | schedule_work(&ddev->cmd_complete_work); | 150 | schedule_work(&ddev->cmd_complete_work); |
149 | } | 151 | } |
150 | 152 | ||
151 | static void digital_wq_cmd(struct work_struct *work) | 153 | static void digital_wq_cmd(struct work_struct *work) |
152 | { | 154 | { |
153 | int rc; | 155 | int rc; |
154 | struct digital_cmd *cmd; | 156 | struct digital_cmd *cmd; |
155 | struct digital_tg_mdaa_params *params; | 157 | struct digital_tg_mdaa_params *params; |
156 | struct nfc_digital_dev *ddev = container_of(work, | 158 | struct nfc_digital_dev *ddev = container_of(work, |
157 | struct nfc_digital_dev, | 159 | struct nfc_digital_dev, |
158 | cmd_work); | 160 | cmd_work); |
159 | 161 | ||
160 | mutex_lock(&ddev->cmd_lock); | 162 | mutex_lock(&ddev->cmd_lock); |
161 | 163 | ||
162 | cmd = list_first_entry_or_null(&ddev->cmd_queue, struct digital_cmd, | 164 | cmd = list_first_entry_or_null(&ddev->cmd_queue, struct digital_cmd, |
163 | queue); | 165 | queue); |
164 | if (!cmd || cmd->pending) { | 166 | if (!cmd || cmd->pending) { |
165 | mutex_unlock(&ddev->cmd_lock); | 167 | mutex_unlock(&ddev->cmd_lock); |
166 | return; | 168 | return; |
167 | } | 169 | } |
168 | 170 | ||
169 | mutex_unlock(&ddev->cmd_lock); | 171 | mutex_unlock(&ddev->cmd_lock); |
170 | 172 | ||
171 | if (cmd->req) | 173 | if (cmd->req) |
172 | print_hex_dump_debug("DIGITAL TX: ", DUMP_PREFIX_NONE, 16, 1, | 174 | print_hex_dump_debug("DIGITAL TX: ", DUMP_PREFIX_NONE, 16, 1, |
173 | cmd->req->data, cmd->req->len, false); | 175 | cmd->req->data, cmd->req->len, false); |
174 | 176 | ||
175 | switch (cmd->type) { | 177 | switch (cmd->type) { |
176 | case DIGITAL_CMD_IN_SEND: | 178 | case DIGITAL_CMD_IN_SEND: |
177 | rc = ddev->ops->in_send_cmd(ddev, cmd->req, cmd->timeout, | 179 | rc = ddev->ops->in_send_cmd(ddev, cmd->req, cmd->timeout, |
178 | digital_send_cmd_complete, cmd); | 180 | digital_send_cmd_complete, cmd); |
179 | break; | 181 | break; |
180 | 182 | ||
181 | case DIGITAL_CMD_TG_SEND: | 183 | case DIGITAL_CMD_TG_SEND: |
182 | rc = ddev->ops->tg_send_cmd(ddev, cmd->req, cmd->timeout, | 184 | rc = ddev->ops->tg_send_cmd(ddev, cmd->req, cmd->timeout, |
183 | digital_send_cmd_complete, cmd); | 185 | digital_send_cmd_complete, cmd); |
184 | break; | 186 | break; |
185 | 187 | ||
186 | case DIGITAL_CMD_TG_LISTEN: | 188 | case DIGITAL_CMD_TG_LISTEN: |
187 | rc = ddev->ops->tg_listen(ddev, cmd->timeout, | 189 | rc = ddev->ops->tg_listen(ddev, cmd->timeout, |
188 | digital_send_cmd_complete, cmd); | 190 | digital_send_cmd_complete, cmd); |
189 | break; | 191 | break; |
190 | 192 | ||
191 | case DIGITAL_CMD_TG_LISTEN_MDAA: | 193 | case DIGITAL_CMD_TG_LISTEN_MDAA: |
192 | params = cmd->mdaa_params; | 194 | params = cmd->mdaa_params; |
193 | 195 | ||
194 | rc = ddev->ops->tg_listen_mdaa(ddev, params, cmd->timeout, | 196 | rc = ddev->ops->tg_listen_mdaa(ddev, params, cmd->timeout, |
195 | digital_send_cmd_complete, cmd); | 197 | digital_send_cmd_complete, cmd); |
196 | break; | 198 | break; |
197 | 199 | ||
198 | default: | 200 | default: |
199 | PR_ERR("Unknown cmd type %d", cmd->type); | 201 | pr_err("Unknown cmd type %d", cmd->type); |
200 | return; | 202 | return; |
201 | } | 203 | } |
202 | 204 | ||
203 | if (!rc) | 205 | if (!rc) |
204 | return; | 206 | return; |
205 | 207 | ||
206 | PR_ERR("in_send_command returned err %d", rc); | 208 | pr_err("in_send_command returned err %d", rc); |
207 | 209 | ||
208 | mutex_lock(&ddev->cmd_lock); | 210 | mutex_lock(&ddev->cmd_lock); |
209 | list_del(&cmd->queue); | 211 | list_del(&cmd->queue); |
210 | mutex_unlock(&ddev->cmd_lock); | 212 | mutex_unlock(&ddev->cmd_lock); |
211 | 213 | ||
212 | kfree_skb(cmd->req); | 214 | kfree_skb(cmd->req); |
213 | kfree(cmd->mdaa_params); | 215 | kfree(cmd->mdaa_params); |
214 | kfree(cmd); | 216 | kfree(cmd); |
215 | 217 | ||
216 | schedule_work(&ddev->cmd_work); | 218 | schedule_work(&ddev->cmd_work); |
217 | } | 219 | } |
218 | 220 | ||
219 | int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, | 221 | int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, |
220 | struct sk_buff *skb, struct digital_tg_mdaa_params *params, | 222 | struct sk_buff *skb, struct digital_tg_mdaa_params *params, |
221 | u16 timeout, nfc_digital_cmd_complete_t cmd_cb, | 223 | u16 timeout, nfc_digital_cmd_complete_t cmd_cb, |
222 | void *cb_context) | 224 | void *cb_context) |
223 | { | 225 | { |
224 | struct digital_cmd *cmd; | 226 | struct digital_cmd *cmd; |
225 | 227 | ||
226 | cmd = kzalloc(sizeof(struct digital_cmd), GFP_KERNEL); | 228 | cmd = kzalloc(sizeof(struct digital_cmd), GFP_KERNEL); |
227 | if (!cmd) | 229 | if (!cmd) |
228 | return -ENOMEM; | 230 | return -ENOMEM; |
229 | 231 | ||
230 | cmd->type = cmd_type; | 232 | cmd->type = cmd_type; |
231 | cmd->timeout = timeout; | 233 | cmd->timeout = timeout; |
232 | cmd->req = skb; | 234 | cmd->req = skb; |
233 | cmd->mdaa_params = params; | 235 | cmd->mdaa_params = params; |
234 | cmd->cmd_cb = cmd_cb; | 236 | cmd->cmd_cb = cmd_cb; |
235 | cmd->cb_context = cb_context; | 237 | cmd->cb_context = cb_context; |
236 | INIT_LIST_HEAD(&cmd->queue); | 238 | INIT_LIST_HEAD(&cmd->queue); |
237 | 239 | ||
238 | mutex_lock(&ddev->cmd_lock); | 240 | mutex_lock(&ddev->cmd_lock); |
239 | list_add_tail(&cmd->queue, &ddev->cmd_queue); | 241 | list_add_tail(&cmd->queue, &ddev->cmd_queue); |
240 | mutex_unlock(&ddev->cmd_lock); | 242 | mutex_unlock(&ddev->cmd_lock); |
241 | 243 | ||
242 | schedule_work(&ddev->cmd_work); | 244 | schedule_work(&ddev->cmd_work); |
243 | 245 | ||
244 | return 0; | 246 | return 0; |
245 | } | 247 | } |
246 | 248 | ||
247 | int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param) | 249 | int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param) |
248 | { | 250 | { |
249 | int rc; | 251 | int rc; |
250 | 252 | ||
251 | rc = ddev->ops->in_configure_hw(ddev, type, param); | 253 | rc = ddev->ops->in_configure_hw(ddev, type, param); |
252 | if (rc) | 254 | if (rc) |
253 | PR_ERR("in_configure_hw failed: %d", rc); | 255 | pr_err("in_configure_hw failed: %d", rc); |
254 | 256 | ||
255 | return rc; | 257 | return rc; |
256 | } | 258 | } |
257 | 259 | ||
258 | int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param) | 260 | int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param) |
259 | { | 261 | { |
260 | int rc; | 262 | int rc; |
261 | 263 | ||
262 | rc = ddev->ops->tg_configure_hw(ddev, type, param); | 264 | rc = ddev->ops->tg_configure_hw(ddev, type, param); |
263 | if (rc) | 265 | if (rc) |
264 | PR_ERR("tg_configure_hw failed: %d", rc); | 266 | pr_err("tg_configure_hw failed: %d", rc); |
265 | 267 | ||
266 | return rc; | 268 | return rc; |
267 | } | 269 | } |
268 | 270 | ||
269 | static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech) | 271 | static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech) |
270 | { | 272 | { |
271 | struct digital_tg_mdaa_params *params; | 273 | struct digital_tg_mdaa_params *params; |
272 | 274 | ||
273 | params = kzalloc(sizeof(struct digital_tg_mdaa_params), GFP_KERNEL); | 275 | params = kzalloc(sizeof(struct digital_tg_mdaa_params), GFP_KERNEL); |
274 | if (!params) | 276 | if (!params) |
275 | return -ENOMEM; | 277 | return -ENOMEM; |
276 | 278 | ||
277 | params->sens_res = DIGITAL_SENS_RES_NFC_DEP; | 279 | params->sens_res = DIGITAL_SENS_RES_NFC_DEP; |
278 | get_random_bytes(params->nfcid1, sizeof(params->nfcid1)); | 280 | get_random_bytes(params->nfcid1, sizeof(params->nfcid1)); |
279 | params->sel_res = DIGITAL_SEL_RES_NFC_DEP; | 281 | params->sel_res = DIGITAL_SEL_RES_NFC_DEP; |
280 | 282 | ||
281 | params->nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1; | 283 | params->nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1; |
282 | params->nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2; | 284 | params->nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2; |
283 | get_random_bytes(params->nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2); | 285 | get_random_bytes(params->nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2); |
284 | params->sc = DIGITAL_SENSF_FELICA_SC; | 286 | params->sc = DIGITAL_SENSF_FELICA_SC; |
285 | 287 | ||
286 | return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MDAA, NULL, params, | 288 | return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MDAA, NULL, params, |
287 | 500, digital_tg_recv_atr_req, NULL); | 289 | 500, digital_tg_recv_atr_req, NULL); |
288 | } | 290 | } |
289 | 291 | ||
290 | int digital_target_found(struct nfc_digital_dev *ddev, | 292 | int digital_target_found(struct nfc_digital_dev *ddev, |
291 | struct nfc_target *target, u8 protocol) | 293 | struct nfc_target *target, u8 protocol) |
292 | { | 294 | { |
293 | int rc; | 295 | int rc; |
294 | u8 framing; | 296 | u8 framing; |
295 | u8 rf_tech; | 297 | u8 rf_tech; |
296 | int (*check_crc)(struct sk_buff *skb); | 298 | int (*check_crc)(struct sk_buff *skb); |
297 | void (*add_crc)(struct sk_buff *skb); | 299 | void (*add_crc)(struct sk_buff *skb); |
298 | 300 | ||
299 | rf_tech = ddev->poll_techs[ddev->poll_tech_index].rf_tech; | 301 | rf_tech = ddev->poll_techs[ddev->poll_tech_index].rf_tech; |
300 | 302 | ||
301 | switch (protocol) { | 303 | switch (protocol) { |
302 | case NFC_PROTO_JEWEL: | 304 | case NFC_PROTO_JEWEL: |
303 | framing = NFC_DIGITAL_FRAMING_NFCA_T1T; | 305 | framing = NFC_DIGITAL_FRAMING_NFCA_T1T; |
304 | check_crc = digital_skb_check_crc_b; | 306 | check_crc = digital_skb_check_crc_b; |
305 | add_crc = digital_skb_add_crc_b; | 307 | add_crc = digital_skb_add_crc_b; |
306 | break; | 308 | break; |
307 | 309 | ||
308 | case NFC_PROTO_MIFARE: | 310 | case NFC_PROTO_MIFARE: |
309 | framing = NFC_DIGITAL_FRAMING_NFCA_T2T; | 311 | framing = NFC_DIGITAL_FRAMING_NFCA_T2T; |
310 | check_crc = digital_skb_check_crc_a; | 312 | check_crc = digital_skb_check_crc_a; |
311 | add_crc = digital_skb_add_crc_a; | 313 | add_crc = digital_skb_add_crc_a; |
312 | break; | 314 | break; |
313 | 315 | ||
314 | case NFC_PROTO_FELICA: | 316 | case NFC_PROTO_FELICA: |
315 | framing = NFC_DIGITAL_FRAMING_NFCF_T3T; | 317 | framing = NFC_DIGITAL_FRAMING_NFCF_T3T; |
316 | check_crc = digital_skb_check_crc_f; | 318 | check_crc = digital_skb_check_crc_f; |
317 | add_crc = digital_skb_add_crc_f; | 319 | add_crc = digital_skb_add_crc_f; |
318 | break; | 320 | break; |
319 | 321 | ||
320 | case NFC_PROTO_NFC_DEP: | 322 | case NFC_PROTO_NFC_DEP: |
321 | if (rf_tech == NFC_DIGITAL_RF_TECH_106A) { | 323 | if (rf_tech == NFC_DIGITAL_RF_TECH_106A) { |
322 | framing = NFC_DIGITAL_FRAMING_NFCA_NFC_DEP; | 324 | framing = NFC_DIGITAL_FRAMING_NFCA_NFC_DEP; |
323 | check_crc = digital_skb_check_crc_a; | 325 | check_crc = digital_skb_check_crc_a; |
324 | add_crc = digital_skb_add_crc_a; | 326 | add_crc = digital_skb_add_crc_a; |
325 | } else { | 327 | } else { |
326 | framing = NFC_DIGITAL_FRAMING_NFCF_NFC_DEP; | 328 | framing = NFC_DIGITAL_FRAMING_NFCF_NFC_DEP; |
327 | check_crc = digital_skb_check_crc_f; | 329 | check_crc = digital_skb_check_crc_f; |
328 | add_crc = digital_skb_add_crc_f; | 330 | add_crc = digital_skb_add_crc_f; |
329 | } | 331 | } |
330 | break; | 332 | break; |
331 | 333 | ||
332 | default: | 334 | default: |
333 | PR_ERR("Invalid protocol %d", protocol); | 335 | pr_err("Invalid protocol %d", protocol); |
334 | return -EINVAL; | 336 | return -EINVAL; |
335 | } | 337 | } |
336 | 338 | ||
337 | PR_DBG("rf_tech=%d, protocol=%d", rf_tech, protocol); | 339 | pr_debug("rf_tech=%d, protocol=%d", rf_tech, protocol); |
338 | 340 | ||
339 | ddev->curr_rf_tech = rf_tech; | 341 | ddev->curr_rf_tech = rf_tech; |
340 | ddev->curr_protocol = protocol; | 342 | ddev->curr_protocol = protocol; |
341 | 343 | ||
342 | if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) { | 344 | if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) { |
343 | ddev->skb_add_crc = digital_skb_add_crc_none; | 345 | ddev->skb_add_crc = digital_skb_add_crc_none; |
344 | ddev->skb_check_crc = digital_skb_check_crc_none; | 346 | ddev->skb_check_crc = digital_skb_check_crc_none; |
345 | } else { | 347 | } else { |
346 | ddev->skb_add_crc = add_crc; | 348 | ddev->skb_add_crc = add_crc; |
347 | ddev->skb_check_crc = check_crc; | 349 | ddev->skb_check_crc = check_crc; |
348 | } | 350 | } |
349 | 351 | ||
350 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, framing); | 352 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, framing); |
351 | if (rc) | 353 | if (rc) |
352 | return rc; | 354 | return rc; |
353 | 355 | ||
354 | target->supported_protocols = (1 << protocol); | 356 | target->supported_protocols = (1 << protocol); |
355 | rc = nfc_targets_found(ddev->nfc_dev, target, 1); | 357 | rc = nfc_targets_found(ddev->nfc_dev, target, 1); |
356 | if (rc) | 358 | if (rc) |
357 | return rc; | 359 | return rc; |
358 | 360 | ||
359 | ddev->poll_tech_count = 0; | 361 | ddev->poll_tech_count = 0; |
360 | 362 | ||
361 | return 0; | 363 | return 0; |
362 | } | 364 | } |
363 | 365 | ||
364 | void digital_poll_next_tech(struct nfc_digital_dev *ddev) | 366 | void digital_poll_next_tech(struct nfc_digital_dev *ddev) |
365 | { | 367 | { |
366 | digital_switch_rf(ddev, 0); | 368 | digital_switch_rf(ddev, 0); |
367 | 369 | ||
368 | mutex_lock(&ddev->poll_lock); | 370 | mutex_lock(&ddev->poll_lock); |
369 | 371 | ||
370 | if (!ddev->poll_tech_count) { | 372 | if (!ddev->poll_tech_count) { |
371 | mutex_unlock(&ddev->poll_lock); | 373 | mutex_unlock(&ddev->poll_lock); |
372 | return; | 374 | return; |
373 | } | 375 | } |
374 | 376 | ||
375 | ddev->poll_tech_index = (ddev->poll_tech_index + 1) % | 377 | ddev->poll_tech_index = (ddev->poll_tech_index + 1) % |
376 | ddev->poll_tech_count; | 378 | ddev->poll_tech_count; |
377 | 379 | ||
378 | mutex_unlock(&ddev->poll_lock); | 380 | mutex_unlock(&ddev->poll_lock); |
379 | 381 | ||
380 | schedule_work(&ddev->poll_work); | 382 | schedule_work(&ddev->poll_work); |
381 | } | 383 | } |
382 | 384 | ||
383 | static void digital_wq_poll(struct work_struct *work) | 385 | static void digital_wq_poll(struct work_struct *work) |
384 | { | 386 | { |
385 | int rc; | 387 | int rc; |
386 | struct digital_poll_tech *poll_tech; | 388 | struct digital_poll_tech *poll_tech; |
387 | struct nfc_digital_dev *ddev = container_of(work, | 389 | struct nfc_digital_dev *ddev = container_of(work, |
388 | struct nfc_digital_dev, | 390 | struct nfc_digital_dev, |
389 | poll_work); | 391 | poll_work); |
390 | mutex_lock(&ddev->poll_lock); | 392 | mutex_lock(&ddev->poll_lock); |
391 | 393 | ||
392 | if (!ddev->poll_tech_count) { | 394 | if (!ddev->poll_tech_count) { |
393 | mutex_unlock(&ddev->poll_lock); | 395 | mutex_unlock(&ddev->poll_lock); |
394 | return; | 396 | return; |
395 | } | 397 | } |
396 | 398 | ||
397 | poll_tech = &ddev->poll_techs[ddev->poll_tech_index]; | 399 | poll_tech = &ddev->poll_techs[ddev->poll_tech_index]; |
398 | 400 | ||
399 | mutex_unlock(&ddev->poll_lock); | 401 | mutex_unlock(&ddev->poll_lock); |
400 | 402 | ||
401 | rc = poll_tech->poll_func(ddev, poll_tech->rf_tech); | 403 | rc = poll_tech->poll_func(ddev, poll_tech->rf_tech); |
402 | if (rc) | 404 | if (rc) |
403 | digital_poll_next_tech(ddev); | 405 | digital_poll_next_tech(ddev); |
404 | } | 406 | } |
405 | 407 | ||
406 | static void digital_add_poll_tech(struct nfc_digital_dev *ddev, u8 rf_tech, | 408 | static void digital_add_poll_tech(struct nfc_digital_dev *ddev, u8 rf_tech, |
407 | digital_poll_t poll_func) | 409 | digital_poll_t poll_func) |
408 | { | 410 | { |
409 | struct digital_poll_tech *poll_tech; | 411 | struct digital_poll_tech *poll_tech; |
410 | 412 | ||
411 | if (ddev->poll_tech_count >= NFC_DIGITAL_POLL_MODE_COUNT_MAX) | 413 | if (ddev->poll_tech_count >= NFC_DIGITAL_POLL_MODE_COUNT_MAX) |
412 | return; | 414 | return; |
413 | 415 | ||
414 | poll_tech = &ddev->poll_techs[ddev->poll_tech_count++]; | 416 | poll_tech = &ddev->poll_techs[ddev->poll_tech_count++]; |
415 | 417 | ||
416 | poll_tech->rf_tech = rf_tech; | 418 | poll_tech->rf_tech = rf_tech; |
417 | poll_tech->poll_func = poll_func; | 419 | poll_tech->poll_func = poll_func; |
418 | } | 420 | } |
419 | 421 | ||
420 | /** | 422 | /** |
421 | * start_poll operation | 423 | * start_poll operation |
422 | * | 424 | * |
423 | * For every supported protocol, the corresponding polling function is added | 425 | * For every supported protocol, the corresponding polling function is added |
424 | * to the table of polling technologies (ddev->poll_techs[]) using | 426 | * to the table of polling technologies (ddev->poll_techs[]) using |
425 | * digital_add_poll_tech(). | 427 | * digital_add_poll_tech(). |
426 | * When a polling function fails (by timeout or protocol error) the next one is | 428 | * When a polling function fails (by timeout or protocol error) the next one is |
427 | * schedule by digital_poll_next_tech() on the poll workqueue (ddev->poll_work). | 429 | * schedule by digital_poll_next_tech() on the poll workqueue (ddev->poll_work). |
428 | */ | 430 | */ |
429 | static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols, | 431 | static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols, |
430 | __u32 tm_protocols) | 432 | __u32 tm_protocols) |
431 | { | 433 | { |
432 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 434 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
433 | u32 matching_im_protocols, matching_tm_protocols; | 435 | u32 matching_im_protocols, matching_tm_protocols; |
434 | 436 | ||
435 | PR_DBG("protocols: im 0x%x, tm 0x%x, supported 0x%x", im_protocols, | 437 | pr_debug("protocols: im 0x%x, tm 0x%x, supported 0x%x", im_protocols, |
436 | tm_protocols, ddev->protocols); | 438 | tm_protocols, ddev->protocols); |
437 | 439 | ||
438 | matching_im_protocols = ddev->protocols & im_protocols; | 440 | matching_im_protocols = ddev->protocols & im_protocols; |
439 | matching_tm_protocols = ddev->protocols & tm_protocols; | 441 | matching_tm_protocols = ddev->protocols & tm_protocols; |
440 | 442 | ||
441 | if (!matching_im_protocols && !matching_tm_protocols) { | 443 | if (!matching_im_protocols && !matching_tm_protocols) { |
442 | PR_ERR("No known protocol"); | 444 | pr_err("No known protocol"); |
443 | return -EINVAL; | 445 | return -EINVAL; |
444 | } | 446 | } |
445 | 447 | ||
446 | if (ddev->poll_tech_count) { | 448 | if (ddev->poll_tech_count) { |
447 | PR_ERR("Already polling"); | 449 | pr_err("Already polling"); |
448 | return -EBUSY; | 450 | return -EBUSY; |
449 | } | 451 | } |
450 | 452 | ||
451 | if (ddev->curr_protocol) { | 453 | if (ddev->curr_protocol) { |
452 | PR_ERR("A target is already active"); | 454 | pr_err("A target is already active"); |
453 | return -EBUSY; | 455 | return -EBUSY; |
454 | } | 456 | } |
455 | 457 | ||
456 | ddev->poll_tech_count = 0; | 458 | ddev->poll_tech_count = 0; |
457 | ddev->poll_tech_index = 0; | 459 | ddev->poll_tech_index = 0; |
458 | 460 | ||
459 | if (matching_im_protocols & DIGITAL_PROTO_NFCA_RF_TECH) | 461 | if (matching_im_protocols & DIGITAL_PROTO_NFCA_RF_TECH) |
460 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, | 462 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, |
461 | digital_in_send_sens_req); | 463 | digital_in_send_sens_req); |
462 | 464 | ||
463 | if (im_protocols & DIGITAL_PROTO_NFCF_RF_TECH) { | 465 | if (im_protocols & DIGITAL_PROTO_NFCF_RF_TECH) { |
464 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, | 466 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, |
465 | digital_in_send_sensf_req); | 467 | digital_in_send_sensf_req); |
466 | 468 | ||
467 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_424F, | 469 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_424F, |
468 | digital_in_send_sensf_req); | 470 | digital_in_send_sensf_req); |
469 | } | 471 | } |
470 | 472 | ||
471 | if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { | 473 | if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { |
472 | if (ddev->ops->tg_listen_mdaa) { | 474 | if (ddev->ops->tg_listen_mdaa) { |
473 | digital_add_poll_tech(ddev, 0, | 475 | digital_add_poll_tech(ddev, 0, |
474 | digital_tg_listen_mdaa); | 476 | digital_tg_listen_mdaa); |
475 | } else { | 477 | } else { |
476 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, | 478 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A, |
477 | digital_tg_listen_nfca); | 479 | digital_tg_listen_nfca); |
478 | 480 | ||
479 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, | 481 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_212F, |
480 | digital_tg_listen_nfcf); | 482 | digital_tg_listen_nfcf); |
481 | 483 | ||
482 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_424F, | 484 | digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_424F, |
483 | digital_tg_listen_nfcf); | 485 | digital_tg_listen_nfcf); |
484 | } | 486 | } |
485 | } | 487 | } |
486 | 488 | ||
487 | if (!ddev->poll_tech_count) { | 489 | if (!ddev->poll_tech_count) { |
488 | PR_ERR("Unsupported protocols: im=0x%x, tm=0x%x", | 490 | pr_err("Unsupported protocols: im=0x%x, tm=0x%x", |
489 | matching_im_protocols, matching_tm_protocols); | 491 | matching_im_protocols, matching_tm_protocols); |
490 | return -EINVAL; | 492 | return -EINVAL; |
491 | } | 493 | } |
492 | 494 | ||
493 | schedule_work(&ddev->poll_work); | 495 | schedule_work(&ddev->poll_work); |
494 | 496 | ||
495 | return 0; | 497 | return 0; |
496 | } | 498 | } |
497 | 499 | ||
498 | static void digital_stop_poll(struct nfc_dev *nfc_dev) | 500 | static void digital_stop_poll(struct nfc_dev *nfc_dev) |
499 | { | 501 | { |
500 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 502 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
501 | 503 | ||
502 | mutex_lock(&ddev->poll_lock); | 504 | mutex_lock(&ddev->poll_lock); |
503 | 505 | ||
504 | if (!ddev->poll_tech_count) { | 506 | if (!ddev->poll_tech_count) { |
505 | PR_ERR("Polling operation was not running"); | 507 | pr_err("Polling operation was not running"); |
506 | mutex_unlock(&ddev->poll_lock); | 508 | mutex_unlock(&ddev->poll_lock); |
507 | return; | 509 | return; |
508 | } | 510 | } |
509 | 511 | ||
510 | ddev->poll_tech_count = 0; | 512 | ddev->poll_tech_count = 0; |
511 | 513 | ||
512 | mutex_unlock(&ddev->poll_lock); | 514 | mutex_unlock(&ddev->poll_lock); |
513 | 515 | ||
514 | cancel_work_sync(&ddev->poll_work); | 516 | cancel_work_sync(&ddev->poll_work); |
515 | 517 | ||
516 | digital_abort_cmd(ddev); | 518 | digital_abort_cmd(ddev); |
517 | } | 519 | } |
518 | 520 | ||
519 | static int digital_dev_up(struct nfc_dev *nfc_dev) | 521 | static int digital_dev_up(struct nfc_dev *nfc_dev) |
520 | { | 522 | { |
521 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 523 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
522 | 524 | ||
523 | digital_switch_rf(ddev, 1); | 525 | digital_switch_rf(ddev, 1); |
524 | 526 | ||
525 | return 0; | 527 | return 0; |
526 | } | 528 | } |
527 | 529 | ||
528 | static int digital_dev_down(struct nfc_dev *nfc_dev) | 530 | static int digital_dev_down(struct nfc_dev *nfc_dev) |
529 | { | 531 | { |
530 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 532 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
531 | 533 | ||
532 | digital_switch_rf(ddev, 0); | 534 | digital_switch_rf(ddev, 0); |
533 | 535 | ||
534 | return 0; | 536 | return 0; |
535 | } | 537 | } |
536 | 538 | ||
537 | static int digital_dep_link_up(struct nfc_dev *nfc_dev, | 539 | static int digital_dep_link_up(struct nfc_dev *nfc_dev, |
538 | struct nfc_target *target, | 540 | struct nfc_target *target, |
539 | __u8 comm_mode, __u8 *gb, size_t gb_len) | 541 | __u8 comm_mode, __u8 *gb, size_t gb_len) |
540 | { | 542 | { |
541 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 543 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
542 | 544 | ||
543 | return digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len); | 545 | return digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len); |
544 | } | 546 | } |
545 | 547 | ||
546 | static int digital_dep_link_down(struct nfc_dev *nfc_dev) | 548 | static int digital_dep_link_down(struct nfc_dev *nfc_dev) |
547 | { | 549 | { |
548 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 550 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
549 | 551 | ||
550 | ddev->curr_protocol = 0; | 552 | ddev->curr_protocol = 0; |
551 | 553 | ||
552 | return 0; | 554 | return 0; |
553 | } | 555 | } |
554 | 556 | ||
555 | static int digital_activate_target(struct nfc_dev *nfc_dev, | 557 | static int digital_activate_target(struct nfc_dev *nfc_dev, |
556 | struct nfc_target *target, __u32 protocol) | 558 | struct nfc_target *target, __u32 protocol) |
557 | { | 559 | { |
558 | return 0; | 560 | return 0; |
559 | } | 561 | } |
560 | 562 | ||
561 | static void digital_deactivate_target(struct nfc_dev *nfc_dev, | 563 | static void digital_deactivate_target(struct nfc_dev *nfc_dev, |
562 | struct nfc_target *target) | 564 | struct nfc_target *target) |
563 | { | 565 | { |
564 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 566 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
565 | 567 | ||
566 | ddev->curr_protocol = 0; | 568 | ddev->curr_protocol = 0; |
567 | } | 569 | } |
568 | 570 | ||
569 | static int digital_tg_send(struct nfc_dev *dev, struct sk_buff *skb) | 571 | static int digital_tg_send(struct nfc_dev *dev, struct sk_buff *skb) |
570 | { | 572 | { |
571 | struct nfc_digital_dev *ddev = nfc_get_drvdata(dev); | 573 | struct nfc_digital_dev *ddev = nfc_get_drvdata(dev); |
572 | 574 | ||
573 | return digital_tg_send_dep_res(ddev, skb); | 575 | return digital_tg_send_dep_res(ddev, skb); |
574 | } | 576 | } |
575 | 577 | ||
576 | static void digital_in_send_complete(struct nfc_digital_dev *ddev, void *arg, | 578 | static void digital_in_send_complete(struct nfc_digital_dev *ddev, void *arg, |
577 | struct sk_buff *resp) | 579 | struct sk_buff *resp) |
578 | { | 580 | { |
579 | struct digital_data_exch *data_exch = arg; | 581 | struct digital_data_exch *data_exch = arg; |
580 | int rc; | 582 | int rc; |
581 | 583 | ||
582 | if (IS_ERR(resp)) { | 584 | if (IS_ERR(resp)) { |
583 | rc = PTR_ERR(resp); | 585 | rc = PTR_ERR(resp); |
584 | goto done; | 586 | goto done; |
585 | } | 587 | } |
586 | 588 | ||
587 | if (ddev->curr_protocol == NFC_PROTO_MIFARE) | 589 | if (ddev->curr_protocol == NFC_PROTO_MIFARE) |
588 | rc = digital_in_recv_mifare_res(resp); | 590 | rc = digital_in_recv_mifare_res(resp); |
589 | else | 591 | else |
590 | rc = ddev->skb_check_crc(resp); | 592 | rc = ddev->skb_check_crc(resp); |
591 | 593 | ||
592 | if (rc) { | 594 | if (rc) { |
593 | kfree_skb(resp); | 595 | kfree_skb(resp); |
594 | resp = NULL; | 596 | resp = NULL; |
595 | } | 597 | } |
596 | 598 | ||
597 | done: | 599 | done: |
598 | data_exch->cb(data_exch->cb_context, resp, rc); | 600 | data_exch->cb(data_exch->cb_context, resp, rc); |
599 | 601 | ||
600 | kfree(data_exch); | 602 | kfree(data_exch); |
601 | } | 603 | } |
602 | 604 | ||
603 | static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, | 605 | static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, |
604 | struct sk_buff *skb, data_exchange_cb_t cb, | 606 | struct sk_buff *skb, data_exchange_cb_t cb, |
605 | void *cb_context) | 607 | void *cb_context) |
606 | { | 608 | { |
607 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); | 609 | struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); |
608 | struct digital_data_exch *data_exch; | 610 | struct digital_data_exch *data_exch; |
609 | 611 | ||
610 | data_exch = kzalloc(sizeof(struct digital_data_exch), GFP_KERNEL); | 612 | data_exch = kzalloc(sizeof(struct digital_data_exch), GFP_KERNEL); |
611 | if (!data_exch) { | 613 | if (!data_exch) { |
612 | PR_ERR("Failed to allocate data_exch struct"); | 614 | pr_err("Failed to allocate data_exch struct"); |
613 | return -ENOMEM; | 615 | return -ENOMEM; |
614 | } | 616 | } |
615 | 617 | ||
616 | data_exch->cb = cb; | 618 | data_exch->cb = cb; |
617 | data_exch->cb_context = cb_context; | 619 | data_exch->cb_context = cb_context; |
618 | 620 | ||
619 | if (ddev->curr_protocol == NFC_PROTO_NFC_DEP) | 621 | if (ddev->curr_protocol == NFC_PROTO_NFC_DEP) |
620 | return digital_in_send_dep_req(ddev, target, skb, data_exch); | 622 | return digital_in_send_dep_req(ddev, target, skb, data_exch); |
621 | 623 | ||
622 | ddev->skb_add_crc(skb); | 624 | ddev->skb_add_crc(skb); |
623 | 625 | ||
624 | return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete, | 626 | return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete, |
625 | data_exch); | 627 | data_exch); |
626 | } | 628 | } |
627 | 629 | ||
628 | static struct nfc_ops digital_nfc_ops = { | 630 | static struct nfc_ops digital_nfc_ops = { |
629 | .dev_up = digital_dev_up, | 631 | .dev_up = digital_dev_up, |
630 | .dev_down = digital_dev_down, | 632 | .dev_down = digital_dev_down, |
631 | .start_poll = digital_start_poll, | 633 | .start_poll = digital_start_poll, |
632 | .stop_poll = digital_stop_poll, | 634 | .stop_poll = digital_stop_poll, |
633 | .dep_link_up = digital_dep_link_up, | 635 | .dep_link_up = digital_dep_link_up, |
634 | .dep_link_down = digital_dep_link_down, | 636 | .dep_link_down = digital_dep_link_down, |
635 | .activate_target = digital_activate_target, | 637 | .activate_target = digital_activate_target, |
636 | .deactivate_target = digital_deactivate_target, | 638 | .deactivate_target = digital_deactivate_target, |
637 | .tm_send = digital_tg_send, | 639 | .tm_send = digital_tg_send, |
638 | .im_transceive = digital_in_send, | 640 | .im_transceive = digital_in_send, |
639 | }; | 641 | }; |
640 | 642 | ||
641 | struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, | 643 | struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, |
642 | __u32 supported_protocols, | 644 | __u32 supported_protocols, |
643 | __u32 driver_capabilities, | 645 | __u32 driver_capabilities, |
644 | int tx_headroom, int tx_tailroom) | 646 | int tx_headroom, int tx_tailroom) |
645 | { | 647 | { |
646 | struct nfc_digital_dev *ddev; | 648 | struct nfc_digital_dev *ddev; |
647 | 649 | ||
648 | if (!ops->in_configure_hw || !ops->in_send_cmd || !ops->tg_listen || | 650 | if (!ops->in_configure_hw || !ops->in_send_cmd || !ops->tg_listen || |
649 | !ops->tg_configure_hw || !ops->tg_send_cmd || !ops->abort_cmd || | 651 | !ops->tg_configure_hw || !ops->tg_send_cmd || !ops->abort_cmd || |
650 | !ops->switch_rf) | 652 | !ops->switch_rf) |
651 | return NULL; | 653 | return NULL; |
652 | 654 | ||
653 | ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL); | 655 | ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL); |
654 | if (!ddev) { | 656 | if (!ddev) { |
655 | PR_ERR("kzalloc failed"); | 657 | pr_err("kzalloc failed"); |
656 | return NULL; | 658 | return NULL; |
657 | } | 659 | } |
658 | 660 | ||
659 | ddev->driver_capabilities = driver_capabilities; | 661 | ddev->driver_capabilities = driver_capabilities; |
660 | ddev->ops = ops; | 662 | ddev->ops = ops; |
661 | 663 | ||
662 | mutex_init(&ddev->cmd_lock); | 664 | mutex_init(&ddev->cmd_lock); |
663 | INIT_LIST_HEAD(&ddev->cmd_queue); | 665 | INIT_LIST_HEAD(&ddev->cmd_queue); |
664 | 666 | ||
665 | INIT_WORK(&ddev->cmd_work, digital_wq_cmd); | 667 | INIT_WORK(&ddev->cmd_work, digital_wq_cmd); |
666 | INIT_WORK(&ddev->cmd_complete_work, digital_wq_cmd_complete); | 668 | INIT_WORK(&ddev->cmd_complete_work, digital_wq_cmd_complete); |
667 | 669 | ||
668 | mutex_init(&ddev->poll_lock); | 670 | mutex_init(&ddev->poll_lock); |
669 | INIT_WORK(&ddev->poll_work, digital_wq_poll); | 671 | INIT_WORK(&ddev->poll_work, digital_wq_poll); |
670 | 672 | ||
671 | if (supported_protocols & NFC_PROTO_JEWEL_MASK) | 673 | if (supported_protocols & NFC_PROTO_JEWEL_MASK) |
672 | ddev->protocols |= NFC_PROTO_JEWEL_MASK; | 674 | ddev->protocols |= NFC_PROTO_JEWEL_MASK; |
673 | if (supported_protocols & NFC_PROTO_MIFARE_MASK) | 675 | if (supported_protocols & NFC_PROTO_MIFARE_MASK) |
674 | ddev->protocols |= NFC_PROTO_MIFARE_MASK; | 676 | ddev->protocols |= NFC_PROTO_MIFARE_MASK; |
675 | if (supported_protocols & NFC_PROTO_FELICA_MASK) | 677 | if (supported_protocols & NFC_PROTO_FELICA_MASK) |
676 | ddev->protocols |= NFC_PROTO_FELICA_MASK; | 678 | ddev->protocols |= NFC_PROTO_FELICA_MASK; |
677 | if (supported_protocols & NFC_PROTO_NFC_DEP_MASK) | 679 | if (supported_protocols & NFC_PROTO_NFC_DEP_MASK) |
678 | ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; | 680 | ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; |
679 | 681 | ||
680 | ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; | 682 | ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; |
681 | ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; | 683 | ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN; |
682 | 684 | ||
683 | ddev->nfc_dev = nfc_allocate_device(&digital_nfc_ops, ddev->protocols, | 685 | ddev->nfc_dev = nfc_allocate_device(&digital_nfc_ops, ddev->protocols, |
684 | ddev->tx_headroom, | 686 | ddev->tx_headroom, |
685 | ddev->tx_tailroom); | 687 | ddev->tx_tailroom); |
686 | if (!ddev->nfc_dev) { | 688 | if (!ddev->nfc_dev) { |
687 | PR_ERR("nfc_allocate_device failed"); | 689 | pr_err("nfc_allocate_device failed"); |
688 | goto free_dev; | 690 | goto free_dev; |
689 | } | 691 | } |
690 | 692 | ||
691 | nfc_set_drvdata(ddev->nfc_dev, ddev); | 693 | nfc_set_drvdata(ddev->nfc_dev, ddev); |
692 | 694 | ||
693 | return ddev; | 695 | return ddev; |
694 | 696 | ||
695 | free_dev: | 697 | free_dev: |
696 | kfree(ddev); | 698 | kfree(ddev); |
697 | 699 | ||
698 | return NULL; | 700 | return NULL; |
699 | } | 701 | } |
700 | EXPORT_SYMBOL(nfc_digital_allocate_device); | 702 | EXPORT_SYMBOL(nfc_digital_allocate_device); |
701 | 703 | ||
702 | void nfc_digital_free_device(struct nfc_digital_dev *ddev) | 704 | void nfc_digital_free_device(struct nfc_digital_dev *ddev) |
703 | { | 705 | { |
704 | nfc_free_device(ddev->nfc_dev); | 706 | nfc_free_device(ddev->nfc_dev); |
705 | kfree(ddev); | 707 | kfree(ddev); |
706 | } | 708 | } |
707 | EXPORT_SYMBOL(nfc_digital_free_device); | 709 | EXPORT_SYMBOL(nfc_digital_free_device); |
708 | 710 | ||
709 | int nfc_digital_register_device(struct nfc_digital_dev *ddev) | 711 | int nfc_digital_register_device(struct nfc_digital_dev *ddev) |
710 | { | 712 | { |
711 | return nfc_register_device(ddev->nfc_dev); | 713 | return nfc_register_device(ddev->nfc_dev); |
712 | } | 714 | } |
713 | EXPORT_SYMBOL(nfc_digital_register_device); | 715 | EXPORT_SYMBOL(nfc_digital_register_device); |
714 | 716 | ||
715 | void nfc_digital_unregister_device(struct nfc_digital_dev *ddev) | 717 | void nfc_digital_unregister_device(struct nfc_digital_dev *ddev) |
716 | { | 718 | { |
717 | struct digital_cmd *cmd, *n; | 719 | struct digital_cmd *cmd, *n; |
718 | 720 | ||
719 | nfc_unregister_device(ddev->nfc_dev); | 721 | nfc_unregister_device(ddev->nfc_dev); |
720 | 722 | ||
721 | mutex_lock(&ddev->poll_lock); | 723 | mutex_lock(&ddev->poll_lock); |
722 | ddev->poll_tech_count = 0; | 724 | ddev->poll_tech_count = 0; |
723 | mutex_unlock(&ddev->poll_lock); | 725 | mutex_unlock(&ddev->poll_lock); |
724 | 726 | ||
725 | cancel_work_sync(&ddev->poll_work); | 727 | cancel_work_sync(&ddev->poll_work); |
726 | cancel_work_sync(&ddev->cmd_work); | 728 | cancel_work_sync(&ddev->cmd_work); |
727 | cancel_work_sync(&ddev->cmd_complete_work); | 729 | cancel_work_sync(&ddev->cmd_complete_work); |
728 | 730 | ||
729 | list_for_each_entry_safe(cmd, n, &ddev->cmd_queue, queue) { | 731 | list_for_each_entry_safe(cmd, n, &ddev->cmd_queue, queue) { |
730 | list_del(&cmd->queue); | 732 | list_del(&cmd->queue); |
731 | kfree(cmd->mdaa_params); | 733 | kfree(cmd->mdaa_params); |
732 | kfree(cmd); | 734 | kfree(cmd); |
733 | } | 735 | } |
734 | } | 736 | } |
735 | EXPORT_SYMBOL(nfc_digital_unregister_device); | 737 | EXPORT_SYMBOL(nfc_digital_unregister_device); |
736 | 738 | ||
737 | MODULE_LICENSE("GPL"); | 739 | MODULE_LICENSE("GPL"); |
738 | 740 |
net/nfc/digital_dep.c
1 | /* | 1 | /* |
2 | * NFC Digital Protocol stack | 2 | * NFC Digital Protocol stack |
3 | * Copyright (c) 2013, Intel Corporation. | 3 | * Copyright (c) 2013, Intel Corporation. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | 9 | * This program is distributed in the hope it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) "digital: %s: " fmt, __func__ | ||
17 | |||
16 | #include "digital.h" | 18 | #include "digital.h" |
17 | 19 | ||
18 | #define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4 | 20 | #define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4 |
19 | #define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5 | 21 | #define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5 |
20 | 22 | ||
21 | #define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0 | 23 | #define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0 |
22 | 24 | ||
23 | #define DIGITAL_CMD_ATR_REQ 0x00 | 25 | #define DIGITAL_CMD_ATR_REQ 0x00 |
24 | #define DIGITAL_CMD_ATR_RES 0x01 | 26 | #define DIGITAL_CMD_ATR_RES 0x01 |
25 | #define DIGITAL_CMD_PSL_REQ 0x04 | 27 | #define DIGITAL_CMD_PSL_REQ 0x04 |
26 | #define DIGITAL_CMD_PSL_RES 0x05 | 28 | #define DIGITAL_CMD_PSL_RES 0x05 |
27 | #define DIGITAL_CMD_DEP_REQ 0x06 | 29 | #define DIGITAL_CMD_DEP_REQ 0x06 |
28 | #define DIGITAL_CMD_DEP_RES 0x07 | 30 | #define DIGITAL_CMD_DEP_RES 0x07 |
29 | 31 | ||
30 | #define DIGITAL_ATR_REQ_MIN_SIZE 16 | 32 | #define DIGITAL_ATR_REQ_MIN_SIZE 16 |
31 | #define DIGITAL_ATR_REQ_MAX_SIZE 64 | 33 | #define DIGITAL_ATR_REQ_MAX_SIZE 64 |
32 | 34 | ||
33 | #define DIGITAL_NFCID3_LEN ((u8)8) | 35 | #define DIGITAL_NFCID3_LEN ((u8)8) |
34 | #define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30 | 36 | #define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30 |
35 | #define DIGITAL_GB_BIT 0x02 | 37 | #define DIGITAL_GB_BIT 0x02 |
36 | 38 | ||
37 | #define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0) | 39 | #define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0) |
38 | 40 | ||
39 | #define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10 | 41 | #define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10 |
40 | 42 | ||
41 | #define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \ | 43 | #define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \ |
42 | ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT) | 44 | ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT) |
43 | #define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & 0x10) | 45 | #define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & 0x10) |
44 | #define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08) | 46 | #define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08) |
45 | #define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04) | 47 | #define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04) |
46 | #define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03) | 48 | #define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03) |
47 | 49 | ||
48 | #define DIGITAL_NFC_DEP_PFB_I_PDU 0x00 | 50 | #define DIGITAL_NFC_DEP_PFB_I_PDU 0x00 |
49 | #define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40 | 51 | #define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40 |
50 | #define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80 | 52 | #define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80 |
51 | 53 | ||
52 | struct digital_atr_req { | 54 | struct digital_atr_req { |
53 | u8 dir; | 55 | u8 dir; |
54 | u8 cmd; | 56 | u8 cmd; |
55 | u8 nfcid3[10]; | 57 | u8 nfcid3[10]; |
56 | u8 did; | 58 | u8 did; |
57 | u8 bs; | 59 | u8 bs; |
58 | u8 br; | 60 | u8 br; |
59 | u8 pp; | 61 | u8 pp; |
60 | u8 gb[0]; | 62 | u8 gb[0]; |
61 | } __packed; | 63 | } __packed; |
62 | 64 | ||
63 | struct digital_atr_res { | 65 | struct digital_atr_res { |
64 | u8 dir; | 66 | u8 dir; |
65 | u8 cmd; | 67 | u8 cmd; |
66 | u8 nfcid3[10]; | 68 | u8 nfcid3[10]; |
67 | u8 did; | 69 | u8 did; |
68 | u8 bs; | 70 | u8 bs; |
69 | u8 br; | 71 | u8 br; |
70 | u8 to; | 72 | u8 to; |
71 | u8 pp; | 73 | u8 pp; |
72 | u8 gb[0]; | 74 | u8 gb[0]; |
73 | } __packed; | 75 | } __packed; |
74 | 76 | ||
75 | struct digital_psl_req { | 77 | struct digital_psl_req { |
76 | u8 dir; | 78 | u8 dir; |
77 | u8 cmd; | 79 | u8 cmd; |
78 | u8 did; | 80 | u8 did; |
79 | u8 brs; | 81 | u8 brs; |
80 | u8 fsl; | 82 | u8 fsl; |
81 | } __packed; | 83 | } __packed; |
82 | 84 | ||
83 | struct digital_psl_res { | 85 | struct digital_psl_res { |
84 | u8 dir; | 86 | u8 dir; |
85 | u8 cmd; | 87 | u8 cmd; |
86 | u8 did; | 88 | u8 did; |
87 | } __packed; | 89 | } __packed; |
88 | 90 | ||
89 | struct digital_dep_req_res { | 91 | struct digital_dep_req_res { |
90 | u8 dir; | 92 | u8 dir; |
91 | u8 cmd; | 93 | u8 cmd; |
92 | u8 pfb; | 94 | u8 pfb; |
93 | } __packed; | 95 | } __packed; |
94 | 96 | ||
95 | static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, | 97 | static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, |
96 | struct sk_buff *resp); | 98 | struct sk_buff *resp); |
97 | 99 | ||
98 | static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev, | 100 | static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev, |
99 | struct sk_buff *skb) | 101 | struct sk_buff *skb) |
100 | { | 102 | { |
101 | skb_push(skb, sizeof(u8)); | 103 | skb_push(skb, sizeof(u8)); |
102 | 104 | ||
103 | skb->data[0] = skb->len; | 105 | skb->data[0] = skb->len; |
104 | 106 | ||
105 | if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A) | 107 | if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A) |
106 | *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB; | 108 | *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB; |
107 | } | 109 | } |
108 | 110 | ||
109 | static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev, | 111 | static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev, |
110 | struct sk_buff *skb) | 112 | struct sk_buff *skb) |
111 | { | 113 | { |
112 | u8 size; | 114 | u8 size; |
113 | 115 | ||
114 | if (skb->len < 2) | 116 | if (skb->len < 2) |
115 | return -EIO; | 117 | return -EIO; |
116 | 118 | ||
117 | if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A) | 119 | if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A) |
118 | skb_pull(skb, sizeof(u8)); | 120 | skb_pull(skb, sizeof(u8)); |
119 | 121 | ||
120 | size = skb->data[0]; | 122 | size = skb->data[0]; |
121 | if (size != skb->len) | 123 | if (size != skb->len) |
122 | return -EIO; | 124 | return -EIO; |
123 | 125 | ||
124 | skb_pull(skb, sizeof(u8)); | 126 | skb_pull(skb, sizeof(u8)); |
125 | 127 | ||
126 | return 0; | 128 | return 0; |
127 | } | 129 | } |
128 | 130 | ||
129 | static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, | 131 | static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, |
130 | struct sk_buff *resp) | 132 | struct sk_buff *resp) |
131 | { | 133 | { |
132 | struct nfc_target *target = arg; | 134 | struct nfc_target *target = arg; |
133 | struct digital_atr_res *atr_res; | 135 | struct digital_atr_res *atr_res; |
134 | u8 gb_len; | 136 | u8 gb_len; |
135 | int rc; | 137 | int rc; |
136 | 138 | ||
137 | if (IS_ERR(resp)) { | 139 | if (IS_ERR(resp)) { |
138 | rc = PTR_ERR(resp); | 140 | rc = PTR_ERR(resp); |
139 | resp = NULL; | 141 | resp = NULL; |
140 | goto exit; | 142 | goto exit; |
141 | } | 143 | } |
142 | 144 | ||
143 | rc = ddev->skb_check_crc(resp); | 145 | rc = ddev->skb_check_crc(resp); |
144 | if (rc) { | 146 | if (rc) { |
145 | PROTOCOL_ERR("14.4.1.6"); | 147 | PROTOCOL_ERR("14.4.1.6"); |
146 | goto exit; | 148 | goto exit; |
147 | } | 149 | } |
148 | 150 | ||
149 | rc = digital_skb_pull_dep_sod(ddev, resp); | 151 | rc = digital_skb_pull_dep_sod(ddev, resp); |
150 | if (rc) { | 152 | if (rc) { |
151 | PROTOCOL_ERR("14.4.1.2"); | 153 | PROTOCOL_ERR("14.4.1.2"); |
152 | goto exit; | 154 | goto exit; |
153 | } | 155 | } |
154 | 156 | ||
155 | if (resp->len < sizeof(struct digital_atr_res)) { | 157 | if (resp->len < sizeof(struct digital_atr_res)) { |
156 | rc = -EIO; | 158 | rc = -EIO; |
157 | goto exit; | 159 | goto exit; |
158 | } | 160 | } |
159 | 161 | ||
160 | gb_len = resp->len - sizeof(struct digital_atr_res); | 162 | gb_len = resp->len - sizeof(struct digital_atr_res); |
161 | 163 | ||
162 | atr_res = (struct digital_atr_res *)resp->data; | 164 | atr_res = (struct digital_atr_res *)resp->data; |
163 | 165 | ||
164 | rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len); | 166 | rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len); |
165 | if (rc) | 167 | if (rc) |
166 | goto exit; | 168 | goto exit; |
167 | 169 | ||
168 | rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE, | 170 | rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE, |
169 | NFC_RF_INITIATOR); | 171 | NFC_RF_INITIATOR); |
170 | 172 | ||
171 | ddev->curr_nfc_dep_pni = 0; | 173 | ddev->curr_nfc_dep_pni = 0; |
172 | 174 | ||
173 | exit: | 175 | exit: |
174 | dev_kfree_skb(resp); | 176 | dev_kfree_skb(resp); |
175 | 177 | ||
176 | if (rc) | 178 | if (rc) |
177 | ddev->curr_protocol = 0; | 179 | ddev->curr_protocol = 0; |
178 | } | 180 | } |
179 | 181 | ||
180 | int digital_in_send_atr_req(struct nfc_digital_dev *ddev, | 182 | int digital_in_send_atr_req(struct nfc_digital_dev *ddev, |
181 | struct nfc_target *target, __u8 comm_mode, __u8 *gb, | 183 | struct nfc_target *target, __u8 comm_mode, __u8 *gb, |
182 | size_t gb_len) | 184 | size_t gb_len) |
183 | { | 185 | { |
184 | struct sk_buff *skb; | 186 | struct sk_buff *skb; |
185 | struct digital_atr_req *atr_req; | 187 | struct digital_atr_req *atr_req; |
186 | uint size; | 188 | uint size; |
187 | 189 | ||
188 | size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len; | 190 | size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len; |
189 | 191 | ||
190 | if (size > DIGITAL_ATR_REQ_MAX_SIZE) { | 192 | if (size > DIGITAL_ATR_REQ_MAX_SIZE) { |
191 | PROTOCOL_ERR("14.6.1.1"); | 193 | PROTOCOL_ERR("14.6.1.1"); |
192 | return -EINVAL; | 194 | return -EINVAL; |
193 | } | 195 | } |
194 | 196 | ||
195 | skb = digital_skb_alloc(ddev, size); | 197 | skb = digital_skb_alloc(ddev, size); |
196 | if (!skb) | 198 | if (!skb) |
197 | return -ENOMEM; | 199 | return -ENOMEM; |
198 | 200 | ||
199 | skb_put(skb, sizeof(struct digital_atr_req)); | 201 | skb_put(skb, sizeof(struct digital_atr_req)); |
200 | 202 | ||
201 | atr_req = (struct digital_atr_req *)skb->data; | 203 | atr_req = (struct digital_atr_req *)skb->data; |
202 | memset(atr_req, 0, sizeof(struct digital_atr_req)); | 204 | memset(atr_req, 0, sizeof(struct digital_atr_req)); |
203 | 205 | ||
204 | atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; | 206 | atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; |
205 | atr_req->cmd = DIGITAL_CMD_ATR_REQ; | 207 | atr_req->cmd = DIGITAL_CMD_ATR_REQ; |
206 | if (target->nfcid2_len) | 208 | if (target->nfcid2_len) |
207 | memcpy(atr_req->nfcid3, target->nfcid2, | 209 | memcpy(atr_req->nfcid3, target->nfcid2, |
208 | max(target->nfcid2_len, DIGITAL_NFCID3_LEN)); | 210 | max(target->nfcid2_len, DIGITAL_NFCID3_LEN)); |
209 | else | 211 | else |
210 | get_random_bytes(atr_req->nfcid3, DIGITAL_NFCID3_LEN); | 212 | get_random_bytes(atr_req->nfcid3, DIGITAL_NFCID3_LEN); |
211 | 213 | ||
212 | atr_req->did = 0; | 214 | atr_req->did = 0; |
213 | atr_req->bs = 0; | 215 | atr_req->bs = 0; |
214 | atr_req->br = 0; | 216 | atr_req->br = 0; |
215 | 217 | ||
216 | atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B; | 218 | atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B; |
217 | 219 | ||
218 | if (gb_len) { | 220 | if (gb_len) { |
219 | atr_req->pp |= DIGITAL_GB_BIT; | 221 | atr_req->pp |= DIGITAL_GB_BIT; |
220 | memcpy(skb_put(skb, gb_len), gb, gb_len); | 222 | memcpy(skb_put(skb, gb_len), gb, gb_len); |
221 | } | 223 | } |
222 | 224 | ||
223 | digital_skb_push_dep_sod(ddev, skb); | 225 | digital_skb_push_dep_sod(ddev, skb); |
224 | 226 | ||
225 | ddev->skb_add_crc(skb); | 227 | ddev->skb_add_crc(skb); |
226 | 228 | ||
227 | digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, target); | 229 | digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, target); |
228 | 230 | ||
229 | return 0; | 231 | return 0; |
230 | } | 232 | } |
231 | 233 | ||
232 | static int digital_in_send_rtox(struct nfc_digital_dev *ddev, | 234 | static int digital_in_send_rtox(struct nfc_digital_dev *ddev, |
233 | struct digital_data_exch *data_exch, u8 rtox) | 235 | struct digital_data_exch *data_exch, u8 rtox) |
234 | { | 236 | { |
235 | struct digital_dep_req_res *dep_req; | 237 | struct digital_dep_req_res *dep_req; |
236 | struct sk_buff *skb; | 238 | struct sk_buff *skb; |
237 | int rc; | 239 | int rc; |
238 | 240 | ||
239 | skb = digital_skb_alloc(ddev, 1); | 241 | skb = digital_skb_alloc(ddev, 1); |
240 | if (!skb) | 242 | if (!skb) |
241 | return -ENOMEM; | 243 | return -ENOMEM; |
242 | 244 | ||
243 | *skb_put(skb, 1) = rtox; | 245 | *skb_put(skb, 1) = rtox; |
244 | 246 | ||
245 | skb_push(skb, sizeof(struct digital_dep_req_res)); | 247 | skb_push(skb, sizeof(struct digital_dep_req_res)); |
246 | 248 | ||
247 | dep_req = (struct digital_dep_req_res *)skb->data; | 249 | dep_req = (struct digital_dep_req_res *)skb->data; |
248 | 250 | ||
249 | dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; | 251 | dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; |
250 | dep_req->cmd = DIGITAL_CMD_DEP_REQ; | 252 | dep_req->cmd = DIGITAL_CMD_DEP_REQ; |
251 | dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU | | 253 | dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU | |
252 | DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT; | 254 | DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT; |
253 | 255 | ||
254 | digital_skb_push_dep_sod(ddev, skb); | 256 | digital_skb_push_dep_sod(ddev, skb); |
255 | 257 | ||
256 | ddev->skb_add_crc(skb); | 258 | ddev->skb_add_crc(skb); |
257 | 259 | ||
258 | rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, | 260 | rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, |
259 | data_exch); | 261 | data_exch); |
260 | 262 | ||
261 | return rc; | 263 | return rc; |
262 | } | 264 | } |
263 | 265 | ||
264 | static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, | 266 | static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, |
265 | struct sk_buff *resp) | 267 | struct sk_buff *resp) |
266 | { | 268 | { |
267 | struct digital_data_exch *data_exch = arg; | 269 | struct digital_data_exch *data_exch = arg; |
268 | struct digital_dep_req_res *dep_res; | 270 | struct digital_dep_req_res *dep_res; |
269 | u8 pfb; | 271 | u8 pfb; |
270 | uint size; | 272 | uint size; |
271 | int rc; | 273 | int rc; |
272 | 274 | ||
273 | if (IS_ERR(resp)) { | 275 | if (IS_ERR(resp)) { |
274 | rc = PTR_ERR(resp); | 276 | rc = PTR_ERR(resp); |
275 | resp = NULL; | 277 | resp = NULL; |
276 | goto exit; | 278 | goto exit; |
277 | } | 279 | } |
278 | 280 | ||
279 | rc = ddev->skb_check_crc(resp); | 281 | rc = ddev->skb_check_crc(resp); |
280 | if (rc) { | 282 | if (rc) { |
281 | PROTOCOL_ERR("14.4.1.6"); | 283 | PROTOCOL_ERR("14.4.1.6"); |
282 | goto error; | 284 | goto error; |
283 | } | 285 | } |
284 | 286 | ||
285 | rc = digital_skb_pull_dep_sod(ddev, resp); | 287 | rc = digital_skb_pull_dep_sod(ddev, resp); |
286 | if (rc) { | 288 | if (rc) { |
287 | PROTOCOL_ERR("14.4.1.2"); | 289 | PROTOCOL_ERR("14.4.1.2"); |
288 | goto exit; | 290 | goto exit; |
289 | } | 291 | } |
290 | 292 | ||
291 | dep_res = (struct digital_dep_req_res *)resp->data; | 293 | dep_res = (struct digital_dep_req_res *)resp->data; |
292 | 294 | ||
293 | if (resp->len < sizeof(struct digital_dep_req_res) || | 295 | if (resp->len < sizeof(struct digital_dep_req_res) || |
294 | dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN || | 296 | dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN || |
295 | dep_res->cmd != DIGITAL_CMD_DEP_RES) { | 297 | dep_res->cmd != DIGITAL_CMD_DEP_RES) { |
296 | rc = -EIO; | 298 | rc = -EIO; |
297 | goto error; | 299 | goto error; |
298 | } | 300 | } |
299 | 301 | ||
300 | pfb = dep_res->pfb; | 302 | pfb = dep_res->pfb; |
301 | 303 | ||
302 | switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) { | 304 | switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) { |
303 | case DIGITAL_NFC_DEP_PFB_I_PDU: | 305 | case DIGITAL_NFC_DEP_PFB_I_PDU: |
304 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { | 306 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { |
305 | PROTOCOL_ERR("14.12.3.3"); | 307 | PROTOCOL_ERR("14.12.3.3"); |
306 | rc = -EIO; | 308 | rc = -EIO; |
307 | goto error; | 309 | goto error; |
308 | } | 310 | } |
309 | 311 | ||
310 | ddev->curr_nfc_dep_pni = | 312 | ddev->curr_nfc_dep_pni = |
311 | DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); | 313 | DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); |
312 | rc = 0; | 314 | rc = 0; |
313 | break; | 315 | break; |
314 | 316 | ||
315 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: | 317 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: |
316 | PR_ERR("Received a ACK/NACK PDU"); | 318 | pr_err("Received a ACK/NACK PDU"); |
317 | rc = -EIO; | 319 | rc = -EIO; |
318 | goto error; | 320 | goto error; |
319 | 321 | ||
320 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: | 322 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: |
321 | if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { | 323 | if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { |
322 | rc = -EINVAL; | 324 | rc = -EINVAL; |
323 | goto error; | 325 | goto error; |
324 | } | 326 | } |
325 | 327 | ||
326 | rc = digital_in_send_rtox(ddev, data_exch, resp->data[3]); | 328 | rc = digital_in_send_rtox(ddev, data_exch, resp->data[3]); |
327 | if (rc) | 329 | if (rc) |
328 | goto error; | 330 | goto error; |
329 | 331 | ||
330 | kfree_skb(resp); | 332 | kfree_skb(resp); |
331 | return; | 333 | return; |
332 | } | 334 | } |
333 | 335 | ||
334 | if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) { | 336 | if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) { |
335 | PR_ERR("MI bit set. Chained PDU not supported."); | 337 | pr_err("MI bit set. Chained PDU not supported."); |
336 | rc = -EIO; | 338 | rc = -EIO; |
337 | goto error; | 339 | goto error; |
338 | } | 340 | } |
339 | 341 | ||
340 | size = sizeof(struct digital_dep_req_res); | 342 | size = sizeof(struct digital_dep_req_res); |
341 | 343 | ||
342 | if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) | 344 | if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) |
343 | size++; | 345 | size++; |
344 | 346 | ||
345 | if (size > resp->len) { | 347 | if (size > resp->len) { |
346 | rc = -EIO; | 348 | rc = -EIO; |
347 | goto error; | 349 | goto error; |
348 | } | 350 | } |
349 | 351 | ||
350 | skb_pull(resp, size); | 352 | skb_pull(resp, size); |
351 | 353 | ||
352 | exit: | 354 | exit: |
353 | data_exch->cb(data_exch->cb_context, resp, rc); | 355 | data_exch->cb(data_exch->cb_context, resp, rc); |
354 | 356 | ||
355 | error: | 357 | error: |
356 | kfree(data_exch); | 358 | kfree(data_exch); |
357 | 359 | ||
358 | if (rc) | 360 | if (rc) |
359 | kfree_skb(resp); | 361 | kfree_skb(resp); |
360 | } | 362 | } |
361 | 363 | ||
362 | int digital_in_send_dep_req(struct nfc_digital_dev *ddev, | 364 | int digital_in_send_dep_req(struct nfc_digital_dev *ddev, |
363 | struct nfc_target *target, struct sk_buff *skb, | 365 | struct nfc_target *target, struct sk_buff *skb, |
364 | struct digital_data_exch *data_exch) | 366 | struct digital_data_exch *data_exch) |
365 | { | 367 | { |
366 | struct digital_dep_req_res *dep_req; | 368 | struct digital_dep_req_res *dep_req; |
367 | 369 | ||
368 | skb_push(skb, sizeof(struct digital_dep_req_res)); | 370 | skb_push(skb, sizeof(struct digital_dep_req_res)); |
369 | 371 | ||
370 | dep_req = (struct digital_dep_req_res *)skb->data; | 372 | dep_req = (struct digital_dep_req_res *)skb->data; |
371 | dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; | 373 | dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; |
372 | dep_req->cmd = DIGITAL_CMD_DEP_REQ; | 374 | dep_req->cmd = DIGITAL_CMD_DEP_REQ; |
373 | dep_req->pfb = ddev->curr_nfc_dep_pni; | 375 | dep_req->pfb = ddev->curr_nfc_dep_pni; |
374 | 376 | ||
375 | digital_skb_push_dep_sod(ddev, skb); | 377 | digital_skb_push_dep_sod(ddev, skb); |
376 | 378 | ||
377 | ddev->skb_add_crc(skb); | 379 | ddev->skb_add_crc(skb); |
378 | 380 | ||
379 | return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, | 381 | return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, |
380 | data_exch); | 382 | data_exch); |
381 | } | 383 | } |
382 | 384 | ||
383 | static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg, | 385 | static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg, |
384 | struct sk_buff *resp) | 386 | struct sk_buff *resp) |
385 | { | 387 | { |
386 | int rc; | 388 | int rc; |
387 | struct digital_dep_req_res *dep_req; | 389 | struct digital_dep_req_res *dep_req; |
388 | size_t size; | 390 | size_t size; |
389 | 391 | ||
390 | if (IS_ERR(resp)) { | 392 | if (IS_ERR(resp)) { |
391 | rc = PTR_ERR(resp); | 393 | rc = PTR_ERR(resp); |
392 | resp = NULL; | 394 | resp = NULL; |
393 | goto exit; | 395 | goto exit; |
394 | } | 396 | } |
395 | 397 | ||
396 | rc = ddev->skb_check_crc(resp); | 398 | rc = ddev->skb_check_crc(resp); |
397 | if (rc) { | 399 | if (rc) { |
398 | PROTOCOL_ERR("14.4.1.6"); | 400 | PROTOCOL_ERR("14.4.1.6"); |
399 | goto exit; | 401 | goto exit; |
400 | } | 402 | } |
401 | 403 | ||
402 | rc = digital_skb_pull_dep_sod(ddev, resp); | 404 | rc = digital_skb_pull_dep_sod(ddev, resp); |
403 | if (rc) { | 405 | if (rc) { |
404 | PROTOCOL_ERR("14.4.1.2"); | 406 | PROTOCOL_ERR("14.4.1.2"); |
405 | goto exit; | 407 | goto exit; |
406 | } | 408 | } |
407 | 409 | ||
408 | size = sizeof(struct digital_dep_req_res); | 410 | size = sizeof(struct digital_dep_req_res); |
409 | dep_req = (struct digital_dep_req_res *)resp->data; | 411 | dep_req = (struct digital_dep_req_res *)resp->data; |
410 | 412 | ||
411 | if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT || | 413 | if (resp->len < size || dep_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT || |
412 | dep_req->cmd != DIGITAL_CMD_DEP_REQ) { | 414 | dep_req->cmd != DIGITAL_CMD_DEP_REQ) { |
413 | rc = -EIO; | 415 | rc = -EIO; |
414 | goto exit; | 416 | goto exit; |
415 | } | 417 | } |
416 | 418 | ||
417 | if (DIGITAL_NFC_DEP_DID_BIT_SET(dep_req->pfb)) | 419 | if (DIGITAL_NFC_DEP_DID_BIT_SET(dep_req->pfb)) |
418 | size++; | 420 | size++; |
419 | 421 | ||
420 | if (resp->len < size) { | 422 | if (resp->len < size) { |
421 | rc = -EIO; | 423 | rc = -EIO; |
422 | goto exit; | 424 | goto exit; |
423 | } | 425 | } |
424 | 426 | ||
425 | switch (DIGITAL_NFC_DEP_PFB_TYPE(dep_req->pfb)) { | 427 | switch (DIGITAL_NFC_DEP_PFB_TYPE(dep_req->pfb)) { |
426 | case DIGITAL_NFC_DEP_PFB_I_PDU: | 428 | case DIGITAL_NFC_DEP_PFB_I_PDU: |
427 | PR_DBG("DIGITAL_NFC_DEP_PFB_I_PDU"); | 429 | pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU"); |
428 | ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(dep_req->pfb); | 430 | ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(dep_req->pfb); |
429 | break; | 431 | break; |
430 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: | 432 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: |
431 | PR_ERR("Received a ACK/NACK PDU"); | 433 | pr_err("Received a ACK/NACK PDU"); |
432 | rc = -EINVAL; | 434 | rc = -EINVAL; |
433 | goto exit; | 435 | goto exit; |
434 | break; | 436 | break; |
435 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: | 437 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: |
436 | PR_ERR("Received a SUPERVISOR PDU"); | 438 | pr_err("Received a SUPERVISOR PDU"); |
437 | rc = -EINVAL; | 439 | rc = -EINVAL; |
438 | goto exit; | 440 | goto exit; |
439 | break; | 441 | break; |
440 | } | 442 | } |
441 | 443 | ||
442 | skb_pull(resp, size); | 444 | skb_pull(resp, size); |
443 | 445 | ||
444 | rc = nfc_tm_data_received(ddev->nfc_dev, resp); | 446 | rc = nfc_tm_data_received(ddev->nfc_dev, resp); |
445 | 447 | ||
446 | exit: | 448 | exit: |
447 | if (rc) | 449 | if (rc) |
448 | kfree_skb(resp); | 450 | kfree_skb(resp); |
449 | } | 451 | } |
450 | 452 | ||
451 | int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb) | 453 | int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb) |
452 | { | 454 | { |
453 | struct digital_dep_req_res *dep_res; | 455 | struct digital_dep_req_res *dep_res; |
454 | 456 | ||
455 | skb_push(skb, sizeof(struct digital_dep_req_res)); | 457 | skb_push(skb, sizeof(struct digital_dep_req_res)); |
456 | dep_res = (struct digital_dep_req_res *)skb->data; | 458 | dep_res = (struct digital_dep_req_res *)skb->data; |
457 | 459 | ||
458 | dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; | 460 | dep_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; |
459 | dep_res->cmd = DIGITAL_CMD_DEP_RES; | 461 | dep_res->cmd = DIGITAL_CMD_DEP_RES; |
460 | dep_res->pfb = ddev->curr_nfc_dep_pni; | 462 | dep_res->pfb = ddev->curr_nfc_dep_pni; |
461 | 463 | ||
462 | digital_skb_push_dep_sod(ddev, skb); | 464 | digital_skb_push_dep_sod(ddev, skb); |
463 | 465 | ||
464 | ddev->skb_add_crc(skb); | 466 | ddev->skb_add_crc(skb); |
465 | 467 | ||
466 | return digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req, | 468 | return digital_tg_send_cmd(ddev, skb, 1500, digital_tg_recv_dep_req, |
467 | NULL); | 469 | NULL); |
468 | } | 470 | } |
469 | 471 | ||
470 | static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev, | 472 | static void digital_tg_send_psl_res_complete(struct nfc_digital_dev *ddev, |
471 | void *arg, struct sk_buff *resp) | 473 | void *arg, struct sk_buff *resp) |
472 | { | 474 | { |
473 | u8 rf_tech = PTR_ERR(arg); | 475 | u8 rf_tech = PTR_ERR(arg); |
474 | 476 | ||
475 | if (IS_ERR(resp)) | 477 | if (IS_ERR(resp)) |
476 | return; | 478 | return; |
477 | 479 | ||
478 | digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); | 480 | digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); |
479 | 481 | ||
480 | digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL); | 482 | digital_tg_listen(ddev, 1500, digital_tg_recv_dep_req, NULL); |
481 | 483 | ||
482 | dev_kfree_skb(resp); | 484 | dev_kfree_skb(resp); |
483 | } | 485 | } |
484 | 486 | ||
485 | static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did, | 487 | static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did, |
486 | u8 rf_tech) | 488 | u8 rf_tech) |
487 | { | 489 | { |
488 | struct digital_psl_res *psl_res; | 490 | struct digital_psl_res *psl_res; |
489 | struct sk_buff *skb; | 491 | struct sk_buff *skb; |
490 | int rc; | 492 | int rc; |
491 | 493 | ||
492 | skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res)); | 494 | skb = digital_skb_alloc(ddev, sizeof(struct digital_psl_res)); |
493 | if (!skb) | 495 | if (!skb) |
494 | return -ENOMEM; | 496 | return -ENOMEM; |
495 | 497 | ||
496 | skb_put(skb, sizeof(struct digital_psl_res)); | 498 | skb_put(skb, sizeof(struct digital_psl_res)); |
497 | 499 | ||
498 | psl_res = (struct digital_psl_res *)skb->data; | 500 | psl_res = (struct digital_psl_res *)skb->data; |
499 | 501 | ||
500 | psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; | 502 | psl_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; |
501 | psl_res->cmd = DIGITAL_CMD_PSL_RES; | 503 | psl_res->cmd = DIGITAL_CMD_PSL_RES; |
502 | psl_res->did = did; | 504 | psl_res->did = did; |
503 | 505 | ||
504 | digital_skb_push_dep_sod(ddev, skb); | 506 | digital_skb_push_dep_sod(ddev, skb); |
505 | 507 | ||
506 | ddev->skb_add_crc(skb); | 508 | ddev->skb_add_crc(skb); |
507 | 509 | ||
508 | rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete, | 510 | rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete, |
509 | ERR_PTR(rf_tech)); | 511 | ERR_PTR(rf_tech)); |
510 | 512 | ||
511 | if (rc) | 513 | if (rc) |
512 | kfree_skb(skb); | 514 | kfree_skb(skb); |
513 | 515 | ||
514 | return rc; | 516 | return rc; |
515 | } | 517 | } |
516 | 518 | ||
517 | static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg, | 519 | static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg, |
518 | struct sk_buff *resp) | 520 | struct sk_buff *resp) |
519 | { | 521 | { |
520 | int rc; | 522 | int rc; |
521 | struct digital_psl_req *psl_req; | 523 | struct digital_psl_req *psl_req; |
522 | u8 rf_tech; | 524 | u8 rf_tech; |
523 | u8 dsi; | 525 | u8 dsi; |
524 | 526 | ||
525 | if (IS_ERR(resp)) { | 527 | if (IS_ERR(resp)) { |
526 | rc = PTR_ERR(resp); | 528 | rc = PTR_ERR(resp); |
527 | resp = NULL; | 529 | resp = NULL; |
528 | goto exit; | 530 | goto exit; |
529 | } | 531 | } |
530 | 532 | ||
531 | rc = ddev->skb_check_crc(resp); | 533 | rc = ddev->skb_check_crc(resp); |
532 | if (rc) { | 534 | if (rc) { |
533 | PROTOCOL_ERR("14.4.1.6"); | 535 | PROTOCOL_ERR("14.4.1.6"); |
534 | goto exit; | 536 | goto exit; |
535 | } | 537 | } |
536 | 538 | ||
537 | rc = digital_skb_pull_dep_sod(ddev, resp); | 539 | rc = digital_skb_pull_dep_sod(ddev, resp); |
538 | if (rc) { | 540 | if (rc) { |
539 | PROTOCOL_ERR("14.4.1.2"); | 541 | PROTOCOL_ERR("14.4.1.2"); |
540 | goto exit; | 542 | goto exit; |
541 | } | 543 | } |
542 | 544 | ||
543 | psl_req = (struct digital_psl_req *)resp->data; | 545 | psl_req = (struct digital_psl_req *)resp->data; |
544 | 546 | ||
545 | if (resp->len != sizeof(struct digital_psl_req) || | 547 | if (resp->len != sizeof(struct digital_psl_req) || |
546 | psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT || | 548 | psl_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT || |
547 | psl_req->cmd != DIGITAL_CMD_PSL_REQ) { | 549 | psl_req->cmd != DIGITAL_CMD_PSL_REQ) { |
548 | rc = -EIO; | 550 | rc = -EIO; |
549 | goto exit; | 551 | goto exit; |
550 | } | 552 | } |
551 | 553 | ||
552 | dsi = (psl_req->brs >> 3) & 0x07; | 554 | dsi = (psl_req->brs >> 3) & 0x07; |
553 | switch (dsi) { | 555 | switch (dsi) { |
554 | case 0: | 556 | case 0: |
555 | rf_tech = NFC_DIGITAL_RF_TECH_106A; | 557 | rf_tech = NFC_DIGITAL_RF_TECH_106A; |
556 | break; | 558 | break; |
557 | case 1: | 559 | case 1: |
558 | rf_tech = NFC_DIGITAL_RF_TECH_212F; | 560 | rf_tech = NFC_DIGITAL_RF_TECH_212F; |
559 | break; | 561 | break; |
560 | case 2: | 562 | case 2: |
561 | rf_tech = NFC_DIGITAL_RF_TECH_424F; | 563 | rf_tech = NFC_DIGITAL_RF_TECH_424F; |
562 | break; | 564 | break; |
563 | default: | 565 | default: |
564 | PR_ERR("Unsuported dsi value %d", dsi); | 566 | pr_err("Unsuported dsi value %d", dsi); |
565 | goto exit; | 567 | goto exit; |
566 | } | 568 | } |
567 | 569 | ||
568 | rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech); | 570 | rc = digital_tg_send_psl_res(ddev, psl_req->did, rf_tech); |
569 | 571 | ||
570 | exit: | 572 | exit: |
571 | kfree_skb(resp); | 573 | kfree_skb(resp); |
572 | } | 574 | } |
573 | 575 | ||
574 | static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev, | 576 | static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev, |
575 | void *arg, struct sk_buff *resp) | 577 | void *arg, struct sk_buff *resp) |
576 | { | 578 | { |
577 | int offset; | 579 | int offset; |
578 | 580 | ||
579 | if (IS_ERR(resp)) { | 581 | if (IS_ERR(resp)) { |
580 | digital_poll_next_tech(ddev); | 582 | digital_poll_next_tech(ddev); |
581 | return; | 583 | return; |
582 | } | 584 | } |
583 | 585 | ||
584 | offset = 2; | 586 | offset = 2; |
585 | if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) | 587 | if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) |
586 | offset++; | 588 | offset++; |
587 | 589 | ||
588 | if (resp->data[offset] == DIGITAL_CMD_PSL_REQ) | 590 | if (resp->data[offset] == DIGITAL_CMD_PSL_REQ) |
589 | digital_tg_recv_psl_req(ddev, arg, resp); | 591 | digital_tg_recv_psl_req(ddev, arg, resp); |
590 | else | 592 | else |
591 | digital_tg_recv_dep_req(ddev, arg, resp); | 593 | digital_tg_recv_dep_req(ddev, arg, resp); |
592 | } | 594 | } |
593 | 595 | ||
594 | static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev, | 596 | static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev, |
595 | struct digital_atr_req *atr_req) | 597 | struct digital_atr_req *atr_req) |
596 | { | 598 | { |
597 | struct digital_atr_res *atr_res; | 599 | struct digital_atr_res *atr_res; |
598 | struct sk_buff *skb; | 600 | struct sk_buff *skb; |
599 | u8 *gb; | 601 | u8 *gb; |
600 | size_t gb_len; | 602 | size_t gb_len; |
601 | int rc; | 603 | int rc; |
602 | 604 | ||
603 | gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len); | 605 | gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len); |
604 | if (!gb) | 606 | if (!gb) |
605 | gb_len = 0; | 607 | gb_len = 0; |
606 | 608 | ||
607 | skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len); | 609 | skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len); |
608 | if (!skb) | 610 | if (!skb) |
609 | return -ENOMEM; | 611 | return -ENOMEM; |
610 | 612 | ||
611 | skb_put(skb, sizeof(struct digital_atr_res)); | 613 | skb_put(skb, sizeof(struct digital_atr_res)); |
612 | atr_res = (struct digital_atr_res *)skb->data; | 614 | atr_res = (struct digital_atr_res *)skb->data; |
613 | 615 | ||
614 | memset(atr_res, 0, sizeof(struct digital_atr_res)); | 616 | memset(atr_res, 0, sizeof(struct digital_atr_res)); |
615 | 617 | ||
616 | atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; | 618 | atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; |
617 | atr_res->cmd = DIGITAL_CMD_ATR_RES; | 619 | atr_res->cmd = DIGITAL_CMD_ATR_RES; |
618 | memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3)); | 620 | memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3)); |
619 | atr_res->to = 8; | 621 | atr_res->to = 8; |
620 | atr_res->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B; | 622 | atr_res->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B; |
621 | if (gb_len) { | 623 | if (gb_len) { |
622 | skb_put(skb, gb_len); | 624 | skb_put(skb, gb_len); |
623 | 625 | ||
624 | atr_res->pp |= DIGITAL_GB_BIT; | 626 | atr_res->pp |= DIGITAL_GB_BIT; |
625 | memcpy(atr_res->gb, gb, gb_len); | 627 | memcpy(atr_res->gb, gb, gb_len); |
626 | } | 628 | } |
627 | 629 | ||
628 | digital_skb_push_dep_sod(ddev, skb); | 630 | digital_skb_push_dep_sod(ddev, skb); |
629 | 631 | ||
630 | ddev->skb_add_crc(skb); | 632 | ddev->skb_add_crc(skb); |
631 | 633 | ||
632 | rc = digital_tg_send_cmd(ddev, skb, 999, | 634 | rc = digital_tg_send_cmd(ddev, skb, 999, |
633 | digital_tg_send_atr_res_complete, NULL); | 635 | digital_tg_send_atr_res_complete, NULL); |
634 | if (rc) { | 636 | if (rc) { |
635 | kfree_skb(skb); | 637 | kfree_skb(skb); |
636 | return rc; | 638 | return rc; |
637 | } | 639 | } |
638 | 640 | ||
639 | return rc; | 641 | return rc; |
640 | } | 642 | } |
641 | 643 | ||
642 | void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg, | 644 | void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg, |
643 | struct sk_buff *resp) | 645 | struct sk_buff *resp) |
644 | { | 646 | { |
645 | int rc; | 647 | int rc; |
646 | struct digital_atr_req *atr_req; | 648 | struct digital_atr_req *atr_req; |
647 | size_t gb_len, min_size; | 649 | size_t gb_len, min_size; |
648 | 650 | ||
649 | if (IS_ERR(resp)) { | 651 | if (IS_ERR(resp)) { |
650 | rc = PTR_ERR(resp); | 652 | rc = PTR_ERR(resp); |
651 | resp = NULL; | 653 | resp = NULL; |
652 | goto exit; | 654 | goto exit; |
653 | } | 655 | } |
654 | 656 | ||
655 | if (!resp->len) { | 657 | if (!resp->len) { |
656 | rc = -EIO; | 658 | rc = -EIO; |
657 | goto exit; | 659 | goto exit; |
658 | } | 660 | } |
659 | 661 | ||
660 | if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) { | 662 | if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) { |
661 | min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2; | 663 | min_size = DIGITAL_ATR_REQ_MIN_SIZE + 2; |
662 | 664 | ||
663 | ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_106A; | 665 | ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_106A; |
664 | ddev->skb_add_crc = digital_skb_add_crc_a; | 666 | ddev->skb_add_crc = digital_skb_add_crc_a; |
665 | ddev->skb_check_crc = digital_skb_check_crc_a; | 667 | ddev->skb_check_crc = digital_skb_check_crc_a; |
666 | } else { | 668 | } else { |
667 | min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1; | 669 | min_size = DIGITAL_ATR_REQ_MIN_SIZE + 1; |
668 | 670 | ||
669 | ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_212F; | 671 | ddev->curr_rf_tech = NFC_DIGITAL_RF_TECH_212F; |
670 | ddev->skb_add_crc = digital_skb_add_crc_f; | 672 | ddev->skb_add_crc = digital_skb_add_crc_f; |
671 | ddev->skb_check_crc = digital_skb_check_crc_f; | 673 | ddev->skb_check_crc = digital_skb_check_crc_f; |
672 | } | 674 | } |
673 | 675 | ||
674 | if (resp->len < min_size) { | 676 | if (resp->len < min_size) { |
675 | rc = -EIO; | 677 | rc = -EIO; |
676 | goto exit; | 678 | goto exit; |
677 | } | 679 | } |
678 | 680 | ||
679 | if (DIGITAL_DRV_CAPS_TG_CRC(ddev)) { | 681 | if (DIGITAL_DRV_CAPS_TG_CRC(ddev)) { |
680 | ddev->skb_add_crc = digital_skb_add_crc_none; | 682 | ddev->skb_add_crc = digital_skb_add_crc_none; |
681 | ddev->skb_check_crc = digital_skb_check_crc_none; | 683 | ddev->skb_check_crc = digital_skb_check_crc_none; |
682 | } | 684 | } |
683 | 685 | ||
684 | rc = ddev->skb_check_crc(resp); | 686 | rc = ddev->skb_check_crc(resp); |
685 | if (rc) { | 687 | if (rc) { |
686 | PROTOCOL_ERR("14.4.1.6"); | 688 | PROTOCOL_ERR("14.4.1.6"); |
687 | goto exit; | 689 | goto exit; |
688 | } | 690 | } |
689 | 691 | ||
690 | rc = digital_skb_pull_dep_sod(ddev, resp); | 692 | rc = digital_skb_pull_dep_sod(ddev, resp); |
691 | if (rc) { | 693 | if (rc) { |
692 | PROTOCOL_ERR("14.4.1.2"); | 694 | PROTOCOL_ERR("14.4.1.2"); |
693 | goto exit; | 695 | goto exit; |
694 | } | 696 | } |
695 | 697 | ||
696 | atr_req = (struct digital_atr_req *)resp->data; | 698 | atr_req = (struct digital_atr_req *)resp->data; |
697 | 699 | ||
698 | if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT || | 700 | if (atr_req->dir != DIGITAL_NFC_DEP_FRAME_DIR_OUT || |
699 | atr_req->cmd != DIGITAL_CMD_ATR_REQ) { | 701 | atr_req->cmd != DIGITAL_CMD_ATR_REQ) { |
700 | rc = -EINVAL; | 702 | rc = -EINVAL; |
701 | goto exit; | 703 | goto exit; |
702 | } | 704 | } |
703 | 705 | ||
704 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 706 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
705 | NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED); | 707 | NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED); |
706 | if (rc) | 708 | if (rc) |
707 | goto exit; | 709 | goto exit; |
708 | 710 | ||
709 | rc = digital_tg_send_atr_res(ddev, atr_req); | 711 | rc = digital_tg_send_atr_res(ddev, atr_req); |
710 | if (rc) | 712 | if (rc) |
711 | goto exit; | 713 | goto exit; |
712 | 714 | ||
713 | gb_len = resp->len - sizeof(struct digital_atr_req); | 715 | gb_len = resp->len - sizeof(struct digital_atr_req); |
714 | rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, | 716 | rc = nfc_tm_activated(ddev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, |
715 | NFC_COMM_PASSIVE, atr_req->gb, gb_len); | 717 | NFC_COMM_PASSIVE, atr_req->gb, gb_len); |
716 | if (rc) | 718 | if (rc) |
717 | goto exit; | 719 | goto exit; |
718 | 720 | ||
719 | ddev->poll_tech_count = 0; | 721 | ddev->poll_tech_count = 0; |
720 | 722 | ||
721 | rc = 0; | 723 | rc = 0; |
722 | exit: | 724 | exit: |
723 | if (rc) | 725 | if (rc) |
724 | digital_poll_next_tech(ddev); | 726 | digital_poll_next_tech(ddev); |
725 | 727 | ||
726 | dev_kfree_skb(resp); | 728 | dev_kfree_skb(resp); |
727 | } | 729 | } |
728 | 730 |
net/nfc/digital_technology.c
1 | /* | 1 | /* |
2 | * NFC Digital Protocol stack | 2 | * NFC Digital Protocol stack |
3 | * Copyright (c) 2013, Intel Corporation. | 3 | * Copyright (c) 2013, Intel Corporation. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | 9 | * This program is distributed in the hope it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) "digital: %s: " fmt, __func__ | ||
17 | |||
16 | #include "digital.h" | 18 | #include "digital.h" |
17 | 19 | ||
18 | #define DIGITAL_CMD_SENS_REQ 0x26 | 20 | #define DIGITAL_CMD_SENS_REQ 0x26 |
19 | #define DIGITAL_CMD_ALL_REQ 0x52 | 21 | #define DIGITAL_CMD_ALL_REQ 0x52 |
20 | #define DIGITAL_CMD_SEL_REQ_CL1 0x93 | 22 | #define DIGITAL_CMD_SEL_REQ_CL1 0x93 |
21 | #define DIGITAL_CMD_SEL_REQ_CL2 0x95 | 23 | #define DIGITAL_CMD_SEL_REQ_CL2 0x95 |
22 | #define DIGITAL_CMD_SEL_REQ_CL3 0x97 | 24 | #define DIGITAL_CMD_SEL_REQ_CL3 0x97 |
23 | 25 | ||
24 | #define DIGITAL_SDD_REQ_SEL_PAR 0x20 | 26 | #define DIGITAL_SDD_REQ_SEL_PAR 0x20 |
25 | 27 | ||
26 | #define DIGITAL_SDD_RES_CT 0x88 | 28 | #define DIGITAL_SDD_RES_CT 0x88 |
27 | #define DIGITAL_SDD_RES_LEN 5 | 29 | #define DIGITAL_SDD_RES_LEN 5 |
28 | 30 | ||
29 | #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) | 31 | #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) |
30 | #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) | 32 | #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) |
31 | #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) | 33 | #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) |
32 | 34 | ||
33 | #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x000C) == 0x000C) | 35 | #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x000C) == 0x000C) |
34 | #define DIGITAL_SENS_RES_IS_VALID(sens_res) \ | 36 | #define DIGITAL_SENS_RES_IS_VALID(sens_res) \ |
35 | ((!((sens_res) & 0x1F00) && (((sens_res) & 0x000C) == 0x000C)) || \ | 37 | ((!((sens_res) & 0x1F00) && (((sens_res) & 0x000C) == 0x000C)) || \ |
36 | (((sens_res) & 0x1F00) && ((sens_res) & 0x000C) != 0x000C)) | 38 | (((sens_res) & 0x1F00) && ((sens_res) & 0x000C) != 0x000C)) |
37 | 39 | ||
38 | #define DIGITAL_MIFARE_READ_RES_LEN 16 | 40 | #define DIGITAL_MIFARE_READ_RES_LEN 16 |
39 | #define DIGITAL_MIFARE_ACK_RES 0x0A | 41 | #define DIGITAL_MIFARE_ACK_RES 0x0A |
40 | 42 | ||
41 | #define DIGITAL_CMD_SENSF_REQ 0x00 | 43 | #define DIGITAL_CMD_SENSF_REQ 0x00 |
42 | #define DIGITAL_CMD_SENSF_RES 0x01 | 44 | #define DIGITAL_CMD_SENSF_RES 0x01 |
43 | 45 | ||
44 | #define DIGITAL_SENSF_RES_MIN_LENGTH 17 | 46 | #define DIGITAL_SENSF_RES_MIN_LENGTH 17 |
45 | #define DIGITAL_SENSF_RES_RD_AP_B1 0x00 | 47 | #define DIGITAL_SENSF_RES_RD_AP_B1 0x00 |
46 | #define DIGITAL_SENSF_RES_RD_AP_B2 0x8F | 48 | #define DIGITAL_SENSF_RES_RD_AP_B2 0x8F |
47 | 49 | ||
48 | #define DIGITAL_SENSF_REQ_RC_NONE 0 | 50 | #define DIGITAL_SENSF_REQ_RC_NONE 0 |
49 | #define DIGITAL_SENSF_REQ_RC_SC 1 | 51 | #define DIGITAL_SENSF_REQ_RC_SC 1 |
50 | #define DIGITAL_SENSF_REQ_RC_AP 2 | 52 | #define DIGITAL_SENSF_REQ_RC_AP 2 |
51 | 53 | ||
52 | struct digital_sdd_res { | 54 | struct digital_sdd_res { |
53 | u8 nfcid1[4]; | 55 | u8 nfcid1[4]; |
54 | u8 bcc; | 56 | u8 bcc; |
55 | } __packed; | 57 | } __packed; |
56 | 58 | ||
57 | struct digital_sel_req { | 59 | struct digital_sel_req { |
58 | u8 sel_cmd; | 60 | u8 sel_cmd; |
59 | u8 b2; | 61 | u8 b2; |
60 | u8 nfcid1[4]; | 62 | u8 nfcid1[4]; |
61 | u8 bcc; | 63 | u8 bcc; |
62 | } __packed; | 64 | } __packed; |
63 | 65 | ||
64 | struct digital_sensf_req { | 66 | struct digital_sensf_req { |
65 | u8 cmd; | 67 | u8 cmd; |
66 | u8 sc1; | 68 | u8 sc1; |
67 | u8 sc2; | 69 | u8 sc2; |
68 | u8 rc; | 70 | u8 rc; |
69 | u8 tsn; | 71 | u8 tsn; |
70 | } __packed; | 72 | } __packed; |
71 | 73 | ||
72 | struct digital_sensf_res { | 74 | struct digital_sensf_res { |
73 | u8 cmd; | 75 | u8 cmd; |
74 | u8 nfcid2[8]; | 76 | u8 nfcid2[8]; |
75 | u8 pad0[2]; | 77 | u8 pad0[2]; |
76 | u8 pad1[3]; | 78 | u8 pad1[3]; |
77 | u8 mrti_check; | 79 | u8 mrti_check; |
78 | u8 mrti_update; | 80 | u8 mrti_update; |
79 | u8 pad2; | 81 | u8 pad2; |
80 | u8 rd[2]; | 82 | u8 rd[2]; |
81 | } __packed; | 83 | } __packed; |
82 | 84 | ||
83 | static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, | 85 | static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, |
84 | struct nfc_target *target); | 86 | struct nfc_target *target); |
85 | 87 | ||
86 | static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, | 88 | static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, |
87 | struct sk_buff *resp) | 89 | struct sk_buff *resp) |
88 | { | 90 | { |
89 | struct nfc_target *target = arg; | 91 | struct nfc_target *target = arg; |
90 | int rc; | 92 | int rc; |
91 | u8 sel_res; | 93 | u8 sel_res; |
92 | u8 nfc_proto; | 94 | u8 nfc_proto; |
93 | 95 | ||
94 | if (IS_ERR(resp)) { | 96 | if (IS_ERR(resp)) { |
95 | rc = PTR_ERR(resp); | 97 | rc = PTR_ERR(resp); |
96 | resp = NULL; | 98 | resp = NULL; |
97 | goto exit; | 99 | goto exit; |
98 | } | 100 | } |
99 | 101 | ||
100 | if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) { | 102 | if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) { |
101 | rc = digital_skb_check_crc_a(resp); | 103 | rc = digital_skb_check_crc_a(resp); |
102 | if (rc) { | 104 | if (rc) { |
103 | PROTOCOL_ERR("4.4.1.3"); | 105 | PROTOCOL_ERR("4.4.1.3"); |
104 | goto exit; | 106 | goto exit; |
105 | } | 107 | } |
106 | } | 108 | } |
107 | 109 | ||
108 | if (!resp->len) { | 110 | if (!resp->len) { |
109 | rc = -EIO; | 111 | rc = -EIO; |
110 | goto exit; | 112 | goto exit; |
111 | } | 113 | } |
112 | 114 | ||
113 | sel_res = resp->data[0]; | 115 | sel_res = resp->data[0]; |
114 | 116 | ||
115 | if (!DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res)) { | 117 | if (!DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res)) { |
116 | rc = digital_in_send_sdd_req(ddev, target); | 118 | rc = digital_in_send_sdd_req(ddev, target); |
117 | if (rc) | 119 | if (rc) |
118 | goto exit; | 120 | goto exit; |
119 | 121 | ||
120 | goto exit_free_skb; | 122 | goto exit_free_skb; |
121 | } | 123 | } |
122 | 124 | ||
123 | if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { | 125 | if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { |
124 | nfc_proto = NFC_PROTO_MIFARE; | 126 | nfc_proto = NFC_PROTO_MIFARE; |
125 | } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { | 127 | } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { |
126 | nfc_proto = NFC_PROTO_NFC_DEP; | 128 | nfc_proto = NFC_PROTO_NFC_DEP; |
127 | } else { | 129 | } else { |
128 | rc = -EOPNOTSUPP; | 130 | rc = -EOPNOTSUPP; |
129 | goto exit; | 131 | goto exit; |
130 | } | 132 | } |
131 | 133 | ||
132 | target->sel_res = sel_res; | 134 | target->sel_res = sel_res; |
133 | 135 | ||
134 | rc = digital_target_found(ddev, target, nfc_proto); | 136 | rc = digital_target_found(ddev, target, nfc_proto); |
135 | 137 | ||
136 | exit: | 138 | exit: |
137 | kfree(target); | 139 | kfree(target); |
138 | 140 | ||
139 | exit_free_skb: | 141 | exit_free_skb: |
140 | dev_kfree_skb(resp); | 142 | dev_kfree_skb(resp); |
141 | 143 | ||
142 | if (rc) | 144 | if (rc) |
143 | digital_poll_next_tech(ddev); | 145 | digital_poll_next_tech(ddev); |
144 | } | 146 | } |
145 | 147 | ||
146 | static int digital_in_send_sel_req(struct nfc_digital_dev *ddev, | 148 | static int digital_in_send_sel_req(struct nfc_digital_dev *ddev, |
147 | struct nfc_target *target, | 149 | struct nfc_target *target, |
148 | struct digital_sdd_res *sdd_res) | 150 | struct digital_sdd_res *sdd_res) |
149 | { | 151 | { |
150 | struct sk_buff *skb; | 152 | struct sk_buff *skb; |
151 | struct digital_sel_req *sel_req; | 153 | struct digital_sel_req *sel_req; |
152 | u8 sel_cmd; | 154 | u8 sel_cmd; |
153 | int rc; | 155 | int rc; |
154 | 156 | ||
155 | skb = digital_skb_alloc(ddev, sizeof(struct digital_sel_req)); | 157 | skb = digital_skb_alloc(ddev, sizeof(struct digital_sel_req)); |
156 | if (!skb) | 158 | if (!skb) |
157 | return -ENOMEM; | 159 | return -ENOMEM; |
158 | 160 | ||
159 | skb_put(skb, sizeof(struct digital_sel_req)); | 161 | skb_put(skb, sizeof(struct digital_sel_req)); |
160 | sel_req = (struct digital_sel_req *)skb->data; | 162 | sel_req = (struct digital_sel_req *)skb->data; |
161 | 163 | ||
162 | if (target->nfcid1_len <= 4) | 164 | if (target->nfcid1_len <= 4) |
163 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL1; | 165 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL1; |
164 | else if (target->nfcid1_len < 10) | 166 | else if (target->nfcid1_len < 10) |
165 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL2; | 167 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL2; |
166 | else | 168 | else |
167 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL3; | 169 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL3; |
168 | 170 | ||
169 | sel_req->sel_cmd = sel_cmd; | 171 | sel_req->sel_cmd = sel_cmd; |
170 | sel_req->b2 = 0x70; | 172 | sel_req->b2 = 0x70; |
171 | memcpy(sel_req->nfcid1, sdd_res->nfcid1, 4); | 173 | memcpy(sel_req->nfcid1, sdd_res->nfcid1, 4); |
172 | sel_req->bcc = sdd_res->bcc; | 174 | sel_req->bcc = sdd_res->bcc; |
173 | 175 | ||
174 | if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) { | 176 | if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) { |
175 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 177 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
176 | NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A); | 178 | NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A); |
177 | if (rc) | 179 | if (rc) |
178 | goto exit; | 180 | goto exit; |
179 | } else { | 181 | } else { |
180 | digital_skb_add_crc_a(skb); | 182 | digital_skb_add_crc_a(skb); |
181 | } | 183 | } |
182 | 184 | ||
183 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sel_res, | 185 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sel_res, |
184 | target); | 186 | target); |
185 | exit: | 187 | exit: |
186 | if (rc) | 188 | if (rc) |
187 | kfree_skb(skb); | 189 | kfree_skb(skb); |
188 | 190 | ||
189 | return rc; | 191 | return rc; |
190 | } | 192 | } |
191 | 193 | ||
192 | static void digital_in_recv_sdd_res(struct nfc_digital_dev *ddev, void *arg, | 194 | static void digital_in_recv_sdd_res(struct nfc_digital_dev *ddev, void *arg, |
193 | struct sk_buff *resp) | 195 | struct sk_buff *resp) |
194 | { | 196 | { |
195 | struct nfc_target *target = arg; | 197 | struct nfc_target *target = arg; |
196 | struct digital_sdd_res *sdd_res; | 198 | struct digital_sdd_res *sdd_res; |
197 | int rc; | 199 | int rc; |
198 | u8 offset, size; | 200 | u8 offset, size; |
199 | u8 i, bcc; | 201 | u8 i, bcc; |
200 | 202 | ||
201 | if (IS_ERR(resp)) { | 203 | if (IS_ERR(resp)) { |
202 | rc = PTR_ERR(resp); | 204 | rc = PTR_ERR(resp); |
203 | resp = NULL; | 205 | resp = NULL; |
204 | goto exit; | 206 | goto exit; |
205 | } | 207 | } |
206 | 208 | ||
207 | if (resp->len < DIGITAL_SDD_RES_LEN) { | 209 | if (resp->len < DIGITAL_SDD_RES_LEN) { |
208 | PROTOCOL_ERR("4.7.2.8"); | 210 | PROTOCOL_ERR("4.7.2.8"); |
209 | rc = -EINVAL; | 211 | rc = -EINVAL; |
210 | goto exit; | 212 | goto exit; |
211 | } | 213 | } |
212 | 214 | ||
213 | sdd_res = (struct digital_sdd_res *)resp->data; | 215 | sdd_res = (struct digital_sdd_res *)resp->data; |
214 | 216 | ||
215 | for (i = 0, bcc = 0; i < 4; i++) | 217 | for (i = 0, bcc = 0; i < 4; i++) |
216 | bcc ^= sdd_res->nfcid1[i]; | 218 | bcc ^= sdd_res->nfcid1[i]; |
217 | 219 | ||
218 | if (bcc != sdd_res->bcc) { | 220 | if (bcc != sdd_res->bcc) { |
219 | PROTOCOL_ERR("4.7.2.6"); | 221 | PROTOCOL_ERR("4.7.2.6"); |
220 | rc = -EINVAL; | 222 | rc = -EINVAL; |
221 | goto exit; | 223 | goto exit; |
222 | } | 224 | } |
223 | 225 | ||
224 | if (sdd_res->nfcid1[0] == DIGITAL_SDD_RES_CT) { | 226 | if (sdd_res->nfcid1[0] == DIGITAL_SDD_RES_CT) { |
225 | offset = 1; | 227 | offset = 1; |
226 | size = 3; | 228 | size = 3; |
227 | } else { | 229 | } else { |
228 | offset = 0; | 230 | offset = 0; |
229 | size = 4; | 231 | size = 4; |
230 | } | 232 | } |
231 | 233 | ||
232 | memcpy(target->nfcid1 + target->nfcid1_len, sdd_res->nfcid1 + offset, | 234 | memcpy(target->nfcid1 + target->nfcid1_len, sdd_res->nfcid1 + offset, |
233 | size); | 235 | size); |
234 | target->nfcid1_len += size; | 236 | target->nfcid1_len += size; |
235 | 237 | ||
236 | rc = digital_in_send_sel_req(ddev, target, sdd_res); | 238 | rc = digital_in_send_sel_req(ddev, target, sdd_res); |
237 | 239 | ||
238 | exit: | 240 | exit: |
239 | dev_kfree_skb(resp); | 241 | dev_kfree_skb(resp); |
240 | 242 | ||
241 | if (rc) { | 243 | if (rc) { |
242 | kfree(target); | 244 | kfree(target); |
243 | digital_poll_next_tech(ddev); | 245 | digital_poll_next_tech(ddev); |
244 | } | 246 | } |
245 | } | 247 | } |
246 | 248 | ||
247 | static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, | 249 | static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, |
248 | struct nfc_target *target) | 250 | struct nfc_target *target) |
249 | { | 251 | { |
250 | int rc; | 252 | int rc; |
251 | struct sk_buff *skb; | 253 | struct sk_buff *skb; |
252 | u8 sel_cmd; | 254 | u8 sel_cmd; |
253 | 255 | ||
254 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 256 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
255 | NFC_DIGITAL_FRAMING_NFCA_STANDARD); | 257 | NFC_DIGITAL_FRAMING_NFCA_STANDARD); |
256 | if (rc) | 258 | if (rc) |
257 | return rc; | 259 | return rc; |
258 | 260 | ||
259 | skb = digital_skb_alloc(ddev, 2); | 261 | skb = digital_skb_alloc(ddev, 2); |
260 | if (!skb) { | 262 | if (!skb) { |
261 | PR_ERR("alloc_skb failed"); | 263 | pr_err("alloc_skb failed"); |
262 | return -ENOMEM; | 264 | return -ENOMEM; |
263 | } | 265 | } |
264 | 266 | ||
265 | if (target->nfcid1_len == 0) | 267 | if (target->nfcid1_len == 0) |
266 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL1; | 268 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL1; |
267 | else if (target->nfcid1_len == 3) | 269 | else if (target->nfcid1_len == 3) |
268 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL2; | 270 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL2; |
269 | else | 271 | else |
270 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL3; | 272 | sel_cmd = DIGITAL_CMD_SEL_REQ_CL3; |
271 | 273 | ||
272 | *skb_put(skb, sizeof(u8)) = sel_cmd; | 274 | *skb_put(skb, sizeof(u8)) = sel_cmd; |
273 | *skb_put(skb, sizeof(u8)) = DIGITAL_SDD_REQ_SEL_PAR; | 275 | *skb_put(skb, sizeof(u8)) = DIGITAL_SDD_REQ_SEL_PAR; |
274 | 276 | ||
275 | return digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res, | 277 | return digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res, |
276 | target); | 278 | target); |
277 | } | 279 | } |
278 | 280 | ||
279 | static void digital_in_recv_sens_res(struct nfc_digital_dev *ddev, void *arg, | 281 | static void digital_in_recv_sens_res(struct nfc_digital_dev *ddev, void *arg, |
280 | struct sk_buff *resp) | 282 | struct sk_buff *resp) |
281 | { | 283 | { |
282 | struct nfc_target *target = NULL; | 284 | struct nfc_target *target = NULL; |
283 | u16 sens_res; | 285 | u16 sens_res; |
284 | int rc; | 286 | int rc; |
285 | 287 | ||
286 | if (IS_ERR(resp)) { | 288 | if (IS_ERR(resp)) { |
287 | rc = PTR_ERR(resp); | 289 | rc = PTR_ERR(resp); |
288 | resp = NULL; | 290 | resp = NULL; |
289 | goto exit; | 291 | goto exit; |
290 | } | 292 | } |
291 | 293 | ||
292 | if (resp->len < sizeof(u16)) { | 294 | if (resp->len < sizeof(u16)) { |
293 | rc = -EIO; | 295 | rc = -EIO; |
294 | goto exit; | 296 | goto exit; |
295 | } | 297 | } |
296 | 298 | ||
297 | target = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); | 299 | target = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); |
298 | if (!target) { | 300 | if (!target) { |
299 | rc = -ENOMEM; | 301 | rc = -ENOMEM; |
300 | goto exit; | 302 | goto exit; |
301 | } | 303 | } |
302 | 304 | ||
303 | memcpy(&target->sens_res, resp->data, sizeof(u16)); | 305 | memcpy(&target->sens_res, resp->data, sizeof(u16)); |
304 | 306 | ||
305 | sens_res = be16_to_cpu(target->sens_res); | 307 | sens_res = be16_to_cpu(target->sens_res); |
306 | 308 | ||
307 | if (!DIGITAL_SENS_RES_IS_VALID(sens_res)) { | 309 | if (!DIGITAL_SENS_RES_IS_VALID(sens_res)) { |
308 | PROTOCOL_ERR("4.6.3.3"); | 310 | PROTOCOL_ERR("4.6.3.3"); |
309 | rc = -EINVAL; | 311 | rc = -EINVAL; |
310 | goto exit; | 312 | goto exit; |
311 | } | 313 | } |
312 | 314 | ||
313 | if (DIGITAL_SENS_RES_IS_T1T(sens_res)) | 315 | if (DIGITAL_SENS_RES_IS_T1T(sens_res)) |
314 | rc = digital_target_found(ddev, target, NFC_PROTO_JEWEL); | 316 | rc = digital_target_found(ddev, target, NFC_PROTO_JEWEL); |
315 | else | 317 | else |
316 | rc = digital_in_send_sdd_req(ddev, target); | 318 | rc = digital_in_send_sdd_req(ddev, target); |
317 | 319 | ||
318 | exit: | 320 | exit: |
319 | dev_kfree_skb(resp); | 321 | dev_kfree_skb(resp); |
320 | 322 | ||
321 | if (rc) { | 323 | if (rc) { |
322 | kfree(target); | 324 | kfree(target); |
323 | digital_poll_next_tech(ddev); | 325 | digital_poll_next_tech(ddev); |
324 | } | 326 | } |
325 | } | 327 | } |
326 | 328 | ||
327 | int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech) | 329 | int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech) |
328 | { | 330 | { |
329 | struct sk_buff *skb; | 331 | struct sk_buff *skb; |
330 | int rc; | 332 | int rc; |
331 | 333 | ||
332 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, | 334 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, |
333 | NFC_DIGITAL_RF_TECH_106A); | 335 | NFC_DIGITAL_RF_TECH_106A); |
334 | if (rc) | 336 | if (rc) |
335 | return rc; | 337 | return rc; |
336 | 338 | ||
337 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 339 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
338 | NFC_DIGITAL_FRAMING_NFCA_SHORT); | 340 | NFC_DIGITAL_FRAMING_NFCA_SHORT); |
339 | if (rc) | 341 | if (rc) |
340 | return rc; | 342 | return rc; |
341 | 343 | ||
342 | skb = digital_skb_alloc(ddev, 1); | 344 | skb = digital_skb_alloc(ddev, 1); |
343 | if (!skb) | 345 | if (!skb) |
344 | return -ENOMEM; | 346 | return -ENOMEM; |
345 | 347 | ||
346 | *skb_put(skb, sizeof(u8)) = DIGITAL_CMD_SENS_REQ; | 348 | *skb_put(skb, sizeof(u8)) = DIGITAL_CMD_SENS_REQ; |
347 | 349 | ||
348 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sens_res, NULL); | 350 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sens_res, NULL); |
349 | if (rc) | 351 | if (rc) |
350 | kfree_skb(skb); | 352 | kfree_skb(skb); |
351 | 353 | ||
352 | return rc; | 354 | return rc; |
353 | } | 355 | } |
354 | 356 | ||
355 | int digital_in_recv_mifare_res(struct sk_buff *resp) | 357 | int digital_in_recv_mifare_res(struct sk_buff *resp) |
356 | { | 358 | { |
357 | /* Successful READ command response is 16 data bytes + 2 CRC bytes long. | 359 | /* Successful READ command response is 16 data bytes + 2 CRC bytes long. |
358 | * Since the driver can't differentiate a ACK/NACK response from a valid | 360 | * Since the driver can't differentiate a ACK/NACK response from a valid |
359 | * READ response, the CRC calculation must be handled at digital level | 361 | * READ response, the CRC calculation must be handled at digital level |
360 | * even if the driver supports it for this technology. | 362 | * even if the driver supports it for this technology. |
361 | */ | 363 | */ |
362 | if (resp->len == DIGITAL_MIFARE_READ_RES_LEN + DIGITAL_CRC_LEN) { | 364 | if (resp->len == DIGITAL_MIFARE_READ_RES_LEN + DIGITAL_CRC_LEN) { |
363 | if (digital_skb_check_crc_a(resp)) { | 365 | if (digital_skb_check_crc_a(resp)) { |
364 | PROTOCOL_ERR("9.4.1.2"); | 366 | PROTOCOL_ERR("9.4.1.2"); |
365 | return -EIO; | 367 | return -EIO; |
366 | } | 368 | } |
367 | 369 | ||
368 | return 0; | 370 | return 0; |
369 | } | 371 | } |
370 | 372 | ||
371 | /* ACK response (i.e. successful WRITE). */ | 373 | /* ACK response (i.e. successful WRITE). */ |
372 | if (resp->len == 1 && resp->data[0] == DIGITAL_MIFARE_ACK_RES) { | 374 | if (resp->len == 1 && resp->data[0] == DIGITAL_MIFARE_ACK_RES) { |
373 | resp->data[0] = 0; | 375 | resp->data[0] = 0; |
374 | return 0; | 376 | return 0; |
375 | } | 377 | } |
376 | 378 | ||
377 | /* NACK and any other responses are treated as error. */ | 379 | /* NACK and any other responses are treated as error. */ |
378 | return -EIO; | 380 | return -EIO; |
379 | } | 381 | } |
380 | 382 | ||
381 | static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg, | 383 | static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg, |
382 | struct sk_buff *resp) | 384 | struct sk_buff *resp) |
383 | { | 385 | { |
384 | int rc; | 386 | int rc; |
385 | u8 proto; | 387 | u8 proto; |
386 | struct nfc_target target; | 388 | struct nfc_target target; |
387 | struct digital_sensf_res *sensf_res; | 389 | struct digital_sensf_res *sensf_res; |
388 | 390 | ||
389 | if (IS_ERR(resp)) { | 391 | if (IS_ERR(resp)) { |
390 | rc = PTR_ERR(resp); | 392 | rc = PTR_ERR(resp); |
391 | resp = NULL; | 393 | resp = NULL; |
392 | goto exit; | 394 | goto exit; |
393 | } | 395 | } |
394 | 396 | ||
395 | if (resp->len < DIGITAL_SENSF_RES_MIN_LENGTH) { | 397 | if (resp->len < DIGITAL_SENSF_RES_MIN_LENGTH) { |
396 | rc = -EIO; | 398 | rc = -EIO; |
397 | goto exit; | 399 | goto exit; |
398 | } | 400 | } |
399 | 401 | ||
400 | if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) { | 402 | if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) { |
401 | rc = digital_skb_check_crc_f(resp); | 403 | rc = digital_skb_check_crc_f(resp); |
402 | if (rc) { | 404 | if (rc) { |
403 | PROTOCOL_ERR("6.4.1.8"); | 405 | PROTOCOL_ERR("6.4.1.8"); |
404 | goto exit; | 406 | goto exit; |
405 | } | 407 | } |
406 | } | 408 | } |
407 | 409 | ||
408 | skb_pull(resp, 1); | 410 | skb_pull(resp, 1); |
409 | 411 | ||
410 | memset(&target, 0, sizeof(struct nfc_target)); | 412 | memset(&target, 0, sizeof(struct nfc_target)); |
411 | 413 | ||
412 | sensf_res = (struct digital_sensf_res *)resp->data; | 414 | sensf_res = (struct digital_sensf_res *)resp->data; |
413 | 415 | ||
414 | memcpy(target.sensf_res, sensf_res, resp->len); | 416 | memcpy(target.sensf_res, sensf_res, resp->len); |
415 | target.sensf_res_len = resp->len; | 417 | target.sensf_res_len = resp->len; |
416 | 418 | ||
417 | memcpy(target.nfcid2, sensf_res->nfcid2, NFC_NFCID2_MAXSIZE); | 419 | memcpy(target.nfcid2, sensf_res->nfcid2, NFC_NFCID2_MAXSIZE); |
418 | target.nfcid2_len = NFC_NFCID2_MAXSIZE; | 420 | target.nfcid2_len = NFC_NFCID2_MAXSIZE; |
419 | 421 | ||
420 | if (target.nfcid2[0] == DIGITAL_SENSF_NFCID2_NFC_DEP_B1 && | 422 | if (target.nfcid2[0] == DIGITAL_SENSF_NFCID2_NFC_DEP_B1 && |
421 | target.nfcid2[1] == DIGITAL_SENSF_NFCID2_NFC_DEP_B2) | 423 | target.nfcid2[1] == DIGITAL_SENSF_NFCID2_NFC_DEP_B2) |
422 | proto = NFC_PROTO_NFC_DEP; | 424 | proto = NFC_PROTO_NFC_DEP; |
423 | else | 425 | else |
424 | proto = NFC_PROTO_FELICA; | 426 | proto = NFC_PROTO_FELICA; |
425 | 427 | ||
426 | rc = digital_target_found(ddev, &target, proto); | 428 | rc = digital_target_found(ddev, &target, proto); |
427 | 429 | ||
428 | exit: | 430 | exit: |
429 | dev_kfree_skb(resp); | 431 | dev_kfree_skb(resp); |
430 | 432 | ||
431 | if (rc) | 433 | if (rc) |
432 | digital_poll_next_tech(ddev); | 434 | digital_poll_next_tech(ddev); |
433 | } | 435 | } |
434 | 436 | ||
435 | int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech) | 437 | int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech) |
436 | { | 438 | { |
437 | struct digital_sensf_req *sensf_req; | 439 | struct digital_sensf_req *sensf_req; |
438 | struct sk_buff *skb; | 440 | struct sk_buff *skb; |
439 | int rc; | 441 | int rc; |
440 | u8 size; | 442 | u8 size; |
441 | 443 | ||
442 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); | 444 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); |
443 | if (rc) | 445 | if (rc) |
444 | return rc; | 446 | return rc; |
445 | 447 | ||
446 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 448 | rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
447 | NFC_DIGITAL_FRAMING_NFCF); | 449 | NFC_DIGITAL_FRAMING_NFCF); |
448 | if (rc) | 450 | if (rc) |
449 | return rc; | 451 | return rc; |
450 | 452 | ||
451 | size = sizeof(struct digital_sensf_req); | 453 | size = sizeof(struct digital_sensf_req); |
452 | 454 | ||
453 | skb = digital_skb_alloc(ddev, size); | 455 | skb = digital_skb_alloc(ddev, size); |
454 | if (!skb) | 456 | if (!skb) |
455 | return -ENOMEM; | 457 | return -ENOMEM; |
456 | 458 | ||
457 | skb_put(skb, size); | 459 | skb_put(skb, size); |
458 | 460 | ||
459 | sensf_req = (struct digital_sensf_req *)skb->data; | 461 | sensf_req = (struct digital_sensf_req *)skb->data; |
460 | sensf_req->cmd = DIGITAL_CMD_SENSF_REQ; | 462 | sensf_req->cmd = DIGITAL_CMD_SENSF_REQ; |
461 | sensf_req->sc1 = 0xFF; | 463 | sensf_req->sc1 = 0xFF; |
462 | sensf_req->sc2 = 0xFF; | 464 | sensf_req->sc2 = 0xFF; |
463 | sensf_req->rc = 0; | 465 | sensf_req->rc = 0; |
464 | sensf_req->tsn = 0; | 466 | sensf_req->tsn = 0; |
465 | 467 | ||
466 | *skb_push(skb, 1) = size + 1; | 468 | *skb_push(skb, 1) = size + 1; |
467 | 469 | ||
468 | if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) | 470 | if (!DIGITAL_DRV_CAPS_IN_CRC(ddev)) |
469 | digital_skb_add_crc_f(skb); | 471 | digital_skb_add_crc_f(skb); |
470 | 472 | ||
471 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sensf_res, | 473 | rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sensf_res, |
472 | NULL); | 474 | NULL); |
473 | if (rc) | 475 | if (rc) |
474 | kfree_skb(skb); | 476 | kfree_skb(skb); |
475 | 477 | ||
476 | return rc; | 478 | return rc; |
477 | } | 479 | } |
478 | 480 | ||
479 | static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev) | 481 | static int digital_tg_send_sel_res(struct nfc_digital_dev *ddev) |
480 | { | 482 | { |
481 | struct sk_buff *skb; | 483 | struct sk_buff *skb; |
482 | int rc; | 484 | int rc; |
483 | 485 | ||
484 | skb = digital_skb_alloc(ddev, 1); | 486 | skb = digital_skb_alloc(ddev, 1); |
485 | if (!skb) | 487 | if (!skb) |
486 | return -ENOMEM; | 488 | return -ENOMEM; |
487 | 489 | ||
488 | *skb_put(skb, 1) = DIGITAL_SEL_RES_NFC_DEP; | 490 | *skb_put(skb, 1) = DIGITAL_SEL_RES_NFC_DEP; |
489 | 491 | ||
490 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) | 492 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) |
491 | digital_skb_add_crc_a(skb); | 493 | digital_skb_add_crc_a(skb); |
492 | 494 | ||
493 | rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_atr_req, | 495 | rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_atr_req, |
494 | NULL); | 496 | NULL); |
495 | if (rc) | 497 | if (rc) |
496 | kfree_skb(skb); | 498 | kfree_skb(skb); |
497 | 499 | ||
498 | return rc; | 500 | return rc; |
499 | } | 501 | } |
500 | 502 | ||
501 | static void digital_tg_recv_sel_req(struct nfc_digital_dev *ddev, void *arg, | 503 | static void digital_tg_recv_sel_req(struct nfc_digital_dev *ddev, void *arg, |
502 | struct sk_buff *resp) | 504 | struct sk_buff *resp) |
503 | { | 505 | { |
504 | int rc; | 506 | int rc; |
505 | 507 | ||
506 | if (IS_ERR(resp)) { | 508 | if (IS_ERR(resp)) { |
507 | rc = PTR_ERR(resp); | 509 | rc = PTR_ERR(resp); |
508 | resp = NULL; | 510 | resp = NULL; |
509 | goto exit; | 511 | goto exit; |
510 | } | 512 | } |
511 | 513 | ||
512 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) { | 514 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) { |
513 | rc = digital_skb_check_crc_a(resp); | 515 | rc = digital_skb_check_crc_a(resp); |
514 | if (rc) { | 516 | if (rc) { |
515 | PROTOCOL_ERR("4.4.1.3"); | 517 | PROTOCOL_ERR("4.4.1.3"); |
516 | goto exit; | 518 | goto exit; |
517 | } | 519 | } |
518 | } | 520 | } |
519 | 521 | ||
520 | /* Silently ignore SEL_REQ content and send a SEL_RES for NFC-DEP */ | 522 | /* Silently ignore SEL_REQ content and send a SEL_RES for NFC-DEP */ |
521 | 523 | ||
522 | rc = digital_tg_send_sel_res(ddev); | 524 | rc = digital_tg_send_sel_res(ddev); |
523 | 525 | ||
524 | exit: | 526 | exit: |
525 | if (rc) | 527 | if (rc) |
526 | digital_poll_next_tech(ddev); | 528 | digital_poll_next_tech(ddev); |
527 | 529 | ||
528 | dev_kfree_skb(resp); | 530 | dev_kfree_skb(resp); |
529 | } | 531 | } |
530 | 532 | ||
531 | static int digital_tg_send_sdd_res(struct nfc_digital_dev *ddev) | 533 | static int digital_tg_send_sdd_res(struct nfc_digital_dev *ddev) |
532 | { | 534 | { |
533 | struct sk_buff *skb; | 535 | struct sk_buff *skb; |
534 | struct digital_sdd_res *sdd_res; | 536 | struct digital_sdd_res *sdd_res; |
535 | int rc, i; | 537 | int rc, i; |
536 | 538 | ||
537 | skb = digital_skb_alloc(ddev, sizeof(struct digital_sdd_res)); | 539 | skb = digital_skb_alloc(ddev, sizeof(struct digital_sdd_res)); |
538 | if (!skb) | 540 | if (!skb) |
539 | return -ENOMEM; | 541 | return -ENOMEM; |
540 | 542 | ||
541 | skb_put(skb, sizeof(struct digital_sdd_res)); | 543 | skb_put(skb, sizeof(struct digital_sdd_res)); |
542 | sdd_res = (struct digital_sdd_res *)skb->data; | 544 | sdd_res = (struct digital_sdd_res *)skb->data; |
543 | 545 | ||
544 | sdd_res->nfcid1[0] = 0x08; | 546 | sdd_res->nfcid1[0] = 0x08; |
545 | get_random_bytes(sdd_res->nfcid1 + 1, 3); | 547 | get_random_bytes(sdd_res->nfcid1 + 1, 3); |
546 | 548 | ||
547 | sdd_res->bcc = 0; | 549 | sdd_res->bcc = 0; |
548 | for (i = 0; i < 4; i++) | 550 | for (i = 0; i < 4; i++) |
549 | sdd_res->bcc ^= sdd_res->nfcid1[i]; | 551 | sdd_res->bcc ^= sdd_res->nfcid1[i]; |
550 | 552 | ||
551 | rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_sel_req, | 553 | rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_sel_req, |
552 | NULL); | 554 | NULL); |
553 | if (rc) | 555 | if (rc) |
554 | kfree_skb(skb); | 556 | kfree_skb(skb); |
555 | 557 | ||
556 | return rc; | 558 | return rc; |
557 | } | 559 | } |
558 | 560 | ||
559 | static void digital_tg_recv_sdd_req(struct nfc_digital_dev *ddev, void *arg, | 561 | static void digital_tg_recv_sdd_req(struct nfc_digital_dev *ddev, void *arg, |
560 | struct sk_buff *resp) | 562 | struct sk_buff *resp) |
561 | { | 563 | { |
562 | u8 *sdd_req; | 564 | u8 *sdd_req; |
563 | int rc; | 565 | int rc; |
564 | 566 | ||
565 | if (IS_ERR(resp)) { | 567 | if (IS_ERR(resp)) { |
566 | rc = PTR_ERR(resp); | 568 | rc = PTR_ERR(resp); |
567 | resp = NULL; | 569 | resp = NULL; |
568 | goto exit; | 570 | goto exit; |
569 | } | 571 | } |
570 | 572 | ||
571 | sdd_req = resp->data; | 573 | sdd_req = resp->data; |
572 | 574 | ||
573 | if (resp->len < 2 || sdd_req[0] != DIGITAL_CMD_SEL_REQ_CL1 || | 575 | if (resp->len < 2 || sdd_req[0] != DIGITAL_CMD_SEL_REQ_CL1 || |
574 | sdd_req[1] != DIGITAL_SDD_REQ_SEL_PAR) { | 576 | sdd_req[1] != DIGITAL_SDD_REQ_SEL_PAR) { |
575 | rc = -EINVAL; | 577 | rc = -EINVAL; |
576 | goto exit; | 578 | goto exit; |
577 | } | 579 | } |
578 | 580 | ||
579 | rc = digital_tg_send_sdd_res(ddev); | 581 | rc = digital_tg_send_sdd_res(ddev); |
580 | 582 | ||
581 | exit: | 583 | exit: |
582 | if (rc) | 584 | if (rc) |
583 | digital_poll_next_tech(ddev); | 585 | digital_poll_next_tech(ddev); |
584 | 586 | ||
585 | dev_kfree_skb(resp); | 587 | dev_kfree_skb(resp); |
586 | } | 588 | } |
587 | 589 | ||
588 | static int digital_tg_send_sens_res(struct nfc_digital_dev *ddev) | 590 | static int digital_tg_send_sens_res(struct nfc_digital_dev *ddev) |
589 | { | 591 | { |
590 | struct sk_buff *skb; | 592 | struct sk_buff *skb; |
591 | u8 *sens_res; | 593 | u8 *sens_res; |
592 | int rc; | 594 | int rc; |
593 | 595 | ||
594 | skb = digital_skb_alloc(ddev, 2); | 596 | skb = digital_skb_alloc(ddev, 2); |
595 | if (!skb) | 597 | if (!skb) |
596 | return -ENOMEM; | 598 | return -ENOMEM; |
597 | 599 | ||
598 | sens_res = skb_put(skb, 2); | 600 | sens_res = skb_put(skb, 2); |
599 | 601 | ||
600 | sens_res[0] = (DIGITAL_SENS_RES_NFC_DEP >> 8) & 0xFF; | 602 | sens_res[0] = (DIGITAL_SENS_RES_NFC_DEP >> 8) & 0xFF; |
601 | sens_res[1] = DIGITAL_SENS_RES_NFC_DEP & 0xFF; | 603 | sens_res[1] = DIGITAL_SENS_RES_NFC_DEP & 0xFF; |
602 | 604 | ||
603 | rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_sdd_req, | 605 | rc = digital_tg_send_cmd(ddev, skb, 300, digital_tg_recv_sdd_req, |
604 | NULL); | 606 | NULL); |
605 | if (rc) | 607 | if (rc) |
606 | kfree_skb(skb); | 608 | kfree_skb(skb); |
607 | 609 | ||
608 | return rc; | 610 | return rc; |
609 | } | 611 | } |
610 | 612 | ||
611 | void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg, | 613 | void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg, |
612 | struct sk_buff *resp) | 614 | struct sk_buff *resp) |
613 | { | 615 | { |
614 | u8 sens_req; | 616 | u8 sens_req; |
615 | int rc; | 617 | int rc; |
616 | 618 | ||
617 | if (IS_ERR(resp)) { | 619 | if (IS_ERR(resp)) { |
618 | rc = PTR_ERR(resp); | 620 | rc = PTR_ERR(resp); |
619 | resp = NULL; | 621 | resp = NULL; |
620 | goto exit; | 622 | goto exit; |
621 | } | 623 | } |
622 | 624 | ||
623 | sens_req = resp->data[0]; | 625 | sens_req = resp->data[0]; |
624 | 626 | ||
625 | if (!resp->len || (sens_req != DIGITAL_CMD_SENS_REQ && | 627 | if (!resp->len || (sens_req != DIGITAL_CMD_SENS_REQ && |
626 | sens_req != DIGITAL_CMD_ALL_REQ)) { | 628 | sens_req != DIGITAL_CMD_ALL_REQ)) { |
627 | rc = -EINVAL; | 629 | rc = -EINVAL; |
628 | goto exit; | 630 | goto exit; |
629 | } | 631 | } |
630 | 632 | ||
631 | rc = digital_tg_send_sens_res(ddev); | 633 | rc = digital_tg_send_sens_res(ddev); |
632 | 634 | ||
633 | exit: | 635 | exit: |
634 | if (rc) | 636 | if (rc) |
635 | digital_poll_next_tech(ddev); | 637 | digital_poll_next_tech(ddev); |
636 | 638 | ||
637 | dev_kfree_skb(resp); | 639 | dev_kfree_skb(resp); |
638 | } | 640 | } |
639 | 641 | ||
640 | int digital_tg_send_sensf_res(struct nfc_digital_dev *ddev, | 642 | int digital_tg_send_sensf_res(struct nfc_digital_dev *ddev, |
641 | struct digital_sensf_req *sensf_req) | 643 | struct digital_sensf_req *sensf_req) |
642 | { | 644 | { |
643 | struct sk_buff *skb; | 645 | struct sk_buff *skb; |
644 | u8 size; | 646 | u8 size; |
645 | int rc; | 647 | int rc; |
646 | struct digital_sensf_res *sensf_res; | 648 | struct digital_sensf_res *sensf_res; |
647 | 649 | ||
648 | size = sizeof(struct digital_sensf_res); | 650 | size = sizeof(struct digital_sensf_res); |
649 | 651 | ||
650 | if (sensf_req->rc != DIGITAL_SENSF_REQ_RC_NONE) | 652 | if (sensf_req->rc != DIGITAL_SENSF_REQ_RC_NONE) |
651 | size -= sizeof(sensf_res->rd); | 653 | size -= sizeof(sensf_res->rd); |
652 | 654 | ||
653 | skb = digital_skb_alloc(ddev, size); | 655 | skb = digital_skb_alloc(ddev, size); |
654 | if (!skb) | 656 | if (!skb) |
655 | return -ENOMEM; | 657 | return -ENOMEM; |
656 | 658 | ||
657 | skb_put(skb, size); | 659 | skb_put(skb, size); |
658 | 660 | ||
659 | sensf_res = (struct digital_sensf_res *)skb->data; | 661 | sensf_res = (struct digital_sensf_res *)skb->data; |
660 | 662 | ||
661 | memset(sensf_res, 0, size); | 663 | memset(sensf_res, 0, size); |
662 | 664 | ||
663 | sensf_res->cmd = DIGITAL_CMD_SENSF_RES; | 665 | sensf_res->cmd = DIGITAL_CMD_SENSF_RES; |
664 | sensf_res->nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1; | 666 | sensf_res->nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1; |
665 | sensf_res->nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2; | 667 | sensf_res->nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2; |
666 | get_random_bytes(&sensf_res->nfcid2[2], 6); | 668 | get_random_bytes(&sensf_res->nfcid2[2], 6); |
667 | 669 | ||
668 | switch (sensf_req->rc) { | 670 | switch (sensf_req->rc) { |
669 | case DIGITAL_SENSF_REQ_RC_SC: | 671 | case DIGITAL_SENSF_REQ_RC_SC: |
670 | sensf_res->rd[0] = sensf_req->sc1; | 672 | sensf_res->rd[0] = sensf_req->sc1; |
671 | sensf_res->rd[1] = sensf_req->sc2; | 673 | sensf_res->rd[1] = sensf_req->sc2; |
672 | break; | 674 | break; |
673 | case DIGITAL_SENSF_REQ_RC_AP: | 675 | case DIGITAL_SENSF_REQ_RC_AP: |
674 | sensf_res->rd[0] = DIGITAL_SENSF_RES_RD_AP_B1; | 676 | sensf_res->rd[0] = DIGITAL_SENSF_RES_RD_AP_B1; |
675 | sensf_res->rd[1] = DIGITAL_SENSF_RES_RD_AP_B2; | 677 | sensf_res->rd[1] = DIGITAL_SENSF_RES_RD_AP_B2; |
676 | break; | 678 | break; |
677 | } | 679 | } |
678 | 680 | ||
679 | *skb_push(skb, sizeof(u8)) = size + 1; | 681 | *skb_push(skb, sizeof(u8)) = size + 1; |
680 | 682 | ||
681 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) | 683 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) |
682 | digital_skb_add_crc_f(skb); | 684 | digital_skb_add_crc_f(skb); |
683 | 685 | ||
684 | rc = digital_tg_send_cmd(ddev, skb, 300, | 686 | rc = digital_tg_send_cmd(ddev, skb, 300, |
685 | digital_tg_recv_atr_req, NULL); | 687 | digital_tg_recv_atr_req, NULL); |
686 | if (rc) | 688 | if (rc) |
687 | kfree_skb(skb); | 689 | kfree_skb(skb); |
688 | 690 | ||
689 | return rc; | 691 | return rc; |
690 | } | 692 | } |
691 | 693 | ||
692 | void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg, | 694 | void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg, |
693 | struct sk_buff *resp) | 695 | struct sk_buff *resp) |
694 | { | 696 | { |
695 | struct digital_sensf_req *sensf_req; | 697 | struct digital_sensf_req *sensf_req; |
696 | int rc; | 698 | int rc; |
697 | 699 | ||
698 | if (IS_ERR(resp)) { | 700 | if (IS_ERR(resp)) { |
699 | rc = PTR_ERR(resp); | 701 | rc = PTR_ERR(resp); |
700 | resp = NULL; | 702 | resp = NULL; |
701 | goto exit; | 703 | goto exit; |
702 | } | 704 | } |
703 | 705 | ||
704 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) { | 706 | if (!DIGITAL_DRV_CAPS_TG_CRC(ddev)) { |
705 | rc = digital_skb_check_crc_f(resp); | 707 | rc = digital_skb_check_crc_f(resp); |
706 | if (rc) { | 708 | if (rc) { |
707 | PROTOCOL_ERR("6.4.1.8"); | 709 | PROTOCOL_ERR("6.4.1.8"); |
708 | goto exit; | 710 | goto exit; |
709 | } | 711 | } |
710 | } | 712 | } |
711 | 713 | ||
712 | if (resp->len != sizeof(struct digital_sensf_req) + 1) { | 714 | if (resp->len != sizeof(struct digital_sensf_req) + 1) { |
713 | rc = -EINVAL; | 715 | rc = -EINVAL; |
714 | goto exit; | 716 | goto exit; |
715 | } | 717 | } |
716 | 718 | ||
717 | skb_pull(resp, 1); | 719 | skb_pull(resp, 1); |
718 | sensf_req = (struct digital_sensf_req *)resp->data; | 720 | sensf_req = (struct digital_sensf_req *)resp->data; |
719 | 721 | ||
720 | if (sensf_req->cmd != DIGITAL_CMD_SENSF_REQ) { | 722 | if (sensf_req->cmd != DIGITAL_CMD_SENSF_REQ) { |
721 | rc = -EINVAL; | 723 | rc = -EINVAL; |
722 | goto exit; | 724 | goto exit; |
723 | } | 725 | } |
724 | 726 | ||
725 | rc = digital_tg_send_sensf_res(ddev, sensf_req); | 727 | rc = digital_tg_send_sensf_res(ddev, sensf_req); |
726 | 728 | ||
727 | exit: | 729 | exit: |
728 | if (rc) | 730 | if (rc) |
729 | digital_poll_next_tech(ddev); | 731 | digital_poll_next_tech(ddev); |
730 | 732 | ||
731 | dev_kfree_skb(resp); | 733 | dev_kfree_skb(resp); |
732 | } | 734 | } |
733 | 735 | ||
734 | int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech) | 736 | int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech) |
735 | { | 737 | { |
736 | int rc; | 738 | int rc; |
737 | 739 | ||
738 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); | 740 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); |
739 | if (rc) | 741 | if (rc) |
740 | return rc; | 742 | return rc; |
741 | 743 | ||
742 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 744 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
743 | NFC_DIGITAL_FRAMING_NFCA_NFC_DEP); | 745 | NFC_DIGITAL_FRAMING_NFCA_NFC_DEP); |
744 | if (rc) | 746 | if (rc) |
745 | return rc; | 747 | return rc; |
746 | 748 | ||
747 | return digital_tg_listen(ddev, 300, digital_tg_recv_sens_req, NULL); | 749 | return digital_tg_listen(ddev, 300, digital_tg_recv_sens_req, NULL); |
748 | } | 750 | } |
749 | 751 | ||
750 | int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech) | 752 | int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech) |
751 | { | 753 | { |
752 | int rc; | 754 | int rc; |
753 | u8 *nfcid2; | 755 | u8 *nfcid2; |
754 | 756 | ||
755 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); | 757 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, rf_tech); |
756 | if (rc) | 758 | if (rc) |
757 | return rc; | 759 | return rc; |
758 | 760 | ||
759 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | 761 | rc = digital_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, |
760 | NFC_DIGITAL_FRAMING_NFCF_NFC_DEP); | 762 | NFC_DIGITAL_FRAMING_NFCF_NFC_DEP); |
761 | if (rc) | 763 | if (rc) |
762 | return rc; | 764 | return rc; |
763 | 765 | ||
764 | nfcid2 = kzalloc(NFC_NFCID2_MAXSIZE, GFP_KERNEL); | 766 | nfcid2 = kzalloc(NFC_NFCID2_MAXSIZE, GFP_KERNEL); |
765 | if (!nfcid2) | 767 | if (!nfcid2) |
766 | return -ENOMEM; | 768 | return -ENOMEM; |
767 | 769 | ||
768 | nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1; | 770 | nfcid2[0] = DIGITAL_SENSF_NFCID2_NFC_DEP_B1; |
769 | nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2; | 771 | nfcid2[1] = DIGITAL_SENSF_NFCID2_NFC_DEP_B2; |
770 | get_random_bytes(nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2); | 772 | get_random_bytes(nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2); |
771 | 773 | ||
772 | return digital_tg_listen(ddev, 300, digital_tg_recv_sensf_req, nfcid2); | 774 | return digital_tg_listen(ddev, 300, digital_tg_recv_sensf_req, nfcid2); |
773 | } | 775 | } |
774 | 776 |