blob: bfb6df56c5058d36d007c0753a8aa31e25e4f9ce [file] [log] [blame]
Christophe Ricard1892bf82014-05-20 22:21:59 +02001/*
2 * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <net/nfc/hci.h>
18
19#include "st21nfca.h"
20#include "st21nfca_dep.h"
21
22#define ST21NFCA_NFCIP1_INITIATOR 0x00
23#define ST21NFCA_NFCIP1_REQ 0xd4
24#define ST21NFCA_NFCIP1_RES 0xd5
25#define ST21NFCA_NFCIP1_ATR_REQ 0x00
26#define ST21NFCA_NFCIP1_ATR_RES 0x01
27#define ST21NFCA_NFCIP1_PSL_REQ 0x04
28#define ST21NFCA_NFCIP1_PSL_RES 0x05
29#define ST21NFCA_NFCIP1_DEP_REQ 0x06
30#define ST21NFCA_NFCIP1_DEP_RES 0x07
31
32#define ST21NFCA_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
33#define ST21NFCA_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
34#define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
35 ((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
36#define ST21NFCA_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
37#define ST21NFCA_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
38#define ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT 0x10
39
40#define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
41 ((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
42
43#define ST21NFCA_NFC_DEP_PFB_I_PDU 0x00
44#define ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU 0x40
45#define ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
46
47#define ST21NFCA_ATR_REQ_MIN_SIZE 17
48#define ST21NFCA_ATR_REQ_MAX_SIZE 65
49#define ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B 0x30
50#define ST21NFCA_GB_BIT 0x02
51
52#define ST21NFCA_EVT_CARD_F_BITRATE 0x16
53#define ST21NFCA_EVT_READER_F_BITRATE 0x13
54#define ST21NFCA_PSL_REQ_SEND_SPEED(brs) (brs & 0x38)
55#define ST21NFCA_PSL_REQ_RECV_SPEED(brs) (brs & 0x07)
56#define ST21NFCA_PP2LRI(pp) ((pp & 0x30) >> 4)
57#define ST21NFCA_CARD_BITRATE_212 0x01
58#define ST21NFCA_CARD_BITRATE_424 0x02
59
60#define ST21NFCA_DEFAULT_TIMEOUT 0x0a
61
62
63#define PROTOCOL_ERR(req) pr_err("%d: ST21NFCA Protocol error: %s\n", \
64 __LINE__, req)
65
66struct st21nfca_atr_req {
67 u8 length;
68 u8 cmd0;
69 u8 cmd1;
70 u8 nfcid3[NFC_NFCID3_MAXSIZE];
71 u8 did;
72 u8 bsi;
73 u8 bri;
74 u8 ppi;
75 u8 gbi[0];
76} __packed;
77
78struct st21nfca_atr_res {
79 u8 length;
80 u8 cmd0;
81 u8 cmd1;
82 u8 nfcid3[NFC_NFCID3_MAXSIZE];
83 u8 did;
84 u8 bsi;
85 u8 bri;
86 u8 to;
87 u8 ppi;
88 u8 gbi[0];
89} __packed;
90
91struct st21nfca_psl_req {
92 u8 length;
93 u8 cmd0;
94 u8 cmd1;
95 u8 did;
96 u8 brs;
97 u8 fsl;
98} __packed;
99
100struct st21nfca_psl_res {
101 u8 length;
102 u8 cmd0;
103 u8 cmd1;
104 u8 did;
105} __packed;
106
107struct st21nfca_dep_req_res {
108 u8 length;
109 u8 cmd0;
110 u8 cmd1;
111 u8 pfb;
112 u8 did;
113 u8 nad;
114} __packed;
115
116static void st21nfca_tx_work(struct work_struct *work)
117{
118 struct st21nfca_hci_info *info = container_of(work,
119 struct st21nfca_hci_info,
120 dep_info.tx_work);
121
122 struct nfc_dev *dev;
123 struct sk_buff *skb;
Christophe Ricard3e6df9192014-07-28 18:11:31 +0200124
Christophe Ricard1892bf82014-05-20 22:21:59 +0200125 if (info) {
126 dev = info->hdev->ndev;
127 skb = info->dep_info.tx_pending;
128
129 device_lock(&dev->dev);
130
131 nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
Christophe Ricardcc3faac2014-09-13 10:28:43 +0200132 ST21NFCA_WR_XCHG_DATA, skb->data, skb->len,
133 info->async_cb, info);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200134 device_unlock(&dev->dev);
135 kfree_skb(skb);
136 }
137}
138
139static void st21nfca_im_send_pdu(struct st21nfca_hci_info *info,
140 struct sk_buff *skb)
141{
142 info->dep_info.tx_pending = skb;
143 schedule_work(&info->dep_info.tx_work);
144}
145
146static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
147 struct st21nfca_atr_req *atr_req)
148{
149 struct st21nfca_atr_res *atr_res;
150 struct sk_buff *skb;
151 size_t gb_len;
152 int r;
153 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
154
155 gb_len = atr_req->length - sizeof(struct st21nfca_atr_req);
156 skb = alloc_skb(atr_req->length + 1, GFP_KERNEL);
157 if (!skb)
158 return -ENOMEM;
159
160 skb_put(skb, sizeof(struct st21nfca_atr_res));
161
162 atr_res = (struct st21nfca_atr_res *)skb->data;
163 memset(atr_res, 0, sizeof(struct st21nfca_atr_res));
164
165 atr_res->length = atr_req->length + 1;
166 atr_res->cmd0 = ST21NFCA_NFCIP1_RES;
167 atr_res->cmd1 = ST21NFCA_NFCIP1_ATR_RES;
168
169 memcpy(atr_res->nfcid3, atr_req->nfcid3, 6);
170 atr_res->bsi = 0x00;
171 atr_res->bri = 0x00;
172 atr_res->to = ST21NFCA_DEFAULT_TIMEOUT;
173 atr_res->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
174
175 if (gb_len) {
176 skb_put(skb, gb_len);
177
178 atr_res->ppi |= ST21NFCA_GB_BIT;
179 memcpy(atr_res->gbi, atr_req->gbi, gb_len);
180 r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi,
181 gb_len);
182 if (r < 0)
183 return r;
184 }
185
186 info->dep_info.curr_nfc_dep_pni = 0;
187
Christophe Ricardecc65222014-09-13 10:28:44 +0200188 r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
Christophe Ricard1892bf82014-05-20 22:21:59 +0200189 ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
Christophe Ricardecc65222014-09-13 10:28:44 +0200190 kfree_skb(skb);
191 return r;
Christophe Ricard1892bf82014-05-20 22:21:59 +0200192}
193
194static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
195 struct sk_buff *skb)
196{
197 struct st21nfca_atr_req *atr_req;
198 size_t gb_len;
199 int r;
200
201 skb_trim(skb, skb->len - 1);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200202
203 if (!skb->len) {
204 r = -EIO;
205 goto exit;
206 }
207
208 if (skb->len < ST21NFCA_ATR_REQ_MIN_SIZE) {
209 r = -EPROTO;
210 goto exit;
211 }
212
213 atr_req = (struct st21nfca_atr_req *)skb->data;
214
Christophe Ricard56f1ffc2014-08-11 00:04:56 +0200215 if (atr_req->length < sizeof(struct st21nfca_atr_req)) {
216 r = -EPROTO;
217 goto exit;
218 }
219
Christophe Ricard1892bf82014-05-20 22:21:59 +0200220 r = st21nfca_tm_send_atr_res(hdev, atr_req);
221 if (r)
222 goto exit;
223
224 gb_len = skb->len - sizeof(struct st21nfca_atr_req);
225
226 r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
227 NFC_COMM_PASSIVE, atr_req->gbi, gb_len);
228 if (r)
229 goto exit;
230
231 r = 0;
232
233exit:
234 return r;
235}
236
237static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
238 struct st21nfca_psl_req *psl_req)
239{
240 struct st21nfca_psl_res *psl_res;
241 struct sk_buff *skb;
242 u8 bitrate[2] = {0, 0};
Christophe Ricard1892bf82014-05-20 22:21:59 +0200243 int r;
244
245 skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
246 if (!skb)
247 return -ENOMEM;
248 skb_put(skb, sizeof(struct st21nfca_psl_res));
249
250 psl_res = (struct st21nfca_psl_res *)skb->data;
251
252 psl_res->length = sizeof(struct st21nfca_psl_res);
253 psl_res->cmd0 = ST21NFCA_NFCIP1_RES;
254 psl_res->cmd1 = ST21NFCA_NFCIP1_PSL_RES;
255 psl_res->did = psl_req->did;
256
257 r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
258 ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
Christophe Ricardecc65222014-09-13 10:28:44 +0200259 if (r < 0)
260 goto error;
Christophe Ricard1892bf82014-05-20 22:21:59 +0200261
262 /*
263 * ST21NFCA only support P2P passive.
264 * PSL_REQ BRS value != 0 has only a meaning to
265 * change technology to type F.
266 * We change to BITRATE 424Kbits.
267 * In other case switch to BITRATE 106Kbits.
268 */
269 if (ST21NFCA_PSL_REQ_SEND_SPEED(psl_req->brs) &&
270 ST21NFCA_PSL_REQ_RECV_SPEED(psl_req->brs)) {
271 bitrate[0] = ST21NFCA_CARD_BITRATE_424;
272 bitrate[1] = ST21NFCA_CARD_BITRATE_424;
273 }
274
275 /* Send an event to change bitrate change event to card f */
Christophe Ricardecc65222014-09-13 10:28:44 +0200276 r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
Christophe Ricard1892bf82014-05-20 22:21:59 +0200277 ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
Christophe Ricardecc65222014-09-13 10:28:44 +0200278error:
279 kfree_skb(skb);
280 return r;
Christophe Ricard1892bf82014-05-20 22:21:59 +0200281}
282
283static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
284 struct sk_buff *skb)
285{
286 struct st21nfca_psl_req *psl_req;
287 int r;
288
289 skb_trim(skb, skb->len - 1);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200290
291 if (!skb->len) {
292 r = -EIO;
293 goto exit;
294 }
295
296 psl_req = (struct st21nfca_psl_req *)skb->data;
297
298 if (skb->len < sizeof(struct st21nfca_psl_req)) {
299 r = -EIO;
300 goto exit;
301 }
302
303 r = st21nfca_tm_send_psl_res(hdev, psl_req);
304exit:
305 return r;
306}
307
308int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
309{
310 int r;
311 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
312
313 *skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
314 *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_RES;
315 *skb_push(skb, 1) = ST21NFCA_NFCIP1_RES;
316 *skb_push(skb, 1) = skb->len;
317
318 r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
Christophe Ricardcc3faac2014-09-13 10:28:43 +0200319 ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200320 kfree_skb(skb);
321
322 return r;
323}
324EXPORT_SYMBOL(st21nfca_tm_send_dep_res);
325
326static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
327 struct sk_buff *skb)
328{
329 struct st21nfca_dep_req_res *dep_req;
330 u8 size;
331 int r;
332 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
333
334 skb_trim(skb, skb->len - 1);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200335
336 size = 4;
337
338 dep_req = (struct st21nfca_dep_req_res *)skb->data;
339 if (skb->len < size) {
340 r = -EIO;
341 goto exit;
342 }
343
344 if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_req->pfb))
345 size++;
346 if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_req->pfb))
347 size++;
348
349 if (skb->len < size) {
350 r = -EIO;
351 goto exit;
352 }
353
354 /* Receiving DEP_REQ - Decoding */
355 switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
356 case ST21NFCA_NFC_DEP_PFB_I_PDU:
357 info->dep_info.curr_nfc_dep_pni =
358 ST21NFCA_NFC_DEP_PFB_PNI(dep_req->pfb);
359 break;
360 case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
361 pr_err("Received a ACK/NACK PDU\n");
362 break;
363 case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
364 pr_err("Received a SUPERVISOR PDU\n");
365 break;
366 }
367
Christophe Ricard1892bf82014-05-20 22:21:59 +0200368 skb_pull(skb, size);
369
370 return nfc_tm_data_received(hdev->ndev, skb);
371exit:
372 return r;
373}
374
375int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev, struct sk_buff *skb,
376 u8 gate)
377{
378 u8 cmd0, cmd1;
379 int r;
380
381 cmd0 = skb->data[1];
382 switch (cmd0) {
383 case ST21NFCA_NFCIP1_REQ:
384 cmd1 = skb->data[2];
385 switch (cmd1) {
386 case ST21NFCA_NFCIP1_ATR_REQ:
387 r = st21nfca_tm_recv_atr_req(hdev, skb);
388 break;
389 case ST21NFCA_NFCIP1_PSL_REQ:
390 r = st21nfca_tm_recv_psl_req(hdev, skb);
391 break;
392 case ST21NFCA_NFCIP1_DEP_REQ:
393 r = st21nfca_tm_recv_dep_req(hdev, skb);
394 break;
395 default:
396 return 1;
397 }
398 default:
399 return 1;
400 }
401 return r;
402}
403EXPORT_SYMBOL(st21nfca_tm_event_send_data);
404
405static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
406 u8 bri, u8 lri)
407{
408 struct sk_buff *skb;
409 struct st21nfca_psl_req *psl_req;
410 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
411
412 skb =
413 alloc_skb(sizeof(struct st21nfca_psl_req) + 1, GFP_KERNEL);
414 if (!skb)
415 return;
416 skb_reserve(skb, 1);
417
418 skb_put(skb, sizeof(struct st21nfca_psl_req));
419 psl_req = (struct st21nfca_psl_req *) skb->data;
420
421 psl_req->length = sizeof(struct st21nfca_psl_req);
422 psl_req->cmd0 = ST21NFCA_NFCIP1_REQ;
423 psl_req->cmd1 = ST21NFCA_NFCIP1_PSL_REQ;
424 psl_req->did = did;
425 psl_req->brs = (0x30 & bsi << 4) | (bri & 0x03);
426 psl_req->fsl = lri;
427
428 *skb_push(skb, 1) = info->dep_info.to | 0x10;
429
430 st21nfca_im_send_pdu(info, skb);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200431}
432
433#define ST21NFCA_CB_TYPE_READER_F 1
434static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
435 int err)
436{
437 struct st21nfca_hci_info *info = context;
438 struct st21nfca_atr_res *atr_res;
439 int r;
440
441 if (err != 0)
442 return;
443
Christophe Ricard459e7942014-09-13 10:28:52 +0200444 if (!skb)
Christophe Ricard1892bf82014-05-20 22:21:59 +0200445 return;
446
447 switch (info->async_cb_type) {
448 case ST21NFCA_CB_TYPE_READER_F:
449 skb_trim(skb, skb->len - 1);
450 atr_res = (struct st21nfca_atr_res *)skb->data;
451 r = nfc_set_remote_general_bytes(info->hdev->ndev,
452 atr_res->gbi,
453 skb->len - sizeof(struct st21nfca_atr_res));
454 if (r < 0)
455 return;
456
457 if (atr_res->to >= 0x0e)
458 info->dep_info.to = 0x0e;
459 else
460 info->dep_info.to = atr_res->to + 1;
461
462 info->dep_info.to |= 0x10;
463
464 r = nfc_dep_link_is_up(info->hdev->ndev, info->dep_info.idx,
465 NFC_COMM_PASSIVE, NFC_RF_INITIATOR);
466 if (r < 0)
467 return;
468
469 info->dep_info.curr_nfc_dep_pni = 0;
470 if (ST21NFCA_PP2LRI(atr_res->ppi) != info->dep_info.lri)
471 st21nfca_im_send_psl_req(info->hdev, atr_res->did,
472 atr_res->bsi, atr_res->bri,
473 ST21NFCA_PP2LRI(atr_res->ppi));
474 break;
475 default:
Christophe Ricard32b41d82014-08-11 00:04:53 +0200476 kfree_skb(skb);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200477 break;
478 }
479}
480
481int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
482{
483 struct sk_buff *skb;
484 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
485 struct st21nfca_atr_req *atr_req;
486 struct nfc_target *target;
487 uint size;
488
489 info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
490 size = ST21NFCA_ATR_REQ_MIN_SIZE + gb_len;
491 if (size > ST21NFCA_ATR_REQ_MAX_SIZE) {
492 PROTOCOL_ERR("14.6.1.1");
493 return -EINVAL;
494 }
495
496 skb =
497 alloc_skb(sizeof(struct st21nfca_atr_req) + gb_len + 1, GFP_KERNEL);
498 if (!skb)
499 return -ENOMEM;
500
501 skb_reserve(skb, 1);
502
503 skb_put(skb, sizeof(struct st21nfca_atr_req));
504
505 atr_req = (struct st21nfca_atr_req *)skb->data;
506 memset(atr_req, 0, sizeof(struct st21nfca_atr_req));
507
508 atr_req->cmd0 = ST21NFCA_NFCIP1_REQ;
509 atr_req->cmd1 = ST21NFCA_NFCIP1_ATR_REQ;
510 memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
511 target = hdev->ndev->targets;
512
Christophe Ricard72030a22014-08-11 00:04:52 +0200513 if (target->sensf_res_len > 0)
Christophe Ricard1892bf82014-05-20 22:21:59 +0200514 memcpy(atr_req->nfcid3, target->sensf_res,
515 target->sensf_res_len);
516 else
517 get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
518
519 atr_req->did = 0x0;
520
521 atr_req->bsi = 0x00;
522 atr_req->bri = 0x00;
523 atr_req->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
524 if (gb_len) {
525 atr_req->ppi |= ST21NFCA_GB_BIT;
526 memcpy(skb_put(skb, gb_len), gb, gb_len);
527 }
528 atr_req->length = sizeof(struct st21nfca_atr_req) + hdev->gb_len;
529
530 *skb_push(skb, 1) = info->dep_info.to | 0x10; /* timeout */
531
532 info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
533 info->async_cb_context = info;
534 info->async_cb = st21nfca_im_recv_atr_res_cb;
535 info->dep_info.bri = atr_req->bri;
536 info->dep_info.bsi = atr_req->bsi;
537 info->dep_info.lri = ST21NFCA_PP2LRI(atr_req->ppi);
538
539 return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
540 ST21NFCA_WR_XCHG_DATA, skb->data,
541 skb->len, info->async_cb, info);
542}
543EXPORT_SYMBOL(st21nfca_im_send_atr_req);
544
545static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
546 int err)
547{
548 struct st21nfca_hci_info *info = context;
549 struct st21nfca_dep_req_res *dep_res;
550
551 int size;
552
553 if (err != 0)
554 return;
555
Christophe Ricard459e7942014-09-13 10:28:52 +0200556 if (!skb)
Christophe Ricard1892bf82014-05-20 22:21:59 +0200557 return;
558
559 switch (info->async_cb_type) {
560 case ST21NFCA_CB_TYPE_READER_F:
561 dep_res = (struct st21nfca_dep_req_res *)skb->data;
562
563 size = 3;
564 if (skb->len < size)
565 goto exit;
566
567 if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_res->pfb))
568 size++;
569 if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_res->pfb))
570 size++;
571
572 if (skb->len < size)
573 goto exit;
574
575 skb_trim(skb, skb->len - 1);
576
577 /* Receiving DEP_REQ - Decoding */
578 switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_res->pfb)) {
579 case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
580 pr_err("Received a ACK/NACK PDU\n");
581 case ST21NFCA_NFC_DEP_PFB_I_PDU:
582 info->dep_info.curr_nfc_dep_pni =
583 ST21NFCA_NFC_DEP_PFB_PNI(dep_res->pfb + 1);
584 size++;
585 skb_pull(skb, size);
586 nfc_tm_data_received(info->hdev->ndev, skb);
587 break;
588 case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
589 pr_err("Received a SUPERVISOR PDU\n");
590 skb_pull(skb, size);
591 *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
592 *skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
593 *skb_push(skb, 1) = skb->len;
594 *skb_push(skb, 1) = info->dep_info.to | 0x10;
595
596 st21nfca_im_send_pdu(info, skb);
597 break;
598 }
599
600 return;
601 default:
602 break;
603 }
604
605exit:
Christophe Ricard32b41d82014-08-11 00:04:53 +0200606 kfree_skb(skb);
Christophe Ricard1892bf82014-05-20 22:21:59 +0200607}
608
609int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)
610{
611 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
612
613 info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
614 info->async_cb_context = info;
615 info->async_cb = st21nfca_im_recv_dep_res_cb;
616
617 *skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
618 *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
619 *skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
620 *skb_push(skb, 1) = skb->len;
621
622 *skb_push(skb, 1) = info->dep_info.to | 0x10;
623
624 return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
625 ST21NFCA_WR_XCHG_DATA,
626 skb->data, skb->len,
627 info->async_cb, info);
628}
629EXPORT_SYMBOL(st21nfca_im_send_dep_req);
630
631void st21nfca_dep_init(struct nfc_hci_dev *hdev)
632{
633 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
634
635 INIT_WORK(&info->dep_info.tx_work, st21nfca_tx_work);
636 info->dep_info.curr_nfc_dep_pni = 0;
637 info->dep_info.idx = 0;
638 info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
639}
640EXPORT_SYMBOL(st21nfca_dep_init);
641
642void st21nfca_dep_deinit(struct nfc_hci_dev *hdev)
643{
644 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
645
646 cancel_work_sync(&info->dep_info.tx_work);
647}
648EXPORT_SYMBOL(st21nfca_dep_deinit);