Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 197bbf0a authored by John W. Linville's avatar John W. Linville
Browse files


Samuel Ortiz <sameo@linux.intel.com> says:

"This is the 2nd NFC pull request for 3.10.

With this one we have:

- A major pn533 update. The pn533 framing support has been changed in order to
  easily support all pn533 derivatives. For example we now support the ACR122
  USB dongle.

- An NFC MEI physical layer code factorization through the mei_phy NFC API.
  Both the microread and the pn544 drivers now use it.

- LLCP aggregation support. This allows NFC p2p devices to send aggregated
  frames containing all sort of LLCP frames except SYMM and aggregation
  frames.

- More LLCP socket options for getting the remote device link parameters.

- Fixes for the LLCP socket option code added with the first pull request for
  3.10.

- Some support for LLCP corner cases like 0 length SDUs and general DISC
  (tagged with a 0,0 dsap ssap couple) handling.

- RFKILL support for NFC."

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parents 9b383672 bb03dceb
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -26,6 +26,16 @@ config NFC_WILINK
	  Say Y here to compile support for Texas Instrument's NFC WiLink driver
	  into the kernel or say M to compile it as module.

config NFC_MEI_PHY
	tristate "MEI bus NFC device support"
	depends on INTEL_MEI_BUS_NFC && NFC_HCI
	help
	  This adds support to use an mei bus nfc device. Select this if you
	  will use an HCI NFC driver for an NFC chip connected behind an
	  Intel's Management Engine chip.

	  If unsure, say N.

source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/microread/Kconfig"

+1 −0
Original line number Diff line number Diff line
@@ -6,5 +6,6 @@ obj-$(CONFIG_NFC_PN544) += pn544/
obj-$(CONFIG_NFC_MICROREAD)	+= microread/
obj-$(CONFIG_NFC_PN533)		+= pn533.o
obj-$(CONFIG_NFC_WILINK)	+= nfcwilink.o
obj-$(CONFIG_NFC_MEI_PHY)	+= mei_phy.o

ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG

drivers/nfc/mei_phy.c

0 → 100644
+164 −0
Original line number Diff line number Diff line
/*
 * MEI Library for mei bus nfc device access
 *
 * Copyright (C) 2013  Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/nfc.h>

#include "mei_phy.h"

struct mei_nfc_hdr {
	u8 cmd;
	u8 status;
	u16 req_id;
	u32 reserved;
	u16 data_size;
} __attribute__((packed));

#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)

#define MEI_DUMP_SKB_IN(info, skb)				\
do {								\
	pr_debug("%s:\n", info);				\
	print_hex_dump_debug("mei in : ", DUMP_PREFIX_OFFSET,	\
			16, 1, (skb)->data, (skb)->len, false);	\
} while (0)

#define MEI_DUMP_SKB_OUT(info, skb)				\
do {								\
	pr_debug("%s:\n", info);				\
	print_hex_dump_debug("mei out: ", DUMP_PREFIX_OFFSET,	\
		       16, 1, (skb)->data, (skb)->len, false);	\
} while (0)

int nfc_mei_phy_enable(void *phy_id)
{
	int r;
	struct nfc_mei_phy *phy = phy_id;

	pr_info("%s\n", __func__);

	if (phy->powered == 1)
		return 0;

	r = mei_cl_enable_device(phy->device);
	if (r < 0) {
                pr_err("MEI_PHY: Could not enable device\n");
                return r;
	}

	phy->powered = 1;

	return 0;
}
EXPORT_SYMBOL_GPL(nfc_mei_phy_enable);

void nfc_mei_phy_disable(void *phy_id)
{
	struct nfc_mei_phy *phy = phy_id;

	pr_info("%s\n", __func__);

	mei_cl_disable_device(phy->device);

	phy->powered = 0;
}
EXPORT_SYMBOL_GPL(nfc_mei_phy_disable);

/*
 * Writing a frame must not return the number of written bytes.
 * It must return either zero for success, or <0 for error.
 * In addition, it must not alter the skb
 */
static int nfc_mei_phy_write(void *phy_id, struct sk_buff *skb)
{
	struct nfc_mei_phy *phy = phy_id;
	int r;

	MEI_DUMP_SKB_OUT("mei frame sent", skb);

	r = mei_cl_send(phy->device, skb->data, skb->len);
	if (r > 0)
		r = 0;

	return r;
}

void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context)
{
	struct nfc_mei_phy *phy = context;

	if (phy->hard_fault != 0)
		return;

	if (events & BIT(MEI_CL_EVENT_RX)) {
		struct sk_buff *skb;
		int reply_size;

		skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL);
		if (!skb)
			return;

		reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ);
		if (reply_size < MEI_NFC_HEADER_SIZE) {
			kfree(skb);
			return;
		}

		skb_put(skb, reply_size);
		skb_pull(skb, MEI_NFC_HEADER_SIZE);

		MEI_DUMP_SKB_IN("mei frame read", skb);

		nfc_hci_recv_frame(phy->hdev, skb);
	}
}
EXPORT_SYMBOL_GPL(nfc_mei_event_cb);

struct nfc_phy_ops mei_phy_ops = {
	.write = nfc_mei_phy_write,
	.enable = nfc_mei_phy_enable,
	.disable = nfc_mei_phy_disable,
};
EXPORT_SYMBOL_GPL(mei_phy_ops);

struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device)
{
	struct nfc_mei_phy *phy;

	phy = kzalloc(sizeof(struct nfc_mei_phy), GFP_KERNEL);
	if (!phy)
		return NULL;

	phy->device = device;
	mei_cl_set_drvdata(device, phy);

	return phy;
}
EXPORT_SYMBOL_GPL(nfc_mei_phy_alloc);

void nfc_mei_phy_free(struct nfc_mei_phy *phy)
{
	kfree(phy);
}
EXPORT_SYMBOL_GPL(nfc_mei_phy_free);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("mei bus NFC device interface");

drivers/nfc/mei_phy.h

0 → 100644
+30 −0
Original line number Diff line number Diff line
#ifndef __LOCAL_MEI_PHY_H_
#define __LOCAL_MEI_PHY_H_

#include <linux/mei_cl_bus.h>
#include <net/nfc/hci.h>

#define MEI_NFC_HEADER_SIZE 10
#define MEI_NFC_MAX_HCI_PAYLOAD 300

struct nfc_mei_phy {
	struct mei_cl_device *device;
	struct nfc_hci_dev *hdev;

	int powered;

	int hard_fault;		/*
				 * < 0 if hardware error occured
				 * and prevents normal operation.
				 */
};

extern struct nfc_phy_ops mei_phy_ops;

int nfc_mei_phy_enable(void *phy_id);
void nfc_mei_phy_disable(void *phy_id);
void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context);
struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device);
void nfc_mei_phy_free(struct nfc_mei_phy *phy);

#endif /* __LOCAL_MEI_PHY_H_ */
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ config NFC_MICROREAD_I2C

config NFC_MICROREAD_MEI
	tristate "NFC Microread MEI support"
	depends on NFC_MICROREAD && INTEL_MEI_BUS_NFC
	depends on NFC_MICROREAD && NFC_MEI_PHY
	---help---
	  This module adds support for the mei interface of adapters using
	  Inside microread chipsets.  Select this if your microread chipset
Loading