0001
0002
0003
0004
0005
0006
0007 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0008
0009 #include <linux/module.h>
0010 #include <linux/slab.h>
0011 #include <linux/nfc.h>
0012
0013 #include "mei_phy.h"
0014
0015 struct mei_nfc_hdr {
0016 u8 cmd;
0017 u8 status;
0018 u16 req_id;
0019 u32 reserved;
0020 u16 data_size;
0021 } __packed;
0022
0023 struct mei_nfc_cmd {
0024 struct mei_nfc_hdr hdr;
0025 u8 sub_command;
0026 u8 data[];
0027 } __packed;
0028
0029 struct mei_nfc_reply {
0030 struct mei_nfc_hdr hdr;
0031 u8 sub_command;
0032 u8 reply_status;
0033 u8 data[];
0034 } __packed;
0035
0036 struct mei_nfc_if_version {
0037 u8 radio_version_sw[3];
0038 u8 reserved[3];
0039 u8 radio_version_hw[3];
0040 u8 i2c_addr;
0041 u8 fw_ivn;
0042 u8 vendor_id;
0043 u8 radio_type;
0044 } __packed;
0045
0046 struct mei_nfc_connect {
0047 u8 fw_ivn;
0048 u8 vendor_id;
0049 } __packed;
0050
0051 struct mei_nfc_connect_resp {
0052 u8 fw_ivn;
0053 u8 vendor_id;
0054 u16 me_major;
0055 u16 me_minor;
0056 u16 me_hotfix;
0057 u16 me_build;
0058 } __packed;
0059
0060
0061 #define MEI_NFC_CMD_MAINTENANCE 0x00
0062 #define MEI_NFC_CMD_HCI_SEND 0x01
0063 #define MEI_NFC_CMD_HCI_RECV 0x02
0064
0065 #define MEI_NFC_SUBCMD_CONNECT 0x00
0066 #define MEI_NFC_SUBCMD_IF_VERSION 0x01
0067
0068 #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)
0069
0070 #define MEI_DUMP_SKB_IN(info, skb) \
0071 do { \
0072 pr_debug("%s:\n", info); \
0073 print_hex_dump_debug("mei in : ", DUMP_PREFIX_OFFSET, \
0074 16, 1, (skb)->data, (skb)->len, false); \
0075 } while (0)
0076
0077 #define MEI_DUMP_SKB_OUT(info, skb) \
0078 do { \
0079 pr_debug("%s:\n", info); \
0080 print_hex_dump_debug("mei out: ", DUMP_PREFIX_OFFSET, \
0081 16, 1, (skb)->data, (skb)->len, false); \
0082 } while (0)
0083
0084 #define MEI_DUMP_NFC_HDR(info, _hdr) \
0085 do { \
0086 pr_debug("%s:\n", info); \
0087 pr_debug("cmd=%02d status=%d req_id=%d rsvd=%d size=%d\n", \
0088 (_hdr)->cmd, (_hdr)->status, (_hdr)->req_id, \
0089 (_hdr)->reserved, (_hdr)->data_size); \
0090 } while (0)
0091
0092 static int mei_nfc_if_version(struct nfc_mei_phy *phy)
0093 {
0094
0095 struct mei_nfc_cmd cmd;
0096 struct mei_nfc_reply *reply = NULL;
0097 struct mei_nfc_if_version *version;
0098 size_t if_version_length;
0099 int bytes_recv, r;
0100
0101 memset(&cmd, 0, sizeof(struct mei_nfc_cmd));
0102 cmd.hdr.cmd = MEI_NFC_CMD_MAINTENANCE;
0103 cmd.hdr.data_size = 1;
0104 cmd.sub_command = MEI_NFC_SUBCMD_IF_VERSION;
0105
0106 MEI_DUMP_NFC_HDR("version", &cmd.hdr);
0107 r = mei_cldev_send(phy->cldev, (u8 *)&cmd, sizeof(struct mei_nfc_cmd));
0108 if (r < 0) {
0109 pr_err("Could not send IF version cmd\n");
0110 return r;
0111 }
0112
0113
0114 if_version_length = sizeof(struct mei_nfc_reply) +
0115 sizeof(struct mei_nfc_if_version);
0116
0117 reply = kzalloc(if_version_length, GFP_KERNEL);
0118 if (!reply)
0119 return -ENOMEM;
0120
0121 bytes_recv = mei_cldev_recv(phy->cldev, (u8 *)reply, if_version_length);
0122 if (bytes_recv < 0 || bytes_recv < if_version_length) {
0123 pr_err("Could not read IF version\n");
0124 r = -EIO;
0125 goto err;
0126 }
0127
0128 version = (struct mei_nfc_if_version *)reply->data;
0129
0130 phy->fw_ivn = version->fw_ivn;
0131 phy->vendor_id = version->vendor_id;
0132 phy->radio_type = version->radio_type;
0133
0134 err:
0135 kfree(reply);
0136 return r;
0137 }
0138
0139 static int mei_nfc_connect(struct nfc_mei_phy *phy)
0140 {
0141 struct mei_nfc_cmd *cmd, *reply;
0142 struct mei_nfc_connect *connect;
0143 struct mei_nfc_connect_resp *connect_resp;
0144 size_t connect_length, connect_resp_length;
0145 int bytes_recv, r;
0146
0147 connect_length = sizeof(struct mei_nfc_cmd) +
0148 sizeof(struct mei_nfc_connect);
0149
0150 connect_resp_length = sizeof(struct mei_nfc_cmd) +
0151 sizeof(struct mei_nfc_connect_resp);
0152
0153 cmd = kzalloc(connect_length, GFP_KERNEL);
0154 if (!cmd)
0155 return -ENOMEM;
0156 connect = (struct mei_nfc_connect *)cmd->data;
0157
0158 reply = kzalloc(connect_resp_length, GFP_KERNEL);
0159 if (!reply) {
0160 kfree(cmd);
0161 return -ENOMEM;
0162 }
0163
0164 connect_resp = (struct mei_nfc_connect_resp *)reply->data;
0165
0166 cmd->hdr.cmd = MEI_NFC_CMD_MAINTENANCE;
0167 cmd->hdr.data_size = 3;
0168 cmd->sub_command = MEI_NFC_SUBCMD_CONNECT;
0169 connect->fw_ivn = phy->fw_ivn;
0170 connect->vendor_id = phy->vendor_id;
0171
0172 MEI_DUMP_NFC_HDR("connect request", &cmd->hdr);
0173 r = mei_cldev_send(phy->cldev, (u8 *)cmd, connect_length);
0174 if (r < 0) {
0175 pr_err("Could not send connect cmd %d\n", r);
0176 goto err;
0177 }
0178
0179 bytes_recv = mei_cldev_recv(phy->cldev, (u8 *)reply,
0180 connect_resp_length);
0181 if (bytes_recv < 0) {
0182 r = bytes_recv;
0183 pr_err("Could not read connect response %d\n", r);
0184 goto err;
0185 }
0186
0187 MEI_DUMP_NFC_HDR("connect reply", &reply->hdr);
0188
0189 pr_info("IVN 0x%x Vendor ID 0x%x\n",
0190 connect_resp->fw_ivn, connect_resp->vendor_id);
0191
0192 pr_info("ME FW %d.%d.%d.%d\n",
0193 connect_resp->me_major, connect_resp->me_minor,
0194 connect_resp->me_hotfix, connect_resp->me_build);
0195
0196 r = 0;
0197
0198 err:
0199 kfree(reply);
0200 kfree(cmd);
0201
0202 return r;
0203 }
0204
0205 static int mei_nfc_send(struct nfc_mei_phy *phy, const u8 *buf, size_t length)
0206 {
0207 struct mei_nfc_hdr *hdr;
0208 u8 *mei_buf;
0209 int err;
0210
0211 err = -ENOMEM;
0212 mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL);
0213 if (!mei_buf)
0214 goto out;
0215
0216 hdr = (struct mei_nfc_hdr *)mei_buf;
0217 hdr->cmd = MEI_NFC_CMD_HCI_SEND;
0218 hdr->status = 0;
0219 hdr->req_id = phy->req_id;
0220 hdr->reserved = 0;
0221 hdr->data_size = length;
0222
0223 MEI_DUMP_NFC_HDR("send", hdr);
0224
0225 memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length);
0226 err = mei_cldev_send(phy->cldev, mei_buf, length + MEI_NFC_HEADER_SIZE);
0227 if (err < 0)
0228 goto out;
0229
0230 if (!wait_event_interruptible_timeout(phy->send_wq,
0231 phy->recv_req_id == phy->req_id, HZ)) {
0232 pr_err("NFC MEI command timeout\n");
0233 err = -ETIME;
0234 } else {
0235 phy->req_id++;
0236 }
0237 out:
0238 kfree(mei_buf);
0239 return err;
0240 }
0241
0242
0243
0244
0245
0246
0247 static int nfc_mei_phy_write(void *phy_id, struct sk_buff *skb)
0248 {
0249 struct nfc_mei_phy *phy = phy_id;
0250 int r;
0251
0252 MEI_DUMP_SKB_OUT("mei frame sent", skb);
0253
0254 r = mei_nfc_send(phy, skb->data, skb->len);
0255 if (r > 0)
0256 r = 0;
0257
0258 return r;
0259 }
0260
0261 static int mei_nfc_recv(struct nfc_mei_phy *phy, u8 *buf, size_t length)
0262 {
0263 struct mei_nfc_hdr *hdr;
0264 int received_length;
0265
0266 received_length = mei_cldev_recv(phy->cldev, buf, length);
0267 if (received_length < 0)
0268 return received_length;
0269
0270 hdr = (struct mei_nfc_hdr *) buf;
0271
0272 MEI_DUMP_NFC_HDR("receive", hdr);
0273 if (hdr->cmd == MEI_NFC_CMD_HCI_SEND) {
0274 phy->recv_req_id = hdr->req_id;
0275 wake_up(&phy->send_wq);
0276
0277 return 0;
0278 }
0279
0280 return received_length;
0281 }
0282
0283
0284 static void nfc_mei_rx_cb(struct mei_cl_device *cldev)
0285 {
0286 struct nfc_mei_phy *phy = mei_cldev_get_drvdata(cldev);
0287 struct sk_buff *skb;
0288 int reply_size;
0289
0290 if (!phy)
0291 return;
0292
0293 if (phy->hard_fault != 0)
0294 return;
0295
0296 skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL);
0297 if (!skb)
0298 return;
0299
0300 reply_size = mei_nfc_recv(phy, skb->data, MEI_NFC_MAX_READ);
0301 if (reply_size < MEI_NFC_HEADER_SIZE) {
0302 kfree_skb(skb);
0303 return;
0304 }
0305
0306 skb_put(skb, reply_size);
0307 skb_pull(skb, MEI_NFC_HEADER_SIZE);
0308
0309 MEI_DUMP_SKB_IN("mei frame read", skb);
0310
0311 nfc_hci_recv_frame(phy->hdev, skb);
0312 }
0313
0314 static int nfc_mei_phy_enable(void *phy_id)
0315 {
0316 int r;
0317 struct nfc_mei_phy *phy = phy_id;
0318
0319 if (phy->powered == 1)
0320 return 0;
0321
0322 r = mei_cldev_enable(phy->cldev);
0323 if (r < 0) {
0324 pr_err("Could not enable device %d\n", r);
0325 return r;
0326 }
0327
0328 r = mei_nfc_if_version(phy);
0329 if (r < 0) {
0330 pr_err("Could not enable device %d\n", r);
0331 goto err;
0332 }
0333
0334 r = mei_nfc_connect(phy);
0335 if (r < 0) {
0336 pr_err("Could not connect to device %d\n", r);
0337 goto err;
0338 }
0339
0340 r = mei_cldev_register_rx_cb(phy->cldev, nfc_mei_rx_cb);
0341 if (r) {
0342 pr_err("Event cb registration failed %d\n", r);
0343 goto err;
0344 }
0345
0346 phy->powered = 1;
0347
0348 return 0;
0349
0350 err:
0351 phy->powered = 0;
0352 mei_cldev_disable(phy->cldev);
0353 return r;
0354 }
0355
0356 static void nfc_mei_phy_disable(void *phy_id)
0357 {
0358 struct nfc_mei_phy *phy = phy_id;
0359
0360 mei_cldev_disable(phy->cldev);
0361
0362 phy->powered = 0;
0363 }
0364
0365 const struct nfc_phy_ops mei_phy_ops = {
0366 .write = nfc_mei_phy_write,
0367 .enable = nfc_mei_phy_enable,
0368 .disable = nfc_mei_phy_disable,
0369 };
0370 EXPORT_SYMBOL_GPL(mei_phy_ops);
0371
0372 struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *cldev)
0373 {
0374 struct nfc_mei_phy *phy;
0375
0376 phy = kzalloc(sizeof(struct nfc_mei_phy), GFP_KERNEL);
0377 if (!phy)
0378 return NULL;
0379
0380 phy->cldev = cldev;
0381 init_waitqueue_head(&phy->send_wq);
0382 mei_cldev_set_drvdata(cldev, phy);
0383
0384 return phy;
0385 }
0386 EXPORT_SYMBOL_GPL(nfc_mei_phy_alloc);
0387
0388 void nfc_mei_phy_free(struct nfc_mei_phy *phy)
0389 {
0390 mei_cldev_disable(phy->cldev);
0391 kfree(phy);
0392 }
0393 EXPORT_SYMBOL_GPL(nfc_mei_phy_free);
0394
0395 MODULE_LICENSE("GPL");
0396 MODULE_DESCRIPTION("mei bus NFC device interface");