diff options
author | Christophe Ricard <christophe.ricard@gmail.com> | 2016-04-30 09:12:53 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2016-05-04 01:51:42 +0200 |
commit | 3aacd7fe552b093fc24a8082e16467eb26c2fa32 (patch) | |
tree | 90f55eb132e2a7deb5c6584cf442d7cc98af3221 | |
parent | 1c53855f6be2e7da270e86cae381745ee6105eab (diff) | |
download | op-kernel-dev-3aacd7fe552b093fc24a8082e16467eb26c2fa32.zip op-kernel-dev-3aacd7fe552b093fc24a8082e16467eb26c2fa32.tar.gz |
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>
-rw-r--r-- | drivers/nfc/st-nci/se.c | 5 | ||||
-rw-r--r-- | drivers/nfc/st-nci/st-nci.h | 13 | ||||
-rw-r--r-- | drivers/nfc/st-nci/vendor_cmds.c | 62 |
3 files changed, 14 insertions, 66 deletions
diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c index 420f019..56f2112 100644 --- a/drivers/nfc/st-nci/se.c +++ b/drivers/nfc/st-nci/se.c @@ -113,8 +113,6 @@ static struct nci_hci_gate st_nci_gates[] = { {NCI_HCI_IDENTITY_MGMT_GATE, NCI_HCI_INVALID_PIPE, ST_NCI_HOST_CONTROLLER_ID}, - {NCI_HCI_LOOPBACK_GATE, NCI_HCI_INVALID_PIPE, - ST_NCI_HOST_CONTROLLER_ID}, /* Secure element pipes are created by secure element host */ {ST_NCI_CONNECTIVITY_GATE, NCI_HCI_DO_NOT_OPEN_PIPE, @@ -385,9 +383,6 @@ void st_nci_hci_event_received(struct nci_dev *ndev, u8 pipe, case ST_NCI_CONNECTIVITY_GATE: st_nci_hci_connectivity_event_received(ndev, host, event, skb); break; - case NCI_HCI_LOOPBACK_GATE: - st_nci_hci_loopback_event_received(ndev, event, skb); - break; } } EXPORT_SYMBOL_GPL(st_nci_hci_event_received); diff --git a/drivers/nfc/st-nci/st-nci.h b/drivers/nfc/st-nci/st-nci.h index 8783f95..afaf138 100644 --- a/drivers/nfc/st-nci/st-nci.h +++ b/drivers/nfc/st-nci/st-nci.h @@ -92,8 +92,7 @@ struct st_nci_se_info { * white list). * @HCI_DM_FIELD_GENERATOR: Allow to generate different kind of RF * technology. When using this command to anti-collision is done. - * @HCI_LOOPBACK: Allow to echo a command and test the Dh to CLF - * connectivity. + * @LOOPBACK: Allow to echo a command and test the Dh to CLF connectivity. * @HCI_DM_VDC_MEASUREMENT_VALUE: Allow to measure the field applied on the * CLF antenna. A value between 0 and 0x0f is returned. 0 is maximum. * @HCI_DM_FWUPD_START: Allow to put CLF into firmware update mode. It is a @@ -115,7 +114,7 @@ enum nfc_vendor_cmds { HCI_DM_RESET, HCI_GET_PARAM, HCI_DM_FIELD_GENERATOR, - HCI_LOOPBACK, + LOOPBACK, HCI_DM_FWUPD_START, HCI_DM_FWUPD_END, HCI_DM_VDC_MEASUREMENT_VALUE, @@ -123,17 +122,11 @@ enum nfc_vendor_cmds { MANUFACTURER_SPECIFIC, }; -struct st_nci_vendor_info { - struct completion req_completion; - struct sk_buff *rx_skb; -}; - struct st_nci_info { struct llt_ndlc *ndlc; unsigned long flags; struct st_nci_se_info se_info; - struct st_nci_vendor_info vendor_info; }; void st_nci_remove(struct nci_dev *ndev); @@ -155,8 +148,6 @@ void st_nci_hci_event_received(struct nci_dev *ndev, u8 pipe, void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, struct sk_buff *skb); -void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, - struct sk_buff *skb); int st_nci_vendor_cmds_init(struct nci_dev *ndev); #endif /* __LOCAL_ST_NCI_H_ */ diff --git a/drivers/nfc/st-nci/vendor_cmds.c b/drivers/nfc/st-nci/vendor_cmds.c index b5debce..1a836c7 100644 --- a/drivers/nfc/st-nci/vendor_cmds.c +++ b/drivers/nfc/st-nci/vendor_cmds.c @@ -333,62 +333,28 @@ exit: return r; } -void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, - struct sk_buff *skb) -{ - struct st_nci_info *info = nci_get_drvdata(ndev); - - switch (event) { - case ST_NCI_EVT_POST_DATA: - info->vendor_info.rx_skb = skb; - break; - default: - nfc_err(&ndev->nfc_dev->dev, "Unexpected event on loopback gate\n"); - } - complete(&info->vendor_info.req_completion); -} -EXPORT_SYMBOL(st_nci_hci_loopback_event_received); - -static int st_nci_hci_loopback(struct nfc_dev *dev, void *data, - size_t data_len) +static int st_nci_loopback(struct nfc_dev *dev, void *data, + size_t data_len) { int r; - struct sk_buff *msg; + struct sk_buff *msg, *skb; struct nci_dev *ndev = nfc_get_drvdata(dev); - struct st_nci_info *info = nci_get_drvdata(ndev); if (data_len <= 0) return -EPROTO; - reinit_completion(&info->vendor_info.req_completion); - info->vendor_info.rx_skb = NULL; + r = nci_nfcc_loopback(ndev, data, data_len, &skb); + if (r < 0) + return r; - r = nci_hci_send_event(ndev, NCI_HCI_LOOPBACK_GATE, - ST_NCI_EVT_POST_DATA, data, data_len); - if (r != data_len) { - r = -EPROTO; - goto exit; - } - - wait_for_completion_interruptible(&info->vendor_info.req_completion); - - if (!info->vendor_info.rx_skb || - info->vendor_info.rx_skb->len != data_len) { - r = -EPROTO; - goto exit; - } - - msg = nfc_vendor_cmd_alloc_reply_skb(ndev->nfc_dev, - ST_NCI_VENDOR_OUI, - HCI_LOOPBACK, - info->vendor_info.rx_skb->len); + msg = nfc_vendor_cmd_alloc_reply_skb(dev, ST_NCI_VENDOR_OUI, + LOOPBACK, skb->len); if (!msg) { r = -ENOMEM; goto free_skb; } - if (nla_put(msg, NFC_ATTR_VENDOR_DATA, info->vendor_info.rx_skb->len, - info->vendor_info.rx_skb->data)) { + if (nla_put(msg, NFC_ATTR_VENDOR_DATA, skb->len, skb->data)) { kfree_skb(msg); r = -ENOBUFS; goto free_skb; @@ -396,8 +362,7 @@ static int st_nci_hci_loopback(struct nfc_dev *dev, void *data, r = nfc_vendor_cmd_reply(msg); free_skb: - kfree_skb(info->vendor_info.rx_skb); -exit: + kfree_skb(skb); return r; } @@ -485,8 +450,8 @@ static struct nfc_vendor_cmd st_nci_vendor_cmds[] = { }, { .vendor_id = ST_NCI_VENDOR_OUI, - .subcmd = HCI_LOOPBACK, - .doit = st_nci_hci_loopback, + .subcmd = LOOPBACK, + .doit = st_nci_loopback, }, { .vendor_id = ST_NCI_VENDOR_OUI, @@ -507,9 +472,6 @@ static struct nfc_vendor_cmd st_nci_vendor_cmds[] = { int st_nci_vendor_cmds_init(struct nci_dev *ndev) { - struct st_nci_info *info = nci_get_drvdata(ndev); - - init_completion(&info->vendor_info.req_completion); return nfc_set_vendor_cmds(ndev->nfc_dev, st_nci_vendor_cmds, sizeof(st_nci_vendor_cmds)); } |