summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Ortiz2012-05-31 00:05:50 +0200
committerSamuel Ortiz2012-06-04 21:34:31 +0200
commit73167ced31d15c04e57b9e0885ac05675e9195a4 (patch)
tree165bc763ef1058ad8ec66ccd8adbb39c5af7e6f1
parentNFC: Introduce target mode tx ops (diff)
downloadkernel-qcow2-linux-73167ced31d15c04e57b9e0885ac05675e9195a4.tar.gz
kernel-qcow2-linux-73167ced31d15c04e57b9e0885ac05675e9195a4.tar.xz
kernel-qcow2-linux-73167ced31d15c04e57b9e0885ac05675e9195a4.zip
NFC: Introduce target mode rx data callback
This routine will be called by drivers whenever they receive data in target mode. This should be unexpected events and as such should be handled by a standalone API (i.e. not as a callback pointer from an existing API). Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--include/net/nfc/nfc.h1
-rw-r--r--net/nfc/core.c12
-rw-r--r--net/nfc/llcp/llcp.c15
-rw-r--r--net/nfc/nfc.h7
4 files changed, 35 insertions, 0 deletions
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index 45c4c970575c..180964b954ab 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -202,5 +202,6 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
u8 *gb, size_t gb_len);
int nfc_tm_deactivated(struct nfc_dev *dev);
+int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb);
#endif /* __NET_NFC_H */
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 76c1e207d297..6a3799eebc30 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -462,6 +462,18 @@ u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len)
}
EXPORT_SYMBOL(nfc_get_local_general_bytes);
+int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb)
+{
+ /* Only LLCP target mode for now */
+ if (dev->dep_link_up == false) {
+ kfree_skb(skb);
+ return -ENOLINK;
+ }
+
+ return nfc_llcp_data_received(dev, skb);
+}
+EXPORT_SYMBOL(nfc_tm_data_received);
+
int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
u8 *gb, size_t gb_len)
{
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 5f7aa3f632fb..5705e6dffb32 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -937,6 +937,21 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err)
return;
}
+int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
+{
+ struct nfc_llcp_local *local;
+
+ local = nfc_llcp_find_local(dev);
+ if (local == NULL)
+ return -ENODEV;
+
+ local->rx_pending = skb_get(skb);
+ del_timer(&local->link_timer);
+ queue_work(local->rx_wq, &local->rx_work);
+
+ return 0;
+}
+
void nfc_llcp_mac_is_down(struct nfc_dev *dev)
{
struct nfc_llcp_local *local;
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h
index cd9fcbe57464..c5e42b79a418 100644
--- a/net/nfc/nfc.h
+++ b/net/nfc/nfc.h
@@ -55,6 +55,7 @@ int nfc_llcp_register_device(struct nfc_dev *dev);
void nfc_llcp_unregister_device(struct nfc_dev *dev);
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
+int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
int __init nfc_llcp_init(void);
void nfc_llcp_exit(void);
@@ -90,6 +91,12 @@ static inline u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *gb_len)
return NULL;
}
+static inline int nfc_llcp_data_received(struct nfc_dev *dev,
+ struct sk_buff *skb)
+{
+ return 0;
+}
+
static inline int nfc_llcp_init(void)
{
return 0;