Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfc: st-nci: Move loopback usage from HCI to NCI

NCI provides possible way to run loopback testing has done over HCI.

For us it offers many advantages:
- It simplifies the code: No more need for a vendor_cmds structure
- Loopback over HCI may not be supported in future st-nci firmware

Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Christophe Ricard and committed by
Samuel Ortiz
3aacd7fe 1c53855f

+14 -66
-5
drivers/nfc/st-nci/se.c
··· 113 113 114 114 {NCI_HCI_IDENTITY_MGMT_GATE, NCI_HCI_INVALID_PIPE, 115 115 ST_NCI_HOST_CONTROLLER_ID}, 116 - {NCI_HCI_LOOPBACK_GATE, NCI_HCI_INVALID_PIPE, 117 - ST_NCI_HOST_CONTROLLER_ID}, 118 116 119 117 /* Secure element pipes are created by secure element host */ 120 118 {ST_NCI_CONNECTIVITY_GATE, NCI_HCI_DO_NOT_OPEN_PIPE, ··· 382 384 break; 383 385 case ST_NCI_CONNECTIVITY_GATE: 384 386 st_nci_hci_connectivity_event_received(ndev, host, event, skb); 385 - break; 386 - case NCI_HCI_LOOPBACK_GATE: 387 - st_nci_hci_loopback_event_received(ndev, event, skb); 388 387 break; 389 388 } 390 389 }
+2 -11
drivers/nfc/st-nci/st-nci.h
··· 92 92 * white list). 93 93 * @HCI_DM_FIELD_GENERATOR: Allow to generate different kind of RF 94 94 * technology. When using this command to anti-collision is done. 95 - * @HCI_LOOPBACK: Allow to echo a command and test the Dh to CLF 96 - * connectivity. 95 + * @LOOPBACK: Allow to echo a command and test the Dh to CLF connectivity. 97 96 * @HCI_DM_VDC_MEASUREMENT_VALUE: Allow to measure the field applied on the 98 97 * CLF antenna. A value between 0 and 0x0f is returned. 0 is maximum. 99 98 * @HCI_DM_FWUPD_START: Allow to put CLF into firmware update mode. It is a ··· 114 115 HCI_DM_RESET, 115 116 HCI_GET_PARAM, 116 117 HCI_DM_FIELD_GENERATOR, 117 - HCI_LOOPBACK, 118 + LOOPBACK, 118 119 HCI_DM_FWUPD_START, 119 120 HCI_DM_FWUPD_END, 120 121 HCI_DM_VDC_MEASUREMENT_VALUE, ··· 122 123 MANUFACTURER_SPECIFIC, 123 124 }; 124 125 125 - struct st_nci_vendor_info { 126 - struct completion req_completion; 127 - struct sk_buff *rx_skb; 128 - }; 129 - 130 126 struct st_nci_info { 131 127 struct llt_ndlc *ndlc; 132 128 unsigned long flags; 133 129 134 130 struct st_nci_se_info se_info; 135 - struct st_nci_vendor_info vendor_info; 136 131 }; 137 132 138 133 void st_nci_remove(struct nci_dev *ndev); ··· 148 155 void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, 149 156 struct sk_buff *skb); 150 157 151 - void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, 152 - struct sk_buff *skb); 153 158 int st_nci_vendor_cmds_init(struct nci_dev *ndev); 154 159 155 160 #endif /* __LOCAL_ST_NCI_H_ */
+12 -50
drivers/nfc/st-nci/vendor_cmds.c
··· 333 333 return r; 334 334 } 335 335 336 - void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, 337 - struct sk_buff *skb) 338 - { 339 - struct st_nci_info *info = nci_get_drvdata(ndev); 340 - 341 - switch (event) { 342 - case ST_NCI_EVT_POST_DATA: 343 - info->vendor_info.rx_skb = skb; 344 - break; 345 - default: 346 - nfc_err(&ndev->nfc_dev->dev, "Unexpected event on loopback gate\n"); 347 - } 348 - complete(&info->vendor_info.req_completion); 349 - } 350 - EXPORT_SYMBOL(st_nci_hci_loopback_event_received); 351 - 352 - static int st_nci_hci_loopback(struct nfc_dev *dev, void *data, 353 - size_t data_len) 336 + static int st_nci_loopback(struct nfc_dev *dev, void *data, 337 + size_t data_len) 354 338 { 355 339 int r; 356 - struct sk_buff *msg; 340 + struct sk_buff *msg, *skb; 357 341 struct nci_dev *ndev = nfc_get_drvdata(dev); 358 - struct st_nci_info *info = nci_get_drvdata(ndev); 359 342 360 343 if (data_len <= 0) 361 344 return -EPROTO; 362 345 363 - reinit_completion(&info->vendor_info.req_completion); 364 - info->vendor_info.rx_skb = NULL; 346 + r = nci_nfcc_loopback(ndev, data, data_len, &skb); 347 + if (r < 0) 348 + return r; 365 349 366 - r = nci_hci_send_event(ndev, NCI_HCI_LOOPBACK_GATE, 367 - ST_NCI_EVT_POST_DATA, data, data_len); 368 - if (r != data_len) { 369 - r = -EPROTO; 370 - goto exit; 371 - } 372 - 373 - wait_for_completion_interruptible(&info->vendor_info.req_completion); 374 - 375 - if (!info->vendor_info.rx_skb || 376 - info->vendor_info.rx_skb->len != data_len) { 377 - r = -EPROTO; 378 - goto exit; 379 - } 380 - 381 - msg = nfc_vendor_cmd_alloc_reply_skb(ndev->nfc_dev, 382 - ST_NCI_VENDOR_OUI, 383 - HCI_LOOPBACK, 384 - info->vendor_info.rx_skb->len); 350 + msg = nfc_vendor_cmd_alloc_reply_skb(dev, ST_NCI_VENDOR_OUI, 351 + LOOPBACK, skb->len); 385 352 if (!msg) { 386 353 r = -ENOMEM; 387 354 goto free_skb; 388 355 } 389 356 390 - if (nla_put(msg, NFC_ATTR_VENDOR_DATA, info->vendor_info.rx_skb->len, 391 - info->vendor_info.rx_skb->data)) { 357 + if (nla_put(msg, NFC_ATTR_VENDOR_DATA, skb->len, skb->data)) { 392 358 kfree_skb(msg); 393 359 r = -ENOBUFS; 394 360 goto free_skb; ··· 362 396 363 397 r = nfc_vendor_cmd_reply(msg); 364 398 free_skb: 365 - kfree_skb(info->vendor_info.rx_skb); 366 - exit: 399 + kfree_skb(skb); 367 400 return r; 368 401 } 369 402 ··· 450 485 }, 451 486 { 452 487 .vendor_id = ST_NCI_VENDOR_OUI, 453 - .subcmd = HCI_LOOPBACK, 454 - .doit = st_nci_hci_loopback, 488 + .subcmd = LOOPBACK, 489 + .doit = st_nci_loopback, 455 490 }, 456 491 { 457 492 .vendor_id = ST_NCI_VENDOR_OUI, ··· 472 507 473 508 int st_nci_vendor_cmds_init(struct nci_dev *ndev) 474 509 { 475 - struct st_nci_info *info = nci_get_drvdata(ndev); 476 - 477 - init_completion(&info->vendor_info.req_completion); 478 510 return nfc_set_vendor_cmds(ndev->nfc_dev, st_nci_vendor_cmds, 479 511 sizeof(st_nci_vendor_cmds)); 480 512 }