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 <ilane@ti.com> 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, see <http://www.gnu.org/licenses/>. 26 * 27 */ 28#include <linux/platform_device.h> 29#include <linux/module.h> 30#include <linux/types.h> 31#include <linux/firmware.h> 32#include <linux/nfc.h> 33#include <net/nfc/nci.h> 34#include <net/nfc/nci_core.h> 35#include <linux/ti_wilink_st.h> 36 37#define NFCWILINK_CHNL 12 38#define NFCWILINK_OPCODE 7 39#define NFCWILINK_MAX_FRAME_SIZE 300 40#define NFCWILINK_HDR_LEN 4 41#define NFCWILINK_OFFSET_LEN_IN_HDR 1 42#define NFCWILINK_LEN_SIZE 2 43#define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ 44#define NFCWILINK_CMD_TIMEOUT 5000 /* 5 sec */ 45 46#define BTS_FILE_NAME_MAX_SIZE 40 47#define BTS_FILE_HDR_MAGIC 0x42535442 48#define BTS_FILE_CMD_MAX_LEN 0xff 49#define BTS_FILE_ACTION_TYPE_SEND_CMD 1 50 51#define NCI_VS_NFCC_INFO_CMD_GID 0x2f 52#define NCI_VS_NFCC_INFO_CMD_OID 0x12 53#define NCI_VS_NFCC_INFO_RSP_GID 0x4f 54#define NCI_VS_NFCC_INFO_RSP_OID 0x12 55 56struct nfcwilink_hdr { 57 __u8 chnl; 58 __u8 opcode; 59 __le16 len; 60} __packed; 61 62struct nci_vs_nfcc_info_cmd { 63 __u8 gid; 64 __u8 oid; 65 __u8 plen; 66} __packed; 67 68struct nci_vs_nfcc_info_rsp { 69 __u8 gid; 70 __u8 oid; 71 __u8 plen; 72 __u8 status; 73 __u8 hw_id; 74 __u8 sw_ver_x; 75 __u8 sw_ver_z; 76 __u8 patch_id; 77} __packed; 78 79struct bts_file_hdr { 80 __le32 magic; 81 __le32 ver; 82 __u8 rfu[24]; 83 __u8 actions[0]; 84} __packed; 85 86struct bts_file_action { 87 __le16 type; 88 __le16 len; 89 __u8 data[0]; 90} __packed; 91 92struct nfcwilink { 93 struct platform_device *pdev; 94 struct nci_dev *ndev; 95 unsigned long flags; 96 97 char st_register_cb_status; 98 long (*st_write) (struct sk_buff *); 99 100 struct completion completed; 101 102 struct nci_vs_nfcc_info_rsp nfcc_info; 103}; 104 105/* NFCWILINK driver flags */ 106enum { 107 NFCWILINK_RUNNING, 108 NFCWILINK_FW_DOWNLOAD, 109}; 110 111static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb); 112 113static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how) 114{ 115 struct sk_buff *skb; 116 117 skb = alloc_skb(len + NFCWILINK_HDR_LEN, how); 118 if (skb) 119 skb_reserve(skb, NFCWILINK_HDR_LEN); 120 121 return skb; 122} 123 124static void nfcwilink_fw_download_receive(struct nfcwilink *drv, 125 struct sk_buff *skb) 126{ 127 struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data; 128 129 /* Detect NCI_VS_NFCC_INFO_RSP and store the result */ 130 if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) && 131 (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) { 132 memcpy(&drv->nfcc_info, rsp, 133 sizeof(struct nci_vs_nfcc_info_rsp)); 134 } 135 136 kfree_skb(skb); 137 138 complete(&drv->completed); 139} 140 141static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) 142{ 143 struct nci_vs_nfcc_info_cmd *cmd; 144 struct sk_buff *skb; 145 unsigned long comp_ret; 146 int rc; 147 148 skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), 149 GFP_KERNEL); 150 if (!skb) { 151 nfc_err(&drv->pdev->dev, 152 "no memory for nci_vs_nfcc_info_cmd\n"); 153 return -ENOMEM; 154 } 155 156 cmd = (struct nci_vs_nfcc_info_cmd *) 157 skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd)); 158 cmd->gid = NCI_VS_NFCC_INFO_CMD_GID; 159 cmd->oid = NCI_VS_NFCC_INFO_CMD_OID; 160 cmd->plen = 0; 161 162 drv->nfcc_info.plen = 0; 163 164 rc = nfcwilink_send(drv->ndev, skb); 165 if (rc) 166 return rc; 167 168 comp_ret = wait_for_completion_timeout(&drv->completed, 169 msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); 170 dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n", 171 comp_ret); 172 if (comp_ret == 0) { 173 nfc_err(&drv->pdev->dev, 174 "timeout on wait_for_completion_timeout\n"); 175 return -ETIMEDOUT; 176 } 177 178 dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d\n", 179 drv->nfcc_info.plen, drv->nfcc_info.status); 180 181 if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { 182 nfc_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp\n"); 183 return -EINVAL; 184 } 185 186 snprintf(file_name, BTS_FILE_NAME_MAX_SIZE, 187 "TINfcInit_%d.%d.%d.%d.bts", 188 drv->nfcc_info.hw_id, 189 drv->nfcc_info.sw_ver_x, 190 drv->nfcc_info.sw_ver_z, 191 drv->nfcc_info.patch_id); 192 193 nfc_info(&drv->pdev->dev, "nfcwilink FW file name: %s\n", file_name); 194 195 return 0; 196} 197 198static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) 199{ 200 struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data; 201 struct sk_buff *skb; 202 unsigned long comp_ret; 203 int rc; 204 205 /* verify valid cmd for the NFC channel */ 206 if ((len <= sizeof(struct nfcwilink_hdr)) || 207 (len > BTS_FILE_CMD_MAX_LEN) || 208 (hdr->chnl != NFCWILINK_CHNL) || 209 (hdr->opcode != NFCWILINK_OPCODE)) { 210 nfc_err(&drv->pdev->dev, 211 "ignoring invalid bts cmd, len %d, chnl %d, opcode %d\n", 212 len, hdr->chnl, hdr->opcode); 213 return 0; 214 } 215 216 /* remove the ST header */ 217 len -= sizeof(struct nfcwilink_hdr); 218 data += sizeof(struct nfcwilink_hdr); 219 220 skb = nfcwilink_skb_alloc(len, GFP_KERNEL); 221 if (!skb) { 222 nfc_err(&drv->pdev->dev, "no memory for bts cmd\n"); 223 return -ENOMEM; 224 } 225 226 memcpy(skb_put(skb, len), data, len); 227 228 rc = nfcwilink_send(drv->ndev, skb); 229 if (rc) 230 return rc; 231 232 comp_ret = wait_for_completion_timeout(&drv->completed, 233 msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); 234 dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n", 235 comp_ret); 236 if (comp_ret == 0) { 237 nfc_err(&drv->pdev->dev, 238 "timeout on wait_for_completion_timeout\n"); 239 return -ETIMEDOUT; 240 } 241 242 return 0; 243} 244 245static int nfcwilink_download_fw(struct nfcwilink *drv) 246{ 247 unsigned char file_name[BTS_FILE_NAME_MAX_SIZE]; 248 const struct firmware *fw; 249 __u16 action_type, action_len; 250 __u8 *ptr; 251 int len, rc; 252 253 set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); 254 255 rc = nfcwilink_get_bts_file_name(drv, file_name); 256 if (rc) 257 goto exit; 258 259 rc = request_firmware(&fw, file_name, &drv->pdev->dev); 260 if (rc) { 261 nfc_err(&drv->pdev->dev, "request_firmware failed %d\n", rc); 262 263 /* if the file is not found, don't exit with failure */ 264 if (rc == -ENOENT) 265 rc = 0; 266 267 goto exit; 268 } 269 270 len = fw->size; 271 ptr = (__u8 *)fw->data; 272 273 if ((len == 0) || (ptr == NULL)) { 274 dev_dbg(&drv->pdev->dev, 275 "request_firmware returned size %d\n", len); 276 goto release_fw; 277 } 278 279 if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) != 280 BTS_FILE_HDR_MAGIC) { 281 nfc_err(&drv->pdev->dev, "wrong bts magic number\n"); 282 rc = -EINVAL; 283 goto release_fw; 284 } 285 286 /* remove the BTS header */ 287 len -= sizeof(struct bts_file_hdr); 288 ptr += sizeof(struct bts_file_hdr); 289 290 while (len > 0) { 291 action_type = 292 __le16_to_cpu(((struct bts_file_action *)ptr)->type); 293 action_len = 294 __le16_to_cpu(((struct bts_file_action *)ptr)->len); 295 296 dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d\n", 297 action_type, action_len); 298 299 switch (action_type) { 300 case BTS_FILE_ACTION_TYPE_SEND_CMD: 301 rc = nfcwilink_send_bts_cmd(drv, 302 ((struct bts_file_action *)ptr)->data, 303 action_len); 304 if (rc) 305 goto release_fw; 306 break; 307 } 308 309 /* advance to the next action */ 310 len -= (sizeof(struct bts_file_action) + action_len); 311 ptr += (sizeof(struct bts_file_action) + action_len); 312 } 313 314release_fw: 315 release_firmware(fw); 316 317exit: 318 clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); 319 return rc; 320} 321 322/* Called by ST when registration is complete */ 323static void nfcwilink_register_complete(void *priv_data, char data) 324{ 325 struct nfcwilink *drv = priv_data; 326 327 /* store ST registration status */ 328 drv->st_register_cb_status = data; 329 330 /* complete the wait in nfc_st_open() */ 331 complete(&drv->completed); 332} 333 334/* Called by ST when receive data is available */ 335static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) 336{ 337 struct nfcwilink *drv = priv_data; 338 int rc; 339 340 if (!skb) 341 return -EFAULT; 342 343 if (!drv) { 344 kfree_skb(skb); 345 return -EFAULT; 346 } 347 348 dev_dbg(&drv->pdev->dev, "receive entry, len %d\n", skb->len); 349 350 /* strip the ST header 351 (apart for the chnl byte, which is not received in the hdr) */ 352 skb_pull(skb, (NFCWILINK_HDR_LEN-1)); 353 354 if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) { 355 nfcwilink_fw_download_receive(drv, skb); 356 return 0; 357 } 358 359 /* Forward skb to NCI core layer */ 360 rc = nci_recv_frame(drv->ndev, skb); 361 if (rc < 0) { 362 nfc_err(&drv->pdev->dev, "nci_recv_frame failed %d\n", rc); 363 return rc; 364 } 365 366 return 0; 367} 368 369/* protocol structure registered with ST */ 370static struct st_proto_s nfcwilink_proto = { 371 .chnl_id = NFCWILINK_CHNL, 372 .max_frame_size = NFCWILINK_MAX_FRAME_SIZE, 373 .hdr_len = (NFCWILINK_HDR_LEN-1), /* not including chnl byte */ 374 .offset_len_in_hdr = NFCWILINK_OFFSET_LEN_IN_HDR, 375 .len_size = NFCWILINK_LEN_SIZE, 376 .reserve = 0, 377 .recv = nfcwilink_receive, 378 .reg_complete_cb = nfcwilink_register_complete, 379 .write = NULL, 380}; 381 382static int nfcwilink_open(struct nci_dev *ndev) 383{ 384 struct nfcwilink *drv = nci_get_drvdata(ndev); 385 unsigned long comp_ret; 386 int rc; 387 388 if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) { 389 rc = -EBUSY; 390 goto exit; 391 } 392 393 nfcwilink_proto.priv_data = drv; 394 395 init_completion(&drv->completed); 396 drv->st_register_cb_status = -EINPROGRESS; 397 398 rc = st_register(&nfcwilink_proto); 399 if (rc < 0) { 400 if (rc == -EINPROGRESS) { 401 comp_ret = wait_for_completion_timeout( 402 &drv->completed, 403 msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); 404 405 dev_dbg(&drv->pdev->dev, 406 "wait_for_completion_timeout returned %ld\n", 407 comp_ret); 408 409 if (comp_ret == 0) { 410 /* timeout */ 411 rc = -ETIMEDOUT; 412 goto clear_exit; 413 } else if (drv->st_register_cb_status != 0) { 414 rc = drv->st_register_cb_status; 415 nfc_err(&drv->pdev->dev, 416 "st_register_cb failed %d\n", rc); 417 goto clear_exit; 418 } 419 } else { 420 nfc_err(&drv->pdev->dev, "st_register failed %d\n", rc); 421 goto clear_exit; 422 } 423 } 424 425 /* st_register MUST fill the write callback */ 426 BUG_ON(nfcwilink_proto.write == NULL); 427 drv->st_write = nfcwilink_proto.write; 428 429 if (nfcwilink_download_fw(drv)) { 430 nfc_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d\n", 431 rc); 432 /* open should succeed, even if the FW download failed */ 433 } 434 435 goto exit; 436 437clear_exit: 438 clear_bit(NFCWILINK_RUNNING, &drv->flags); 439 440exit: 441 return rc; 442} 443 444static int nfcwilink_close(struct nci_dev *ndev) 445{ 446 struct nfcwilink *drv = nci_get_drvdata(ndev); 447 int rc; 448 449 if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags)) 450 return 0; 451 452 rc = st_unregister(&nfcwilink_proto); 453 if (rc) 454 nfc_err(&drv->pdev->dev, "st_unregister failed %d\n", rc); 455 456 drv->st_write = NULL; 457 458 return rc; 459} 460 461static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb) 462{ 463 struct nfcwilink *drv = nci_get_drvdata(ndev); 464 struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000}; 465 long len; 466 467 dev_dbg(&drv->pdev->dev, "send entry, len %d\n", skb->len); 468 469 if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { 470 kfree_skb(skb); 471 return -EINVAL; 472 } 473 474 /* add the ST hdr to the start of the buffer */ 475 hdr.len = cpu_to_le16(skb->len); 476 memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); 477 478 /* Insert skb to shared transport layer's transmit queue. 479 * Freeing skb memory is taken care in shared transport layer, 480 * so don't free skb memory here. 481 */ 482 len = drv->st_write(skb); 483 if (len < 0) { 484 kfree_skb(skb); 485 nfc_err(&drv->pdev->dev, "st_write failed %ld\n", len); 486 return -EFAULT; 487 } 488 489 return 0; 490} 491 492static struct nci_ops nfcwilink_ops = { 493 .open = nfcwilink_open, 494 .close = nfcwilink_close, 495 .send = nfcwilink_send, 496}; 497 498static int nfcwilink_probe(struct platform_device *pdev) 499{ 500 static struct nfcwilink *drv; 501 int rc; 502 __u32 protocols; 503 504 drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL); 505 if (!drv) { 506 rc = -ENOMEM; 507 goto exit; 508 } 509 510 drv->pdev = pdev; 511 512 protocols = NFC_PROTO_JEWEL_MASK 513 | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK 514 | NFC_PROTO_ISO14443_MASK 515 | NFC_PROTO_ISO14443_B_MASK 516 | NFC_PROTO_NFC_DEP_MASK; 517 518 drv->ndev = nci_allocate_device(&nfcwilink_ops, 519 protocols, 520 NFCWILINK_HDR_LEN, 521 0); 522 if (!drv->ndev) { 523 nfc_err(&pdev->dev, "nci_allocate_device failed\n"); 524 rc = -ENOMEM; 525 goto exit; 526 } 527 528 nci_set_parent_dev(drv->ndev, &pdev->dev); 529 nci_set_drvdata(drv->ndev, drv); 530 531 rc = nci_register_device(drv->ndev); 532 if (rc < 0) { 533 nfc_err(&pdev->dev, "nci_register_device failed %d\n", rc); 534 goto free_dev_exit; 535 } 536 537 dev_set_drvdata(&pdev->dev, drv); 538 539 goto exit; 540 541free_dev_exit: 542 nci_free_device(drv->ndev); 543 544exit: 545 return rc; 546} 547 548static int nfcwilink_remove(struct platform_device *pdev) 549{ 550 struct nfcwilink *drv = dev_get_drvdata(&pdev->dev); 551 struct nci_dev *ndev; 552 553 if (!drv) 554 return -EFAULT; 555 556 ndev = drv->ndev; 557 558 nci_unregister_device(ndev); 559 nci_free_device(ndev); 560 561 return 0; 562} 563 564static struct platform_driver nfcwilink_driver = { 565 .probe = nfcwilink_probe, 566 .remove = nfcwilink_remove, 567 .driver = { 568 .name = "nfcwilink", 569 }, 570}; 571 572module_platform_driver(nfcwilink_driver); 573 574/* ------ Module Info ------ */ 575 576MODULE_AUTHOR("Ilan Elias <ilane@ti.com>"); 577MODULE_DESCRIPTION("NFC Driver for TI Shared Transport"); 578MODULE_LICENSE("GPL"); 579