blob: fa12f59cf7b97736f3751497c719e35cc4daaddf [file] [log] [blame]
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001/*
2 * Copyright (C) 2011 Instituto Nokia de Tecnologia
Waldemar Rymarkiewicze70b96e2013-04-03 08:02:01 +02003 * Copyright (C) 2012-2013 Tieto Poland
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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/device.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/usb.h>
26#include <linux/nfc.h>
27#include <linux/netdevice.h>
Ilan Elias55eb94f2011-09-18 11:19:34 +030028#include <net/nfc/nfc.h>
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030029
Waldemar Rymarkiewicz495af722013-04-03 08:02:16 +020030#define VERSION "0.2"
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030031
32#define PN533_VENDOR_ID 0x4CC
33#define PN533_PRODUCT_ID 0x2533
34
35#define SCM_VENDOR_ID 0x4E6
36#define SCL3711_PRODUCT_ID 0x5591
37
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020038#define SONY_VENDOR_ID 0x054c
39#define PASORI_PRODUCT_ID 0x02e1
40
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +020041#define ACS_VENDOR_ID 0x072f
42#define ACR122U_PRODUCT_ID 0x2200
43
44#define PN533_DEVICE_STD 0x1
45#define PN533_DEVICE_PASORI 0x2
46#define PN533_DEVICE_ACR122U 0x3
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020047
Samuel Ortiz01d719a2012-07-04 00:14:04 +020048#define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\
49 NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\
50 NFC_PROTO_NFC_DEP_MASK |\
51 NFC_PROTO_ISO14443_B_MASK)
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020052
53#define PN533_NO_TYPE_B_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
54 NFC_PROTO_MIFARE_MASK | \
55 NFC_PROTO_FELICA_MASK | \
Samuel Ortiz01d719a2012-07-04 00:14:04 +020056 NFC_PROTO_ISO14443_MASK | \
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020057 NFC_PROTO_NFC_DEP_MASK)
58
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030059static const struct usb_device_id pn533_table[] = {
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020060 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
61 .idVendor = PN533_VENDOR_ID,
62 .idProduct = PN533_PRODUCT_ID,
63 .driver_info = PN533_DEVICE_STD,
64 },
65 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
66 .idVendor = SCM_VENDOR_ID,
67 .idProduct = SCL3711_PRODUCT_ID,
68 .driver_info = PN533_DEVICE_STD,
69 },
70 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
71 .idVendor = SONY_VENDOR_ID,
72 .idProduct = PASORI_PRODUCT_ID,
73 .driver_info = PN533_DEVICE_PASORI,
74 },
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +020075 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
76 .idVendor = ACS_VENDOR_ID,
77 .idProduct = ACR122U_PRODUCT_ID,
78 .driver_info = PN533_DEVICE_ACR122U,
79 },
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030080 { }
81};
82MODULE_DEVICE_TABLE(usb, pn533_table);
83
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +020084/* How much time we spend listening for initiators */
85#define PN533_LISTEN_TIME 2
86
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +020087/* Standard pn533 frame definitions */
88#define PN533_STD_FRAME_HEADER_LEN (sizeof(struct pn533_std_frame) \
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +010089 + 2) /* data[0] TFI, data[1] CC */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +020090#define PN533_STD_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/
Waldemar Rymarkiewicz82dec342012-10-11 14:03:58 +020091
Waldemar Rymarkiewicz15461ae2012-11-26 14:18:35 +010092/*
93 * Max extended frame payload len, excluding TFI and CC
94 * which are already in PN533_FRAME_HEADER_LEN.
95 */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +020096#define PN533_STD_FRAME_MAX_PAYLOAD_LEN 263
Waldemar Rymarkiewicz15461ae2012-11-26 14:18:35 +010097
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +020098#define PN533_STD_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2),
Waldemar Rymarkiewicz5b5a4432012-12-10 14:42:56 +010099 Postamble (1) */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200100#define PN533_STD_FRAME_CHECKSUM(f) (f->data[f->datalen])
101#define PN533_STD_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1])
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300102
103/* start of frame */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200104#define PN533_STD_FRAME_SOF 0x00FF
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300105
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200106/* standard frame identifier: in/out/error */
107#define PN533_STD_FRAME_IDENTIFIER(f) (f->data[0]) /* TFI */
108#define PN533_STD_FRAME_DIR_OUT 0xD4
109#define PN533_STD_FRAME_DIR_IN 0xD5
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300110
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +0200111/* ACS ACR122 pn533 frame definitions */
112#define PN533_ACR122_TX_FRAME_HEADER_LEN (sizeof(struct pn533_acr122_tx_frame) \
113 + 2)
114#define PN533_ACR122_TX_FRAME_TAIL_LEN 0
115#define PN533_ACR122_RX_FRAME_HEADER_LEN (sizeof(struct pn533_acr122_rx_frame) \
116 + 2)
117#define PN533_ACR122_RX_FRAME_TAIL_LEN 2
118#define PN533_ACR122_FRAME_MAX_PAYLOAD_LEN PN533_STD_FRAME_MAX_PAYLOAD_LEN
119
120/* CCID messages types */
121#define PN533_ACR122_PC_TO_RDR_ICCPOWERON 0x62
122#define PN533_ACR122_PC_TO_RDR_ESCAPE 0x6B
123
124#define PN533_ACR122_RDR_TO_PC_ESCAPE 0x83
125
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300126/* PN533 Commands */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200127#define PN533_STD_FRAME_CMD(f) (f->data[1])
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300128
129#define PN533_CMD_GET_FIRMWARE_VERSION 0x02
130#define PN533_CMD_RF_CONFIGURATION 0x32
131#define PN533_CMD_IN_DATA_EXCHANGE 0x40
Samuel Ortiz5c7b0532012-07-02 20:04:01 +0200132#define PN533_CMD_IN_COMM_THRU 0x42
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300133#define PN533_CMD_IN_LIST_PASSIVE_TARGET 0x4A
134#define PN533_CMD_IN_ATR 0x50
135#define PN533_CMD_IN_RELEASE 0x52
Samuel Ortiz361f3cb2011-12-14 16:43:11 +0100136#define PN533_CMD_IN_JUMP_FOR_DEP 0x56
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300137
Samuel Ortizad3823c2012-05-30 23:54:55 +0200138#define PN533_CMD_TG_INIT_AS_TARGET 0x8c
Samuel Ortiz103b34c2012-05-31 00:07:51 +0200139#define PN533_CMD_TG_GET_DATA 0x86
Samuel Ortizdadb06f2012-05-31 00:09:11 +0200140#define PN533_CMD_TG_SET_DATA 0x8e
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100141#define PN533_CMD_UNDEF 0xff
Samuel Ortizad3823c2012-05-30 23:54:55 +0200142
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300143#define PN533_CMD_RESPONSE(cmd) (cmd + 1)
144
145/* PN533 Return codes */
146#define PN533_CMD_RET_MASK 0x3F
147#define PN533_CMD_MI_MASK 0x40
148#define PN533_CMD_RET_SUCCESS 0x00
149
150struct pn533;
151
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100152typedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg,
153 struct sk_buff *resp);
154
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300155/* structs for pn533 commands */
156
157/* PN533_CMD_GET_FIRMWARE_VERSION */
158struct pn533_fw_version {
159 u8 ic;
160 u8 ver;
161 u8 rev;
162 u8 support;
163};
164
165/* PN533_CMD_RF_CONFIGURATION */
Samuel Ortiz60d9edd52013-04-11 11:45:41 +0200166#define PN533_CFGITEM_RF_FIELD 0x01
167#define PN533_CFGITEM_TIMING 0x02
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300168#define PN533_CFGITEM_MAX_RETRIES 0x05
Samuel Ortiz60d9edd52013-04-11 11:45:41 +0200169#define PN533_CFGITEM_PASORI 0x82
170
171#define PN533_CFGITEM_RF_FIELD_ON 0x1
172#define PN533_CFGITEM_RF_FIELD_OFF 0x0
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300173
Samuel Ortiz34a85bf2012-05-29 21:34:08 +0200174#define PN533_CONFIG_TIMING_102 0xb
175#define PN533_CONFIG_TIMING_204 0xc
176#define PN533_CONFIG_TIMING_409 0xd
177#define PN533_CONFIG_TIMING_819 0xe
178
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300179#define PN533_CONFIG_MAX_RETRIES_NO_RETRY 0x00
180#define PN533_CONFIG_MAX_RETRIES_ENDLESS 0xFF
181
182struct pn533_config_max_retries {
183 u8 mx_rty_atr;
184 u8 mx_rty_psl;
185 u8 mx_rty_passive_act;
186} __packed;
187
Samuel Ortiz34a85bf2012-05-29 21:34:08 +0200188struct pn533_config_timing {
189 u8 rfu;
190 u8 atr_res_timeout;
191 u8 dep_timeout;
192} __packed;
193
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300194/* PN533_CMD_IN_LIST_PASSIVE_TARGET */
195
196/* felica commands opcode */
197#define PN533_FELICA_OPC_SENSF_REQ 0
198#define PN533_FELICA_OPC_SENSF_RES 1
199/* felica SENSF_REQ parameters */
200#define PN533_FELICA_SENSF_SC_ALL 0xFFFF
201#define PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE 0
202#define PN533_FELICA_SENSF_RC_SYSTEM_CODE 1
203#define PN533_FELICA_SENSF_RC_ADVANCED_PROTOCOL 2
204
205/* type B initiator_data values */
206#define PN533_TYPE_B_AFI_ALL_FAMILIES 0
207#define PN533_TYPE_B_POLL_METHOD_TIMESLOT 0
208#define PN533_TYPE_B_POLL_METHOD_PROBABILISTIC 1
209
210union pn533_cmd_poll_initdata {
211 struct {
212 u8 afi;
213 u8 polling_method;
214 } __packed type_b;
215 struct {
216 u8 opcode;
217 __be16 sc;
218 u8 rc;
219 u8 tsn;
220 } __packed felica;
221};
222
223/* Poll modulations */
224enum {
225 PN533_POLL_MOD_106KBPS_A,
226 PN533_POLL_MOD_212KBPS_FELICA,
227 PN533_POLL_MOD_424KBPS_FELICA,
228 PN533_POLL_MOD_106KBPS_JEWEL,
229 PN533_POLL_MOD_847KBPS_B,
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200230 PN533_LISTEN_MOD,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300231
232 __PN533_POLL_MOD_AFTER_LAST,
233};
234#define PN533_POLL_MOD_MAX (__PN533_POLL_MOD_AFTER_LAST - 1)
235
236struct pn533_poll_modulations {
237 struct {
238 u8 maxtg;
239 u8 brty;
240 union pn533_cmd_poll_initdata initiator_data;
241 } __packed data;
242 u8 len;
243};
244
Waldemar Rymarkiewiczef3d56e2013-01-16 15:51:51 +0100245static const struct pn533_poll_modulations poll_mod[] = {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300246 [PN533_POLL_MOD_106KBPS_A] = {
247 .data = {
248 .maxtg = 1,
249 .brty = 0,
250 },
251 .len = 2,
252 },
253 [PN533_POLL_MOD_212KBPS_FELICA] = {
254 .data = {
255 .maxtg = 1,
256 .brty = 1,
257 .initiator_data.felica = {
258 .opcode = PN533_FELICA_OPC_SENSF_REQ,
259 .sc = PN533_FELICA_SENSF_SC_ALL,
Samuel Ortiza94e10f2013-06-28 15:43:19 +0200260 .rc = PN533_FELICA_SENSF_RC_SYSTEM_CODE,
Samuel Ortiz31c44462013-05-27 14:59:40 +0200261 .tsn = 0x03,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300262 },
263 },
264 .len = 7,
265 },
266 [PN533_POLL_MOD_424KBPS_FELICA] = {
267 .data = {
268 .maxtg = 1,
269 .brty = 2,
270 .initiator_data.felica = {
271 .opcode = PN533_FELICA_OPC_SENSF_REQ,
272 .sc = PN533_FELICA_SENSF_SC_ALL,
Samuel Ortiza94e10f2013-06-28 15:43:19 +0200273 .rc = PN533_FELICA_SENSF_RC_SYSTEM_CODE,
Samuel Ortiz31c44462013-05-27 14:59:40 +0200274 .tsn = 0x03,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300275 },
276 },
277 .len = 7,
278 },
279 [PN533_POLL_MOD_106KBPS_JEWEL] = {
280 .data = {
281 .maxtg = 1,
282 .brty = 4,
283 },
284 .len = 2,
285 },
286 [PN533_POLL_MOD_847KBPS_B] = {
287 .data = {
288 .maxtg = 1,
289 .brty = 8,
290 .initiator_data.type_b = {
291 .afi = PN533_TYPE_B_AFI_ALL_FAMILIES,
292 .polling_method =
293 PN533_TYPE_B_POLL_METHOD_TIMESLOT,
294 },
295 },
296 .len = 3,
297 },
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200298 [PN533_LISTEN_MOD] = {
299 .len = 0,
300 },
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300301};
302
303/* PN533_CMD_IN_ATR */
304
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300305struct pn533_cmd_activate_response {
306 u8 status;
307 u8 nfcid3t[10];
308 u8 didt;
309 u8 bst;
310 u8 brt;
311 u8 to;
312 u8 ppt;
313 /* optional */
314 u8 gt[];
315} __packed;
316
Samuel Ortiz361f3cb2011-12-14 16:43:11 +0100317struct pn533_cmd_jump_dep_response {
318 u8 status;
319 u8 tg;
320 u8 nfcid3t[10];
321 u8 didt;
322 u8 bst;
323 u8 brt;
324 u8 to;
325 u8 ppt;
326 /* optional */
327 u8 gt[];
328} __packed;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300329
Samuel Ortizad3823c2012-05-30 23:54:55 +0200330
331/* PN533_TG_INIT_AS_TARGET */
332#define PN533_INIT_TARGET_PASSIVE 0x1
333#define PN533_INIT_TARGET_DEP 0x2
334
Samuel Ortizfc40a8c2012-06-01 13:21:13 +0200335#define PN533_INIT_TARGET_RESP_FRAME_MASK 0x3
336#define PN533_INIT_TARGET_RESP_ACTIVE 0x1
337#define PN533_INIT_TARGET_RESP_DEP 0x4
338
Waldemar Rymarkiewicz58520372013-04-03 08:02:12 +0200339enum pn533_protocol_type {
340 PN533_PROTO_REQ_ACK_RESP = 0,
341 PN533_PROTO_REQ_RESP
342};
343
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300344struct pn533 {
345 struct usb_device *udev;
346 struct usb_interface *interface;
347 struct nfc_dev *nfc_dev;
Waldemar Rymarkiewiczd5590bb2013-04-03 08:02:10 +0200348 u32 device_type;
Waldemar Rymarkiewicz58520372013-04-03 08:02:12 +0200349 enum pn533_protocol_type protocol_type;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300350
351 struct urb *out_urb;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300352 struct urb *in_urb;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300353
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +0200354 struct sk_buff_head resp_q;
355
Samuel Ortiz4849f852012-04-10 19:43:17 +0200356 struct workqueue_struct *wq;
357 struct work_struct cmd_work;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200358 struct work_struct cmd_complete_work;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200359 struct work_struct poll_work;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +0200360 struct work_struct mi_work;
Samuel Ortiz103b34c2012-05-31 00:07:51 +0200361 struct work_struct tg_work;
Samuel Ortiz17e9d9d2013-06-26 18:16:21 +0200362 struct work_struct rf_work;
Waldemar Rymarkiewiczd5590bb2013-04-03 08:02:10 +0200363
364 struct list_head cmd_queue;
365 struct pn533_cmd *cmd;
366 u8 cmd_pending;
Waldemar Rymarkiewiczd5590bb2013-04-03 08:02:10 +0200367 struct mutex cmd_lock; /* protects cmd queue */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300368
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100369 void *cmd_complete_mi_arg;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300370
371 struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1];
372 u8 poll_mod_count;
373 u8 poll_mod_curr;
374 u32 poll_protocols;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200375 u32 listen_protocols;
Waldemar Rymarkiewiczd5590bb2013-04-03 08:02:10 +0200376 struct timer_list listen_timer;
377 int cancel_listen;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200378
379 u8 *gb;
380 size_t gb_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300381
382 u8 tgt_available_prots;
383 u8 tgt_active_prot;
Samuel Ortiz51ad3042012-05-31 20:01:32 +0200384 u8 tgt_mode;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +0200385
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100386 struct pn533_frame_ops *ops;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200387};
388
389struct pn533_cmd {
390 struct list_head queue;
Waldemar Rymarkiewicz4b2a9532013-04-03 08:02:06 +0200391 u8 code;
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200392 int status;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100393 struct sk_buff *req;
394 struct sk_buff *resp;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100395 int resp_len;
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200396 pn533_send_async_complete_t complete_cb;
397 void *complete_cb_context;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300398};
399
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200400struct pn533_std_frame {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300401 u8 preamble;
402 __be16 start_frame;
403 u8 datalen;
404 u8 datalen_checksum;
405 u8 data[];
406} __packed;
407
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100408struct pn533_frame_ops {
409 void (*tx_frame_init)(void *frame, u8 cmd_code);
410 void (*tx_frame_finish)(void *frame);
411 void (*tx_update_payload_len)(void *frame, int len);
412 int tx_header_len;
413 int tx_tail_len;
414
415 bool (*rx_is_frame_valid)(void *frame);
416 int (*rx_frame_size)(void *frame);
417 int rx_header_len;
418 int rx_tail_len;
419
420 int max_payload_len;
421 u8 (*get_cmd_code)(void *frame);
422};
423
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +0200424struct pn533_acr122_ccid_hdr {
425 u8 type;
426 u32 datalen;
427 u8 slot;
428 u8 seq;
429 u8 params[3]; /* 3 msg specific bytes or status, error and 1 specific
430 byte for reposnse msg */
431 u8 data[]; /* payload */
432} __packed;
433
434struct pn533_acr122_apdu_hdr {
435 u8 class;
436 u8 ins;
437 u8 p1;
438 u8 p2;
439} __packed;
440
441struct pn533_acr122_tx_frame {
442 struct pn533_acr122_ccid_hdr ccid;
443 struct pn533_acr122_apdu_hdr apdu;
444 u8 datalen;
445 u8 data[]; /* pn533 frame: TFI ... */
446} __packed;
447
448struct pn533_acr122_rx_frame {
449 struct pn533_acr122_ccid_hdr ccid;
450 u8 data[]; /* pn533 frame : TFI ... */
451} __packed;
452
453static void pn533_acr122_tx_frame_init(void *_frame, u8 cmd_code)
454{
455 struct pn533_acr122_tx_frame *frame = _frame;
456
457 frame->ccid.type = PN533_ACR122_PC_TO_RDR_ESCAPE;
458 frame->ccid.datalen = sizeof(frame->apdu) + 1; /* sizeof(apdu_hdr) +
459 sizeof(datalen) */
460 frame->ccid.slot = 0;
461 frame->ccid.seq = 0;
462 frame->ccid.params[0] = 0;
463 frame->ccid.params[1] = 0;
464 frame->ccid.params[2] = 0;
465
466 frame->data[0] = PN533_STD_FRAME_DIR_OUT;
467 frame->data[1] = cmd_code;
468 frame->datalen = 2; /* data[0] + data[1] */
469
470 frame->apdu.class = 0xFF;
471 frame->apdu.ins = 0;
472 frame->apdu.p1 = 0;
473 frame->apdu.p2 = 0;
474}
475
476static void pn533_acr122_tx_frame_finish(void *_frame)
477{
478 struct pn533_acr122_tx_frame *frame = _frame;
479
480 frame->ccid.datalen += frame->datalen;
481}
482
483static void pn533_acr122_tx_update_payload_len(void *_frame, int len)
484{
485 struct pn533_acr122_tx_frame *frame = _frame;
486
487 frame->datalen += len;
488}
489
490static bool pn533_acr122_is_rx_frame_valid(void *_frame)
491{
492 struct pn533_acr122_rx_frame *frame = _frame;
493
494 if (frame->ccid.type != 0x83)
495 return false;
496
497 if (frame->data[frame->ccid.datalen - 2] == 0x63)
498 return false;
499
500 return true;
501}
502
503static int pn533_acr122_rx_frame_size(void *frame)
504{
505 struct pn533_acr122_rx_frame *f = frame;
506
507 /* f->ccid.datalen already includes tail length */
508 return sizeof(struct pn533_acr122_rx_frame) + f->ccid.datalen;
509}
510
511static u8 pn533_acr122_get_cmd_code(void *frame)
512{
513 struct pn533_acr122_rx_frame *f = frame;
514
515 return PN533_STD_FRAME_CMD(f);
516}
517
518static struct pn533_frame_ops pn533_acr122_frame_ops = {
519 .tx_frame_init = pn533_acr122_tx_frame_init,
520 .tx_frame_finish = pn533_acr122_tx_frame_finish,
521 .tx_update_payload_len = pn533_acr122_tx_update_payload_len,
522 .tx_header_len = PN533_ACR122_TX_FRAME_HEADER_LEN,
523 .tx_tail_len = PN533_ACR122_TX_FRAME_TAIL_LEN,
524
525 .rx_is_frame_valid = pn533_acr122_is_rx_frame_valid,
526 .rx_header_len = PN533_ACR122_RX_FRAME_HEADER_LEN,
527 .rx_tail_len = PN533_ACR122_RX_FRAME_TAIL_LEN,
528 .rx_frame_size = pn533_acr122_rx_frame_size,
529
530 .max_payload_len = PN533_ACR122_FRAME_MAX_PAYLOAD_LEN,
531 .get_cmd_code = pn533_acr122_get_cmd_code,
532};
533
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300534/* The rule: value + checksum = 0 */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200535static inline u8 pn533_std_checksum(u8 value)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300536{
537 return ~value + 1;
538}
539
540/* The rule: sum(data elements) + checksum = 0 */
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200541static u8 pn533_std_data_checksum(u8 *data, int datalen)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300542{
543 u8 sum = 0;
544 int i;
545
546 for (i = 0; i < datalen; i++)
547 sum += data[i];
548
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200549 return pn533_std_checksum(sum);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300550}
551
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200552static void pn533_std_tx_frame_init(void *_frame, u8 cmd_code)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300553{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200554 struct pn533_std_frame *frame = _frame;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100555
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300556 frame->preamble = 0;
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200557 frame->start_frame = cpu_to_be16(PN533_STD_FRAME_SOF);
558 PN533_STD_FRAME_IDENTIFIER(frame) = PN533_STD_FRAME_DIR_OUT;
559 PN533_STD_FRAME_CMD(frame) = cmd_code;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300560 frame->datalen = 2;
561}
562
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200563static void pn533_std_tx_frame_finish(void *_frame)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300564{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200565 struct pn533_std_frame *frame = _frame;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100566
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200567 frame->datalen_checksum = pn533_std_checksum(frame->datalen);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300568
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200569 PN533_STD_FRAME_CHECKSUM(frame) =
570 pn533_std_data_checksum(frame->data, frame->datalen);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300571
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200572 PN533_STD_FRAME_POSTAMBLE(frame) = 0;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300573}
574
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200575static void pn533_std_tx_update_payload_len(void *_frame, int len)
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100576{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200577 struct pn533_std_frame *frame = _frame;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100578
579 frame->datalen += len;
580}
581
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200582static bool pn533_std_rx_frame_is_valid(void *_frame)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300583{
584 u8 checksum;
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200585 struct pn533_std_frame *frame = _frame;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300586
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200587 if (frame->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300588 return false;
589
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200590 checksum = pn533_std_checksum(frame->datalen);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300591 if (checksum != frame->datalen_checksum)
592 return false;
593
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200594 checksum = pn533_std_data_checksum(frame->data, frame->datalen);
595 if (checksum != PN533_STD_FRAME_CHECKSUM(frame))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300596 return false;
597
598 return true;
599}
600
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200601static bool pn533_std_rx_frame_is_ack(struct pn533_std_frame *frame)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300602{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200603 if (frame->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300604 return false;
605
606 if (frame->datalen != 0 || frame->datalen_checksum != 0xFF)
607 return false;
608
609 return true;
610}
611
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200612static inline int pn533_std_rx_frame_size(void *frame)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300613{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200614 struct pn533_std_frame *f = frame;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100615
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200616 return sizeof(struct pn533_std_frame) + f->datalen +
617 PN533_STD_FRAME_TAIL_LEN;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100618}
619
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200620static u8 pn533_std_get_cmd_code(void *frame)
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100621{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200622 struct pn533_std_frame *f = frame;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100623
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200624 return PN533_STD_FRAME_CMD(f);
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100625}
626
Waldemar Rymarkiewiczef3d56e2013-01-16 15:51:51 +0100627static struct pn533_frame_ops pn533_std_frame_ops = {
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200628 .tx_frame_init = pn533_std_tx_frame_init,
629 .tx_frame_finish = pn533_std_tx_frame_finish,
630 .tx_update_payload_len = pn533_std_tx_update_payload_len,
631 .tx_header_len = PN533_STD_FRAME_HEADER_LEN,
632 .tx_tail_len = PN533_STD_FRAME_TAIL_LEN,
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100633
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200634 .rx_is_frame_valid = pn533_std_rx_frame_is_valid,
635 .rx_frame_size = pn533_std_rx_frame_size,
636 .rx_header_len = PN533_STD_FRAME_HEADER_LEN,
637 .rx_tail_len = PN533_STD_FRAME_TAIL_LEN,
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100638
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200639 .max_payload_len = PN533_STD_FRAME_MAX_PAYLOAD_LEN,
640 .get_cmd_code = pn533_std_get_cmd_code,
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100641};
642
643static bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame)
644{
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +0200645 return (dev->ops->get_cmd_code(frame) ==
Waldemar Rymarkiewicz4b2a9532013-04-03 08:02:06 +0200646 PN533_CMD_RESPONSE(dev->cmd->code));
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300647}
648
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300649static void pn533_recv_response(struct urb *urb)
650{
651 struct pn533 *dev = urb->context;
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200652 struct pn533_cmd *cmd = dev->cmd;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100653 u8 *in_frame;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300654
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200655 cmd->status = urb->status;
656
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300657 switch (urb->status) {
658 case 0:
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100659 break; /* success */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300660 case -ECONNRESET:
661 case -ENOENT:
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +0100662 nfc_dev_dbg(&dev->interface->dev,
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100663 "The urb has been canceled (status %d)",
664 urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200665 goto sched_wq;
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100666 case -ESHUTDOWN:
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300667 default:
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +0100668 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100669 "Urb failure (status %d)", urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200670 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300671 }
672
673 in_frame = dev->in_urb->transfer_buffer;
674
Waldemar Rymarkiewiczfcfafc72012-12-10 14:42:55 +0100675 nfc_dev_dbg(&dev->interface->dev, "Received a frame.");
Samuel Ortize279f842013-03-20 11:27:57 +0100676 print_hex_dump_debug("PN533 RX: ", DUMP_PREFIX_NONE, 16, 1, in_frame,
677 dev->ops->rx_frame_size(in_frame), false);
Waldemar Rymarkiewicz99e591b2012-12-10 14:42:47 +0100678
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100679 if (!dev->ops->rx_is_frame_valid(in_frame)) {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300680 nfc_dev_err(&dev->interface->dev, "Received an invalid frame");
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200681 cmd->status = -EIO;
Samuel Ortiz4849f852012-04-10 19:43:17 +0200682 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300683 }
684
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100685 if (!pn533_rx_frame_is_cmd_response(dev, in_frame)) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +0100686 nfc_dev_err(&dev->interface->dev,
687 "It it not the response to the last command");
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200688 cmd->status = -EIO;
Samuel Ortiz4849f852012-04-10 19:43:17 +0200689 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300690 }
691
Samuel Ortiz4849f852012-04-10 19:43:17 +0200692sched_wq:
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200693 queue_work(dev->wq, &dev->cmd_complete_work);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300694}
695
696static int pn533_submit_urb_for_response(struct pn533 *dev, gfp_t flags)
697{
698 dev->in_urb->complete = pn533_recv_response;
699
700 return usb_submit_urb(dev->in_urb, flags);
701}
702
703static void pn533_recv_ack(struct urb *urb)
704{
705 struct pn533 *dev = urb->context;
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200706 struct pn533_cmd *cmd = dev->cmd;
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200707 struct pn533_std_frame *in_frame;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300708 int rc;
709
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200710 cmd->status = urb->status;
711
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300712 switch (urb->status) {
713 case 0:
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100714 break; /* success */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300715 case -ECONNRESET:
716 case -ENOENT:
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +0100717 nfc_dev_dbg(&dev->interface->dev,
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100718 "The urb has been stopped (status %d)",
719 urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200720 goto sched_wq;
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100721 case -ESHUTDOWN:
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300722 default:
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +0100723 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +0100724 "Urb failure (status %d)", urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200725 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300726 }
727
728 in_frame = dev->in_urb->transfer_buffer;
729
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200730 if (!pn533_std_rx_frame_is_ack(in_frame)) {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300731 nfc_dev_err(&dev->interface->dev, "Received an invalid ack");
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200732 cmd->status = -EIO;
Samuel Ortiz4849f852012-04-10 19:43:17 +0200733 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300734 }
735
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300736 rc = pn533_submit_urb_for_response(dev, GFP_ATOMIC);
737 if (rc) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +0100738 nfc_dev_err(&dev->interface->dev,
739 "usb_submit_urb failed with result %d", rc);
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200740 cmd->status = rc;
Samuel Ortiz4849f852012-04-10 19:43:17 +0200741 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300742 }
743
744 return;
745
Samuel Ortiz4849f852012-04-10 19:43:17 +0200746sched_wq:
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200747 queue_work(dev->wq, &dev->cmd_complete_work);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300748}
749
750static int pn533_submit_urb_for_ack(struct pn533 *dev, gfp_t flags)
751{
752 dev->in_urb->complete = pn533_recv_ack;
753
754 return usb_submit_urb(dev->in_urb, flags);
755}
756
757static int pn533_send_ack(struct pn533 *dev, gfp_t flags)
758{
Waldemar Rymarkiewicz63123102013-04-03 08:01:58 +0200759 u8 ack[PN533_STD_FRAME_ACK_SIZE] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
Waldemar Rymarkiewicz5b5a4432012-12-10 14:42:56 +0100760 /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300761 int rc;
762
763 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
764
Waldemar Rymarkiewicz5b5a4432012-12-10 14:42:56 +0100765 dev->out_urb->transfer_buffer = ack;
766 dev->out_urb->transfer_buffer_length = sizeof(ack);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300767 rc = usb_submit_urb(dev->out_urb, flags);
768
769 return rc;
770}
771
Waldemar Rymarkiewicze8f40532012-12-10 14:42:57 +0100772static int __pn533_send_frame_async(struct pn533 *dev,
773 struct sk_buff *out,
774 struct sk_buff *in,
Waldemar Rymarkiewiczddf19d22013-04-03 08:02:08 +0200775 int in_len)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300776{
777 int rc;
778
Waldemar Rymarkiewicze8f40532012-12-10 14:42:57 +0100779 dev->out_urb->transfer_buffer = out->data;
780 dev->out_urb->transfer_buffer_length = out->len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300781
Waldemar Rymarkiewicze8f40532012-12-10 14:42:57 +0100782 dev->in_urb->transfer_buffer = in->data;
783 dev->in_urb->transfer_buffer_length = in_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300784
Samuel Ortize279f842013-03-20 11:27:57 +0100785 print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1,
786 out->data, out->len, false);
Waldemar Rymarkiewicz99e591b2012-12-10 14:42:47 +0100787
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100788 rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300789 if (rc)
790 return rc;
791
Waldemar Rymarkiewicz58520372013-04-03 08:02:12 +0200792 if (dev->protocol_type == PN533_PROTO_REQ_RESP) {
793 /* request for response for sent packet directly */
794 rc = pn533_submit_urb_for_response(dev, GFP_ATOMIC);
795 if (rc)
796 goto error;
797 } else if (dev->protocol_type == PN533_PROTO_REQ_ACK_RESP) {
798 /* request for ACK if that's the case */
799 rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL);
800 if (rc)
801 goto error;
802 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300803
804 return 0;
805
806error:
807 usb_unlink_urb(dev->out_urb);
808 return rc;
809}
810
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100811static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code,
812 struct sk_buff *skb)
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100813{
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100814 /* payload is already there, just update datalen */
815 int payload_len = skb->len;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100816 struct pn533_frame_ops *ops = dev->ops;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100817
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100818
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100819 skb_push(skb, ops->tx_header_len);
820 skb_put(skb, ops->tx_tail_len);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100821
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100822 ops->tx_frame_init(skb->data, cmd_code);
823 ops->tx_update_payload_len(skb->data, payload_len);
824 ops->tx_frame_finish(skb->data);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100825}
826
Waldemar Rymarkiewiczddf19d22013-04-03 08:02:08 +0200827static int pn533_send_async_complete(struct pn533 *dev)
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100828{
Waldemar Rymarkiewiczddf19d22013-04-03 08:02:08 +0200829 struct pn533_cmd *cmd = dev->cmd;
Waldemar Rymarkiewiczf87bc9f2013-04-03 08:02:11 +0200830 int status = cmd->status;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100831
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200832 struct sk_buff *req = cmd->req;
833 struct sk_buff *resp = cmd->resp;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100834
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100835 int rc;
836
837 dev_kfree_skb(req);
838
Waldemar Rymarkiewicz0c33d262012-12-10 14:42:59 +0100839 if (status < 0) {
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200840 rc = cmd->complete_cb(dev, cmd->complete_cb_context,
841 ERR_PTR(status));
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100842 dev_kfree_skb(resp);
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +0200843 goto done;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100844 }
845
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100846 skb_put(resp, dev->ops->rx_frame_size(resp->data));
847 skb_pull(resp, dev->ops->rx_header_len);
848 skb_trim(resp, resp->len - dev->ops->rx_tail_len);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100849
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200850 rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100851
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +0200852done:
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200853 kfree(cmd);
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +0200854 dev->cmd = NULL;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100855 return rc;
856}
857
858static int __pn533_send_async(struct pn533 *dev, u8 cmd_code,
859 struct sk_buff *req, struct sk_buff *resp,
860 int resp_len,
861 pn533_send_async_complete_t complete_cb,
862 void *complete_cb_context)
863{
864 struct pn533_cmd *cmd;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100865 int rc = 0;
866
Waldemar Rymarkiewiczfcfafc72012-12-10 14:42:55 +0100867 nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x", cmd_code);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100868
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200869 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
870 if (!cmd)
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100871 return -ENOMEM;
872
Waldemar Rymarkiewicz4b2a9532013-04-03 08:02:06 +0200873 cmd->code = cmd_code;
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200874 cmd->req = req;
875 cmd->resp = resp;
876 cmd->resp_len = resp_len;
877 cmd->complete_cb = complete_cb;
878 cmd->complete_cb_context = complete_cb_context;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100879
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100880 pn533_build_cmd_frame(dev, cmd_code, req);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100881
882 mutex_lock(&dev->cmd_lock);
883
884 if (!dev->cmd_pending) {
Waldemar Rymarkiewiczddf19d22013-04-03 08:02:08 +0200885 rc = __pn533_send_frame_async(dev, req, resp, resp_len);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100886 if (rc)
887 goto error;
888
889 dev->cmd_pending = 1;
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +0200890 dev->cmd = cmd;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100891 goto unlock;
892 }
893
Waldemar Rymarkiewiczfcfafc72012-12-10 14:42:55 +0100894 nfc_dev_dbg(&dev->interface->dev, "%s Queueing command 0x%x", __func__,
895 cmd_code);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100896
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100897 INIT_LIST_HEAD(&cmd->queue);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100898 list_add_tail(&cmd->queue, &dev->cmd_queue);
899
900 goto unlock;
901
902error:
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200903 kfree(cmd);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100904unlock:
905 mutex_unlock(&dev->cmd_lock);
906 return rc;
907}
908
Waldemar Rymarkiewicz15461ae2012-11-26 14:18:35 +0100909static int pn533_send_data_async(struct pn533 *dev, u8 cmd_code,
910 struct sk_buff *req,
911 pn533_send_async_complete_t complete_cb,
912 void *complete_cb_context)
913{
914 struct sk_buff *resp;
915 int rc;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100916 int resp_len = dev->ops->rx_header_len +
917 dev->ops->max_payload_len +
918 dev->ops->rx_tail_len;
Waldemar Rymarkiewicz15461ae2012-11-26 14:18:35 +0100919
Waldemar Rymarkiewicz15461ae2012-11-26 14:18:35 +0100920 resp = nfc_alloc_recv_skb(resp_len, GFP_KERNEL);
921 if (!resp)
922 return -ENOMEM;
923
924 rc = __pn533_send_async(dev, cmd_code, req, resp, resp_len, complete_cb,
925 complete_cb_context);
926 if (rc)
927 dev_kfree_skb(resp);
928
929 return rc;
930}
931
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100932static int pn533_send_cmd_async(struct pn533 *dev, u8 cmd_code,
933 struct sk_buff *req,
934 pn533_send_async_complete_t complete_cb,
935 void *complete_cb_context)
936{
937 struct sk_buff *resp;
938 int rc;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100939 int resp_len = dev->ops->rx_header_len +
940 dev->ops->max_payload_len +
941 dev->ops->rx_tail_len;
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100942
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100943 resp = alloc_skb(resp_len, GFP_KERNEL);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100944 if (!resp)
945 return -ENOMEM;
946
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100947 rc = __pn533_send_async(dev, cmd_code, req, resp, resp_len, complete_cb,
948 complete_cb_context);
Waldemar Rymarkiewiczaada17a2012-11-26 14:18:34 +0100949 if (rc)
950 dev_kfree_skb(resp);
951
952 return rc;
953}
954
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100955/*
956 * pn533_send_cmd_direct_async
957 *
958 * The function sends a piority cmd directly to the chip omiting the cmd
959 * queue. It's intended to be used by chaining mechanism of received responses
960 * where the host has to request every single chunk of data before scheduling
961 * next cmd from the queue.
962 */
963static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code,
964 struct sk_buff *req,
965 pn533_send_async_complete_t complete_cb,
966 void *complete_cb_context)
967{
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100968 struct sk_buff *resp;
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200969 struct pn533_cmd *cmd;
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100970 int rc;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100971 int resp_len = dev->ops->rx_header_len +
972 dev->ops->max_payload_len +
973 dev->ops->rx_tail_len;
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100974
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100975 resp = alloc_skb(resp_len, GFP_KERNEL);
976 if (!resp)
977 return -ENOMEM;
978
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200979 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
980 if (!cmd) {
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100981 dev_kfree_skb(resp);
982 return -ENOMEM;
983 }
984
Waldemar Rymarkiewicz4b2a9532013-04-03 08:02:06 +0200985 cmd->code = cmd_code;
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200986 cmd->req = req;
987 cmd->resp = resp;
988 cmd->resp_len = resp_len;
989 cmd->complete_cb = complete_cb;
990 cmd->complete_cb_context = complete_cb_context;
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100991
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +0100992 pn533_build_cmd_frame(dev, cmd_code, req);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100993
Waldemar Rymarkiewiczddf19d22013-04-03 08:02:08 +0200994 rc = __pn533_send_frame_async(dev, req, resp, resp_len);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +0100995 if (rc < 0) {
996 dev_kfree_skb(resp);
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +0200997 kfree(cmd);
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +0200998 } else {
999 dev->cmd = cmd;
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01001000 }
1001
1002 return rc;
1003}
1004
Waldemar Rymarkiewiczc79490e2013-04-03 08:02:09 +02001005static void pn533_wq_cmd_complete(struct work_struct *work)
1006{
1007 struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work);
1008 int rc;
1009
1010 rc = pn533_send_async_complete(dev);
1011 if (rc != -EINPROGRESS)
1012 queue_work(dev->wq, &dev->cmd_work);
1013}
1014
Samuel Ortiz5d50b362012-08-17 23:47:54 +02001015static void pn533_wq_cmd(struct work_struct *work)
1016{
1017 struct pn533 *dev = container_of(work, struct pn533, cmd_work);
1018 struct pn533_cmd *cmd;
Waldemar Rymarkiewicz0ce1fbd2013-04-03 08:02:03 +02001019 int rc;
Samuel Ortiz5d50b362012-08-17 23:47:54 +02001020
1021 mutex_lock(&dev->cmd_lock);
1022
1023 if (list_empty(&dev->cmd_queue)) {
1024 dev->cmd_pending = 0;
1025 mutex_unlock(&dev->cmd_lock);
1026 return;
1027 }
1028
1029 cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
1030
Szymon Janc60ad07a2012-10-25 17:29:45 +02001031 list_del(&cmd->queue);
1032
Samuel Ortiz5d50b362012-08-17 23:47:54 +02001033 mutex_unlock(&dev->cmd_lock);
1034
Waldemar Rymarkiewiczddf19d22013-04-03 08:02:08 +02001035 rc = __pn533_send_frame_async(dev, cmd->req, cmd->resp, cmd->resp_len);
Waldemar Rymarkiewicz0ce1fbd2013-04-03 08:02:03 +02001036 if (rc < 0) {
1037 dev_kfree_skb(cmd->req);
1038 dev_kfree_skb(cmd->resp);
Waldemar Rymarkiewicz42316042013-04-03 08:02:04 +02001039 kfree(cmd);
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +02001040 return;
Waldemar Rymarkiewicz0ce1fbd2013-04-03 08:02:03 +02001041 }
Waldemar Rymarkiewicz2c206fb2013-04-03 08:02:05 +02001042
1043 dev->cmd = cmd;
Samuel Ortiz5d50b362012-08-17 23:47:54 +02001044}
1045
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001046struct pn533_sync_cmd_response {
Waldemar Rymarkiewicz94c5c152012-11-26 14:18:36 +01001047 struct sk_buff *resp;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001048 struct completion done;
1049};
1050
Waldemar Rymarkiewicz94c5c152012-11-26 14:18:36 +01001051static int pn533_send_sync_complete(struct pn533 *dev, void *_arg,
1052 struct sk_buff *resp)
1053{
1054 struct pn533_sync_cmd_response *arg = _arg;
1055
Waldemar Rymarkiewicz94c5c152012-11-26 14:18:36 +01001056 arg->resp = resp;
1057 complete(&arg->done);
1058
1059 return 0;
1060}
1061
1062/* pn533_send_cmd_sync
1063 *
1064 * Please note the req parameter is freed inside the function to
1065 * limit a number of return value interpretations by the caller.
1066 *
1067 * 1. negative in case of error during TX path -> req should be freed
1068 *
1069 * 2. negative in case of error during RX path -> req should not be freed
1070 * as it's been already freed at the begining of RX path by
1071 * async_complete_cb.
1072 *
1073 * 3. valid pointer in case of succesfult RX path
1074 *
1075 * A caller has to check a return value with IS_ERR macro. If the test pass,
1076 * the returned pointer is valid.
1077 *
1078 * */
1079static struct sk_buff *pn533_send_cmd_sync(struct pn533 *dev, u8 cmd_code,
1080 struct sk_buff *req)
1081{
1082 int rc;
1083 struct pn533_sync_cmd_response arg;
1084
Waldemar Rymarkiewicz94c5c152012-11-26 14:18:36 +01001085 init_completion(&arg.done);
1086
1087 rc = pn533_send_cmd_async(dev, cmd_code, req,
1088 pn533_send_sync_complete, &arg);
1089 if (rc) {
1090 dev_kfree_skb(req);
1091 return ERR_PTR(rc);
1092 }
1093
1094 wait_for_completion(&arg.done);
1095
1096 return arg.resp;
1097}
1098
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001099static void pn533_send_complete(struct urb *urb)
1100{
1101 struct pn533 *dev = urb->context;
1102
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001103 switch (urb->status) {
1104 case 0:
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +01001105 break; /* success */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001106 case -ECONNRESET:
1107 case -ENOENT:
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001108 nfc_dev_dbg(&dev->interface->dev,
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +01001109 "The urb has been stopped (status %d)",
1110 urb->status);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001111 break;
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +01001112 case -ESHUTDOWN:
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001113 default:
Waldemar Rymarkiewiczf8f99172012-12-10 14:42:54 +01001114 nfc_dev_err(&dev->interface->dev,
1115 "Urb failure (status %d)", urb->status);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001116 }
1117}
1118
Waldemar Rymarkiewicz10cff292013-04-03 08:02:14 +02001119static void pn533_abort_cmd(struct pn533 *dev, gfp_t flags)
1120{
1121 /* ACR122U does not support any command which aborts last
1122 * issued command i.e. as ACK for standard PN533. Additionally,
1123 * it behaves stange, sending broken or incorrect responses,
1124 * when we cancel urb before the chip will send response.
1125 */
1126 if (dev->device_type == PN533_DEVICE_ACR122U)
1127 return;
1128
1129 /* An ack will cancel the last issued command */
1130 pn533_send_ack(dev, flags);
1131
1132 /* cancel the urb request */
1133 usb_kill_urb(dev->in_urb);
1134}
1135
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001136static struct sk_buff *pn533_alloc_skb(struct pn533 *dev, unsigned int size)
Waldemar Rymarkiewiczd22b2db2012-11-26 14:18:37 +01001137{
1138 struct sk_buff *skb;
1139
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001140 skb = alloc_skb(dev->ops->tx_header_len +
Waldemar Rymarkiewiczd22b2db2012-11-26 14:18:37 +01001141 size +
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001142 dev->ops->tx_tail_len, GFP_KERNEL);
Waldemar Rymarkiewiczd22b2db2012-11-26 14:18:37 +01001143
1144 if (skb)
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001145 skb_reserve(skb, dev->ops->tx_header_len);
Waldemar Rymarkiewiczd22b2db2012-11-26 14:18:37 +01001146
1147 return skb;
1148}
1149
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001150struct pn533_target_type_a {
1151 __be16 sens_res;
1152 u8 sel_res;
1153 u8 nfcid_len;
1154 u8 nfcid_data[];
1155} __packed;
1156
1157
1158#define PN533_TYPE_A_SENS_RES_NFCID1(x) ((u8)((be16_to_cpu(x) & 0x00C0) >> 6))
1159#define PN533_TYPE_A_SENS_RES_SSD(x) ((u8)((be16_to_cpu(x) & 0x001F) >> 0))
1160#define PN533_TYPE_A_SENS_RES_PLATCONF(x) ((u8)((be16_to_cpu(x) & 0x0F00) >> 8))
1161
1162#define PN533_TYPE_A_SENS_RES_SSD_JEWEL 0x00
1163#define PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL 0x0C
1164
1165#define PN533_TYPE_A_SEL_PROT(x) (((x) & 0x60) >> 5)
1166#define PN533_TYPE_A_SEL_CASCADE(x) (((x) & 0x04) >> 2)
1167
1168#define PN533_TYPE_A_SEL_PROT_MIFARE 0
1169#define PN533_TYPE_A_SEL_PROT_ISO14443 1
1170#define PN533_TYPE_A_SEL_PROT_DEP 2
1171#define PN533_TYPE_A_SEL_PROT_ISO14443_DEP 3
1172
1173static bool pn533_target_type_a_is_valid(struct pn533_target_type_a *type_a,
1174 int target_data_len)
1175{
1176 u8 ssd;
1177 u8 platconf;
1178
1179 if (target_data_len < sizeof(struct pn533_target_type_a))
1180 return false;
1181
1182 /* The lenght check of nfcid[] and ats[] are not being performed because
1183 the values are not being used */
1184
1185 /* Requirement 4.6.3.3 from NFC Forum Digital Spec */
1186 ssd = PN533_TYPE_A_SENS_RES_SSD(type_a->sens_res);
1187 platconf = PN533_TYPE_A_SENS_RES_PLATCONF(type_a->sens_res);
1188
1189 if ((ssd == PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01001190 platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
1191 (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
1192 platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001193 return false;
1194
1195 /* Requirements 4.8.2.1, 4.8.2.3, 4.8.2.5 and 4.8.2.7 from NFC Forum */
1196 if (PN533_TYPE_A_SEL_CASCADE(type_a->sel_res) != 0)
1197 return false;
1198
1199 return true;
1200}
1201
1202static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data,
1203 int tgt_data_len)
1204{
1205 struct pn533_target_type_a *tgt_type_a;
1206
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001207 tgt_type_a = (struct pn533_target_type_a *)tgt_data;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001208
1209 if (!pn533_target_type_a_is_valid(tgt_type_a, tgt_data_len))
1210 return -EPROTO;
1211
1212 switch (PN533_TYPE_A_SEL_PROT(tgt_type_a->sel_res)) {
1213 case PN533_TYPE_A_SEL_PROT_MIFARE:
1214 nfc_tgt->supported_protocols = NFC_PROTO_MIFARE_MASK;
1215 break;
1216 case PN533_TYPE_A_SEL_PROT_ISO14443:
1217 nfc_tgt->supported_protocols = NFC_PROTO_ISO14443_MASK;
1218 break;
1219 case PN533_TYPE_A_SEL_PROT_DEP:
1220 nfc_tgt->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
1221 break;
1222 case PN533_TYPE_A_SEL_PROT_ISO14443_DEP:
1223 nfc_tgt->supported_protocols = NFC_PROTO_ISO14443_MASK |
1224 NFC_PROTO_NFC_DEP_MASK;
1225 break;
1226 }
1227
1228 nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res);
1229 nfc_tgt->sel_res = tgt_type_a->sel_res;
Samuel Ortizc3b1e1e2012-03-05 01:03:33 +01001230 nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len;
1231 memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001232
1233 return 0;
1234}
1235
1236struct pn533_target_felica {
1237 u8 pol_res;
1238 u8 opcode;
Samuel Ortiz322bce92013-05-27 15:29:11 +02001239 u8 nfcid2[NFC_NFCID2_MAXSIZE];
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001240 u8 pad[8];
1241 /* optional */
1242 u8 syst_code[];
1243} __packed;
1244
1245#define PN533_FELICA_SENSF_NFCID2_DEP_B1 0x01
1246#define PN533_FELICA_SENSF_NFCID2_DEP_B2 0xFE
1247
1248static bool pn533_target_felica_is_valid(struct pn533_target_felica *felica,
1249 int target_data_len)
1250{
1251 if (target_data_len < sizeof(struct pn533_target_felica))
1252 return false;
1253
1254 if (felica->opcode != PN533_FELICA_OPC_SENSF_RES)
1255 return false;
1256
1257 return true;
1258}
1259
1260static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data,
1261 int tgt_data_len)
1262{
1263 struct pn533_target_felica *tgt_felica;
1264
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001265 tgt_felica = (struct pn533_target_felica *)tgt_data;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001266
1267 if (!pn533_target_felica_is_valid(tgt_felica, tgt_data_len))
1268 return -EPROTO;
1269
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01001270 if ((tgt_felica->nfcid2[0] == PN533_FELICA_SENSF_NFCID2_DEP_B1) &&
1271 (tgt_felica->nfcid2[1] == PN533_FELICA_SENSF_NFCID2_DEP_B2))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001272 nfc_tgt->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
1273 else
1274 nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK;
1275
Samuel Ortiz79757542012-03-05 01:03:45 +01001276 memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9);
1277 nfc_tgt->sensf_res_len = 9;
1278
Samuel Ortiz322bce92013-05-27 15:29:11 +02001279 memcpy(nfc_tgt->nfcid2, tgt_felica->nfcid2, NFC_NFCID2_MAXSIZE);
1280 nfc_tgt->nfcid2_len = NFC_NFCID2_MAXSIZE;
1281
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001282 return 0;
1283}
1284
1285struct pn533_target_jewel {
1286 __be16 sens_res;
1287 u8 jewelid[4];
1288} __packed;
1289
1290static bool pn533_target_jewel_is_valid(struct pn533_target_jewel *jewel,
1291 int target_data_len)
1292{
1293 u8 ssd;
1294 u8 platconf;
1295
1296 if (target_data_len < sizeof(struct pn533_target_jewel))
1297 return false;
1298
1299 /* Requirement 4.6.3.3 from NFC Forum Digital Spec */
1300 ssd = PN533_TYPE_A_SENS_RES_SSD(jewel->sens_res);
1301 platconf = PN533_TYPE_A_SENS_RES_PLATCONF(jewel->sens_res);
1302
1303 if ((ssd == PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01001304 platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
1305 (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
1306 platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001307 return false;
1308
1309 return true;
1310}
1311
1312static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data,
1313 int tgt_data_len)
1314{
1315 struct pn533_target_jewel *tgt_jewel;
1316
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001317 tgt_jewel = (struct pn533_target_jewel *)tgt_data;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001318
1319 if (!pn533_target_jewel_is_valid(tgt_jewel, tgt_data_len))
1320 return -EPROTO;
1321
1322 nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK;
1323 nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res);
Samuel Ortizd8dc1072012-03-05 01:03:46 +01001324 nfc_tgt->nfcid1_len = 4;
1325 memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001326
1327 return 0;
1328}
1329
1330struct pn533_type_b_prot_info {
1331 u8 bitrate;
1332 u8 fsci_type;
1333 u8 fwi_adc_fo;
1334} __packed;
1335
1336#define PN533_TYPE_B_PROT_FCSI(x) (((x) & 0xF0) >> 4)
1337#define PN533_TYPE_B_PROT_TYPE(x) (((x) & 0x0F) >> 0)
1338#define PN533_TYPE_B_PROT_TYPE_RFU_MASK 0x8
1339
1340struct pn533_type_b_sens_res {
1341 u8 opcode;
1342 u8 nfcid[4];
1343 u8 appdata[4];
1344 struct pn533_type_b_prot_info prot_info;
1345} __packed;
1346
1347#define PN533_TYPE_B_OPC_SENSB_RES 0x50
1348
1349struct pn533_target_type_b {
1350 struct pn533_type_b_sens_res sensb_res;
1351 u8 attrib_res_len;
1352 u8 attrib_res[];
1353} __packed;
1354
1355static bool pn533_target_type_b_is_valid(struct pn533_target_type_b *type_b,
1356 int target_data_len)
1357{
1358 if (target_data_len < sizeof(struct pn533_target_type_b))
1359 return false;
1360
1361 if (type_b->sensb_res.opcode != PN533_TYPE_B_OPC_SENSB_RES)
1362 return false;
1363
1364 if (PN533_TYPE_B_PROT_TYPE(type_b->sensb_res.prot_info.fsci_type) &
1365 PN533_TYPE_B_PROT_TYPE_RFU_MASK)
1366 return false;
1367
1368 return true;
1369}
1370
1371static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data,
1372 int tgt_data_len)
1373{
1374 struct pn533_target_type_b *tgt_type_b;
1375
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001376 tgt_type_b = (struct pn533_target_type_b *)tgt_data;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001377
1378 if (!pn533_target_type_b_is_valid(tgt_type_b, tgt_data_len))
1379 return -EPROTO;
1380
Samuel Ortiz01d719a2012-07-04 00:14:04 +02001381 nfc_tgt->supported_protocols = NFC_PROTO_ISO14443_B_MASK;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001382
1383 return 0;
1384}
1385
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001386static int pn533_target_found(struct pn533 *dev, u8 tg, u8 *tgdata,
1387 int tgdata_len)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001388{
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001389 struct nfc_target nfc_tgt;
1390 int rc;
1391
1392 nfc_dev_dbg(&dev->interface->dev, "%s - modulation=%d", __func__,
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001393 dev->poll_mod_curr);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001394
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001395 if (tg != 1)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001396 return -EPROTO;
1397
Samuel Ortiz98b3ac12012-03-05 01:03:39 +01001398 memset(&nfc_tgt, 0, sizeof(struct nfc_target));
1399
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001400 switch (dev->poll_mod_curr) {
1401 case PN533_POLL_MOD_106KBPS_A:
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001402 rc = pn533_target_found_type_a(&nfc_tgt, tgdata, tgdata_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001403 break;
1404 case PN533_POLL_MOD_212KBPS_FELICA:
1405 case PN533_POLL_MOD_424KBPS_FELICA:
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001406 rc = pn533_target_found_felica(&nfc_tgt, tgdata, tgdata_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001407 break;
1408 case PN533_POLL_MOD_106KBPS_JEWEL:
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001409 rc = pn533_target_found_jewel(&nfc_tgt, tgdata, tgdata_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001410 break;
1411 case PN533_POLL_MOD_847KBPS_B:
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001412 rc = pn533_target_found_type_b(&nfc_tgt, tgdata, tgdata_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001413 break;
1414 default:
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001415 nfc_dev_err(&dev->interface->dev,
1416 "Unknown current poll modulation");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001417 return -EPROTO;
1418 }
1419
1420 if (rc)
1421 return rc;
1422
1423 if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) {
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001424 nfc_dev_dbg(&dev->interface->dev,
1425 "The Tg found doesn't have the desired protocol");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001426 return -EAGAIN;
1427 }
1428
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001429 nfc_dev_dbg(&dev->interface->dev,
1430 "Target found - supported protocols: 0x%x",
1431 nfc_tgt.supported_protocols);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001432
1433 dev->tgt_available_prots = nfc_tgt.supported_protocols;
1434
1435 nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1);
1436
1437 return 0;
1438}
1439
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001440static inline void pn533_poll_next_mod(struct pn533 *dev)
1441{
1442 dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count;
1443}
1444
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001445static void pn533_poll_reset_mod_list(struct pn533 *dev)
1446{
1447 dev->poll_mod_count = 0;
1448}
1449
1450static void pn533_poll_add_mod(struct pn533 *dev, u8 mod_index)
1451{
1452 dev->poll_mod_active[dev->poll_mod_count] =
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001453 (struct pn533_poll_modulations *)&poll_mod[mod_index];
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001454 dev->poll_mod_count++;
1455}
1456
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001457static void pn533_poll_create_mod_list(struct pn533 *dev,
1458 u32 im_protocols, u32 tm_protocols)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001459{
1460 pn533_poll_reset_mod_list(dev);
1461
Waldemar Rymarkiewiczb08e8602012-12-10 14:42:52 +01001462 if ((im_protocols & NFC_PROTO_MIFARE_MASK) ||
1463 (im_protocols & NFC_PROTO_ISO14443_MASK) ||
1464 (im_protocols & NFC_PROTO_NFC_DEP_MASK))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001465 pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A);
1466
Waldemar Rymarkiewiczb08e8602012-12-10 14:42:52 +01001467 if (im_protocols & NFC_PROTO_FELICA_MASK ||
1468 im_protocols & NFC_PROTO_NFC_DEP_MASK) {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001469 pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA);
1470 pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA);
1471 }
1472
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001473 if (im_protocols & NFC_PROTO_JEWEL_MASK)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001474 pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL);
1475
Samuel Ortiz01d719a2012-07-04 00:14:04 +02001476 if (im_protocols & NFC_PROTO_ISO14443_B_MASK)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001477 pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001478
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001479 if (tm_protocols)
1480 pn533_poll_add_mod(dev, PN533_LISTEN_MOD);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001481}
1482
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001483static int pn533_start_poll_complete(struct pn533 *dev, struct sk_buff *resp)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001484{
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001485 u8 nbtg, tg, *tgdata;
1486 int rc, tgdata_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001487
1488 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1489
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001490 nbtg = resp->data[0];
1491 tg = resp->data[1];
1492 tgdata = &resp->data[2];
1493 tgdata_len = resp->len - 2; /* nbtg + tg */
1494
1495 if (nbtg) {
1496 rc = pn533_target_found(dev, tg, tgdata, tgdata_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001497
1498 /* We must stop the poll after a valid target found */
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001499 if (rc == 0) {
1500 pn533_poll_reset_mod_list(dev);
1501 return 0;
1502 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001503 }
1504
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001505 return -EAGAIN;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001506}
1507
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001508static struct sk_buff *pn533_alloc_poll_tg_frame(struct pn533 *dev)
Samuel Ortizad3823c2012-05-30 23:54:55 +02001509{
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001510 struct sk_buff *skb;
1511 u8 *felica, *nfcid3, *gb;
1512
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001513 u8 *gbytes = dev->gb;
1514 size_t gbytes_len = dev->gb_len;
1515
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001516 u8 felica_params[18] = {0x1, 0xfe, /* DEP */
1517 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* random */
1518 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1519 0xff, 0xff}; /* System code */
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001520
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001521 u8 mifare_params[6] = {0x1, 0x1, /* SENS_RES */
1522 0x0, 0x0, 0x0,
1523 0x40}; /* SEL_RES for DEP */
Samuel Ortizad3823c2012-05-30 23:54:55 +02001524
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001525 unsigned int skb_len = 36 + /* mode (1), mifare (6),
1526 felica (18), nfcid3 (10), gb_len (1) */
1527 gbytes_len +
1528 1; /* len Tk*/
Samuel Ortizad3823c2012-05-30 23:54:55 +02001529
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001530 skb = pn533_alloc_skb(dev, skb_len);
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001531 if (!skb)
1532 return NULL;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001533
1534 /* DEP support only */
Thierry Escande52f2eae2013-02-05 10:08:35 +01001535 *skb_put(skb, 1) = PN533_INIT_TARGET_DEP;
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001536
1537 /* MIFARE params */
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001538 memcpy(skb_put(skb, 6), mifare_params, 6);
1539
1540 /* Felica params */
1541 felica = skb_put(skb, 18);
1542 memcpy(felica, felica_params, 18);
1543 get_random_bytes(felica + 2, 6);
1544
1545 /* NFCID3 */
1546 nfcid3 = skb_put(skb, 10);
1547 memset(nfcid3, 0, 10);
1548 memcpy(nfcid3, felica, 8);
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001549
1550 /* General bytes */
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001551 *skb_put(skb, 1) = gbytes_len;
1552
1553 gb = skb_put(skb, gbytes_len);
1554 memcpy(gb, gbytes, gbytes_len);
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001555
Samuel Ortizad3823c2012-05-30 23:54:55 +02001556 /* Len Tk */
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001557 *skb_put(skb, 1) = 0;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001558
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001559 return skb;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001560}
1561
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001562#define PN533_CMD_DATAEXCH_HEAD_LEN 1
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001563#define PN533_CMD_DATAEXCH_DATA_MAXLEN 262
1564static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg,
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001565 struct sk_buff *resp)
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001566{
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001567 u8 status;
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001568
1569 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1570
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001571 if (IS_ERR(resp))
1572 return PTR_ERR(resp);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001573
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001574 status = resp->data[0];
1575 skb_pull(resp, sizeof(status));
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001576
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001577 if (status != 0) {
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001578 nfc_tm_deactivated(dev->nfc_dev);
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001579 dev->tgt_mode = 0;
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001580 dev_kfree_skb(resp);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001581 return 0;
1582 }
1583
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001584 return nfc_tm_data_received(dev->nfc_dev, resp);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001585}
1586
1587static void pn533_wq_tg_get_data(struct work_struct *work)
1588{
1589 struct pn533 *dev = container_of(work, struct pn533, tg_work);
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001590
1591 struct sk_buff *skb;
1592 int rc;
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001593
1594 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1595
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001596 skb = pn533_alloc_skb(dev, 0);
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001597 if (!skb)
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001598 return;
1599
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001600 rc = pn533_send_data_async(dev, PN533_CMD_TG_GET_DATA, skb,
1601 pn533_tm_get_data_complete, NULL);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001602
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01001603 if (rc < 0)
1604 dev_kfree_skb(skb);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001605
1606 return;
1607}
1608
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001609#define ATR_REQ_GB_OFFSET 17
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001610static int pn533_init_target_complete(struct pn533 *dev, struct sk_buff *resp)
Samuel Ortizad3823c2012-05-30 23:54:55 +02001611{
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001612 u8 mode, *cmd, comm_mode = NFC_COMM_PASSIVE, *gb;
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001613 size_t gb_len;
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001614 int rc;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001615
1616 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1617
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001618 if (resp->len < ATR_REQ_GB_OFFSET + 1)
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001619 return -EINVAL;
1620
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001621 mode = resp->data[0];
1622 cmd = &resp->data[1];
Samuel Ortizad3823c2012-05-30 23:54:55 +02001623
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001624 nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x len %d\n",
1625 mode, resp->len);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001626
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001627 if ((mode & PN533_INIT_TARGET_RESP_FRAME_MASK) ==
1628 PN533_INIT_TARGET_RESP_ACTIVE)
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001629 comm_mode = NFC_COMM_ACTIVE;
1630
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001631 if ((mode & PN533_INIT_TARGET_RESP_DEP) == 0) /* Only DEP supported */
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001632 return -EOPNOTSUPP;
1633
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001634 gb = cmd + ATR_REQ_GB_OFFSET;
1635 gb_len = resp->len - (ATR_REQ_GB_OFFSET + 1);
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001636
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001637 rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
1638 comm_mode, gb, gb_len);
1639 if (rc < 0) {
1640 nfc_dev_err(&dev->interface->dev,
1641 "Error when signaling target activation");
1642 return rc;
1643 }
1644
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001645 dev->tgt_mode = 1;
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001646 queue_work(dev->wq, &dev->tg_work);
1647
1648 return 0;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001649}
1650
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001651static void pn533_listen_mode_timer(unsigned long data)
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001652{
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001653 struct pn533 *dev = (struct pn533 *)data;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001654
1655 nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout");
1656
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001657 dev->cancel_listen = 1;
1658
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001659 pn533_poll_next_mod(dev);
1660
1661 queue_work(dev->wq, &dev->poll_work);
1662}
1663
Samuel Ortiz17e9d9d2013-06-26 18:16:21 +02001664static int pn533_rf_complete(struct pn533 *dev, void *arg,
1665 struct sk_buff *resp)
1666{
1667 int rc = 0;
1668
1669 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1670
1671 if (IS_ERR(resp)) {
1672 rc = PTR_ERR(resp);
1673
1674 nfc_dev_err(&dev->interface->dev, "%s RF setting error %d",
1675 __func__, rc);
1676
1677 return rc;
1678 }
1679
1680 queue_work(dev->wq, &dev->poll_work);
1681
1682 dev_kfree_skb(resp);
1683 return rc;
1684}
1685
1686static void pn533_wq_rf(struct work_struct *work)
1687{
1688 struct pn533 *dev = container_of(work, struct pn533, rf_work);
1689 struct sk_buff *skb;
1690 int rc;
1691
1692 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1693
1694 skb = pn533_alloc_skb(dev, 2);
1695 if (!skb)
1696 return;
1697
1698 *skb_put(skb, 1) = PN533_CFGITEM_RF_FIELD;
1699 *skb_put(skb, 1) = 0;
1700
1701 rc = pn533_send_cmd_async(dev, PN533_CMD_RF_CONFIGURATION, skb,
1702 pn533_rf_complete, NULL);
1703 if (rc < 0) {
1704 dev_kfree_skb(skb);
1705 nfc_dev_err(&dev->interface->dev, "RF setting error %d", rc);
1706 }
1707
1708 return;
1709}
1710
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001711static int pn533_poll_complete(struct pn533 *dev, void *arg,
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001712 struct sk_buff *resp)
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001713{
1714 struct pn533_poll_modulations *cur_mod;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001715 int rc;
1716
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001717 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1718
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001719 if (IS_ERR(resp)) {
1720 rc = PTR_ERR(resp);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001721
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001722 nfc_dev_err(&dev->interface->dev, "%s Poll complete error %d",
1723 __func__, rc);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001724
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001725 if (rc == -ENOENT) {
1726 if (dev->poll_mod_count != 0)
1727 return rc;
1728 else
1729 goto stop_poll;
1730 } else if (rc < 0) {
1731 nfc_dev_err(&dev->interface->dev,
1732 "Error %d when running poll", rc);
1733 goto stop_poll;
1734 }
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001735 }
1736
1737 cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
1738
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001739 if (cur_mod->len == 0) { /* Target mode */
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001740 del_timer(&dev->listen_timer);
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001741 rc = pn533_init_target_complete(dev, resp);
1742 goto done;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001743 }
1744
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001745 /* Initiator mode */
1746 rc = pn533_start_poll_complete(dev, resp);
1747 if (!rc)
1748 goto done;
1749
Waldemar Rymarkiewicz95cb9e12013-04-03 08:02:00 +02001750 if (!dev->poll_mod_count) {
Masanari Iida8b513d02013-05-21 23:13:12 +09001751 nfc_dev_dbg(&dev->interface->dev, "Polling has been stopped.");
Waldemar Rymarkiewicz95cb9e12013-04-03 08:02:00 +02001752 goto done;
1753 }
1754
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001755 pn533_poll_next_mod(dev);
Samuel Ortiz17e9d9d2013-06-26 18:16:21 +02001756 /* Not target found, turn radio off */
1757 queue_work(dev->wq, &dev->rf_work);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001758
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001759done:
1760 dev_kfree_skb(resp);
1761 return rc;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001762
1763stop_poll:
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001764 nfc_dev_err(&dev->interface->dev, "Polling operation has been stopped");
1765
Samuel Ortizad3823c2012-05-30 23:54:55 +02001766 pn533_poll_reset_mod_list(dev);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001767 dev->poll_protocols = 0;
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001768 return rc;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001769}
Samuel Ortizad3823c2012-05-30 23:54:55 +02001770
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001771static struct sk_buff *pn533_alloc_poll_in_frame(struct pn533 *dev,
1772 struct pn533_poll_modulations *mod)
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001773{
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001774 struct sk_buff *skb;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001775
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001776 skb = pn533_alloc_skb(dev, mod->len);
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001777 if (!skb)
1778 return NULL;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001779
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001780 memcpy(skb_put(skb, mod->len), &mod->data, mod->len);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001781
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001782 return skb;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001783}
1784
1785static int pn533_send_poll_frame(struct pn533 *dev)
1786{
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001787 struct pn533_poll_modulations *mod;
1788 struct sk_buff *skb;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001789 int rc;
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001790 u8 cmd_code;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001791
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001792 mod = dev->poll_mod_active[dev->poll_mod_curr];
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001793
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001794 nfc_dev_dbg(&dev->interface->dev, "%s mod len %d\n",
1795 __func__, mod->len);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001796
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001797 if (mod->len == 0) { /* Listen mode */
1798 cmd_code = PN533_CMD_TG_INIT_AS_TARGET;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001799 skb = pn533_alloc_poll_tg_frame(dev);
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001800 } else { /* Polling mode */
1801 cmd_code = PN533_CMD_IN_LIST_PASSIVE_TARGET;
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001802 skb = pn533_alloc_poll_in_frame(dev, mod);
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001803 }
1804
1805 if (!skb) {
1806 nfc_dev_err(&dev->interface->dev, "Failed to allocate skb.");
1807 return -ENOMEM;
1808 }
1809
1810 rc = pn533_send_cmd_async(dev, cmd_code, skb, pn533_poll_complete,
1811 NULL);
1812 if (rc < 0) {
1813 dev_kfree_skb(skb);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001814 nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc);
Waldemar Rymarkiewiczb5193e52012-12-10 14:42:48 +01001815 }
Samuel Ortizad3823c2012-05-30 23:54:55 +02001816
1817 return rc;
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001818}
1819
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001820static void pn533_wq_poll(struct work_struct *work)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001821{
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001822 struct pn533 *dev = container_of(work, struct pn533, poll_work);
1823 struct pn533_poll_modulations *cur_mod;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001824 int rc;
1825
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001826 cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
1827
1828 nfc_dev_dbg(&dev->interface->dev,
1829 "%s cancel_listen %d modulation len %d",
1830 __func__, dev->cancel_listen, cur_mod->len);
1831
1832 if (dev->cancel_listen == 1) {
1833 dev->cancel_listen = 0;
Waldemar Rymarkiewicz10cff292013-04-03 08:02:14 +02001834 pn533_abort_cmd(dev, GFP_ATOMIC);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001835 }
1836
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001837 rc = pn533_send_poll_frame(dev);
1838 if (rc)
1839 return;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001840
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001841 if (cur_mod->len == 0 && dev->poll_mod_count > 1)
1842 mod_timer(&dev->listen_timer, jiffies + PN533_LISTEN_TIME * HZ);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001843
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001844 return;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001845}
1846
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001847static int pn533_start_poll(struct nfc_dev *nfc_dev,
1848 u32 im_protocols, u32 tm_protocols)
1849{
1850 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1851
1852 nfc_dev_dbg(&dev->interface->dev,
1853 "%s: im protocols 0x%x tm protocols 0x%x",
1854 __func__, im_protocols, tm_protocols);
1855
1856 if (dev->tgt_active_prot) {
1857 nfc_dev_err(&dev->interface->dev,
1858 "Cannot poll with a target already activated");
1859 return -EBUSY;
1860 }
1861
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001862 if (dev->tgt_mode) {
1863 nfc_dev_err(&dev->interface->dev,
1864 "Cannot poll while already being activated");
1865 return -EBUSY;
1866 }
1867
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001868 if (tm_protocols) {
1869 dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
1870 if (dev->gb == NULL)
1871 tm_protocols = 0;
1872 }
Samuel Ortizad3823c2012-05-30 23:54:55 +02001873
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001874 dev->poll_mod_curr = 0;
1875 pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
1876 dev->poll_protocols = im_protocols;
1877 dev->listen_protocols = tm_protocols;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001878
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001879 return pn533_send_poll_frame(dev);
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001880}
1881
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001882static void pn533_stop_poll(struct nfc_dev *nfc_dev)
1883{
1884 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1885
1886 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1887
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001888 del_timer(&dev->listen_timer);
1889
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001890 if (!dev->poll_mod_count) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001891 nfc_dev_dbg(&dev->interface->dev,
1892 "Polling operation was not running");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001893 return;
1894 }
1895
Waldemar Rymarkiewicz10cff292013-04-03 08:02:14 +02001896 pn533_abort_cmd(dev, GFP_KERNEL);
Samuel Ortiz7c2a04a932012-05-21 16:20:01 +02001897 pn533_poll_reset_mod_list(dev);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001898}
1899
1900static int pn533_activate_target_nfcdep(struct pn533 *dev)
1901{
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001902 struct pn533_cmd_activate_response *rsp;
Samuel Ortiz541d9202011-12-14 16:43:10 +01001903 u16 gt_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001904 int rc;
1905
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001906 struct sk_buff *skb;
1907 struct sk_buff *resp;
1908
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001909 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1910
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01001911 skb = pn533_alloc_skb(dev, sizeof(u8) * 2); /*TG + Next*/
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001912 if (!skb)
1913 return -ENOMEM;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001914
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001915 *skb_put(skb, sizeof(u8)) = 1; /* TG */
1916 *skb_put(skb, sizeof(u8)) = 0; /* Next */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001917
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001918 resp = pn533_send_cmd_sync(dev, PN533_CMD_IN_ATR, skb);
1919 if (IS_ERR(resp))
1920 return PTR_ERR(resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001921
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01001922 rsp = (struct pn533_cmd_activate_response *)resp->data;
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001923 rc = rsp->status & PN533_CMD_RET_MASK;
Waldemar Rymarkiewicz8a0ecfe2012-12-21 10:39:01 +01001924 if (rc != PN533_CMD_RET_SUCCESS) {
Waldemar Rymarkiewicza45e1c82013-04-03 08:01:59 +02001925 nfc_dev_err(&dev->interface->dev,
1926 "Target activation failed (error 0x%x)", rc);
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001927 dev_kfree_skb(resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001928 return -EIO;
Waldemar Rymarkiewicz8a0ecfe2012-12-21 10:39:01 +01001929 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001930
Samuel Ortiz541d9202011-12-14 16:43:10 +01001931 /* ATR_RES general bytes are located at offset 16 */
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001932 gt_len = resp->len - 16;
1933 rc = nfc_set_remote_general_bytes(dev->nfc_dev, rsp->gt, gt_len);
Samuel Ortiz541d9202011-12-14 16:43:10 +01001934
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001935 dev_kfree_skb(resp);
Samuel Ortiz541d9202011-12-14 16:43:10 +01001936 return rc;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001937}
1938
Eric Lapuyade90099432012-05-07 12:31:13 +02001939static int pn533_activate_target(struct nfc_dev *nfc_dev,
1940 struct nfc_target *target, u32 protocol)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001941{
1942 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1943 int rc;
1944
1945 nfc_dev_dbg(&dev->interface->dev, "%s - protocol=%u", __func__,
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01001946 protocol);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001947
1948 if (dev->poll_mod_count) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001949 nfc_dev_err(&dev->interface->dev,
1950 "Cannot activate while polling");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001951 return -EBUSY;
1952 }
1953
1954 if (dev->tgt_active_prot) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001955 nfc_dev_err(&dev->interface->dev,
1956 "There is already an active target");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001957 return -EBUSY;
1958 }
1959
1960 if (!dev->tgt_available_prots) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001961 nfc_dev_err(&dev->interface->dev,
1962 "There is no available target to activate");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001963 return -EINVAL;
1964 }
1965
1966 if (!(dev->tgt_available_prots & (1 << protocol))) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001967 nfc_dev_err(&dev->interface->dev,
1968 "Target doesn't support requested proto %u",
1969 protocol);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001970 return -EINVAL;
1971 }
1972
1973 if (protocol == NFC_PROTO_NFC_DEP) {
1974 rc = pn533_activate_target_nfcdep(dev);
1975 if (rc) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01001976 nfc_dev_err(&dev->interface->dev,
1977 "Activating target with DEP failed %d", rc);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001978 return rc;
1979 }
1980 }
1981
1982 dev->tgt_active_prot = protocol;
1983 dev->tgt_available_prots = 0;
1984
1985 return 0;
1986}
1987
Eric Lapuyade90099432012-05-07 12:31:13 +02001988static void pn533_deactivate_target(struct nfc_dev *nfc_dev,
1989 struct nfc_target *target)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001990{
1991 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01001992
1993 struct sk_buff *skb;
1994 struct sk_buff *resp;
1995
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001996 int rc;
1997
1998 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1999
2000 if (!dev->tgt_active_prot) {
2001 nfc_dev_err(&dev->interface->dev, "There is no active target");
2002 return;
2003 }
2004
2005 dev->tgt_active_prot = 0;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002006 skb_queue_purge(&dev->resp_q);
2007
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002008 skb = pn533_alloc_skb(dev, sizeof(u8));
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002009 if (!skb)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002010 return;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002011
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002012 *skb_put(skb, 1) = 1; /* TG*/
2013
2014 resp = pn533_send_cmd_sync(dev, PN533_CMD_IN_RELEASE, skb);
2015 if (IS_ERR(resp))
2016 return;
2017
2018 rc = resp->data[0] & PN533_CMD_RET_MASK;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002019 if (rc != PN533_CMD_RET_SUCCESS)
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01002020 nfc_dev_err(&dev->interface->dev,
2021 "Error 0x%x when releasing the target", rc);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002022
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002023 dev_kfree_skb(resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002024 return;
2025}
2026
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002027
2028static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002029 struct sk_buff *resp)
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002030{
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002031 struct pn533_cmd_jump_dep_response *rsp;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002032 u8 target_gt_len;
2033 int rc;
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002034 u8 active = *(u8 *)arg;
Waldemar Rymarkiewicz70418e62012-10-11 14:04:00 +02002035
2036 kfree(arg);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002037
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002038 if (IS_ERR(resp))
2039 return PTR_ERR(resp);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002040
2041 if (dev->tgt_available_prots &&
2042 !(dev->tgt_available_prots & (1 << NFC_PROTO_NFC_DEP))) {
2043 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01002044 "The target does not support DEP");
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002045 rc = -EINVAL;
2046 goto error;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002047 }
2048
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002049 rsp = (struct pn533_cmd_jump_dep_response *)resp->data;
2050
2051 rc = rsp->status & PN533_CMD_RET_MASK;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002052 if (rc != PN533_CMD_RET_SUCCESS) {
2053 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewicza45e1c82013-04-03 08:01:59 +02002054 "Bringing DEP link up failed (error 0x%x)", rc);
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002055 goto error;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002056 }
2057
2058 if (!dev->tgt_available_prots) {
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002059 struct nfc_target nfc_target;
2060
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002061 nfc_dev_dbg(&dev->interface->dev, "Creating new target");
2062
2063 nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
Samuel Ortiz2fbabfa2012-03-05 01:03:47 +01002064 nfc_target.nfcid1_len = 10;
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002065 memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002066 rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1);
2067 if (rc)
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002068 goto error;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002069
2070 dev->tgt_available_prots = 0;
2071 }
2072
2073 dev->tgt_active_prot = NFC_PROTO_NFC_DEP;
2074
2075 /* ATR_RES general bytes are located at offset 17 */
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002076 target_gt_len = resp->len - 17;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002077 rc = nfc_set_remote_general_bytes(dev->nfc_dev,
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002078 rsp->gt, target_gt_len);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002079 if (rc == 0)
2080 rc = nfc_dep_link_is_up(dev->nfc_dev,
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002081 dev->nfc_dev->targets[0].idx,
2082 !active, NFC_RF_INITIATOR);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002083
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002084error:
2085 dev_kfree_skb(resp);
2086 return rc;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002087}
2088
Samuel Ortiz41a8ec42012-05-31 17:44:44 +02002089static int pn533_mod_to_baud(struct pn533 *dev)
2090{
2091 switch (dev->poll_mod_curr) {
2092 case PN533_POLL_MOD_106KBPS_A:
2093 return 0;
2094 case PN533_POLL_MOD_212KBPS_FELICA:
2095 return 1;
2096 case PN533_POLL_MOD_424KBPS_FELICA:
2097 return 2;
2098 default:
2099 return -EINVAL;
2100 }
2101}
2102
Samuel Ortiz17e9d9d2013-06-26 18:16:21 +02002103static int pn533_rf_field(struct nfc_dev *nfc_dev, u8 rf);
Samuel Ortizd7f33452012-05-29 21:45:21 +02002104#define PASSIVE_DATA_LEN 5
Eric Lapuyade90099432012-05-07 12:31:13 +02002105static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
Waldemar Rymarkiewicz37cf4fc2012-12-10 14:42:50 +01002106 u8 comm_mode, u8 *gb, size_t gb_len)
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002107{
2108 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002109 struct sk_buff *skb;
2110 int rc, baud, skb_len;
2111 u8 *next, *arg;
2112
Samuel Ortizd7f33452012-05-29 21:45:21 +02002113 u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3};
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002114
2115 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2116
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002117 if (dev->poll_mod_count) {
2118 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01002119 "Cannot bring the DEP link up while polling");
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002120 return -EBUSY;
2121 }
2122
2123 if (dev->tgt_active_prot) {
2124 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01002125 "There is already an active target");
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002126 return -EBUSY;
2127 }
2128
Samuel Ortiz41a8ec42012-05-31 17:44:44 +02002129 baud = pn533_mod_to_baud(dev);
2130 if (baud < 0) {
2131 nfc_dev_err(&dev->interface->dev,
2132 "Invalid curr modulation %d", dev->poll_mod_curr);
2133 return baud;
2134 }
2135
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002136 skb_len = 3 + gb_len; /* ActPass + BR + Next */
Samuel Ortizd7f33452012-05-29 21:45:21 +02002137 if (comm_mode == NFC_COMM_PASSIVE)
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002138 skb_len += PASSIVE_DATA_LEN;
Samuel Ortizd7f33452012-05-29 21:45:21 +02002139
Samuel Ortiz322bce92013-05-27 15:29:11 +02002140 if (target && target->nfcid2_len)
2141 skb_len += NFC_NFCID3_MAXSIZE;
2142
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002143 skb = pn533_alloc_skb(dev, skb_len);
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002144 if (!skb)
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002145 return -ENOMEM;
2146
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002147 *skb_put(skb, 1) = !comm_mode; /* ActPass */
2148 *skb_put(skb, 1) = baud; /* Baud rate */
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002149
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002150 next = skb_put(skb, 1); /* Next */
2151 *next = 0;
2152
2153 if (comm_mode == NFC_COMM_PASSIVE && baud > 0) {
2154 memcpy(skb_put(skb, PASSIVE_DATA_LEN), passive_data,
2155 PASSIVE_DATA_LEN);
2156 *next |= 1;
Samuel Ortizd7f33452012-05-29 21:45:21 +02002157 }
2158
Samuel Ortiz322bce92013-05-27 15:29:11 +02002159 if (target && target->nfcid2_len) {
2160 memcpy(skb_put(skb, NFC_NFCID3_MAXSIZE), target->nfcid2,
2161 target->nfcid2_len);
2162 *next |= 2;
2163 }
2164
Samuel Ortiz47807d32012-03-05 01:03:50 +01002165 if (gb != NULL && gb_len > 0) {
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002166 memcpy(skb_put(skb, gb_len), gb, gb_len);
2167 *next |= 4; /* We have some Gi */
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002168 } else {
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002169 *next = 0;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002170 }
2171
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002172 arg = kmalloc(sizeof(*arg), GFP_KERNEL);
2173 if (!arg) {
2174 dev_kfree_skb(skb);
2175 return -ENOMEM;
2176 }
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002177
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002178 *arg = !comm_mode;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002179
Samuel Ortiz17e9d9d2013-06-26 18:16:21 +02002180 pn533_rf_field(dev->nfc_dev, 0);
2181
Waldemar Rymarkiewicz13003642012-12-10 14:42:45 +01002182 rc = pn533_send_cmd_async(dev, PN533_CMD_IN_JUMP_FOR_DEP, skb,
2183 pn533_in_dep_link_up_complete, arg);
2184
2185 if (rc < 0) {
2186 dev_kfree_skb(skb);
2187 kfree(arg);
2188 }
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002189
2190 return rc;
2191}
2192
2193static int pn533_dep_link_down(struct nfc_dev *nfc_dev)
2194{
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002195 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
2196
Waldemar Rymarkiewiczfcfafc72012-12-10 14:42:55 +01002197 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2198
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002199 pn533_poll_reset_mod_list(dev);
2200
Waldemar Rymarkiewicz10cff292013-04-03 08:02:14 +02002201 if (dev->tgt_mode || dev->tgt_active_prot)
2202 pn533_abort_cmd(dev, GFP_KERNEL);
Samuel Ortiz51ad3042012-05-31 20:01:32 +02002203
2204 dev->tgt_active_prot = 0;
2205 dev->tgt_mode = 0;
2206
2207 skb_queue_purge(&dev->resp_q);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002208
2209 return 0;
2210}
2211
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002212struct pn533_data_exchange_arg {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002213 data_exchange_cb_t cb;
2214 void *cb_context;
2215};
2216
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002217static struct sk_buff *pn533_build_response(struct pn533 *dev)
2218{
2219 struct sk_buff *skb, *tmp, *t;
2220 unsigned int skb_len = 0, tmp_len = 0;
2221
Waldemar Rymarkiewiczfcfafc72012-12-10 14:42:55 +01002222 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002223
2224 if (skb_queue_empty(&dev->resp_q))
2225 return NULL;
2226
2227 if (skb_queue_len(&dev->resp_q) == 1) {
2228 skb = skb_dequeue(&dev->resp_q);
2229 goto out;
2230 }
2231
2232 skb_queue_walk_safe(&dev->resp_q, tmp, t)
2233 skb_len += tmp->len;
2234
2235 nfc_dev_dbg(&dev->interface->dev, "%s total length %d\n",
2236 __func__, skb_len);
2237
2238 skb = alloc_skb(skb_len, GFP_KERNEL);
2239 if (skb == NULL)
2240 goto out;
2241
2242 skb_put(skb, skb_len);
2243
2244 skb_queue_walk_safe(&dev->resp_q, tmp, t) {
2245 memcpy(skb->data + tmp_len, tmp->data, tmp->len);
2246 tmp_len += tmp->len;
2247 }
2248
2249out:
2250 skb_queue_purge(&dev->resp_q);
2251
2252 return skb;
2253}
2254
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002255static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg,
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002256 struct sk_buff *resp)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002257{
2258 struct pn533_data_exchange_arg *arg = _arg;
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002259 struct sk_buff *skb;
2260 int rc = 0;
2261 u8 status, ret, mi;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002262
2263 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2264
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002265 if (IS_ERR(resp)) {
2266 rc = PTR_ERR(resp);
2267 goto _error;
2268 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002269
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002270 status = resp->data[0];
2271 ret = status & PN533_CMD_RET_MASK;
2272 mi = status & PN533_CMD_MI_MASK;
2273
2274 skb_pull(resp, sizeof(status));
2275
2276 if (ret != PN533_CMD_RET_SUCCESS) {
2277 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewicza45e1c82013-04-03 08:01:59 +02002278 "Exchanging data failed (error 0x%x)", ret);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002279 rc = -EIO;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002280 goto error;
2281 }
2282
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002283 skb_queue_tail(&dev->resp_q, resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002284
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002285 if (mi) {
2286 dev->cmd_complete_mi_arg = arg;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002287 queue_work(dev->wq, &dev->mi_work);
2288 return -EINPROGRESS;
2289 }
2290
2291 skb = pn533_build_response(dev);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002292 if (!skb)
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002293 goto error;
2294
2295 arg->cb(arg->cb_context, skb, 0);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002296 kfree(arg);
2297 return 0;
2298
2299error:
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002300 dev_kfree_skb(resp);
2301_error:
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002302 skb_queue_purge(&dev->resp_q);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002303 arg->cb(arg->cb_context, NULL, rc);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002304 kfree(arg);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002305 return rc;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002306}
2307
Samuel Ortizbe9ae4c2012-05-16 15:55:48 +02002308static int pn533_transceive(struct nfc_dev *nfc_dev,
2309 struct nfc_target *target, struct sk_buff *skb,
2310 data_exchange_cb_t cb, void *cb_context)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002311{
2312 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002313 struct pn533_data_exchange_arg *arg = NULL;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002314 int rc;
2315
2316 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2317
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002318 if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) {
2319 /* TODO: Implement support to multi-part data exchange */
2320 nfc_dev_err(&dev->interface->dev,
2321 "Data length greater than the max allowed: %d",
2322 PN533_CMD_DATAEXCH_DATA_MAXLEN);
2323 rc = -ENOSYS;
2324 goto error;
2325 }
2326
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002327 if (!dev->tgt_active_prot) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01002328 nfc_dev_err(&dev->interface->dev,
2329 "Can't exchange data if there is no active target");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002330 rc = -EINVAL;
2331 goto error;
2332 }
2333
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002334 arg = kmalloc(sizeof(*arg), GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002335 if (!arg) {
2336 rc = -ENOMEM;
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002337 goto error;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002338 }
2339
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002340 arg->cb = cb;
2341 arg->cb_context = cb_context;
2342
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002343 switch (dev->device_type) {
2344 case PN533_DEVICE_PASORI:
2345 if (dev->tgt_active_prot == NFC_PROTO_FELICA) {
2346 rc = pn533_send_data_async(dev, PN533_CMD_IN_COMM_THRU,
2347 skb,
2348 pn533_data_exchange_complete,
2349 arg);
2350
2351 break;
2352 }
2353 default:
2354 *skb_push(skb, sizeof(u8)) = 1; /*TG*/
2355
2356 rc = pn533_send_data_async(dev, PN533_CMD_IN_DATA_EXCHANGE,
2357 skb, pn533_data_exchange_complete,
2358 arg);
2359
2360 break;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002361 }
2362
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002363 if (rc < 0) /* rc from send_async */
2364 goto error;
2365
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002366 return 0;
2367
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002368error:
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002369 kfree(arg);
2370 dev_kfree_skb(skb);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002371 return rc;
2372}
2373
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002374static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002375 struct sk_buff *resp)
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002376{
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002377 u8 status;
Thierry Escande5b412fd2012-11-15 18:24:28 +01002378
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002379 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2380
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002381 if (IS_ERR(resp))
2382 return PTR_ERR(resp);
Thierry Escande5b412fd2012-11-15 18:24:28 +01002383
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002384 status = resp->data[0];
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002385
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002386 dev_kfree_skb(resp);
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002387
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002388 if (status != 0) {
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002389 nfc_tm_deactivated(dev->nfc_dev);
2390
Samuel Ortiz51ad3042012-05-31 20:01:32 +02002391 dev->tgt_mode = 0;
2392
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002393 return 0;
2394 }
2395
2396 queue_work(dev->wq, &dev->tg_work);
2397
2398 return 0;
2399}
2400
2401static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
2402{
2403 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002404 int rc;
2405
2406 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2407
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002408 if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) {
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002409 nfc_dev_err(&dev->interface->dev,
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002410 "Data length greater than the max allowed: %d",
2411 PN533_CMD_DATAEXCH_DATA_MAXLEN);
2412 return -ENOSYS;
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002413 }
2414
Waldemar Rymarkiewicze4878822012-12-10 14:42:44 +01002415 rc = pn533_send_data_async(dev, PN533_CMD_TG_SET_DATA, skb,
2416 pn533_tm_send_complete, NULL);
2417 if (rc < 0)
2418 dev_kfree_skb(skb);
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002419
2420 return rc;
2421}
2422
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002423static void pn533_wq_mi_recv(struct work_struct *work)
2424{
2425 struct pn533 *dev = container_of(work, struct pn533, mi_work);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002426
2427 struct sk_buff *skb;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002428 int rc;
2429
2430 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2431
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002432 skb = pn533_alloc_skb(dev, PN533_CMD_DATAEXCH_HEAD_LEN);
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002433 if (!skb)
2434 goto error;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002435
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002436 switch (dev->device_type) {
2437 case PN533_DEVICE_PASORI:
2438 if (dev->tgt_active_prot == NFC_PROTO_FELICA) {
2439 rc = pn533_send_cmd_direct_async(dev,
2440 PN533_CMD_IN_COMM_THRU,
2441 skb,
2442 pn533_data_exchange_complete,
2443 dev->cmd_complete_mi_arg);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002444
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002445 break;
2446 }
2447 default:
2448 *skb_put(skb, sizeof(u8)) = 1; /*TG*/
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002449
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002450 rc = pn533_send_cmd_direct_async(dev,
2451 PN533_CMD_IN_DATA_EXCHANGE,
2452 skb,
2453 pn533_data_exchange_complete,
2454 dev->cmd_complete_mi_arg);
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002455
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002456 break;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002457 }
2458
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002459 if (rc == 0) /* success */
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002460 return;
2461
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002462 nfc_dev_err(&dev->interface->dev,
2463 "Error %d when trying to perform data_exchange", rc);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002464
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002465 dev_kfree_skb(skb);
Waldemar Rymarkiewicz140ef7f2013-04-03 08:02:07 +02002466 kfree(dev->cmd_complete_mi_arg);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002467
Waldemar Rymarkiewiczb1e666f2012-12-10 14:42:46 +01002468error:
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002469 pn533_send_ack(dev, GFP_KERNEL);
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002470 queue_work(dev->wq, &dev->cmd_work);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002471}
2472
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002473static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata,
2474 u8 cfgdata_len)
2475{
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002476 struct sk_buff *skb;
2477 struct sk_buff *resp;
2478
2479 int skb_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002480
2481 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2482
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002483 skb_len = sizeof(cfgitem) + cfgdata_len; /* cfgitem + cfgdata */
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002484
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002485 skb = pn533_alloc_skb(dev, skb_len);
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002486 if (!skb)
2487 return -ENOMEM;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002488
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002489 *skb_put(skb, sizeof(cfgitem)) = cfgitem;
2490 memcpy(skb_put(skb, cfgdata_len), cfgdata, cfgdata_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002491
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002492 resp = pn533_send_cmd_sync(dev, PN533_CMD_RF_CONFIGURATION, skb);
2493 if (IS_ERR(resp))
2494 return PTR_ERR(resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002495
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002496 dev_kfree_skb(resp);
2497 return 0;
2498}
2499
2500static int pn533_get_firmware_version(struct pn533 *dev,
2501 struct pn533_fw_version *fv)
2502{
2503 struct sk_buff *skb;
2504 struct sk_buff *resp;
2505
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002506 skb = pn533_alloc_skb(dev, 0);
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002507 if (!skb)
2508 return -ENOMEM;
2509
2510 resp = pn533_send_cmd_sync(dev, PN533_CMD_GET_FIRMWARE_VERSION, skb);
2511 if (IS_ERR(resp))
2512 return PTR_ERR(resp);
2513
2514 fv->ic = resp->data[0];
2515 fv->ver = resp->data[1];
2516 fv->rev = resp->data[2];
2517 fv->support = resp->data[3];
2518
2519 dev_kfree_skb(resp);
2520 return 0;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002521}
2522
Waldemar Rymarkiewiczf75c2912013-04-03 08:02:02 +02002523static int pn533_pasori_fw_reset(struct pn533 *dev)
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002524{
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002525 struct sk_buff *skb;
2526 struct sk_buff *resp;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002527
2528 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2529
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002530 skb = pn533_alloc_skb(dev, sizeof(u8));
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002531 if (!skb)
2532 return -ENOMEM;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002533
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002534 *skb_put(skb, sizeof(u8)) = 0x1;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002535
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002536 resp = pn533_send_cmd_sync(dev, 0x18, skb);
2537 if (IS_ERR(resp))
2538 return PTR_ERR(resp);
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002539
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002540 dev_kfree_skb(resp);
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002541
Waldemar Rymarkiewicz94c5c152012-11-26 14:18:36 +01002542 return 0;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002543}
2544
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +02002545struct pn533_acr122_poweron_rdr_arg {
2546 int rc;
2547 struct completion done;
2548};
2549
2550static void pn533_acr122_poweron_rdr_resp(struct urb *urb)
2551{
2552 struct pn533_acr122_poweron_rdr_arg *arg = urb->context;
2553
2554 nfc_dev_dbg(&urb->dev->dev, "%s", __func__);
2555
Olivier Guiter86eca4e2013-06-03 12:02:29 +02002556 print_hex_dump_debug("ACR122 RX: ", DUMP_PREFIX_NONE, 16, 1,
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +02002557 urb->transfer_buffer, urb->transfer_buffer_length,
2558 false);
2559
2560 arg->rc = urb->status;
2561 complete(&arg->done);
2562}
2563
2564static int pn533_acr122_poweron_rdr(struct pn533 *dev)
2565{
2566 /* Power on th reader (CCID cmd) */
2567 u8 cmd[10] = {PN533_ACR122_PC_TO_RDR_ICCPOWERON,
2568 0, 0, 0, 0, 0, 0, 3, 0, 0};
2569 u8 buf[255];
2570 int rc;
2571 void *cntx;
2572 struct pn533_acr122_poweron_rdr_arg arg;
2573
2574 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2575
2576 init_completion(&arg.done);
2577 cntx = dev->in_urb->context; /* backup context */
2578
2579 dev->in_urb->transfer_buffer = buf;
2580 dev->in_urb->transfer_buffer_length = 255;
2581 dev->in_urb->complete = pn533_acr122_poweron_rdr_resp;
2582 dev->in_urb->context = &arg;
2583
2584 dev->out_urb->transfer_buffer = cmd;
2585 dev->out_urb->transfer_buffer_length = sizeof(cmd);
2586
Olivier Guiter86eca4e2013-06-03 12:02:29 +02002587 print_hex_dump_debug("ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1,
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +02002588 cmd, sizeof(cmd), false);
2589
2590 rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
2591 if (rc) {
2592 nfc_dev_err(&dev->interface->dev,
2593 "Reader power on cmd error %d", rc);
2594 return rc;
2595 }
2596
2597 rc = usb_submit_urb(dev->in_urb, GFP_KERNEL);
2598 if (rc) {
2599 nfc_dev_err(&dev->interface->dev,
2600 "Can't submit for reader power on cmd response %d",
2601 rc);
2602 return rc;
2603 }
2604
2605 wait_for_completion(&arg.done);
2606 dev->in_urb->context = cntx; /* restore context */
2607
2608 return arg.rc;
2609}
2610
Samuel Ortiz60d9edd52013-04-11 11:45:41 +02002611static int pn533_rf_field(struct nfc_dev *nfc_dev, u8 rf)
2612{
2613 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
2614 u8 rf_field = !!rf;
2615 int rc;
2616
2617 rc = pn533_set_configuration(dev, PN533_CFGITEM_RF_FIELD,
2618 (u8 *)&rf_field, 1);
2619 if (rc) {
2620 nfc_dev_err(&dev->interface->dev,
2621 "Error on setting RF field");
2622 return rc;
2623 }
2624
2625 return rc;
2626}
2627
2628int pn533_dev_up(struct nfc_dev *nfc_dev)
2629{
2630 return pn533_rf_field(nfc_dev, 1);
2631}
2632
2633int pn533_dev_down(struct nfc_dev *nfc_dev)
2634{
2635 return pn533_rf_field(nfc_dev, 0);
2636}
2637
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002638static struct nfc_ops pn533_nfc_ops = {
Samuel Ortiz60d9edd52013-04-11 11:45:41 +02002639 .dev_up = pn533_dev_up,
2640 .dev_down = pn533_dev_down,
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002641 .dep_link_up = pn533_dep_link_up,
2642 .dep_link_down = pn533_dep_link_down,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002643 .start_poll = pn533_start_poll,
2644 .stop_poll = pn533_stop_poll,
2645 .activate_target = pn533_activate_target,
2646 .deactivate_target = pn533_deactivate_target,
Samuel Ortizbe9ae4c2012-05-16 15:55:48 +02002647 .im_transceive = pn533_transceive,
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002648 .tm_send = pn533_tm_send,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002649};
2650
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002651static int pn533_setup(struct pn533 *dev)
2652{
2653 struct pn533_config_max_retries max_retries;
2654 struct pn533_config_timing timing;
2655 u8 pasori_cfg[3] = {0x08, 0x01, 0x08};
2656 int rc;
2657
2658 switch (dev->device_type) {
2659 case PN533_DEVICE_STD:
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002660 case PN533_DEVICE_PASORI:
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +02002661 case PN533_DEVICE_ACR122U:
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002662 max_retries.mx_rty_atr = 0x2;
2663 max_retries.mx_rty_psl = 0x1;
2664 max_retries.mx_rty_passive_act =
2665 PN533_CONFIG_MAX_RETRIES_NO_RETRY;
2666
2667 timing.rfu = PN533_CONFIG_TIMING_102;
2668 timing.atr_res_timeout = PN533_CONFIG_TIMING_102;
2669 timing.dep_timeout = PN533_CONFIG_TIMING_204;
2670
2671 break;
2672
2673 default:
2674 nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n",
2675 dev->device_type);
2676 return -EINVAL;
2677 }
2678
2679 rc = pn533_set_configuration(dev, PN533_CFGITEM_MAX_RETRIES,
2680 (u8 *)&max_retries, sizeof(max_retries));
2681 if (rc) {
2682 nfc_dev_err(&dev->interface->dev,
2683 "Error on setting MAX_RETRIES config");
2684 return rc;
2685 }
2686
2687
2688 rc = pn533_set_configuration(dev, PN533_CFGITEM_TIMING,
2689 (u8 *)&timing, sizeof(timing));
2690 if (rc) {
2691 nfc_dev_err(&dev->interface->dev,
2692 "Error on setting RF timings");
2693 return rc;
2694 }
2695
2696 switch (dev->device_type) {
2697 case PN533_DEVICE_STD:
2698 break;
2699
2700 case PN533_DEVICE_PASORI:
Waldemar Rymarkiewiczf75c2912013-04-03 08:02:02 +02002701 pn533_pasori_fw_reset(dev);
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002702
2703 rc = pn533_set_configuration(dev, PN533_CFGITEM_PASORI,
2704 pasori_cfg, 3);
2705 if (rc) {
2706 nfc_dev_err(&dev->interface->dev,
2707 "Error while settings PASORI config");
2708 return rc;
2709 }
2710
Waldemar Rymarkiewiczf75c2912013-04-03 08:02:02 +02002711 pn533_pasori_fw_reset(dev);
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002712
2713 break;
2714 }
2715
2716 return 0;
2717}
2718
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002719static int pn533_probe(struct usb_interface *interface,
2720 const struct usb_device_id *id)
2721{
Waldemar Rymarkiewiczcb950d92012-11-26 14:18:38 +01002722 struct pn533_fw_version fw_ver;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002723 struct pn533 *dev;
2724 struct usb_host_interface *iface_desc;
2725 struct usb_endpoint_descriptor *endpoint;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002726 int in_endpoint = 0;
2727 int out_endpoint = 0;
2728 int rc = -ENOMEM;
2729 int i;
2730 u32 protocols;
2731
2732 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2733 if (!dev)
2734 return -ENOMEM;
2735
2736 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2737 dev->interface = interface;
Samuel Ortiz0201ed02012-05-31 17:56:46 +02002738 mutex_init(&dev->cmd_lock);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002739
2740 iface_desc = interface->cur_altsetting;
2741 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2742 endpoint = &iface_desc->endpoint[i].desc;
2743
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002744 if (!in_endpoint && usb_endpoint_is_bulk_in(endpoint))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002745 in_endpoint = endpoint->bEndpointAddress;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002746
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002747 if (!out_endpoint && usb_endpoint_is_bulk_out(endpoint))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002748 out_endpoint = endpoint->bEndpointAddress;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002749 }
2750
2751 if (!in_endpoint || !out_endpoint) {
Waldemar Rymarkiewicz6ca55372012-12-10 14:42:49 +01002752 nfc_dev_err(&interface->dev,
2753 "Could not find bulk-in or bulk-out endpoint");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002754 rc = -ENODEV;
2755 goto error;
2756 }
2757
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002758 dev->in_urb = usb_alloc_urb(0, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002759 dev->out_urb = usb_alloc_urb(0, GFP_KERNEL);
2760
Waldemar Rymarkiewicza5798092012-12-10 14:42:58 +01002761 if (!dev->in_urb || !dev->out_urb)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002762 goto error;
2763
2764 usb_fill_bulk_urb(dev->in_urb, dev->udev,
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01002765 usb_rcvbulkpipe(dev->udev, in_endpoint),
2766 NULL, 0, NULL, dev);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002767 usb_fill_bulk_urb(dev->out_urb, dev->udev,
Waldemar Rymarkiewicz5d467742012-12-10 14:42:51 +01002768 usb_sndbulkpipe(dev->udev, out_endpoint),
2769 NULL, 0, pn533_send_complete, dev);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002770
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002771 INIT_WORK(&dev->cmd_work, pn533_wq_cmd);
2772 INIT_WORK(&dev->cmd_complete_work, pn533_wq_cmd_complete);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002773 INIT_WORK(&dev->mi_work, pn533_wq_mi_recv);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02002774 INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002775 INIT_WORK(&dev->poll_work, pn533_wq_poll);
Samuel Ortiz17e9d9d2013-06-26 18:16:21 +02002776 INIT_WORK(&dev->rf_work, pn533_wq_rf);
Tejun Heo58637c92012-08-22 16:28:46 -07002777 dev->wq = alloc_ordered_workqueue("pn533", 0);
Samuel Ortiz4849f852012-04-10 19:43:17 +02002778 if (dev->wq == NULL)
2779 goto error;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002780
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002781 init_timer(&dev->listen_timer);
2782 dev->listen_timer.data = (unsigned long) dev;
2783 dev->listen_timer.function = pn533_listen_mode_timer;
2784
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002785 skb_queue_head_init(&dev->resp_q);
2786
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002787 INIT_LIST_HEAD(&dev->cmd_queue);
2788
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002789 usb_set_intfdata(interface, dev);
2790
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002791 dev->ops = &pn533_std_frame_ops;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002792
Waldemar Rymarkiewicz58520372013-04-03 08:02:12 +02002793 dev->protocol_type = PN533_PROTO_REQ_ACK_RESP;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002794 dev->device_type = id->driver_info;
2795 switch (dev->device_type) {
2796 case PN533_DEVICE_STD:
2797 protocols = PN533_ALL_PROTOCOLS;
2798 break;
2799
2800 case PN533_DEVICE_PASORI:
2801 protocols = PN533_NO_TYPE_B_PROTOCOLS;
2802 break;
2803
Waldemar Rymarkiewicz53cf4832013-04-03 08:02:13 +02002804 case PN533_DEVICE_ACR122U:
2805 protocols = PN533_NO_TYPE_B_PROTOCOLS;
2806 dev->ops = &pn533_acr122_frame_ops;
2807 dev->protocol_type = PN533_PROTO_REQ_RESP,
2808
2809 rc = pn533_acr122_poweron_rdr(dev);
2810 if (rc < 0) {
2811 nfc_dev_err(&dev->interface->dev,
2812 "Couldn't poweron the reader (error %d)",
2813 rc);
2814 goto destroy_wq;
2815 }
2816 break;
2817
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002818 default:
2819 nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n",
2820 dev->device_type);
2821 rc = -EINVAL;
2822 goto destroy_wq;
2823 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002824
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002825 memset(&fw_ver, 0, sizeof(fw_ver));
2826 rc = pn533_get_firmware_version(dev, &fw_ver);
2827 if (rc < 0)
2828 goto destroy_wq;
2829
2830 nfc_dev_info(&dev->interface->dev,
Olivier Guiter86eca4e2013-06-03 12:02:29 +02002831 "NXP PN5%02X firmware ver %d.%d now attached",
2832 fw_ver.ic, fw_ver.ver, fw_ver.rev);
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002833
2834
Samuel Ortize8753042011-08-19 15:47:11 +02002835 dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002836 dev->ops->tx_header_len +
Samuel Ortize8753042011-08-19 15:47:11 +02002837 PN533_CMD_DATAEXCH_HEAD_LEN,
Waldemar Rymarkiewicz9e2d4932012-12-10 14:43:01 +01002838 dev->ops->tx_tail_len);
Wei Yongjun4674d0f2013-05-07 20:07:52 +08002839 if (!dev->nfc_dev) {
2840 rc = -ENOMEM;
Samuel Ortiz4849f852012-04-10 19:43:17 +02002841 goto destroy_wq;
Wei Yongjun4674d0f2013-05-07 20:07:52 +08002842 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002843
2844 nfc_set_parent_dev(dev->nfc_dev, &interface->dev);
2845 nfc_set_drvdata(dev->nfc_dev, dev);
2846
2847 rc = nfc_register_device(dev->nfc_dev);
2848 if (rc)
2849 goto free_nfc_dev;
2850
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002851 rc = pn533_setup(dev);
2852 if (rc)
Samuel Ortiz9f2f8ba2012-05-29 21:28:58 +02002853 goto unregister_nfc_dev;
Samuel Ortiz34a85bf2012-05-29 21:34:08 +02002854
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002855 return 0;
2856
Samuel Ortiz9f2f8ba2012-05-29 21:28:58 +02002857unregister_nfc_dev:
2858 nfc_unregister_device(dev->nfc_dev);
2859
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002860free_nfc_dev:
2861 nfc_free_device(dev->nfc_dev);
Samuel Ortiz9f2f8ba2012-05-29 21:28:58 +02002862
Samuel Ortiz4849f852012-04-10 19:43:17 +02002863destroy_wq:
2864 destroy_workqueue(dev->wq);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002865error:
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002866 usb_free_urb(dev->in_urb);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002867 usb_free_urb(dev->out_urb);
Marina Makienko7c5a54f2013-02-26 11:41:18 +04002868 usb_put_dev(dev->udev);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002869 kfree(dev);
2870 return rc;
2871}
2872
2873static void pn533_disconnect(struct usb_interface *interface)
2874{
2875 struct pn533 *dev;
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002876 struct pn533_cmd *cmd, *n;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002877
2878 dev = usb_get_intfdata(interface);
2879 usb_set_intfdata(interface, NULL);
2880
2881 nfc_unregister_device(dev->nfc_dev);
2882 nfc_free_device(dev->nfc_dev);
2883
2884 usb_kill_urb(dev->in_urb);
2885 usb_kill_urb(dev->out_urb);
2886
Samuel Ortiz4849f852012-04-10 19:43:17 +02002887 destroy_workqueue(dev->wq);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002888
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002889 skb_queue_purge(&dev->resp_q);
2890
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002891 del_timer(&dev->listen_timer);
2892
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002893 list_for_each_entry_safe(cmd, n, &dev->cmd_queue, queue) {
2894 list_del(&cmd->queue);
2895 kfree(cmd);
2896 }
2897
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002898 usb_free_urb(dev->in_urb);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002899 usb_free_urb(dev->out_urb);
2900 kfree(dev);
2901
Dan Carpenter276556d2011-07-08 10:21:15 +03002902 nfc_dev_info(&interface->dev, "NXP PN533 NFC device disconnected");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002903}
2904
2905static struct usb_driver pn533_driver = {
2906 .name = "pn533",
2907 .probe = pn533_probe,
2908 .disconnect = pn533_disconnect,
2909 .id_table = pn533_table,
2910};
2911
Greg Kroah-Hartmanfe748482011-11-18 09:52:10 -08002912module_usb_driver(pn533_driver);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002913
Waldemar Rymarkiewicze70b96e2013-04-03 08:02:01 +02002914MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>");
2915MODULE_AUTHOR("Aloisio Almeida Jr <aloisio.almeida@openbossa.org>");
2916MODULE_AUTHOR("Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002917MODULE_DESCRIPTION("PN533 usb driver ver " VERSION);
2918MODULE_VERSION(VERSION);
2919MODULE_LICENSE("GPL");