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>
This commit is contained in:
parent
1c53855f6b
commit
3aacd7fe55
|
@ -113,8 +113,6 @@ static struct nci_hci_gate st_nci_gates[] = {
|
||||||
|
|
||||||
{NCI_HCI_IDENTITY_MGMT_GATE, NCI_HCI_INVALID_PIPE,
|
{NCI_HCI_IDENTITY_MGMT_GATE, NCI_HCI_INVALID_PIPE,
|
||||||
ST_NCI_HOST_CONTROLLER_ID},
|
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 */
|
/* Secure element pipes are created by secure element host */
|
||||||
{ST_NCI_CONNECTIVITY_GATE, NCI_HCI_DO_NOT_OPEN_PIPE,
|
{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:
|
case ST_NCI_CONNECTIVITY_GATE:
|
||||||
st_nci_hci_connectivity_event_received(ndev, host, event, skb);
|
st_nci_hci_connectivity_event_received(ndev, host, event, skb);
|
||||||
break;
|
break;
|
||||||
case NCI_HCI_LOOPBACK_GATE:
|
|
||||||
st_nci_hci_loopback_event_received(ndev, event, skb);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(st_nci_hci_event_received);
|
EXPORT_SYMBOL_GPL(st_nci_hci_event_received);
|
||||||
|
|
|
@ -92,8 +92,7 @@ struct st_nci_se_info {
|
||||||
* white list).
|
* white list).
|
||||||
* @HCI_DM_FIELD_GENERATOR: Allow to generate different kind of RF
|
* @HCI_DM_FIELD_GENERATOR: Allow to generate different kind of RF
|
||||||
* technology. When using this command to anti-collision is done.
|
* technology. When using this command to anti-collision is done.
|
||||||
* @HCI_LOOPBACK: Allow to echo a command and test the Dh to CLF
|
* @LOOPBACK: Allow to echo a command and test the Dh to CLF connectivity.
|
||||||
* connectivity.
|
|
||||||
* @HCI_DM_VDC_MEASUREMENT_VALUE: Allow to measure the field applied on the
|
* @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.
|
* 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
|
* @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_DM_RESET,
|
||||||
HCI_GET_PARAM,
|
HCI_GET_PARAM,
|
||||||
HCI_DM_FIELD_GENERATOR,
|
HCI_DM_FIELD_GENERATOR,
|
||||||
HCI_LOOPBACK,
|
LOOPBACK,
|
||||||
HCI_DM_FWUPD_START,
|
HCI_DM_FWUPD_START,
|
||||||
HCI_DM_FWUPD_END,
|
HCI_DM_FWUPD_END,
|
||||||
HCI_DM_VDC_MEASUREMENT_VALUE,
|
HCI_DM_VDC_MEASUREMENT_VALUE,
|
||||||
|
@ -123,17 +122,11 @@ enum nfc_vendor_cmds {
|
||||||
MANUFACTURER_SPECIFIC,
|
MANUFACTURER_SPECIFIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct st_nci_vendor_info {
|
|
||||||
struct completion req_completion;
|
|
||||||
struct sk_buff *rx_skb;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct st_nci_info {
|
struct st_nci_info {
|
||||||
struct llt_ndlc *ndlc;
|
struct llt_ndlc *ndlc;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
struct st_nci_se_info se_info;
|
struct st_nci_se_info se_info;
|
||||||
struct st_nci_vendor_info vendor_info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void st_nci_remove(struct nci_dev *ndev);
|
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,
|
void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd,
|
||||||
struct sk_buff *skb);
|
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);
|
int st_nci_vendor_cmds_init(struct nci_dev *ndev);
|
||||||
|
|
||||||
#endif /* __LOCAL_ST_NCI_H_ */
|
#endif /* __LOCAL_ST_NCI_H_ */
|
||||||
|
|
|
@ -333,62 +333,28 @@ exit:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event,
|
static int st_nci_loopback(struct nfc_dev *dev, void *data,
|
||||||
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)
|
size_t data_len)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct sk_buff *msg;
|
struct sk_buff *msg, *skb;
|
||||||
struct nci_dev *ndev = nfc_get_drvdata(dev);
|
struct nci_dev *ndev = nfc_get_drvdata(dev);
|
||||||
struct st_nci_info *info = nci_get_drvdata(ndev);
|
|
||||||
|
|
||||||
if (data_len <= 0)
|
if (data_len <= 0)
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
|
|
||||||
reinit_completion(&info->vendor_info.req_completion);
|
r = nci_nfcc_loopback(ndev, data, data_len, &skb);
|
||||||
info->vendor_info.rx_skb = NULL;
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = nci_hci_send_event(ndev, NCI_HCI_LOOPBACK_GATE,
|
msg = nfc_vendor_cmd_alloc_reply_skb(dev, ST_NCI_VENDOR_OUI,
|
||||||
ST_NCI_EVT_POST_DATA, data, data_len);
|
LOOPBACK, skb->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);
|
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto free_skb;
|
goto free_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nla_put(msg, NFC_ATTR_VENDOR_DATA, info->vendor_info.rx_skb->len,
|
if (nla_put(msg, NFC_ATTR_VENDOR_DATA, skb->len, skb->data)) {
|
||||||
info->vendor_info.rx_skb->data)) {
|
|
||||||
kfree_skb(msg);
|
kfree_skb(msg);
|
||||||
r = -ENOBUFS;
|
r = -ENOBUFS;
|
||||||
goto free_skb;
|
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);
|
r = nfc_vendor_cmd_reply(msg);
|
||||||
free_skb:
|
free_skb:
|
||||||
kfree_skb(info->vendor_info.rx_skb);
|
kfree_skb(skb);
|
||||||
exit:
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,8 +450,8 @@ static struct nfc_vendor_cmd st_nci_vendor_cmds[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor_id = ST_NCI_VENDOR_OUI,
|
.vendor_id = ST_NCI_VENDOR_OUI,
|
||||||
.subcmd = HCI_LOOPBACK,
|
.subcmd = LOOPBACK,
|
||||||
.doit = st_nci_hci_loopback,
|
.doit = st_nci_loopback,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.vendor_id = ST_NCI_VENDOR_OUI,
|
.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)
|
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,
|
return nfc_set_vendor_cmds(ndev->nfc_dev, st_nci_vendor_cmds,
|
||||||
sizeof(st_nci_vendor_cmds));
|
sizeof(st_nci_vendor_cmds));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue