Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nfcwilink.c
Go to the documentation of this file.
1 /*
2  * Texas Instrument's NFC Driver For Shared Transport.
3  *
4  * NFC Driver acts as interface between NCI core and
5  * TI Shared Transport Layer.
6  *
7  * Copyright (C) 2011 Texas Instruments, Inc.
8  *
9  * Written by Ilan Elias <[email protected]>
10  *
11  * Acknowledgements:
12  * This file is based on btwilink.c, which was written
13  * by Raja Mani and Pavan Savoy.
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License version 2 as
17  * published by the Free Software Foundation.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27  *
28  */
29 #include <linux/platform_device.h>
30 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/firmware.h>
33 #include <linux/nfc.h>
34 #include <net/nfc/nci.h>
35 #include <net/nfc/nci_core.h>
36 #include <linux/ti_wilink_st.h>
37 
38 #define NFCWILINK_CHNL 12
39 #define NFCWILINK_OPCODE 7
40 #define NFCWILINK_MAX_FRAME_SIZE 300
41 #define NFCWILINK_HDR_LEN 4
42 #define NFCWILINK_OFFSET_LEN_IN_HDR 1
43 #define NFCWILINK_LEN_SIZE 2
44 #define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */
45 #define NFCWILINK_CMD_TIMEOUT 5000 /* 5 sec */
46 
47 #define BTS_FILE_NAME_MAX_SIZE 40
48 #define BTS_FILE_HDR_MAGIC 0x42535442
49 #define BTS_FILE_CMD_MAX_LEN 0xff
50 #define BTS_FILE_ACTION_TYPE_SEND_CMD 1
51 
52 #define NCI_VS_NFCC_INFO_CMD_GID 0x2f
53 #define NCI_VS_NFCC_INFO_CMD_OID 0x12
54 #define NCI_VS_NFCC_INFO_RSP_GID 0x4f
55 #define NCI_VS_NFCC_INFO_RSP_OID 0x12
56 
57 struct nfcwilink_hdr {
61 } __packed;
62 
67 } __packed;
68 
78 } __packed;
79 
80 struct bts_file_hdr {
83  __u8 rfu[24];
85 } __packed;
86 
90  __u8 data[0];
91 } __packed;
92 
93 struct nfcwilink {
95  struct nci_dev *ndev;
96  unsigned long flags;
97 
99  long (*st_write) (struct sk_buff *);
100 
102 
104 };
105 
106 /* NFCWILINK driver flags */
107 enum {
110 };
111 
112 static int nfcwilink_send(struct sk_buff *skb);
113 
114 static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how)
115 {
116  struct sk_buff *skb;
117 
118  skb = alloc_skb(len + NFCWILINK_HDR_LEN, how);
119  if (skb)
120  skb_reserve(skb, NFCWILINK_HDR_LEN);
121 
122  return skb;
123 }
124 
125 static void nfcwilink_fw_download_receive(struct nfcwilink *drv,
126  struct sk_buff *skb)
127 {
128  struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data;
129 
130  /* Detect NCI_VS_NFCC_INFO_RSP and store the result */
131  if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) &&
132  (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) {
133  memcpy(&drv->nfcc_info, rsp,
134  sizeof(struct nci_vs_nfcc_info_rsp));
135  }
136 
137  kfree_skb(skb);
138 
139  complete(&drv->completed);
140 }
141 
142 static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
143 {
144  struct nci_vs_nfcc_info_cmd *cmd;
145  struct sk_buff *skb;
146  unsigned long comp_ret;
147  int rc;
148 
149  nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry");
150 
151  skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd),
152  GFP_KERNEL);
153  if (!skb) {
154  nfc_dev_err(&drv->pdev->dev,
155  "no memory for nci_vs_nfcc_info_cmd");
156  return -ENOMEM;
157  }
158 
159  skb->dev = (void *)drv->ndev;
160 
161  cmd = (struct nci_vs_nfcc_info_cmd *)
162  skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd));
165  cmd->plen = 0;
166 
167  drv->nfcc_info.plen = 0;
168 
169  rc = nfcwilink_send(skb);
170  if (rc)
171  return rc;
172 
173  comp_ret = wait_for_completion_timeout(&drv->completed,
175  nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld",
176  comp_ret);
177  if (comp_ret == 0) {
178  nfc_dev_err(&drv->pdev->dev,
179  "timeout on wait_for_completion_timeout");
180  return -ETIMEDOUT;
181  }
182 
183  nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d",
184  drv->nfcc_info.plen,
185  drv->nfcc_info.status);
186 
187  if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) {
188  nfc_dev_err(&drv->pdev->dev,
189  "invalid nci_vs_nfcc_info_rsp");
190  return -EINVAL;
191  }
192 
193  snprintf(file_name, BTS_FILE_NAME_MAX_SIZE,
194  "TINfcInit_%d.%d.%d.%d.bts",
195  drv->nfcc_info.hw_id,
196  drv->nfcc_info.sw_ver_x,
197  drv->nfcc_info.sw_ver_z,
198  drv->nfcc_info.patch_id);
199 
200  nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name);
201 
202  return 0;
203 }
204 
205 static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
206 {
207  struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data;
208  struct sk_buff *skb;
209  unsigned long comp_ret;
210  int rc;
211 
212  nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry");
213 
214  /* verify valid cmd for the NFC channel */
215  if ((len <= sizeof(struct nfcwilink_hdr)) ||
216  (len > BTS_FILE_CMD_MAX_LEN) ||
217  (hdr->chnl != NFCWILINK_CHNL) ||
218  (hdr->opcode != NFCWILINK_OPCODE)) {
219  nfc_dev_err(&drv->pdev->dev,
220  "ignoring invalid bts cmd, len %d, chnl %d, opcode %d",
221  len, hdr->chnl, hdr->opcode);
222  return 0;
223  }
224 
225  /* remove the ST header */
226  len -= sizeof(struct nfcwilink_hdr);
227  data += sizeof(struct nfcwilink_hdr);
228 
229  skb = nfcwilink_skb_alloc(len, GFP_KERNEL);
230  if (!skb) {
231  nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd");
232  return -ENOMEM;
233  }
234 
235  skb->dev = (void *)drv->ndev;
236 
237  memcpy(skb_put(skb, len), data, len);
238 
239  rc = nfcwilink_send(skb);
240  if (rc)
241  return rc;
242 
243  comp_ret = wait_for_completion_timeout(&drv->completed,
245  nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld",
246  comp_ret);
247  if (comp_ret == 0) {
248  nfc_dev_err(&drv->pdev->dev,
249  "timeout on wait_for_completion_timeout");
250  return -ETIMEDOUT;
251  }
252 
253  return 0;
254 }
255 
256 static int nfcwilink_download_fw(struct nfcwilink *drv)
257 {
258  unsigned char file_name[BTS_FILE_NAME_MAX_SIZE];
259  const struct firmware *fw;
260  __u16 action_type, action_len;
261  __u8 *ptr;
262  int len, rc;
263 
264  nfc_dev_dbg(&drv->pdev->dev, "download_fw entry");
265 
267 
268  rc = nfcwilink_get_bts_file_name(drv, file_name);
269  if (rc)
270  goto exit;
271 
272  rc = request_firmware(&fw, file_name, &drv->pdev->dev);
273  if (rc) {
274  nfc_dev_err(&drv->pdev->dev, "request_firmware failed %d", rc);
275 
276  /* if the file is not found, don't exit with failure */
277  if (rc == -ENOENT)
278  rc = 0;
279 
280  goto exit;
281  }
282 
283  len = fw->size;
284  ptr = (__u8 *)fw->data;
285 
286  if ((len == 0) || (ptr == NULL)) {
287  nfc_dev_dbg(&drv->pdev->dev,
288  "request_firmware returned size %d", len);
289  goto release_fw;
290  }
291 
292  if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) !=
294  nfc_dev_err(&drv->pdev->dev, "wrong bts magic number");
295  rc = -EINVAL;
296  goto release_fw;
297  }
298 
299  /* remove the BTS header */
300  len -= sizeof(struct bts_file_hdr);
301  ptr += sizeof(struct bts_file_hdr);
302 
303  while (len > 0) {
304  action_type =
305  __le16_to_cpu(((struct bts_file_action *)ptr)->type);
306  action_len =
307  __le16_to_cpu(((struct bts_file_action *)ptr)->len);
308 
309  nfc_dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d",
310  action_type, action_len);
311 
312  switch (action_type) {
314  rc = nfcwilink_send_bts_cmd(drv,
315  ((struct bts_file_action *)ptr)->data,
316  action_len);
317  if (rc)
318  goto release_fw;
319  break;
320  }
321 
322  /* advance to the next action */
323  len -= (sizeof(struct bts_file_action) + action_len);
324  ptr += (sizeof(struct bts_file_action) + action_len);
325  }
326 
327 release_fw:
328  release_firmware(fw);
329 
330 exit:
332  return rc;
333 }
334 
335 /* Called by ST when registration is complete */
336 static void nfcwilink_register_complete(void *priv_data, char data)
337 {
338  struct nfcwilink *drv = priv_data;
339 
340  nfc_dev_dbg(&drv->pdev->dev, "register_complete entry");
341 
342  /* store ST registration status */
344 
345  /* complete the wait in nfc_st_open() */
346  complete(&drv->completed);
347 }
348 
349 /* Called by ST when receive data is available */
350 static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
351 {
352  struct nfcwilink *drv = priv_data;
353  int rc;
354 
355  if (!skb)
356  return -EFAULT;
357 
358  if (!drv) {
359  kfree_skb(skb);
360  return -EFAULT;
361  }
362 
363  nfc_dev_dbg(&drv->pdev->dev, "receive entry, len %d", skb->len);
364 
365  /* strip the ST header
366  (apart for the chnl byte, which is not received in the hdr) */
367  skb_pull(skb, (NFCWILINK_HDR_LEN-1));
368 
369  if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) {
370  nfcwilink_fw_download_receive(drv, skb);
371  return 0;
372  }
373 
374  skb->dev = (void *) drv->ndev;
375 
376  /* Forward skb to NCI core layer */
377  rc = nci_recv_frame(skb);
378  if (rc < 0) {
379  nfc_dev_err(&drv->pdev->dev, "nci_recv_frame failed %d", rc);
380  return rc;
381  }
382 
383  return 0;
384 }
385 
386 /* protocol structure registered with ST */
387 static struct st_proto_s nfcwilink_proto = {
388  .chnl_id = NFCWILINK_CHNL,
389  .max_frame_size = NFCWILINK_MAX_FRAME_SIZE,
390  .hdr_len = (NFCWILINK_HDR_LEN-1), /* not including chnl byte */
393  .reserve = 0,
394  .recv = nfcwilink_receive,
395  .reg_complete_cb = nfcwilink_register_complete,
396  .write = NULL,
397 };
398 
399 static int nfcwilink_open(struct nci_dev *ndev)
400 {
401  struct nfcwilink *drv = nci_get_drvdata(ndev);
402  unsigned long comp_ret;
403  int rc;
404 
405  nfc_dev_dbg(&drv->pdev->dev, "open entry");
406 
408  rc = -EBUSY;
409  goto exit;
410  }
411 
412  nfcwilink_proto.priv_data = drv;
413 
414  init_completion(&drv->completed);
416 
417  rc = st_register(&nfcwilink_proto);
418  if (rc < 0) {
419  if (rc == -EINPROGRESS) {
420  comp_ret = wait_for_completion_timeout(
421  &drv->completed,
423 
424  nfc_dev_dbg(&drv->pdev->dev,
425  "wait_for_completion_timeout returned %ld",
426  comp_ret);
427 
428  if (comp_ret == 0) {
429  /* timeout */
430  rc = -ETIMEDOUT;
431  goto clear_exit;
432  } else if (drv->st_register_cb_status != 0) {
433  rc = drv->st_register_cb_status;
434  nfc_dev_err(&drv->pdev->dev,
435  "st_register_cb failed %d", rc);
436  goto clear_exit;
437  }
438  } else {
439  nfc_dev_err(&drv->pdev->dev,
440  "st_register failed %d", rc);
441  goto clear_exit;
442  }
443  }
444 
445  /* st_register MUST fill the write callback */
446  BUG_ON(nfcwilink_proto.write == NULL);
447  drv->st_write = nfcwilink_proto.write;
448 
449  if (nfcwilink_download_fw(drv)) {
450  nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d",
451  rc);
452  /* open should succeed, even if the FW download failed */
453  }
454 
455  goto exit;
456 
457 clear_exit:
459 
460 exit:
461  return rc;
462 }
463 
464 static int nfcwilink_close(struct nci_dev *ndev)
465 {
466  struct nfcwilink *drv = nci_get_drvdata(ndev);
467  int rc;
468 
469  nfc_dev_dbg(&drv->pdev->dev, "close entry");
470 
472  return 0;
473 
474  rc = st_unregister(&nfcwilink_proto);
475  if (rc)
476  nfc_dev_err(&drv->pdev->dev, "st_unregister failed %d", rc);
477 
478  drv->st_write = NULL;
479 
480  return rc;
481 }
482 
483 static int nfcwilink_send(struct sk_buff *skb)
484 {
485  struct nci_dev *ndev = (struct nci_dev *)skb->dev;
486  struct nfcwilink *drv = nci_get_drvdata(ndev);
487  struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000};
488  long len;
489 
490  nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len);
491 
492  if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) {
493  kfree_skb(skb);
494  return -EINVAL;
495  }
496 
497  /* add the ST hdr to the start of the buffer */
498  hdr.len = cpu_to_le16(skb->len);
500 
501  /* Insert skb to shared transport layer's transmit queue.
502  * Freeing skb memory is taken care in shared transport layer,
503  * so don't free skb memory here.
504  */
505  len = drv->st_write(skb);
506  if (len < 0) {
507  kfree_skb(skb);
508  nfc_dev_err(&drv->pdev->dev, "st_write failed %ld", len);
509  return -EFAULT;
510  }
511 
512  return 0;
513 }
514 
515 static struct nci_ops nfcwilink_ops = {
516  .open = nfcwilink_open,
517  .close = nfcwilink_close,
518  .send = nfcwilink_send,
519 };
520 
521 static int nfcwilink_probe(struct platform_device *pdev)
522 {
523  static struct nfcwilink *drv;
524  int rc;
525  __u32 protocols;
526 
527  nfc_dev_dbg(&pdev->dev, "probe entry");
528 
529  drv = kzalloc(sizeof(struct nfcwilink), GFP_KERNEL);
530  if (!drv) {
531  rc = -ENOMEM;
532  goto exit;
533  }
534 
535  drv->pdev = pdev;
536 
537  protocols = NFC_PROTO_JEWEL_MASK
542 
543  drv->ndev = nci_allocate_device(&nfcwilink_ops,
544  protocols,
546  0);
547  if (!drv->ndev) {
548  nfc_dev_err(&pdev->dev, "nci_allocate_device failed");
549  rc = -ENOMEM;
550  goto free_exit;
551  }
552 
553  nci_set_parent_dev(drv->ndev, &pdev->dev);
554  nci_set_drvdata(drv->ndev, drv);
555 
556  rc = nci_register_device(drv->ndev);
557  if (rc < 0) {
558  nfc_dev_err(&pdev->dev, "nci_register_device failed %d", rc);
559  goto free_dev_exit;
560  }
561 
562  dev_set_drvdata(&pdev->dev, drv);
563 
564  goto exit;
565 
566 free_dev_exit:
567  nci_free_device(drv->ndev);
568 
569 free_exit:
570  kfree(drv);
571 
572 exit:
573  return rc;
574 }
575 
576 static int nfcwilink_remove(struct platform_device *pdev)
577 {
578  struct nfcwilink *drv = dev_get_drvdata(&pdev->dev);
579  struct nci_dev *ndev;
580 
581  nfc_dev_dbg(&pdev->dev, "remove entry");
582 
583  if (!drv)
584  return -EFAULT;
585 
586  ndev = drv->ndev;
587 
588  nci_unregister_device(ndev);
589  nci_free_device(ndev);
590 
591  kfree(drv);
592 
593  dev_set_drvdata(&pdev->dev, NULL);
594 
595  return 0;
596 }
597 
598 static struct platform_driver nfcwilink_driver = {
599  .probe = nfcwilink_probe,
600  .remove = nfcwilink_remove,
601  .driver = {
602  .name = "nfcwilink",
603  .owner = THIS_MODULE,
604  },
605 };
606 
607 module_platform_driver(nfcwilink_driver);
608 
609 /* ------ Module Info ------ */
610 
611 MODULE_AUTHOR("Ilan Elias <[email protected]>");
612 MODULE_DESCRIPTION("NFC Driver for TI Shared Transport");
613 MODULE_LICENSE("GPL");