^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2011 Instituto Nokia de Tecnologia
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Lauro Ramos Venancio <lauro.venancio@openbossa.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Vendor commands implementation based on net/wireless/nl80211.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright 2013-2014 Intel Mobile Communications GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/nfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "nfc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "llcp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static const struct genl_multicast_group nfc_genl_mcgrps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { .name = NFC_GENL_MCAST_EVENT_NAME, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static struct genl_family nfc_genl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .len = NFC_DEVICE_NAME_MAXSIZE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) [NFC_ATTR_TARGET_INDEX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) [NFC_ATTR_LLC_PARAM_LTO] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [NFC_ATTR_LLC_PARAM_RW] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) [NFC_ATTR_LLC_PARAM_MIUX] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) [NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .len = NFC_FIRMWARE_NAME_MAXSIZE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [NFC_ATTR_SE_INDEX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [NFC_ATTR_SE_APDU] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) [NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [NFC_SDP_ATTR_URI] = { .type = NLA_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .len = U8_MAX - 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct netlink_callback *cb, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (target->nfcid1_len > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) target->nfcid1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (target->sensb_res_len > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) target->sensb_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (target->sensf_res_len > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) target->sensf_res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (target->is_iso15693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (nla_put_u8(msg, NFC_ATTR_TARGET_ISO15693_DSFID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) target->iso15693_dsfid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) nla_put(msg, NFC_ATTR_TARGET_ISO15693_UID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) sizeof(target->iso15693_uid), target->iso15693_uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const struct genl_dumpit_info *info = genl_dumpit_info(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int nfc_genl_dump_targets(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int i = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev = __get_device_from_cb(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (IS_ERR(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) cb->args[1] = (long) dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) device_lock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) cb->seq = dev->targets_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) while (i < dev->n_targets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) cb->args[0] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int nfc_genl_targets_found(struct nfc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dev->genl_data.poll_req_portid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) NFC_EVENT_TARGETS_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) NFC_EVENT_TARGET_LOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) NFC_EVENT_TM_ACTIVATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int nfc_genl_tm_deactivated(struct nfc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) NFC_EVENT_TM_DEACTIVATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int nfc_genl_setup_device_added(struct nfc_dev *dev, struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int nfc_genl_device_added(struct nfc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) NFC_EVENT_DEVICE_ADDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (nfc_genl_setup_device_added(dev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int nfc_genl_device_removed(struct nfc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) NFC_EVENT_DEVICE_REMOVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct nlattr *sdp_attr, *uri_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct nfc_llcp_sdp_tlv *sdres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct hlist_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int rc = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) NFC_EVENT_LLC_SDRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) sdp_attr = nla_nest_start_noflag(msg, NFC_ATTR_LLC_SDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (sdp_attr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) hlist_for_each_entry_safe(sdres, n, sdres_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pr_debug("uri: %s, sap: %d\n", sdres->uri, sdres->sap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) uri_attr = nla_nest_start_noflag(msg, i++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (uri_attr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (nla_put_u8(msg, NFC_SDP_ATTR_SAP, sdres->sap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (nla_put_string(msg, NFC_SDP_ATTR_URI, sdres->uri))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) nla_nest_end(msg, uri_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) hlist_del(&sdres->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) nfc_llcp_free_sdp_tlv(sdres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) nla_nest_end(msg, sdp_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) nfc_llcp_free_sdp_tlv_list(sdres_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) NFC_EVENT_SE_ADDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) nla_put_u8(msg, NFC_ATTR_SE_TYPE, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) NFC_EVENT_SE_REMOVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int nfc_genl_se_transaction(struct nfc_dev *dev, u8 se_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct nfc_evt_transaction *evt_transaction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct nfc_se *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) NFC_EVENT_SE_TRANSACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) se = nfc_find_se(dev, se_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) nla_put(msg, NFC_ATTR_SE_AID, evt_transaction->aid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) evt_transaction->aid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) nla_put(msg, NFC_ATTR_SE_PARAMS, evt_transaction->params_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) evt_transaction->params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* evt_transaction is no more used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) devm_kfree(&dev->dev, evt_transaction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* evt_transaction is no more used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) devm_kfree(&dev->dev, evt_transaction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int nfc_genl_se_connectivity(struct nfc_dev *dev, u8 se_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct nfc_se *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) NFC_EVENT_SE_CONNECTIVITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) se = nfc_find_se(dev, se_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) NFC_CMD_GET_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (nfc_genl_setup_device_added(dev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int nfc_genl_dump_devices(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) bool first_call = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (!iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) first_call = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (!iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) cb->args[0] = (long) iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) mutex_lock(&nfc_devlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) cb->seq = nfc_devlist_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (first_call) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) nfc_device_iter_init(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) dev = nfc_device_iter_next(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) while (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dev = nfc_device_iter_next(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) mutex_unlock(&nfc_devlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) cb->args[1] = (long) dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) nfc_device_iter_exit(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) kfree(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u8 comm_mode, u8 rf_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) pr_debug("DEP link is up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (rf_mode == NFC_RF_INITIATOR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev->dep_link_up = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) pr_debug("DEP link is down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) NFC_CMD_DEP_LINK_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int rc = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) goto out_putdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) rc = nfc_genl_send_device(msg, dev, info->snd_portid, info->snd_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) out_putdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) rc = nfc_dev_up(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) rc = nfc_dev_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) u32 im_protocols = 0, tm_protocols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) pr_debug("Poll start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) !info->attrs[NFC_ATTR_PROTOCOLS]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) !info->attrs[NFC_ATTR_TM_PROTOCOLS]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (info->attrs[NFC_ATTR_TM_PROTOCOLS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (info->attrs[NFC_ATTR_IM_PROTOCOLS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) else if (info->attrs[NFC_ATTR_PROTOCOLS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) im_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) mutex_lock(&dev->genl_data.genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) rc = nfc_start_poll(dev, im_protocols, tm_protocols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dev->genl_data.poll_req_portid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) mutex_unlock(&dev->genl_data.genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) device_lock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!dev->polling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) mutex_lock(&dev->genl_data.genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (dev->genl_data.poll_req_portid != info->snd_portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rc = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) rc = nfc_stop_poll(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) dev->genl_data.poll_req_portid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) mutex_unlock(&dev->genl_data.genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) u32 device_idx, target_idx, protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) !info->attrs[NFC_ATTR_TARGET_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) !info->attrs[NFC_ATTR_PROTOCOLS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev = nfc_get_device(device_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) protocol = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) nfc_deactivate_target(dev, target_idx, NFC_TARGET_MODE_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) rc = nfc_activate_target(dev, target_idx, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static int nfc_genl_deactivate_target(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) u32 device_idx, target_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) !info->attrs[NFC_ATTR_TARGET_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dev = nfc_get_device(device_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) rc = nfc_deactivate_target(dev, target_idx, NFC_TARGET_MODE_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) int rc, tgt_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) u8 comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) pr_debug("DEP link up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) !info->attrs[NFC_ATTR_COMM_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!info->attrs[NFC_ATTR_TARGET_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) tgt_idx = NFC_TARGET_IDX_ANY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) rc = nfc_dep_link_up(dev, tgt_idx, comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) !info->attrs[NFC_ATTR_TARGET_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) rc = nfc_dep_link_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static int nfc_genl_send_params(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct nfc_llcp_local *local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) u32 portid, u32 seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) NFC_CMD_LLC_GET_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct nfc_llcp_local *local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct sk_buff *msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) !info->attrs[NFC_ATTR_FIRMWARE_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) device_lock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) local = nfc_llcp_find_local(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!local) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct nfc_llcp_local *local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) u8 rw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) u16 miux = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) (!info->attrs[NFC_ATTR_LLC_PARAM_LTO] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) !info->attrs[NFC_ATTR_LLC_PARAM_RW] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) !info->attrs[NFC_ATTR_LLC_PARAM_MIUX]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (rw > LLCP_MAX_RW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (miux > LLCP_MAX_MIUX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) device_lock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) local = nfc_llcp_find_local(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (!local) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (dev->dep_link_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) rc = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (info->attrs[NFC_ATTR_LLC_PARAM_RW])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) local->rw = rw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) local->miux = cpu_to_be16(miux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct nfc_llcp_local *local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct nlattr *attr, *sdp_attrs[NFC_SDP_ATTR_MAX+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) u8 tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) char *uri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) int rc = 0, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) size_t uri_len, tlvs_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct hlist_head sdreq_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct nfc_llcp_sdp_tlv *sdreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) !info->attrs[NFC_ATTR_LLC_SDP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) device_lock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (dev->dep_link_up == false) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) rc = -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) local = nfc_llcp_find_local(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (!local) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) INIT_HLIST_HEAD(&sdreq_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) tlvs_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) nla_for_each_nested(attr, info->attrs[NFC_ATTR_LLC_SDP], rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) rc = nla_parse_nested_deprecated(sdp_attrs, NFC_SDP_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) attr, nfc_sdp_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (!sdp_attrs[NFC_SDP_ATTR_URI])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) uri_len = nla_len(sdp_attrs[NFC_SDP_ATTR_URI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (uri_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) uri = nla_data(sdp_attrs[NFC_SDP_ATTR_URI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (uri == NULL || *uri == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) tid = local->sdreq_next_tid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (sdreq == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) tlvs_len += sdreq->tlv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) hlist_add_head(&sdreq->node, &sdreq_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (hlist_empty(&sdreq_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) char firmware_name[NFC_FIRMWARE_NAME_MAXSIZE + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || !info->attrs[NFC_ATTR_FIRMWARE_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) sizeof(firmware_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) rc = nfc_fw_download(dev, firmware_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) u32 result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) NFC_CMD_FW_DOWNLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (nla_put_string(msg, NFC_ATTR_FIRMWARE_NAME, firmware_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) nla_put_u32(msg, NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS, result) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static int nfc_genl_enable_se(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) u32 idx, se_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) !info->attrs[NFC_ATTR_SE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) rc = nfc_enable_se(dev, se_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) static int nfc_genl_disable_se(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) u32 idx, se_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) !info->attrs[NFC_ATTR_SE_INDEX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) dev = nfc_get_device(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rc = nfc_disable_se(dev, se_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) nfc_put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static int nfc_genl_send_se(struct sk_buff *msg, struct nfc_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct nfc_se *se, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) list_for_each_entry_safe(se, n, &dev->secure_elements, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) NFC_CMD_GET_SE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) nla_put_u32(msg, NFC_ATTR_SE_INDEX, se->idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static int nfc_genl_dump_ses(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) bool first_call = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (!iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) first_call = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (!iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) cb->args[0] = (long) iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) mutex_lock(&nfc_devlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) cb->seq = nfc_devlist_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (first_call) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) nfc_device_iter_init(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) dev = nfc_device_iter_next(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) while (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) rc = nfc_genl_send_se(skb, dev, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) dev = nfc_device_iter_next(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) mutex_unlock(&nfc_devlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) cb->args[1] = (long) dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) static int nfc_genl_dump_ses_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) nfc_device_iter_exit(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) kfree(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static int nfc_se_io(struct nfc_dev *dev, u32 se_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) u8 *apdu, size_t apdu_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) se_io_cb_t cb, void *cb_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) struct nfc_se *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) device_lock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (!device_is_registered(&dev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (!dev->dev_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (!dev->ops->se_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) se = nfc_find_se(dev, se_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (!se) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (se->state != NFC_SE_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) rc = dev->ops->se_io(dev, se_idx, apdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) apdu_length, cb, cb_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) device_unlock(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct se_io_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) u32 dev_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) u32 se_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) static void se_io_cb(void *context, u8 *apdu, size_t apdu_len, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) struct se_io_ctx *ctx = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) NFC_CMD_SE_IO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, ctx->dev_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) nla_put_u32(msg, NFC_ATTR_SE_INDEX, ctx->se_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) nla_put(msg, NFC_ATTR_SE_APDU, apdu_len, apdu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct se_io_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) u32 dev_idx, se_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) u8 *apdu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) size_t apdu_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) !info->attrs[NFC_ATTR_SE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) !info->attrs[NFC_ATTR_SE_APDU])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) dev_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) dev = nfc_get_device(dev_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (!dev->ops || !dev->ops->se_io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (apdu_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) if (!apdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (!ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ctx->dev_idx = dev_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) ctx->se_idx = se_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) static int nfc_genl_vendor_cmd(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) struct nfc_vendor_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) u32 dev_idx, vid, subcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) size_t data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) !info->attrs[NFC_ATTR_VENDOR_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) !info->attrs[NFC_ATTR_VENDOR_SUBCMD])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) dev_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) vid = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) dev = nfc_get_device(dev_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (info->attrs[NFC_ATTR_VENDOR_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (data_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) for (i = 0; i < dev->n_vendor_cmds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) cmd = &dev->vendor_cmds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (cmd->vendor_id != vid || cmd->subcmd != subcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) dev->cur_cmd_info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) err = cmd->doit(dev, data, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) dev->cur_cmd_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* message building helper */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static inline void *nfc_hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) int flags, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /* since there is no private header just add the generic one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) return genlmsg_put(skb, portid, seq, &nfc_genl_family, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) __nfc_alloc_vendor_cmd_skb(struct nfc_dev *dev, int approxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) enum nfc_attrs attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) u32 oui, u32 subcmd, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) skb = nlmsg_new(approxlen + 100, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) hdr = nfc_hdr_put(skb, portid, seq, 0, NFC_CMD_VENDOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (nla_put_u32(skb, NFC_ATTR_DEVICE_INDEX, dev->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (nla_put_u32(skb, NFC_ATTR_VENDOR_ID, oui))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (nla_put_u32(skb, NFC_ATTR_VENDOR_SUBCMD, subcmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) ((void **)skb->cb)[0] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) ((void **)skb->cb)[1] = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) struct sk_buff *__nfc_alloc_vendor_cmd_reply_skb(struct nfc_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) enum nfc_attrs attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) u32 oui, u32 subcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) int approxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (WARN_ON(!dev->cur_cmd_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) return __nfc_alloc_vendor_cmd_skb(dev, approxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) dev->cur_cmd_info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) dev->cur_cmd_info->snd_seq, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) oui, subcmd, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) EXPORT_SYMBOL(__nfc_alloc_vendor_cmd_reply_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) int nfc_vendor_cmd_reply(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) struct nfc_dev *dev = ((void **)skb->cb)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) void *hdr = ((void **)skb->cb)[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* clear CB data for netlink core to own from now on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) memset(skb->cb, 0, sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (WARN_ON(!dev->cur_cmd_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) return genlmsg_reply(skb, dev->cur_cmd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) EXPORT_SYMBOL(nfc_vendor_cmd_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static const struct genl_ops nfc_genl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) .cmd = NFC_CMD_GET_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .doit = nfc_genl_get_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .dumpit = nfc_genl_dump_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) .done = nfc_genl_dump_devices_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) .cmd = NFC_CMD_DEV_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .doit = nfc_genl_dev_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .cmd = NFC_CMD_DEV_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) .doit = nfc_genl_dev_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) .cmd = NFC_CMD_START_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) .doit = nfc_genl_start_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) .cmd = NFC_CMD_STOP_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) .doit = nfc_genl_stop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) .cmd = NFC_CMD_DEP_LINK_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) .doit = nfc_genl_dep_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) .cmd = NFC_CMD_DEP_LINK_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) .doit = nfc_genl_dep_link_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) .cmd = NFC_CMD_GET_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) .validate = GENL_DONT_VALIDATE_STRICT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) GENL_DONT_VALIDATE_DUMP_STRICT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) .dumpit = nfc_genl_dump_targets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) .done = nfc_genl_dump_targets_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) .cmd = NFC_CMD_LLC_GET_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) .doit = nfc_genl_llc_get_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) .cmd = NFC_CMD_LLC_SET_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) .doit = nfc_genl_llc_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) .cmd = NFC_CMD_LLC_SDREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) .doit = nfc_genl_llc_sdreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) .cmd = NFC_CMD_FW_DOWNLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) .doit = nfc_genl_fw_download,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) .cmd = NFC_CMD_ENABLE_SE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) .doit = nfc_genl_enable_se,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) .cmd = NFC_CMD_DISABLE_SE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) .doit = nfc_genl_disable_se,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) .cmd = NFC_CMD_GET_SE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) .dumpit = nfc_genl_dump_ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) .done = nfc_genl_dump_ses_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) .cmd = NFC_CMD_SE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) .doit = nfc_genl_se_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .cmd = NFC_CMD_ACTIVATE_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) .doit = nfc_genl_activate_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) .cmd = NFC_CMD_VENDOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) .doit = nfc_genl_vendor_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) .cmd = NFC_CMD_DEACTIVATE_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) .doit = nfc_genl_deactivate_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) static struct genl_family nfc_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) .hdrsize = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) .name = NFC_GENL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) .version = NFC_GENL_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) .maxattr = NFC_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .policy = nfc_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .ops = nfc_genl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .n_ops = ARRAY_SIZE(nfc_genl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .mcgrps = nfc_genl_mcgrps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) .n_mcgrps = ARRAY_SIZE(nfc_genl_mcgrps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) struct urelease_work {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) struct work_struct w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) u32 portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static void nfc_urelease_event_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) struct urelease_work *w = container_of(work, struct urelease_work, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) struct class_dev_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) struct nfc_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) pr_debug("portid %d\n", w->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) mutex_lock(&nfc_devlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) nfc_device_iter_init(&iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) dev = nfc_device_iter_next(&iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) while (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) mutex_lock(&dev->genl_data.genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (dev->genl_data.poll_req_portid == w->portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) nfc_stop_poll(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) dev->genl_data.poll_req_portid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) mutex_unlock(&dev->genl_data.genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) dev = nfc_device_iter_next(&iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) nfc_device_iter_exit(&iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) mutex_unlock(&nfc_devlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) kfree(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) static int nfc_genl_rcv_nl_event(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) struct netlink_notify *n = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) struct urelease_work *w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) pr_debug("NETLINK_URELEASE event from id %d\n", n->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) w = kmalloc(sizeof(*w), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (w) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) w->portid = n->portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) schedule_work((struct work_struct *) w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) void nfc_genl_data_init(struct nfc_genl_data *genl_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) genl_data->poll_req_portid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) mutex_init(&genl_data->genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) mutex_destroy(&genl_data->genl_data_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static struct notifier_block nl_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) .notifier_call = nfc_genl_rcv_nl_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) * nfc_genl_init() - Initialize netlink interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) * This initialization function registers the nfc netlink family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) int __init nfc_genl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) rc = genl_register_family(&nfc_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) netlink_register_notifier(&nl_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) * nfc_genl_exit() - Deinitialize netlink interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) * This exit function unregisters the nfc netlink family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) void nfc_genl_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) netlink_unregister_notifier(&nl_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) genl_unregister_family(&nfc_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }