aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2014-10-13 20:19:46 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2015-06-08 19:21:35 -0400
commit9e58095f9660f88d6a2febe87d5073a6b2e9c399 (patch)
tree9fc7677478b4439ad426892643de9b29eae053d7 /net/nfc
parent8115dd5905318afcde713726064ec052b7d488cf (diff)
NFC: netlink: Implement vendor command support
Vendor commands are passed from userspace through the NFC_CMD_VENDOR netlink command, allowing driver and hardware specific operations implementations like for example RF tuning or production line calibration. Drivers will associate a set of vendor commands to a vendor id, which could typically be an OUI. The netlink kernel implementation will try to match the received vendor id and sub command attributes with the registered ones. When such match is found, the driver defined sub command routine is called. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/netlink.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 3763036710ae..f85f37ed19b2 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -5,6 +5,12 @@
5 * Lauro Ramos Venancio <lauro.venancio@openbossa.org> 5 * Lauro Ramos Venancio <lauro.venancio@openbossa.org>
6 * Aloisio Almeida Jr <aloisio.almeida@openbossa.org> 6 * Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
7 * 7 *
8 * Vendor commands implementation based on net/wireless/nl80211.c
9 * which is:
10 *
11 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
12 * Copyright 2013-2014 Intel Mobile Communications GmbH
13 *
8 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 16 * the Free Software Foundation; either version 2 of the License, or
@@ -1489,6 +1495,50 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
1489 return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx); 1495 return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
1490} 1496}
1491 1497
1498static int nfc_genl_vendor_cmd(struct sk_buff *skb,
1499 struct genl_info *info)
1500{
1501 struct nfc_dev *dev;
1502 struct nfc_vendor_cmd *cmd;
1503 u32 dev_idx, vid, subcmd;
1504 u8 *data;
1505 size_t data_len;
1506 int i;
1507
1508 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1509 !info->attrs[NFC_ATTR_VENDOR_ID] ||
1510 !info->attrs[NFC_ATTR_VENDOR_SUBCMD])
1511 return -EINVAL;
1512
1513 dev_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1514 vid = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_ID]);
1515 subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
1516
1517 dev = nfc_get_device(dev_idx);
1518 if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
1519 return -ENODEV;
1520
1521 data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
1522 if (data) {
1523 data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
1524 if (data_len == 0)
1525 return -EINVAL;
1526 } else {
1527 data_len = 0;
1528 }
1529
1530 for (i = 0; i < dev->n_vendor_cmds; i++) {
1531 cmd = &dev->vendor_cmds[i];
1532
1533 if (cmd->vendor_id != vid || cmd->subcmd != subcmd)
1534 continue;
1535
1536 return cmd->doit(dev, data, data_len);
1537 }
1538
1539 return -EOPNOTSUPP;
1540}
1541
1492static const struct genl_ops nfc_genl_ops[] = { 1542static const struct genl_ops nfc_genl_ops[] = {
1493 { 1543 {
1494 .cmd = NFC_CMD_GET_DEVICE, 1544 .cmd = NFC_CMD_GET_DEVICE,
@@ -1579,6 +1629,11 @@ static const struct genl_ops nfc_genl_ops[] = {
1579 .doit = nfc_genl_activate_target, 1629 .doit = nfc_genl_activate_target,
1580 .policy = nfc_genl_policy, 1630 .policy = nfc_genl_policy,
1581 }, 1631 },
1632 {
1633 .cmd = NFC_CMD_VENDOR,
1634 .doit = nfc_genl_vendor_cmd,
1635 .policy = nfc_genl_policy,
1636 },
1582}; 1637};
1583 1638
1584 1639