mirror of https://gitee.com/openkylin/linux.git
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,
|
||||
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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -333,62 +333,28 @@ static int st_nci_hci_dm_vdc_value_comparison(struct nfc_dev *dev, void *data,
|
|||
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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue