nfc: st-nci: Move loopback usage from HCI to NCI
authorChristophe Ricard <christophe.ricard@gmail.com>
Sat, 30 Apr 2016 07:12:53 +0000 (09:12 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 3 May 2016 23:51:42 +0000 (01:51 +0200)
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>
drivers/nfc/st-nci/se.c
drivers/nfc/st-nci/st-nci.h
drivers/nfc/st-nci/vendor_cmds.c

index 420f019..56f2112 100644 (file)
@@ -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);
index 8783f95..afaf138 100644 (file)
@@ -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_ */
index b5debce..1a836c7 100644 (file)
@@ -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));
 }