diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-02-18 13:47:13 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-02-18 13:47:13 -0500 |
commit | 98d5fac2330779e6eea6431a90b44c7476260dcc (patch) | |
tree | 99870656d835fc6c12093bc67517956cc7b3d6ec /drivers/nfc | |
parent | 4153577a8d318ae02b3791341e10e78416de402f (diff) | |
parent | 9e97d14b4923da524d202f2e005d5d30b70db9d6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/ti/wlcore/sdio.c
drivers/net/wireless/ti/wlcore/spi.c
Diffstat (limited to 'drivers/nfc')
-rw-r--r-- | drivers/nfc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/nfc/Makefile | 1 | ||||
-rw-r--r-- | drivers/nfc/microread/Kconfig | 35 | ||||
-rw-r--r-- | drivers/nfc/microread/Makefile | 10 | ||||
-rw-r--r-- | drivers/nfc/microread/i2c.c | 340 | ||||
-rw-r--r-- | drivers/nfc/microread/mei.c | 246 | ||||
-rw-r--r-- | drivers/nfc/microread/microread.c | 728 | ||||
-rw-r--r-- | drivers/nfc/microread/microread.h | 33 | ||||
-rw-r--r-- | drivers/nfc/pn533.c | 8 |
9 files changed, 1397 insertions, 5 deletions
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 80c728b28828..e57034971ccc 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig | |||
@@ -27,5 +27,6 @@ config NFC_WILINK | |||
27 | into the kernel or say M to compile it as module. | 27 | into the kernel or say M to compile it as module. |
28 | 28 | ||
29 | source "drivers/nfc/pn544/Kconfig" | 29 | source "drivers/nfc/pn544/Kconfig" |
30 | source "drivers/nfc/microread/Kconfig" | ||
30 | 31 | ||
31 | endmenu | 32 | endmenu |
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index 574bbc04d97a..a189ada0926a 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_NFC_PN544) += pn544/ | 5 | obj-$(CONFIG_NFC_PN544) += pn544/ |
6 | obj-$(CONFIG_NFC_MICROREAD) += microread/ | ||
6 | obj-$(CONFIG_NFC_PN533) += pn533.o | 7 | obj-$(CONFIG_NFC_PN533) += pn533.o |
7 | obj-$(CONFIG_NFC_WILINK) += nfcwilink.o | 8 | obj-$(CONFIG_NFC_WILINK) += nfcwilink.o |
8 | 9 | ||
diff --git a/drivers/nfc/microread/Kconfig b/drivers/nfc/microread/Kconfig new file mode 100644 index 000000000000..572305be6e37 --- /dev/null +++ b/drivers/nfc/microread/Kconfig | |||
@@ -0,0 +1,35 @@ | |||
1 | config NFC_MICROREAD | ||
2 | tristate "Inside Secure microread NFC driver" | ||
3 | depends on NFC_HCI | ||
4 | select CRC_CCITT | ||
5 | default n | ||
6 | ---help--- | ||
7 | This module contains the main code for Inside Secure microread | ||
8 | NFC chipsets. It implements the chipset HCI logic and hooks into | ||
9 | the NFC kernel APIs. Physical layers will register against it. | ||
10 | |||
11 | To compile this driver as a module, choose m here. The module will | ||
12 | be called microread. | ||
13 | Say N if unsure. | ||
14 | |||
15 | config NFC_MICROREAD_I2C | ||
16 | tristate "NFC Microread i2c support" | ||
17 | depends on NFC_MICROREAD && I2C && NFC_SHDLC | ||
18 | ---help--- | ||
19 | This module adds support for the i2c interface of adapters using | ||
20 | Inside microread chipsets. Select this if your platform is using | ||
21 | the i2c bus. | ||
22 | |||
23 | If you choose to build a module, it'll be called microread_i2c. | ||
24 | Say N if unsure. | ||
25 | |||
26 | config NFC_MICROREAD_MEI | ||
27 | tristate "NFC Microread MEI support" | ||
28 | depends on NFC_MICROREAD && INTEL_MEI_BUS_NFC | ||
29 | ---help--- | ||
30 | This module adds support for the mei interface of adapters using | ||
31 | Inside microread chipsets. Select this if your microread chipset | ||
32 | is handled by Intel's Management Engine Interface on your platform. | ||
33 | |||
34 | If you choose to build a module, it'll be called microread_mei. | ||
35 | Say N if unsure. | ||
diff --git a/drivers/nfc/microread/Makefile b/drivers/nfc/microread/Makefile new file mode 100644 index 000000000000..755c24cba253 --- /dev/null +++ b/drivers/nfc/microread/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for Microread HCI based NFC driver | ||
3 | # | ||
4 | |||
5 | microread_i2c-objs = i2c.o | ||
6 | microread_mei-objs = mei.o | ||
7 | |||
8 | obj-$(CONFIG_NFC_MICROREAD) += microread.o | ||
9 | obj-$(CONFIG_NFC_MICROREAD_I2C) += microread_i2c.o | ||
10 | obj-$(CONFIG_NFC_MICROREAD_MEI) += microread_mei.o | ||
diff --git a/drivers/nfc/microread/i2c.c b/drivers/nfc/microread/i2c.c new file mode 100644 index 000000000000..101089495bf8 --- /dev/null +++ b/drivers/nfc/microread/i2c.c | |||
@@ -0,0 +1,340 @@ | |||
1 | /* | ||
2 | * HCI based Driver for Inside Secure microread NFC Chip - i2c layer | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the | ||
17 | * Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/gpio.h> | ||
27 | |||
28 | #include <linux/nfc.h> | ||
29 | #include <net/nfc/hci.h> | ||
30 | #include <net/nfc/llc.h> | ||
31 | |||
32 | #include "microread.h" | ||
33 | |||
34 | #define MICROREAD_I2C_DRIVER_NAME "microread" | ||
35 | |||
36 | #define MICROREAD_I2C_FRAME_HEADROOM 1 | ||
37 | #define MICROREAD_I2C_FRAME_TAILROOM 1 | ||
38 | |||
39 | /* framing in HCI mode */ | ||
40 | #define MICROREAD_I2C_LLC_LEN 1 | ||
41 | #define MICROREAD_I2C_LLC_CRC 1 | ||
42 | #define MICROREAD_I2C_LLC_LEN_CRC (MICROREAD_I2C_LLC_LEN + \ | ||
43 | MICROREAD_I2C_LLC_CRC) | ||
44 | #define MICROREAD_I2C_LLC_MIN_SIZE (1 + MICROREAD_I2C_LLC_LEN_CRC) | ||
45 | #define MICROREAD_I2C_LLC_MAX_PAYLOAD 29 | ||
46 | #define MICROREAD_I2C_LLC_MAX_SIZE (MICROREAD_I2C_LLC_LEN_CRC + 1 + \ | ||
47 | MICROREAD_I2C_LLC_MAX_PAYLOAD) | ||
48 | |||
49 | struct microread_i2c_phy { | ||
50 | struct i2c_client *i2c_dev; | ||
51 | struct nfc_hci_dev *hdev; | ||
52 | |||
53 | int irq; | ||
54 | |||
55 | int hard_fault; /* | ||
56 | * < 0 if hardware error occured (e.g. i2c err) | ||
57 | * and prevents normal operation. | ||
58 | */ | ||
59 | }; | ||
60 | |||
61 | #define I2C_DUMP_SKB(info, skb) \ | ||
62 | do { \ | ||
63 | pr_debug("%s:\n", info); \ | ||
64 | print_hex_dump(KERN_DEBUG, "i2c: ", DUMP_PREFIX_OFFSET, \ | ||
65 | 16, 1, (skb)->data, (skb)->len, 0); \ | ||
66 | } while (0) | ||
67 | |||
68 | static void microread_i2c_add_len_crc(struct sk_buff *skb) | ||
69 | { | ||
70 | int i; | ||
71 | u8 crc = 0; | ||
72 | int len; | ||
73 | |||
74 | len = skb->len; | ||
75 | *skb_push(skb, 1) = len; | ||
76 | |||
77 | for (i = 0; i < skb->len; i++) | ||
78 | crc = crc ^ skb->data[i]; | ||
79 | |||
80 | *skb_put(skb, 1) = crc; | ||
81 | } | ||
82 | |||
83 | static void microread_i2c_remove_len_crc(struct sk_buff *skb) | ||
84 | { | ||
85 | skb_pull(skb, MICROREAD_I2C_FRAME_HEADROOM); | ||
86 | skb_trim(skb, MICROREAD_I2C_FRAME_TAILROOM); | ||
87 | } | ||
88 | |||
89 | static int check_crc(struct sk_buff *skb) | ||
90 | { | ||
91 | int i; | ||
92 | u8 crc = 0; | ||
93 | |||
94 | for (i = 0; i < skb->len - 1; i++) | ||
95 | crc = crc ^ skb->data[i]; | ||
96 | |||
97 | if (crc != skb->data[skb->len-1]) { | ||
98 | pr_err(MICROREAD_I2C_DRIVER_NAME | ||
99 | ": CRC error 0x%x != 0x%x\n", | ||
100 | crc, skb->data[skb->len-1]); | ||
101 | |||
102 | pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); | ||
103 | |||
104 | return -EPERM; | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int microread_i2c_enable(void *phy_id) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static void microread_i2c_disable(void *phy_id) | ||
116 | { | ||
117 | return; | ||
118 | } | ||
119 | |||
120 | static int microread_i2c_write(void *phy_id, struct sk_buff *skb) | ||
121 | { | ||
122 | int r; | ||
123 | struct microread_i2c_phy *phy = phy_id; | ||
124 | struct i2c_client *client = phy->i2c_dev; | ||
125 | |||
126 | if (phy->hard_fault != 0) | ||
127 | return phy->hard_fault; | ||
128 | |||
129 | usleep_range(3000, 6000); | ||
130 | |||
131 | microread_i2c_add_len_crc(skb); | ||
132 | |||
133 | I2C_DUMP_SKB("i2c frame written", skb); | ||
134 | |||
135 | r = i2c_master_send(client, skb->data, skb->len); | ||
136 | |||
137 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | ||
138 | usleep_range(6000, 10000); | ||
139 | r = i2c_master_send(client, skb->data, skb->len); | ||
140 | } | ||
141 | |||
142 | if (r >= 0) { | ||
143 | if (r != skb->len) | ||
144 | r = -EREMOTEIO; | ||
145 | else | ||
146 | r = 0; | ||
147 | } | ||
148 | |||
149 | microread_i2c_remove_len_crc(skb); | ||
150 | |||
151 | return r; | ||
152 | } | ||
153 | |||
154 | |||
155 | static int microread_i2c_read(struct microread_i2c_phy *phy, | ||
156 | struct sk_buff **skb) | ||
157 | { | ||
158 | int r; | ||
159 | u8 len; | ||
160 | u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1]; | ||
161 | struct i2c_client *client = phy->i2c_dev; | ||
162 | |||
163 | pr_debug("%s\n", __func__); | ||
164 | |||
165 | r = i2c_master_recv(client, &len, 1); | ||
166 | if (r != 1) { | ||
167 | dev_err(&client->dev, "cannot read len byte\n"); | ||
168 | return -EREMOTEIO; | ||
169 | } | ||
170 | |||
171 | if ((len < MICROREAD_I2C_LLC_MIN_SIZE) || | ||
172 | (len > MICROREAD_I2C_LLC_MAX_SIZE)) { | ||
173 | dev_err(&client->dev, "invalid len byte\n"); | ||
174 | pr_err("invalid len byte\n"); | ||
175 | r = -EBADMSG; | ||
176 | goto flush; | ||
177 | } | ||
178 | |||
179 | *skb = alloc_skb(1 + len, GFP_KERNEL); | ||
180 | if (*skb == NULL) { | ||
181 | r = -ENOMEM; | ||
182 | goto flush; | ||
183 | } | ||
184 | |||
185 | *skb_put(*skb, 1) = len; | ||
186 | |||
187 | r = i2c_master_recv(client, skb_put(*skb, len), len); | ||
188 | if (r != len) { | ||
189 | kfree_skb(*skb); | ||
190 | return -EREMOTEIO; | ||
191 | } | ||
192 | |||
193 | I2C_DUMP_SKB("cc frame read", *skb); | ||
194 | |||
195 | r = check_crc(*skb); | ||
196 | if (r != 0) { | ||
197 | kfree_skb(*skb); | ||
198 | r = -EBADMSG; | ||
199 | goto flush; | ||
200 | } | ||
201 | |||
202 | skb_pull(*skb, 1); | ||
203 | skb_trim(*skb, (*skb)->len - MICROREAD_I2C_FRAME_TAILROOM); | ||
204 | |||
205 | usleep_range(3000, 6000); | ||
206 | |||
207 | return 0; | ||
208 | |||
209 | flush: | ||
210 | if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) | ||
211 | r = -EREMOTEIO; | ||
212 | |||
213 | usleep_range(3000, 6000); | ||
214 | |||
215 | return r; | ||
216 | } | ||
217 | |||
218 | static irqreturn_t microread_i2c_irq_thread_fn(int irq, void *phy_id) | ||
219 | { | ||
220 | struct microread_i2c_phy *phy = phy_id; | ||
221 | struct i2c_client *client; | ||
222 | struct sk_buff *skb = NULL; | ||
223 | int r; | ||
224 | |||
225 | if (!phy || irq != phy->i2c_dev->irq) { | ||
226 | WARN_ON_ONCE(1); | ||
227 | return IRQ_NONE; | ||
228 | } | ||
229 | |||
230 | client = phy->i2c_dev; | ||
231 | dev_dbg(&client->dev, "IRQ\n"); | ||
232 | |||
233 | if (phy->hard_fault != 0) | ||
234 | return IRQ_HANDLED; | ||
235 | |||
236 | r = microread_i2c_read(phy, &skb); | ||
237 | if (r == -EREMOTEIO) { | ||
238 | phy->hard_fault = r; | ||
239 | |||
240 | nfc_hci_recv_frame(phy->hdev, NULL); | ||
241 | |||
242 | return IRQ_HANDLED; | ||
243 | } else if ((r == -ENOMEM) || (r == -EBADMSG)) { | ||
244 | return IRQ_HANDLED; | ||
245 | } | ||
246 | |||
247 | nfc_hci_recv_frame(phy->hdev, skb); | ||
248 | |||
249 | return IRQ_HANDLED; | ||
250 | } | ||
251 | |||
252 | static struct nfc_phy_ops i2c_phy_ops = { | ||
253 | .write = microread_i2c_write, | ||
254 | .enable = microread_i2c_enable, | ||
255 | .disable = microread_i2c_disable, | ||
256 | }; | ||
257 | |||
258 | static int microread_i2c_probe(struct i2c_client *client, | ||
259 | const struct i2c_device_id *id) | ||
260 | { | ||
261 | struct microread_i2c_phy *phy; | ||
262 | struct microread_nfc_platform_data *pdata = | ||
263 | dev_get_platdata(&client->dev); | ||
264 | int r; | ||
265 | |||
266 | dev_dbg(&client->dev, "client %p", client); | ||
267 | |||
268 | if (!pdata) { | ||
269 | dev_err(&client->dev, "client %p: missing platform data", | ||
270 | client); | ||
271 | return -EINVAL; | ||
272 | } | ||
273 | |||
274 | phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy), | ||
275 | GFP_KERNEL); | ||
276 | if (!phy) { | ||
277 | dev_err(&client->dev, "Can't allocate microread phy"); | ||
278 | return -ENOMEM; | ||
279 | } | ||
280 | |||
281 | i2c_set_clientdata(client, phy); | ||
282 | phy->i2c_dev = client; | ||
283 | |||
284 | r = request_threaded_irq(client->irq, NULL, microread_i2c_irq_thread_fn, | ||
285 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
286 | MICROREAD_I2C_DRIVER_NAME, phy); | ||
287 | if (r) { | ||
288 | dev_err(&client->dev, "Unable to register IRQ handler"); | ||
289 | return r; | ||
290 | } | ||
291 | |||
292 | r = microread_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, | ||
293 | MICROREAD_I2C_FRAME_HEADROOM, | ||
294 | MICROREAD_I2C_FRAME_TAILROOM, | ||
295 | MICROREAD_I2C_LLC_MAX_PAYLOAD, &phy->hdev); | ||
296 | if (r < 0) | ||
297 | goto err_irq; | ||
298 | |||
299 | dev_info(&client->dev, "Probed"); | ||
300 | |||
301 | return 0; | ||
302 | |||
303 | err_irq: | ||
304 | free_irq(client->irq, phy); | ||
305 | |||
306 | return r; | ||
307 | } | ||
308 | |||
309 | static int microread_i2c_remove(struct i2c_client *client) | ||
310 | { | ||
311 | struct microread_i2c_phy *phy = i2c_get_clientdata(client); | ||
312 | |||
313 | dev_dbg(&client->dev, "%s\n", __func__); | ||
314 | |||
315 | microread_remove(phy->hdev); | ||
316 | |||
317 | free_irq(client->irq, phy); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static struct i2c_device_id microread_i2c_id[] = { | ||
323 | { MICROREAD_I2C_DRIVER_NAME, 0}, | ||
324 | { } | ||
325 | }; | ||
326 | MODULE_DEVICE_TABLE(i2c, microread_i2c_id); | ||
327 | |||
328 | static struct i2c_driver microread_i2c_driver = { | ||
329 | .driver = { | ||
330 | .name = MICROREAD_I2C_DRIVER_NAME, | ||
331 | }, | ||
332 | .probe = microread_i2c_probe, | ||
333 | .remove = microread_i2c_remove, | ||
334 | .id_table = microread_i2c_id, | ||
335 | }; | ||
336 | |||
337 | module_i2c_driver(microread_i2c_driver); | ||
338 | |||
339 | MODULE_LICENSE("GPL"); | ||
340 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c new file mode 100644 index 000000000000..eef38cfd812e --- /dev/null +++ b/drivers/nfc/microread/mei.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * HCI based Driver for Inside Secure microread NFC Chip | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the | ||
17 | * Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/gpio.h> | ||
25 | #include <linux/mei_bus.h> | ||
26 | |||
27 | #include <linux/nfc.h> | ||
28 | #include <net/nfc/hci.h> | ||
29 | #include <net/nfc/llc.h> | ||
30 | |||
31 | #include "microread.h" | ||
32 | |||
33 | #define MICROREAD_DRIVER_NAME "microread" | ||
34 | |||
35 | #define MICROREAD_UUID UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 0x94, \ | ||
36 | 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c) | ||
37 | |||
38 | struct mei_nfc_hdr { | ||
39 | u8 cmd; | ||
40 | u8 status; | ||
41 | u16 req_id; | ||
42 | u32 reserved; | ||
43 | u16 data_size; | ||
44 | } __attribute__((packed)); | ||
45 | |||
46 | #define MEI_NFC_HEADER_SIZE 10 | ||
47 | #define MEI_NFC_MAX_HCI_PAYLOAD 300 | ||
48 | #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) | ||
49 | |||
50 | struct microread_mei_phy { | ||
51 | struct mei_device *mei_device; | ||
52 | struct nfc_hci_dev *hdev; | ||
53 | |||
54 | int powered; | ||
55 | |||
56 | int hard_fault; /* | ||
57 | * < 0 if hardware error occured (e.g. i2c err) | ||
58 | * and prevents normal operation. | ||
59 | */ | ||
60 | }; | ||
61 | |||
62 | #define MEI_DUMP_SKB_IN(info, skb) \ | ||
63 | do { \ | ||
64 | pr_debug("%s:\n", info); \ | ||
65 | print_hex_dump(KERN_DEBUG, "mei in : ", DUMP_PREFIX_OFFSET, \ | ||
66 | 16, 1, (skb)->data, (skb)->len, 0); \ | ||
67 | } while (0) | ||
68 | |||
69 | #define MEI_DUMP_SKB_OUT(info, skb) \ | ||
70 | do { \ | ||
71 | pr_debug("%s:\n", info); \ | ||
72 | print_hex_dump(KERN_DEBUG, "mei out: ", DUMP_PREFIX_OFFSET, \ | ||
73 | 16, 1, (skb)->data, (skb)->len, 0); \ | ||
74 | } while (0) | ||
75 | |||
76 | static int microread_mei_enable(void *phy_id) | ||
77 | { | ||
78 | struct microread_mei_phy *phy = phy_id; | ||
79 | |||
80 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
81 | |||
82 | phy->powered = 1; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static void microread_mei_disable(void *phy_id) | ||
88 | { | ||
89 | struct microread_mei_phy *phy = phy_id; | ||
90 | |||
91 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
92 | |||
93 | phy->powered = 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Writing a frame must not return the number of written bytes. | ||
98 | * It must return either zero for success, or <0 for error. | ||
99 | * In addition, it must not alter the skb | ||
100 | */ | ||
101 | static int microread_mei_write(void *phy_id, struct sk_buff *skb) | ||
102 | { | ||
103 | struct microread_mei_phy *phy = phy_id; | ||
104 | int r; | ||
105 | |||
106 | MEI_DUMP_SKB_OUT("mei frame sent", skb); | ||
107 | |||
108 | r = mei_send(phy->device, skb->data, skb->len); | ||
109 | if (r > 0) | ||
110 | r = 0; | ||
111 | |||
112 | return r; | ||
113 | } | ||
114 | |||
115 | static void microread_event_cb(struct mei_device *device, u32 events, | ||
116 | void *context) | ||
117 | { | ||
118 | struct microread_mei_phy *phy = context; | ||
119 | |||
120 | if (phy->hard_fault != 0) | ||
121 | return; | ||
122 | |||
123 | if (events & BIT(MEI_EVENT_RX)) { | ||
124 | struct sk_buff *skb; | ||
125 | int reply_size; | ||
126 | |||
127 | skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL); | ||
128 | if (!skb) | ||
129 | return; | ||
130 | |||
131 | reply_size = mei_recv(device, skb->data, MEI_NFC_MAX_READ); | ||
132 | if (reply_size < MEI_NFC_HEADER_SIZE) { | ||
133 | kfree(skb); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | skb_put(skb, reply_size); | ||
138 | skb_pull(skb, MEI_NFC_HEADER_SIZE); | ||
139 | |||
140 | MEI_DUMP_SKB_IN("mei frame read", skb); | ||
141 | |||
142 | nfc_hci_recv_frame(phy->hdev, skb); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static struct nfc_phy_ops mei_phy_ops = { | ||
147 | .write = microread_mei_write, | ||
148 | .enable = microread_mei_enable, | ||
149 | .disable = microread_mei_disable, | ||
150 | }; | ||
151 | |||
152 | static int microread_mei_probe(struct mei_device *device, | ||
153 | const struct mei_id *id) | ||
154 | { | ||
155 | struct microread_mei_phy *phy; | ||
156 | int r; | ||
157 | |||
158 | pr_info("Probing NFC microread\n"); | ||
159 | |||
160 | phy = kzalloc(sizeof(struct microread_mei_phy), GFP_KERNEL); | ||
161 | if (!phy) { | ||
162 | pr_err("Cannot allocate memory for microread mei phy.\n"); | ||
163 | return -ENOMEM; | ||
164 | } | ||
165 | |||
166 | phy->device = device; | ||
167 | mei_set_clientdata(device, phy); | ||
168 | |||
169 | r = mei_register_event_cb(device, microread_event_cb, phy); | ||
170 | if (r) { | ||
171 | pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); | ||
172 | goto err_out; | ||
173 | } | ||
174 | |||
175 | r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME, | ||
176 | MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD, | ||
177 | &phy->hdev); | ||
178 | if (r < 0) | ||
179 | goto err_out; | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | err_out: | ||
184 | kfree(phy); | ||
185 | |||
186 | return r; | ||
187 | } | ||
188 | |||
189 | static int microread_mei_remove(struct mei_device *device) | ||
190 | { | ||
191 | struct microread_mei_phy *phy = mei_get_clientdata(device); | ||
192 | |||
193 | pr_info("Removing microread\n"); | ||
194 | |||
195 | microread_remove(phy->hdev); | ||
196 | |||
197 | if (phy->powered) | ||
198 | microread_mei_disable(phy); | ||
199 | |||
200 | kfree(phy); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static struct mei_id microread_mei_tbl[] = { | ||
206 | { MICROREAD_DRIVER_NAME, MICROREAD_UUID }, | ||
207 | |||
208 | /* required last entry */ | ||
209 | { } | ||
210 | }; | ||
211 | |||
212 | MODULE_DEVICE_TABLE(mei, microread_mei_tbl); | ||
213 | |||
214 | static struct mei_driver microread_driver = { | ||
215 | .id_table = microread_mei_tbl, | ||
216 | .name = MICROREAD_DRIVER_NAME, | ||
217 | |||
218 | .probe = microread_mei_probe, | ||
219 | .remove = microread_mei_remove, | ||
220 | }; | ||
221 | |||
222 | static int microread_mei_init(void) | ||
223 | { | ||
224 | int r; | ||
225 | |||
226 | pr_debug(DRIVER_DESC ": %s\n", __func__); | ||
227 | |||
228 | r = mei_driver_register(µread_driver); | ||
229 | if (r) { | ||
230 | pr_err(MICROREAD_DRIVER_NAME ": driver registration failed\n"); | ||
231 | return r; | ||
232 | } | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static void microread_mei_exit(void) | ||
238 | { | ||
239 | mei_driver_unregister(µread_driver); | ||
240 | } | ||
241 | |||
242 | module_init(microread_mei_init); | ||
243 | module_exit(microread_mei_exit); | ||
244 | |||
245 | MODULE_LICENSE("GPL"); | ||
246 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/drivers/nfc/microread/microread.c b/drivers/nfc/microread/microread.c new file mode 100644 index 000000000000..3420d833db17 --- /dev/null +++ b/drivers/nfc/microread/microread.c | |||
@@ -0,0 +1,728 @@ | |||
1 | /* | ||
2 | * HCI based Driver for Inside Secure microread NFC Chip | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the | ||
17 | * Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/crc-ccitt.h> | ||
25 | |||
26 | #include <linux/nfc.h> | ||
27 | #include <net/nfc/nfc.h> | ||
28 | #include <net/nfc/hci.h> | ||
29 | #include <net/nfc/llc.h> | ||
30 | |||
31 | #include "microread.h" | ||
32 | |||
33 | /* Proprietary gates, events, commands and registers */ | ||
34 | /* Admin */ | ||
35 | #define MICROREAD_GATE_ID_ADM NFC_HCI_ADMIN_GATE | ||
36 | #define MICROREAD_GATE_ID_MGT 0x01 | ||
37 | #define MICROREAD_GATE_ID_OS 0x02 | ||
38 | #define MICROREAD_GATE_ID_TESTRF 0x03 | ||
39 | #define MICROREAD_GATE_ID_LOOPBACK NFC_HCI_LOOPBACK_GATE | ||
40 | #define MICROREAD_GATE_ID_IDT NFC_HCI_ID_MGMT_GATE | ||
41 | #define MICROREAD_GATE_ID_LMS NFC_HCI_LINK_MGMT_GATE | ||
42 | |||
43 | /* Reader */ | ||
44 | #define MICROREAD_GATE_ID_MREAD_GEN 0x10 | ||
45 | #define MICROREAD_GATE_ID_MREAD_ISO_B NFC_HCI_RF_READER_B_GATE | ||
46 | #define MICROREAD_GATE_ID_MREAD_NFC_T1 0x12 | ||
47 | #define MICROREAD_GATE_ID_MREAD_ISO_A NFC_HCI_RF_READER_A_GATE | ||
48 | #define MICROREAD_GATE_ID_MREAD_NFC_T3 0x14 | ||
49 | #define MICROREAD_GATE_ID_MREAD_ISO_15_3 0x15 | ||
50 | #define MICROREAD_GATE_ID_MREAD_ISO_15_2 0x16 | ||
51 | #define MICROREAD_GATE_ID_MREAD_ISO_B_3 0x17 | ||
52 | #define MICROREAD_GATE_ID_MREAD_BPRIME 0x18 | ||
53 | #define MICROREAD_GATE_ID_MREAD_ISO_A_3 0x19 | ||
54 | |||
55 | /* Card */ | ||
56 | #define MICROREAD_GATE_ID_MCARD_GEN 0x20 | ||
57 | #define MICROREAD_GATE_ID_MCARD_ISO_B 0x21 | ||
58 | #define MICROREAD_GATE_ID_MCARD_BPRIME 0x22 | ||
59 | #define MICROREAD_GATE_ID_MCARD_ISO_A 0x23 | ||
60 | #define MICROREAD_GATE_ID_MCARD_NFC_T3 0x24 | ||
61 | #define MICROREAD_GATE_ID_MCARD_ISO_15_3 0x25 | ||
62 | #define MICROREAD_GATE_ID_MCARD_ISO_15_2 0x26 | ||
63 | #define MICROREAD_GATE_ID_MCARD_ISO_B_2 0x27 | ||
64 | #define MICROREAD_GATE_ID_MCARD_ISO_CUSTOM 0x28 | ||
65 | #define MICROREAD_GATE_ID_SECURE_ELEMENT 0x2F | ||
66 | |||
67 | /* P2P */ | ||
68 | #define MICROREAD_GATE_ID_P2P_GEN 0x30 | ||
69 | #define MICROREAD_GATE_ID_P2P_TARGET 0x31 | ||
70 | #define MICROREAD_PAR_P2P_TARGET_MODE 0x01 | ||
71 | #define MICROREAD_PAR_P2P_TARGET_GT 0x04 | ||
72 | #define MICROREAD_GATE_ID_P2P_INITIATOR 0x32 | ||
73 | #define MICROREAD_PAR_P2P_INITIATOR_GI 0x01 | ||
74 | #define MICROREAD_PAR_P2P_INITIATOR_GT 0x03 | ||
75 | |||
76 | /* Those pipes are created/opened by default in the chip */ | ||
77 | #define MICROREAD_PIPE_ID_LMS 0x00 | ||
78 | #define MICROREAD_PIPE_ID_ADMIN 0x01 | ||
79 | #define MICROREAD_PIPE_ID_MGT 0x02 | ||
80 | #define MICROREAD_PIPE_ID_OS 0x03 | ||
81 | #define MICROREAD_PIPE_ID_HDS_LOOPBACK 0x04 | ||
82 | #define MICROREAD_PIPE_ID_HDS_IDT 0x05 | ||
83 | #define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B 0x08 | ||
84 | #define MICROREAD_PIPE_ID_HDS_MCARD_ISO_BPRIME 0x09 | ||
85 | #define MICROREAD_PIPE_ID_HDS_MCARD_ISO_A 0x0A | ||
86 | #define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_3 0x0B | ||
87 | #define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_2 0x0C | ||
88 | #define MICROREAD_PIPE_ID_HDS_MCARD_NFC_T3 0x0D | ||
89 | #define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B_2 0x0E | ||
90 | #define MICROREAD_PIPE_ID_HDS_MCARD_CUSTOM 0x0F | ||
91 | #define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B 0x10 | ||
92 | #define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1 0x11 | ||
93 | #define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A 0x12 | ||
94 | #define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_3 0x13 | ||
95 | #define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_2 0x14 | ||
96 | #define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3 0x15 | ||
97 | #define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B_3 0x16 | ||
98 | #define MICROREAD_PIPE_ID_HDS_MREAD_BPRIME 0x17 | ||
99 | #define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3 0x18 | ||
100 | #define MICROREAD_PIPE_ID_HDS_MREAD_GEN 0x1B | ||
101 | #define MICROREAD_PIPE_ID_HDS_STACKED_ELEMENT 0x1C | ||
102 | #define MICROREAD_PIPE_ID_HDS_INSTANCES 0x1D | ||
103 | #define MICROREAD_PIPE_ID_HDS_TESTRF 0x1E | ||
104 | #define MICROREAD_PIPE_ID_HDS_P2P_TARGET 0x1F | ||
105 | #define MICROREAD_PIPE_ID_HDS_P2P_INITIATOR 0x20 | ||
106 | |||
107 | /* Events */ | ||
108 | #define MICROREAD_EVT_MREAD_DISCOVERY_OCCURED NFC_HCI_EVT_TARGET_DISCOVERED | ||
109 | #define MICROREAD_EVT_MREAD_CARD_FOUND 0x3D | ||
110 | #define MICROREAD_EMCF_A_ATQA 0 | ||
111 | #define MICROREAD_EMCF_A_SAK 2 | ||
112 | #define MICROREAD_EMCF_A_LEN 3 | ||
113 | #define MICROREAD_EMCF_A_UID 4 | ||
114 | #define MICROREAD_EMCF_A3_ATQA 0 | ||
115 | #define MICROREAD_EMCF_A3_SAK 2 | ||
116 | #define MICROREAD_EMCF_A3_LEN 3 | ||
117 | #define MICROREAD_EMCF_A3_UID 4 | ||
118 | #define MICROREAD_EMCF_B_UID 0 | ||
119 | #define MICROREAD_EMCF_T1_ATQA 0 | ||
120 | #define MICROREAD_EMCF_T1_UID 4 | ||
121 | #define MICROREAD_EMCF_T3_UID 0 | ||
122 | #define MICROREAD_EVT_MREAD_DISCOVERY_START NFC_HCI_EVT_READER_REQUESTED | ||
123 | #define MICROREAD_EVT_MREAD_DISCOVERY_START_SOME 0x3E | ||
124 | #define MICROREAD_EVT_MREAD_DISCOVERY_STOP NFC_HCI_EVT_END_OPERATION | ||
125 | #define MICROREAD_EVT_MREAD_SIM_REQUESTS 0x3F | ||
126 | #define MICROREAD_EVT_MCARD_EXCHANGE NFC_HCI_EVT_TARGET_DISCOVERED | ||
127 | #define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF 0x20 | ||
128 | #define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF 0x21 | ||
129 | #define MICROREAD_EVT_MCARD_FIELD_ON 0x11 | ||
130 | #define MICROREAD_EVT_P2P_TARGET_ACTIVATED 0x13 | ||
131 | #define MICROREAD_EVT_P2P_TARGET_DEACTIVATED 0x12 | ||
132 | #define MICROREAD_EVT_MCARD_FIELD_OFF 0x14 | ||
133 | |||
134 | /* Commands */ | ||
135 | #define MICROREAD_CMD_MREAD_EXCHANGE 0x10 | ||
136 | #define MICROREAD_CMD_MREAD_SUBSCRIBE 0x3F | ||
137 | |||
138 | /* Hosts IDs */ | ||
139 | #define MICROREAD_ELT_ID_HDS NFC_HCI_TERMINAL_HOST_ID | ||
140 | #define MICROREAD_ELT_ID_SIM NFC_HCI_UICC_HOST_ID | ||
141 | #define MICROREAD_ELT_ID_SE1 0x03 | ||
142 | #define MICROREAD_ELT_ID_SE2 0x04 | ||
143 | #define MICROREAD_ELT_ID_SE3 0x05 | ||
144 | |||
145 | static struct nfc_hci_gate microread_gates[] = { | ||
146 | {MICROREAD_GATE_ID_ADM, MICROREAD_PIPE_ID_ADMIN}, | ||
147 | {MICROREAD_GATE_ID_LOOPBACK, MICROREAD_PIPE_ID_HDS_LOOPBACK}, | ||
148 | {MICROREAD_GATE_ID_IDT, MICROREAD_PIPE_ID_HDS_IDT}, | ||
149 | {MICROREAD_GATE_ID_LMS, MICROREAD_PIPE_ID_LMS}, | ||
150 | {MICROREAD_GATE_ID_MREAD_ISO_B, MICROREAD_PIPE_ID_HDS_MREAD_ISO_B}, | ||
151 | {MICROREAD_GATE_ID_MREAD_ISO_A, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A}, | ||
152 | {MICROREAD_GATE_ID_MREAD_ISO_A_3, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3}, | ||
153 | {MICROREAD_GATE_ID_MGT, MICROREAD_PIPE_ID_MGT}, | ||
154 | {MICROREAD_GATE_ID_OS, MICROREAD_PIPE_ID_OS}, | ||
155 | {MICROREAD_GATE_ID_MREAD_NFC_T1, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1}, | ||
156 | {MICROREAD_GATE_ID_MREAD_NFC_T3, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3}, | ||
157 | {MICROREAD_GATE_ID_P2P_TARGET, MICROREAD_PIPE_ID_HDS_P2P_TARGET}, | ||
158 | {MICROREAD_GATE_ID_P2P_INITIATOR, MICROREAD_PIPE_ID_HDS_P2P_INITIATOR} | ||
159 | }; | ||
160 | |||
161 | /* Largest headroom needed for outgoing custom commands */ | ||
162 | #define MICROREAD_CMDS_HEADROOM 2 | ||
163 | #define MICROREAD_CMD_TAILROOM 2 | ||
164 | |||
165 | struct microread_info { | ||
166 | struct nfc_phy_ops *phy_ops; | ||
167 | void *phy_id; | ||
168 | |||
169 | struct nfc_hci_dev *hdev; | ||
170 | |||
171 | int async_cb_type; | ||
172 | data_exchange_cb_t async_cb; | ||
173 | void *async_cb_context; | ||
174 | }; | ||
175 | |||
176 | static int microread_open(struct nfc_hci_dev *hdev) | ||
177 | { | ||
178 | struct microread_info *info = nfc_hci_get_clientdata(hdev); | ||
179 | |||
180 | return info->phy_ops->enable(info->phy_id); | ||
181 | } | ||
182 | |||
183 | static void microread_close(struct nfc_hci_dev *hdev) | ||
184 | { | ||
185 | struct microread_info *info = nfc_hci_get_clientdata(hdev); | ||
186 | |||
187 | info->phy_ops->disable(info->phy_id); | ||
188 | } | ||
189 | |||
190 | static int microread_hci_ready(struct nfc_hci_dev *hdev) | ||
191 | { | ||
192 | int r; | ||
193 | u8 param[4]; | ||
194 | |||
195 | param[0] = 0x03; | ||
196 | r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A, | ||
197 | MICROREAD_CMD_MREAD_SUBSCRIBE, param, 1, NULL); | ||
198 | if (r) | ||
199 | return r; | ||
200 | |||
201 | r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A_3, | ||
202 | MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL); | ||
203 | if (r) | ||
204 | return r; | ||
205 | |||
206 | param[0] = 0x00; | ||
207 | param[1] = 0x03; | ||
208 | param[2] = 0x00; | ||
209 | r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_B, | ||
210 | MICROREAD_CMD_MREAD_SUBSCRIBE, param, 3, NULL); | ||
211 | if (r) | ||
212 | return r; | ||
213 | |||
214 | r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T1, | ||
215 | MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL); | ||
216 | if (r) | ||
217 | return r; | ||
218 | |||
219 | param[0] = 0xFF; | ||
220 | param[1] = 0xFF; | ||
221 | param[2] = 0x00; | ||
222 | param[3] = 0x00; | ||
223 | r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T3, | ||
224 | MICROREAD_CMD_MREAD_SUBSCRIBE, param, 4, NULL); | ||
225 | |||
226 | return r; | ||
227 | } | ||
228 | |||
229 | static int microread_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) | ||
230 | { | ||
231 | struct microread_info *info = nfc_hci_get_clientdata(hdev); | ||
232 | |||
233 | return info->phy_ops->write(info->phy_id, skb); | ||
234 | } | ||
235 | |||
236 | static int microread_start_poll(struct nfc_hci_dev *hdev, | ||
237 | u32 im_protocols, u32 tm_protocols) | ||
238 | { | ||
239 | int r; | ||
240 | |||
241 | u8 param[2]; | ||
242 | u8 mode; | ||
243 | |||
244 | param[0] = 0x00; | ||
245 | param[1] = 0x00; | ||
246 | |||
247 | if (im_protocols & NFC_PROTO_ISO14443_MASK) | ||
248 | param[0] |= (1 << 2); | ||
249 | |||
250 | if (im_protocols & NFC_PROTO_ISO14443_B_MASK) | ||
251 | param[0] |= 1; | ||
252 | |||
253 | if (im_protocols & NFC_PROTO_MIFARE_MASK) | ||
254 | param[1] |= 1; | ||
255 | |||
256 | if (im_protocols & NFC_PROTO_JEWEL_MASK) | ||
257 | param[0] |= (1 << 1); | ||
258 | |||
259 | if (im_protocols & NFC_PROTO_FELICA_MASK) | ||
260 | param[0] |= (1 << 5); | ||
261 | |||
262 | if (im_protocols & NFC_PROTO_NFC_DEP_MASK) | ||
263 | param[1] |= (1 << 1); | ||
264 | |||
265 | if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) { | ||
266 | hdev->gb = nfc_get_local_general_bytes(hdev->ndev, | ||
267 | &hdev->gb_len); | ||
268 | if (hdev->gb == NULL || hdev->gb_len == 0) { | ||
269 | im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; | ||
270 | tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A, | ||
275 | MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0); | ||
276 | if (r) | ||
277 | return r; | ||
278 | |||
279 | mode = 0xff; | ||
280 | r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, | ||
281 | MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1); | ||
282 | if (r) | ||
283 | return r; | ||
284 | |||
285 | if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
286 | r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_INITIATOR, | ||
287 | MICROREAD_PAR_P2P_INITIATOR_GI, | ||
288 | hdev->gb, hdev->gb_len); | ||
289 | if (r) | ||
290 | return r; | ||
291 | } | ||
292 | |||
293 | if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
294 | r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, | ||
295 | MICROREAD_PAR_P2P_TARGET_GT, | ||
296 | hdev->gb, hdev->gb_len); | ||
297 | if (r) | ||
298 | return r; | ||
299 | |||
300 | mode = 0x02; | ||
301 | r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, | ||
302 | MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1); | ||
303 | if (r) | ||
304 | return r; | ||
305 | } | ||
306 | |||
307 | return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A, | ||
308 | MICROREAD_EVT_MREAD_DISCOVERY_START_SOME, | ||
309 | param, 2); | ||
310 | } | ||
311 | |||
312 | static int microread_dep_link_up(struct nfc_hci_dev *hdev, | ||
313 | struct nfc_target *target, u8 comm_mode, | ||
314 | u8 *gb, size_t gb_len) | ||
315 | { | ||
316 | struct sk_buff *rgb_skb = NULL; | ||
317 | int r; | ||
318 | |||
319 | r = nfc_hci_get_param(hdev, target->hci_reader_gate, | ||
320 | MICROREAD_PAR_P2P_INITIATOR_GT, &rgb_skb); | ||
321 | if (r < 0) | ||
322 | return r; | ||
323 | |||
324 | if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) { | ||
325 | r = -EPROTO; | ||
326 | goto exit; | ||
327 | } | ||
328 | |||
329 | r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data, | ||
330 | rgb_skb->len); | ||
331 | if (r == 0) | ||
332 | r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode, | ||
333 | NFC_RF_INITIATOR); | ||
334 | exit: | ||
335 | kfree_skb(rgb_skb); | ||
336 | |||
337 | return r; | ||
338 | } | ||
339 | |||
340 | static int microread_dep_link_down(struct nfc_hci_dev *hdev) | ||
341 | { | ||
342 | return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_INITIATOR, | ||
343 | MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0); | ||
344 | } | ||
345 | |||
346 | static int microread_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, | ||
347 | struct nfc_target *target) | ||
348 | { | ||
349 | switch (gate) { | ||
350 | case MICROREAD_GATE_ID_P2P_INITIATOR: | ||
351 | target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; | ||
352 | break; | ||
353 | default: | ||
354 | return -EPROTO; | ||
355 | } | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int microread_complete_target_discovered(struct nfc_hci_dev *hdev, | ||
361 | u8 gate, | ||
362 | struct nfc_target *target) | ||
363 | { | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | #define MICROREAD_CB_TYPE_READER_ALL 1 | ||
368 | |||
369 | static void microread_im_transceive_cb(void *context, struct sk_buff *skb, | ||
370 | int err) | ||
371 | { | ||
372 | struct microread_info *info = context; | ||
373 | |||
374 | switch (info->async_cb_type) { | ||
375 | case MICROREAD_CB_TYPE_READER_ALL: | ||
376 | if (err == 0) { | ||
377 | if (skb->len == 0) { | ||
378 | err = -EPROTO; | ||
379 | kfree_skb(skb); | ||
380 | info->async_cb(info->async_cb_context, NULL, | ||
381 | -EPROTO); | ||
382 | return; | ||
383 | } | ||
384 | |||
385 | if (skb->data[skb->len - 1] != 0) { | ||
386 | err = nfc_hci_result_to_errno( | ||
387 | skb->data[skb->len - 1]); | ||
388 | kfree_skb(skb); | ||
389 | info->async_cb(info->async_cb_context, NULL, | ||
390 | err); | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | skb_trim(skb, skb->len - 1); /* RF Error ind. */ | ||
395 | } | ||
396 | info->async_cb(info->async_cb_context, skb, err); | ||
397 | break; | ||
398 | default: | ||
399 | if (err == 0) | ||
400 | kfree_skb(skb); | ||
401 | break; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * Returns: | ||
407 | * <= 0: driver handled the data exchange | ||
408 | * 1: driver doesn't especially handle, please do standard processing | ||
409 | */ | ||
410 | static int microread_im_transceive(struct nfc_hci_dev *hdev, | ||
411 | struct nfc_target *target, | ||
412 | struct sk_buff *skb, data_exchange_cb_t cb, | ||
413 | void *cb_context) | ||
414 | { | ||
415 | struct microread_info *info = nfc_hci_get_clientdata(hdev); | ||
416 | u8 control_bits; | ||
417 | u16 crc; | ||
418 | |||
419 | pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate); | ||
420 | |||
421 | if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) { | ||
422 | *skb_push(skb, 1) = 0; | ||
423 | |||
424 | return nfc_hci_send_event(hdev, target->hci_reader_gate, | ||
425 | MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF, | ||
426 | skb->data, skb->len); | ||
427 | } | ||
428 | |||
429 | switch (target->hci_reader_gate) { | ||
430 | case MICROREAD_GATE_ID_MREAD_ISO_A: | ||
431 | control_bits = 0xCB; | ||
432 | break; | ||
433 | case MICROREAD_GATE_ID_MREAD_ISO_A_3: | ||
434 | control_bits = 0xCB; | ||
435 | break; | ||
436 | case MICROREAD_GATE_ID_MREAD_ISO_B: | ||
437 | control_bits = 0xCB; | ||
438 | break; | ||
439 | case MICROREAD_GATE_ID_MREAD_NFC_T1: | ||
440 | control_bits = 0x1B; | ||
441 | |||
442 | crc = crc_ccitt(0xffff, skb->data, skb->len); | ||
443 | crc = ~crc; | ||
444 | *skb_put(skb, 1) = crc & 0xff; | ||
445 | *skb_put(skb, 1) = crc >> 8; | ||
446 | break; | ||
447 | case MICROREAD_GATE_ID_MREAD_NFC_T3: | ||
448 | control_bits = 0xDB; | ||
449 | break; | ||
450 | default: | ||
451 | pr_info("Abort im_transceive to invalid gate 0x%x\n", | ||
452 | target->hci_reader_gate); | ||
453 | return 1; | ||
454 | } | ||
455 | |||
456 | *skb_push(skb, 1) = control_bits; | ||
457 | |||
458 | info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL; | ||
459 | info->async_cb = cb; | ||
460 | info->async_cb_context = cb_context; | ||
461 | |||
462 | return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, | ||
463 | MICROREAD_CMD_MREAD_EXCHANGE, | ||
464 | skb->data, skb->len, | ||
465 | microread_im_transceive_cb, info); | ||
466 | } | ||
467 | |||
468 | static int microread_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) | ||
469 | { | ||
470 | int r; | ||
471 | |||
472 | r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_TARGET, | ||
473 | MICROREAD_EVT_MCARD_EXCHANGE, | ||
474 | skb->data, skb->len); | ||
475 | |||
476 | kfree_skb(skb); | ||
477 | |||
478 | return r; | ||
479 | } | ||
480 | |||
481 | static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate, | ||
482 | struct sk_buff *skb) | ||
483 | { | ||
484 | struct nfc_target *targets; | ||
485 | int r = 0; | ||
486 | |||
487 | pr_info("target discovered to gate 0x%x\n", gate); | ||
488 | |||
489 | targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); | ||
490 | if (targets == NULL) { | ||
491 | r = -ENOMEM; | ||
492 | goto exit; | ||
493 | } | ||
494 | |||
495 | targets->hci_reader_gate = gate; | ||
496 | |||
497 | switch (gate) { | ||
498 | case MICROREAD_GATE_ID_MREAD_ISO_A: | ||
499 | targets->supported_protocols = | ||
500 | nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]); | ||
501 | targets->sens_res = | ||
502 | be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]); | ||
503 | targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK]; | ||
504 | memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A_UID], | ||
505 | skb->data[MICROREAD_EMCF_A_LEN]); | ||
506 | targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN]; | ||
507 | break; | ||
508 | case MICROREAD_GATE_ID_MREAD_ISO_A_3: | ||
509 | targets->supported_protocols = | ||
510 | nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]); | ||
511 | targets->sens_res = | ||
512 | be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]); | ||
513 | targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK]; | ||
514 | memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A3_UID], | ||
515 | skb->data[MICROREAD_EMCF_A3_LEN]); | ||
516 | targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN]; | ||
517 | break; | ||
518 | case MICROREAD_GATE_ID_MREAD_ISO_B: | ||
519 | targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK; | ||
520 | memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4); | ||
521 | targets->nfcid1_len = 4; | ||
522 | break; | ||
523 | case MICROREAD_GATE_ID_MREAD_NFC_T1: | ||
524 | targets->supported_protocols = NFC_PROTO_JEWEL_MASK; | ||
525 | targets->sens_res = | ||
526 | le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]); | ||
527 | memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T1_UID], 4); | ||
528 | targets->nfcid1_len = 4; | ||
529 | break; | ||
530 | case MICROREAD_GATE_ID_MREAD_NFC_T3: | ||
531 | targets->supported_protocols = NFC_PROTO_FELICA_MASK; | ||
532 | memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8); | ||
533 | targets->nfcid1_len = 8; | ||
534 | break; | ||
535 | default: | ||
536 | pr_info("discard target discovered to gate 0x%x\n", gate); | ||
537 | goto exit_free; | ||
538 | } | ||
539 | |||
540 | r = nfc_targets_found(hdev->ndev, targets, 1); | ||
541 | |||
542 | exit_free: | ||
543 | kfree(targets); | ||
544 | |||
545 | exit: | ||
546 | kfree_skb(skb); | ||
547 | |||
548 | if (r) | ||
549 | pr_err("Failed to handle discovered target err=%d", r); | ||
550 | } | ||
551 | |||
552 | static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate, | ||
553 | u8 event, struct sk_buff *skb) | ||
554 | { | ||
555 | int r; | ||
556 | u8 mode; | ||
557 | |||
558 | pr_info("Microread received event 0x%x to gate 0x%x\n", event, gate); | ||
559 | |||
560 | switch (event) { | ||
561 | case MICROREAD_EVT_MREAD_CARD_FOUND: | ||
562 | microread_target_discovered(hdev, gate, skb); | ||
563 | return 0; | ||
564 | |||
565 | case MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF: | ||
566 | if (skb->len < 1) { | ||
567 | kfree_skb(skb); | ||
568 | return -EPROTO; | ||
569 | } | ||
570 | |||
571 | if (skb->data[skb->len - 1]) { | ||
572 | kfree_skb(skb); | ||
573 | return -EIO; | ||
574 | } | ||
575 | |||
576 | skb_trim(skb, skb->len - 1); | ||
577 | |||
578 | r = nfc_tm_data_received(hdev->ndev, skb); | ||
579 | break; | ||
580 | |||
581 | case MICROREAD_EVT_MCARD_FIELD_ON: | ||
582 | case MICROREAD_EVT_MCARD_FIELD_OFF: | ||
583 | kfree_skb(skb); | ||
584 | return 0; | ||
585 | |||
586 | case MICROREAD_EVT_P2P_TARGET_ACTIVATED: | ||
587 | r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, | ||
588 | NFC_COMM_PASSIVE, skb->data, | ||
589 | skb->len); | ||
590 | |||
591 | kfree_skb(skb); | ||
592 | break; | ||
593 | |||
594 | case MICROREAD_EVT_MCARD_EXCHANGE: | ||
595 | if (skb->len < 1) { | ||
596 | kfree_skb(skb); | ||
597 | return -EPROTO; | ||
598 | } | ||
599 | |||
600 | if (skb->data[skb->len-1]) { | ||
601 | kfree_skb(skb); | ||
602 | return -EIO; | ||
603 | } | ||
604 | |||
605 | skb_trim(skb, skb->len - 1); | ||
606 | |||
607 | r = nfc_tm_data_received(hdev->ndev, skb); | ||
608 | break; | ||
609 | |||
610 | case MICROREAD_EVT_P2P_TARGET_DEACTIVATED: | ||
611 | kfree_skb(skb); | ||
612 | |||
613 | mode = 0xff; | ||
614 | r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, | ||
615 | MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1); | ||
616 | if (r) | ||
617 | break; | ||
618 | |||
619 | r = nfc_hci_send_event(hdev, gate, | ||
620 | MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, | ||
621 | 0); | ||
622 | break; | ||
623 | |||
624 | default: | ||
625 | return 1; | ||
626 | } | ||
627 | |||
628 | return r; | ||
629 | } | ||
630 | |||
631 | static struct nfc_hci_ops microread_hci_ops = { | ||
632 | .open = microread_open, | ||
633 | .close = microread_close, | ||
634 | .hci_ready = microread_hci_ready, | ||
635 | .xmit = microread_xmit, | ||
636 | .start_poll = microread_start_poll, | ||
637 | .dep_link_up = microread_dep_link_up, | ||
638 | .dep_link_down = microread_dep_link_down, | ||
639 | .target_from_gate = microread_target_from_gate, | ||
640 | .complete_target_discovered = microread_complete_target_discovered, | ||
641 | .im_transceive = microread_im_transceive, | ||
642 | .tm_send = microread_tm_send, | ||
643 | .check_presence = NULL, | ||
644 | .event_received = microread_event_received, | ||
645 | }; | ||
646 | |||
647 | int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, | ||
648 | int phy_headroom, int phy_tailroom, int phy_payload, | ||
649 | struct nfc_hci_dev **hdev) | ||
650 | { | ||
651 | struct microread_info *info; | ||
652 | unsigned long quirks = 0; | ||
653 | u32 protocols, se; | ||
654 | struct nfc_hci_init_data init_data; | ||
655 | int r; | ||
656 | |||
657 | info = kzalloc(sizeof(struct microread_info), GFP_KERNEL); | ||
658 | if (!info) { | ||
659 | pr_err("Cannot allocate memory for microread_info.\n"); | ||
660 | r = -ENOMEM; | ||
661 | goto err_info_alloc; | ||
662 | } | ||
663 | |||
664 | info->phy_ops = phy_ops; | ||
665 | info->phy_id = phy_id; | ||
666 | |||
667 | init_data.gate_count = ARRAY_SIZE(microread_gates); | ||
668 | memcpy(init_data.gates, microread_gates, sizeof(microread_gates)); | ||
669 | |||
670 | strcpy(init_data.session_id, "MICROREA"); | ||
671 | |||
672 | set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); | ||
673 | |||
674 | protocols = NFC_PROTO_JEWEL_MASK | | ||
675 | NFC_PROTO_MIFARE_MASK | | ||
676 | NFC_PROTO_FELICA_MASK | | ||
677 | NFC_PROTO_ISO14443_MASK | | ||
678 | NFC_PROTO_ISO14443_B_MASK | | ||
679 | NFC_PROTO_NFC_DEP_MASK; | ||
680 | |||
681 | se = NFC_SE_UICC | NFC_SE_EMBEDDED; | ||
682 | |||
683 | info->hdev = nfc_hci_allocate_device(µread_hci_ops, &init_data, | ||
684 | quirks, protocols, se, llc_name, | ||
685 | phy_headroom + | ||
686 | MICROREAD_CMDS_HEADROOM, | ||
687 | phy_tailroom + | ||
688 | MICROREAD_CMD_TAILROOM, | ||
689 | phy_payload); | ||
690 | if (!info->hdev) { | ||
691 | pr_err("Cannot allocate nfc hdev.\n"); | ||
692 | r = -ENOMEM; | ||
693 | goto err_alloc_hdev; | ||
694 | } | ||
695 | |||
696 | nfc_hci_set_clientdata(info->hdev, info); | ||
697 | |||
698 | r = nfc_hci_register_device(info->hdev); | ||
699 | if (r) | ||
700 | goto err_regdev; | ||
701 | |||
702 | *hdev = info->hdev; | ||
703 | |||
704 | return 0; | ||
705 | |||
706 | err_regdev: | ||
707 | nfc_hci_free_device(info->hdev); | ||
708 | |||
709 | err_alloc_hdev: | ||
710 | kfree(info); | ||
711 | |||
712 | err_info_alloc: | ||
713 | return r; | ||
714 | } | ||
715 | EXPORT_SYMBOL(microread_probe); | ||
716 | |||
717 | void microread_remove(struct nfc_hci_dev *hdev) | ||
718 | { | ||
719 | struct microread_info *info = nfc_hci_get_clientdata(hdev); | ||
720 | |||
721 | nfc_hci_unregister_device(hdev); | ||
722 | nfc_hci_free_device(hdev); | ||
723 | kfree(info); | ||
724 | } | ||
725 | EXPORT_SYMBOL(microread_remove); | ||
726 | |||
727 | MODULE_LICENSE("GPL"); | ||
728 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/drivers/nfc/microread/microread.h b/drivers/nfc/microread/microread.h new file mode 100644 index 000000000000..64b447a1c5bf --- /dev/null +++ b/drivers/nfc/microread/microread.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 - 2012 Intel Corporation. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __LOCAL_MICROREAD_H_ | ||
21 | #define __LOCAL_MICROREAD_H_ | ||
22 | |||
23 | #include <net/nfc/hci.h> | ||
24 | |||
25 | #define DRIVER_DESC "NFC driver for microread" | ||
26 | |||
27 | int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, | ||
28 | int phy_headroom, int phy_tailroom, int phy_payload, | ||
29 | struct nfc_hci_dev **hdev); | ||
30 | |||
31 | void microread_remove(struct nfc_hci_dev *hdev); | ||
32 | |||
33 | #endif /* __LOCAL_MICROREAD_H_ */ | ||
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index f696318cfb51..f0f6763d67ae 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
@@ -219,7 +219,7 @@ struct pn533_poll_modulations { | |||
219 | u8 len; | 219 | u8 len; |
220 | }; | 220 | }; |
221 | 221 | ||
222 | const struct pn533_poll_modulations poll_mod[] = { | 222 | static const struct pn533_poll_modulations poll_mod[] = { |
223 | [PN533_POLL_MOD_106KBPS_A] = { | 223 | [PN533_POLL_MOD_106KBPS_A] = { |
224 | .data = { | 224 | .data = { |
225 | .maxtg = 1, | 225 | .maxtg = 1, |
@@ -485,7 +485,7 @@ static u8 pn533_get_cmd_code(void *frame) | |||
485 | return PN533_FRAME_CMD(f); | 485 | return PN533_FRAME_CMD(f); |
486 | } | 486 | } |
487 | 487 | ||
488 | struct pn533_frame_ops pn533_std_frame_ops = { | 488 | static struct pn533_frame_ops pn533_std_frame_ops = { |
489 | .tx_frame_init = pn533_tx_frame_init, | 489 | .tx_frame_init = pn533_tx_frame_init, |
490 | .tx_frame_finish = pn533_tx_frame_finish, | 490 | .tx_frame_finish = pn533_tx_frame_finish, |
491 | .tx_update_payload_len = pn533_tx_update_payload_len, | 491 | .tx_update_payload_len = pn533_tx_update_payload_len, |
@@ -532,7 +532,6 @@ static void pn533_recv_response(struct urb *urb) | |||
532 | urb->status); | 532 | urb->status); |
533 | dev->wq_in_error = urb->status; | 533 | dev->wq_in_error = urb->status; |
534 | goto sched_wq; | 534 | goto sched_wq; |
535 | break; | ||
536 | case -ESHUTDOWN: | 535 | case -ESHUTDOWN: |
537 | default: | 536 | default: |
538 | nfc_dev_err(&dev->interface->dev, | 537 | nfc_dev_err(&dev->interface->dev, |
@@ -589,7 +588,6 @@ static void pn533_recv_ack(struct urb *urb) | |||
589 | urb->status); | 588 | urb->status); |
590 | dev->wq_in_error = urb->status; | 589 | dev->wq_in_error = urb->status; |
591 | goto sched_wq; | 590 | goto sched_wq; |
592 | break; | ||
593 | case -ESHUTDOWN: | 591 | case -ESHUTDOWN: |
594 | default: | 592 | default: |
595 | nfc_dev_err(&dev->interface->dev, | 593 | nfc_dev_err(&dev->interface->dev, |
@@ -1380,7 +1378,7 @@ static struct sk_buff *pn533_alloc_poll_tg_frame(struct pn533 *dev) | |||
1380 | return NULL; | 1378 | return NULL; |
1381 | 1379 | ||
1382 | /* DEP support only */ | 1380 | /* DEP support only */ |
1383 | *skb_put(skb, 1) |= PN533_INIT_TARGET_DEP; | 1381 | *skb_put(skb, 1) = PN533_INIT_TARGET_DEP; |
1384 | 1382 | ||
1385 | /* MIFARE params */ | 1383 | /* MIFARE params */ |
1386 | memcpy(skb_put(skb, 6), mifare_params, 6); | 1384 | memcpy(skb_put(skb, 6), mifare_params, 6); |