0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/nfc.h>
0010 #include <net/nfc/nci.h>
0011 #include <net/nfc/nci_core.h>
0012
0013 #include "st-nci.h"
0014
0015 #define DRIVER_DESC "NCI NFC driver for ST_NCI"
0016
0017 #define ST_NCI1_X_PROPRIETARY_ISO15693 0x83
0018
0019 static int st_nci_init(struct nci_dev *ndev)
0020 {
0021 struct nci_mode_set_cmd cmd;
0022
0023 cmd.cmd_type = ST_NCI_SET_NFC_MODE;
0024 cmd.mode = 1;
0025
0026 return nci_prop_cmd(ndev, ST_NCI_CORE_PROP,
0027 sizeof(struct nci_mode_set_cmd), (__u8 *)&cmd);
0028 }
0029
0030 static int st_nci_open(struct nci_dev *ndev)
0031 {
0032 struct st_nci_info *info = nci_get_drvdata(ndev);
0033 int r;
0034
0035 if (test_and_set_bit(ST_NCI_RUNNING, &info->flags))
0036 return 0;
0037
0038 r = ndlc_open(info->ndlc);
0039 if (r)
0040 clear_bit(ST_NCI_RUNNING, &info->flags);
0041
0042 return r;
0043 }
0044
0045 static int st_nci_close(struct nci_dev *ndev)
0046 {
0047 struct st_nci_info *info = nci_get_drvdata(ndev);
0048
0049 if (!test_bit(ST_NCI_RUNNING, &info->flags))
0050 return 0;
0051
0052 ndlc_close(info->ndlc);
0053
0054 clear_bit(ST_NCI_RUNNING, &info->flags);
0055
0056 return 0;
0057 }
0058
0059 static int st_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
0060 {
0061 struct st_nci_info *info = nci_get_drvdata(ndev);
0062
0063 skb->dev = (void *)ndev;
0064
0065 if (!test_bit(ST_NCI_RUNNING, &info->flags))
0066 return -EBUSY;
0067
0068 return ndlc_send(info->ndlc, skb);
0069 }
0070
0071 static __u32 st_nci_get_rfprotocol(struct nci_dev *ndev,
0072 __u8 rf_protocol)
0073 {
0074 return rf_protocol == ST_NCI1_X_PROPRIETARY_ISO15693 ?
0075 NFC_PROTO_ISO15693_MASK : 0;
0076 }
0077
0078 static int st_nci_prop_rsp_packet(struct nci_dev *ndev,
0079 struct sk_buff *skb)
0080 {
0081 __u8 status = skb->data[0];
0082
0083 nci_req_complete(ndev, status);
0084 return 0;
0085 }
0086
0087 static const struct nci_driver_ops st_nci_prop_ops[] = {
0088 {
0089 .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
0090 ST_NCI_CORE_PROP),
0091 .rsp = st_nci_prop_rsp_packet,
0092 },
0093 };
0094
0095 static const struct nci_ops st_nci_ops = {
0096 .init = st_nci_init,
0097 .open = st_nci_open,
0098 .close = st_nci_close,
0099 .send = st_nci_send,
0100 .get_rfprotocol = st_nci_get_rfprotocol,
0101 .discover_se = st_nci_discover_se,
0102 .enable_se = st_nci_enable_se,
0103 .disable_se = st_nci_disable_se,
0104 .se_io = st_nci_se_io,
0105 .hci_load_session = st_nci_hci_load_session,
0106 .hci_event_received = st_nci_hci_event_received,
0107 .hci_cmd_received = st_nci_hci_cmd_received,
0108 .prop_ops = st_nci_prop_ops,
0109 .n_prop_ops = ARRAY_SIZE(st_nci_prop_ops),
0110 };
0111
0112 int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
0113 int phy_tailroom, struct st_nci_se_status *se_status)
0114 {
0115 struct st_nci_info *info;
0116 int r;
0117 u32 protocols;
0118
0119 info = devm_kzalloc(ndlc->dev,
0120 sizeof(struct st_nci_info), GFP_KERNEL);
0121 if (!info)
0122 return -ENOMEM;
0123
0124 protocols = NFC_PROTO_JEWEL_MASK
0125 | NFC_PROTO_MIFARE_MASK
0126 | NFC_PROTO_FELICA_MASK
0127 | NFC_PROTO_ISO14443_MASK
0128 | NFC_PROTO_ISO14443_B_MASK
0129 | NFC_PROTO_ISO15693_MASK
0130 | NFC_PROTO_NFC_DEP_MASK;
0131
0132 BUILD_BUG_ON(ARRAY_SIZE(st_nci_prop_ops) > NCI_MAX_PROPRIETARY_CMD);
0133 ndlc->ndev = nci_allocate_device(&st_nci_ops, protocols,
0134 phy_headroom, phy_tailroom);
0135 if (!ndlc->ndev) {
0136 pr_err("Cannot allocate nfc ndev\n");
0137 return -ENOMEM;
0138 }
0139 info->ndlc = ndlc;
0140
0141 nci_set_drvdata(ndlc->ndev, info);
0142
0143 r = st_nci_vendor_cmds_init(ndlc->ndev);
0144 if (r) {
0145 pr_err("Cannot register proprietary vendor cmds\n");
0146 goto err_reg_dev;
0147 }
0148
0149 r = nci_register_device(ndlc->ndev);
0150 if (r) {
0151 pr_err("Cannot register nfc device to nci core\n");
0152 goto err_reg_dev;
0153 }
0154
0155 return st_nci_se_init(ndlc->ndev, se_status);
0156
0157 err_reg_dev:
0158 nci_free_device(ndlc->ndev);
0159 return r;
0160 }
0161 EXPORT_SYMBOL_GPL(st_nci_probe);
0162
0163 void st_nci_remove(struct nci_dev *ndev)
0164 {
0165 struct st_nci_info *info = nci_get_drvdata(ndev);
0166
0167 ndlc_close(info->ndlc);
0168
0169 nci_unregister_device(ndev);
0170 nci_free_device(ndev);
0171 }
0172 EXPORT_SYMBOL_GPL(st_nci_remove);
0173
0174 MODULE_LICENSE("GPL");
0175 MODULE_DESCRIPTION(DRIVER_DESC);