// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2011  Intel Corporation. All rights reserved.
 */

#define pr_fmt(fmt) "llcp: %s: " fmt, __func__

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/nfc.h>
#include <linux/sched/signal.h>

#include "nfc.h"
#include "llcp.h"

static int sock_wait_state(struct sock *sk, int state, unsigned long timeo)
{
	DECLARE_WAITQUEUE(wait, current);
	int err = 0;

	pr_debug("sk %p", sk);

	add_wait_queue(sk_sleep(sk), &wait);
	set_current_state(TASK_INTERRUPTIBLE);

	while (sk->sk_state != state) {
		if (!timeo) {
			err = -EINPROGRESS;
			break;
		}

		if (signal_pending(current)) {
			err = sock_intr_errno(timeo);
			break;
		}

		release_sock(sk);
		timeo = schedule_timeout(timeo);
		lock_sock(sk);
		set_current_state(TASK_INTERRUPTIBLE);

		err = sock_error(sk);
		if (err)
			break;
	}

	__set_current_state(TASK_RUNNING);
	remove_wait_queue(sk_sleep(sk), &wait);
	return err;
}

static struct proto llcp_sock_proto = {
	.name     = "NFC_LLCP",
	.owner    = THIS_MODULE,
	.obj_size = sizeof(struct nfc_llcp_sock),
};

static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	struct nfc_llcp_local *local;
	struct nfc_dev *dev;
	struct sockaddr_nfc_llcp llcp_addr;
	int len, ret = 0;

	if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
	    addr->sa_family != AF_NFC)
		return -EINVAL;

	pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);

	memset(&llcp_addr, 0, sizeof(llcp_addr));
	len = min_t(unsigned int, sizeof(llcp_addr), alen);
	memcpy(&llcp_addr, addr, len);

	/* This is going to be a listening socket, dsap must be 0 */
	if (llcp_addr.dsap != 0)
		return -EINVAL;

	lock_sock(sk);

	if (sk->sk_state != LLCP_CLOSED) {
		ret = -EBADFD;
		goto error;
	}

	dev = nfc_get_device(llcp_addr.dev_idx);
	if (dev == NULL) {
		ret = -ENODEV;
		goto error;
	}

	local = nfc_llcp_find_local(dev);
	if (local == NULL) {
		ret = -ENODEV;
		goto put_dev;
	}

	llcp_sock->dev = dev;
	llcp_sock->local = local;
	llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
	llcp_sock->service_name_len = min_t(unsigned int,
					    llcp_addr.service_name_len,
					    NFC_LLCP_MAX_SERVICE_NAME);
	llcp_sock->service_name = kmemdup(llcp_addr.service_name,
					  llcp_sock->service_name_len,
					  GFP_KERNEL);
	if (!llcp_sock->service_name) {
		ret = -ENOMEM;
		goto sock_llcp_put_local;
	}
	llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
	if (llcp_sock->ssap == LLCP_SAP_MAX) {
		ret = -EADDRINUSE;
		goto free_service_name;
	}

	llcp_sock->reserved_ssap = llcp_sock->ssap;

	nfc_llcp_sock_link(&local->sockets, sk);

	pr_debug("Socket bound to SAP %d\n", llcp_sock->ssap);

	sk->sk_state = LLCP_BOUND;
	nfc_put_device(dev);
	release_sock(sk);

	return 0;

free_service_name:
	kfree(llcp_sock->service_name);
	llcp_sock->service_name = NULL;

sock_llcp_put_local:
	nfc_llcp_local_put(llcp_sock->local);
	llcp_sock->local = NULL;
	llcp_sock->dev = NULL;

put_dev:
	nfc_put_device(dev);

error:
	release_sock(sk);
	return ret;
}

static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr,
			      int alen)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	struct nfc_llcp_local *local;
	struct nfc_dev *dev;
	struct sockaddr_nfc_llcp llcp_addr;
	int len, ret = 0;

	if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
	    addr->sa_family != AF_NFC)
		return -EINVAL;

	pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);

	memset(&llcp_addr, 0, sizeof(llcp_addr));
	len = min_t(unsigned int, sizeof(llcp_addr), alen);
	memcpy(&llcp_addr, addr, len);

	lock_sock(sk);

	if (sk->sk_state != LLCP_CLOSED) {
		ret = -EBADFD;
		goto error;
	}

	dev = nfc_get_device(llcp_addr.dev_idx);
	if (dev == NULL) {
		ret = -ENODEV;
		goto error;
	}

	local = nfc_llcp_find_local(dev);
	if (local == NULL) {
		ret = -ENODEV;
		goto put_dev;
	}

	llcp_sock->dev = dev;
	llcp_sock->local = local;
	llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;

	nfc_llcp_sock_link(&local->raw_sockets, sk);

	sk->sk_state = LLCP_BOUND;

put_dev:
	nfc_put_device(dev);

error:
	release_sock(sk);
	return ret;
}

static int llcp_sock_listen(struct socket *sock, int backlog)
{
	struct sock *sk = sock->sk;
	int ret = 0;

	pr_debug("sk %p backlog %d\n", sk, backlog);

	lock_sock(sk);

	if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) ||
	    sk->sk_state != LLCP_BOUND) {
		ret = -EBADFD;
		goto error;
	}

	sk->sk_max_ack_backlog = backlog;
	sk->sk_ack_backlog = 0;

	pr_debug("Socket listening\n");
	sk->sk_state = LLCP_LISTEN;

error:
	release_sock(sk);

	return ret;
}

static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname,
			       sockptr_t optval, unsigned int optlen)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	u32 opt;
	int err = 0;

	pr_debug("%p optname %d\n", sk, optname);

	if (level != SOL_NFC)
		return -ENOPROTOOPT;

	lock_sock(sk);

	switch (optname) {
	case NFC_LLCP_RW:
		if (sk->sk_state == LLCP_CONNECTED ||
		    sk->sk_state == LLCP_BOUND ||
		    sk->sk_state == LLCP_LISTEN) {
			err = -EINVAL;
			break;
		}

		err = copy_safe_from_sockptr(&opt, sizeof(opt),
					     optval, optlen);
		if (err)
			break;

		if (opt > LLCP_MAX_RW) {
			err = -EINVAL;
			break;
		}

		llcp_sock->rw = (u8) opt;

		break;

	case NFC_LLCP_MIUX:
		if (sk->sk_state == LLCP_CONNECTED ||
		    sk->sk_state == LLCP_BOUND ||
		    sk->sk_state == LLCP_LISTEN) {
			err = -EINVAL;
			break;
		}

		err = copy_safe_from_sockptr(&opt, sizeof(opt),
					     optval, optlen);
		if (err)
			break;

		if (opt > LLCP_MAX_MIUX) {
			err = -EINVAL;
			break;
		}

		llcp_sock->miux = cpu_to_be16((u16) opt);

		break;

	default:
		err = -ENOPROTOOPT;
		break;
	}

	release_sock(sk);

	pr_debug("%p rw %d miux %d\n", llcp_sock,
		 llcp_sock->rw, llcp_sock->miux);

	return err;
}

static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname,
			       char __user *optval, int __user *optlen)
{
	struct nfc_llcp_local *local;
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	int len, err = 0;
	u16 miux, remote_miu;
	u8 rw;

	pr_debug("%p optname %d\n", sk, optname);

	if (level != SOL_NFC)
		return -ENOPROTOOPT;

	if (get_user(len, optlen))
		return -EFAULT;

	local = llcp_sock->local;
	if (!local)
		return -ENODEV;

	len = min_t(u32, len, sizeof(u32));

	lock_sock(sk);

	switch (optname) {
	case NFC_LLCP_RW:
		rw = llcp_sock->rw > LLCP_MAX_RW ? local->rw : llcp_sock->rw;
		if (put_user(rw, (u32 __user *) optval))
			err = -EFAULT;

		break;

	case NFC_LLCP_MIUX:
		miux = be16_to_cpu(llcp_sock->miux) > LLCP_MAX_MIUX ?
			be16_to_cpu(local->miux) : be16_to_cpu(llcp_sock->miux);

		if (put_user(miux, (u32 __user *) optval))
			err = -EFAULT;

		break;

	case NFC_LLCP_REMOTE_MIU:
		remote_miu = llcp_sock->remote_miu > LLCP_MAX_MIU ?
				local->remote_miu : llcp_sock->remote_miu;

		if (put_user(remote_miu, (u32 __user *) optval))
			err = -EFAULT;

		break;

	case NFC_LLCP_REMOTE_LTO:
		if (put_user(local->remote_lto / 10, (u32 __user *) optval))
			err = -EFAULT;

		break;

	case NFC_LLCP_REMOTE_RW:
		if (put_user(llcp_sock->remote_rw, (u32 __user *) optval))
			err = -EFAULT;

		break;

	default:
		err = -ENOPROTOOPT;
		break;
	}

	release_sock(sk);

	if (put_user(len, optlen))
		return -EFAULT;

	return err;
}

void nfc_llcp_accept_unlink(struct sock *sk)
{
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);

	pr_debug("state %d\n", sk->sk_state);

	list_del_init(&llcp_sock->accept_queue);
	sk_acceptq_removed(llcp_sock->parent);
	llcp_sock->parent = NULL;

	sock_put(sk);
}

void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk)
{
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	struct nfc_llcp_sock *llcp_sock_parent = nfc_llcp_sock(parent);

	/* Lock will be free from unlink */
	sock_hold(sk);

	list_add_tail(&llcp_sock->accept_queue,
		      &llcp_sock_parent->accept_queue);
	llcp_sock->parent = parent;
	sk_acceptq_added(parent);
}

struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
				     struct socket *newsock)
{
	struct nfc_llcp_sock *lsk, *n, *llcp_parent;
	struct sock *sk;

	llcp_parent = nfc_llcp_sock(parent);

	list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue,
				 accept_queue) {
		sk = &lsk->sk;
		lock_sock(sk);

		if (sk->sk_state == LLCP_CLOSED) {
			release_sock(sk);
			nfc_llcp_accept_unlink(sk);
			continue;
		}

		if (sk->sk_state == LLCP_CONNECTED || !newsock) {
			list_del_init(&lsk->accept_queue);
			sock_put(sk);

			if (newsock)
				sock_graft(sk, newsock);

			release_sock(sk);

			pr_debug("Returning sk state %d\n", sk->sk_state);

			sk_acceptq_removed(parent);

			return sk;
		}

		release_sock(sk);
	}

	return NULL;
}

static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
			    struct proto_accept_arg *arg)
{
	DECLARE_WAITQUEUE(wait, current);
	struct sock *sk = sock->sk, *new_sk;
	long timeo;
	int ret = 0;

	pr_debug("parent %p\n", sk);

	lock_sock_nested(sk, SINGLE_DEPTH_NESTING);

	if (sk->sk_state != LLCP_LISTEN) {
		ret = -EBADFD;
		goto error;
	}

	timeo = sock_rcvtimeo(sk, arg->flags & O_NONBLOCK);

	/* Wait for an incoming connection. */
	add_wait_queue_exclusive(sk_sleep(sk), &wait);
	while (!(new_sk = nfc_llcp_accept_dequeue(sk, newsock))) {
		set_current_state(TASK_INTERRUPTIBLE);

		if (!timeo) {
			ret = -EAGAIN;
			break;
		}

		if (signal_pending(current)) {
			ret = sock_intr_errno(timeo);
			break;
		}

		release_sock(sk);
		timeo = schedule_timeout(timeo);
		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
	}
	__set_current_state(TASK_RUNNING);
	remove_wait_queue(sk_sleep(sk), &wait);

	if (ret)
		goto error;

	newsock->state = SS_CONNECTED;

	pr_debug("new socket %p\n", new_sk);

error:
	release_sock(sk);

	return ret;
}

static int llcp_sock_getname(struct socket *sock, struct sockaddr *uaddr,
			     int peer)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	DECLARE_SOCKADDR(struct sockaddr_nfc_llcp *, llcp_addr, uaddr);

	if (llcp_sock == NULL || llcp_sock->dev == NULL)
		return -EBADFD;

	pr_debug("%p %d %d %d\n", sk, llcp_sock->target_idx,
		 llcp_sock->dsap, llcp_sock->ssap);

	memset(llcp_addr, 0, sizeof(*llcp_addr));

	lock_sock(sk);
	if (!llcp_sock->dev) {
		release_sock(sk);
		return -EBADFD;
	}
	llcp_addr->sa_family = AF_NFC;
	llcp_addr->dev_idx = llcp_sock->dev->idx;
	llcp_addr->target_idx = llcp_sock->target_idx;
	llcp_addr->nfc_protocol = llcp_sock->nfc_protocol;
	llcp_addr->dsap = llcp_sock->dsap;
	llcp_addr->ssap = llcp_sock->ssap;
	llcp_addr->service_name_len = llcp_sock->service_name_len;
	memcpy(llcp_addr->service_name, llcp_sock->service_name,
	       llcp_addr->service_name_len);
	release_sock(sk);

	return sizeof(struct sockaddr_nfc_llcp);
}

static inline __poll_t llcp_accept_poll(struct sock *parent)
{
	struct nfc_llcp_sock *llcp_sock, *parent_sock;
	struct sock *sk;

	parent_sock = nfc_llcp_sock(parent);

	list_for_each_entry(llcp_sock, &parent_sock->accept_queue,
			    accept_queue) {
		sk = &llcp_sock->sk;

		if (sk->sk_state == LLCP_CONNECTED)
			return EPOLLIN | EPOLLRDNORM;
	}

	return 0;
}

static __poll_t llcp_sock_poll(struct file *file, struct socket *sock,
				   poll_table *wait)
{
	struct sock *sk = sock->sk;
	__poll_t mask = 0;

	pr_debug("%p\n", sk);

	sock_poll_wait(file, sock, wait);

	if (sk->sk_state == LLCP_LISTEN)
		return llcp_accept_poll(sk);

	if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
		mask |= EPOLLERR |
			(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);

	if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
		mask |= EPOLLIN | EPOLLRDNORM;

	if (sk->sk_state == LLCP_CLOSED)
		mask |= EPOLLHUP;

	if (sk->sk_shutdown & RCV_SHUTDOWN)
		mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;

	if (sk->sk_shutdown == SHUTDOWN_MASK)
		mask |= EPOLLHUP;

	if (sock_writeable(sk) && sk->sk_state == LLCP_CONNECTED)
		mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
	else
		sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);

	pr_debug("mask 0x%x\n", mask);

	return mask;
}

static int llcp_sock_release(struct socket *sock)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_local *local;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	int err = 0;

	if (!sk)
		return 0;

	pr_debug("%p\n", sk);

	local = llcp_sock->local;
	if (local == NULL) {
		err = -ENODEV;
		goto out;
	}

	lock_sock(sk);

	/* Send a DISC */
	if (sk->sk_state == LLCP_CONNECTED)
		nfc_llcp_send_disconnect(llcp_sock);

	if (sk->sk_state == LLCP_LISTEN) {
		struct nfc_llcp_sock *lsk, *n;
		struct sock *accept_sk;

		list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
					 accept_queue) {
			accept_sk = &lsk->sk;
			lock_sock(accept_sk);

			nfc_llcp_send_disconnect(lsk);
			nfc_llcp_accept_unlink(accept_sk);

			release_sock(accept_sk);
		}
	}

	if (sock->type == SOCK_RAW)
		nfc_llcp_sock_unlink(&local->raw_sockets, sk);
	else
		nfc_llcp_sock_unlink(&local->sockets, sk);

	if (llcp_sock->reserved_ssap < LLCP_SAP_MAX)
		nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);

	release_sock(sk);

out:
	sock_orphan(sk);
	sock_put(sk);

	return err;
}

static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
			     int len, int flags)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	struct sockaddr_nfc_llcp *addr = (struct sockaddr_nfc_llcp *)_addr;
	struct nfc_dev *dev;
	struct nfc_llcp_local *local;
	int ret = 0;

	pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);

	if (!addr || len < sizeof(*addr) || addr->sa_family != AF_NFC)
		return -EINVAL;

	if (addr->service_name_len == 0 && addr->dsap == 0)
		return -EINVAL;

	pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx,
		 addr->target_idx, addr->nfc_protocol);

	lock_sock(sk);

	if (sk->sk_state == LLCP_CONNECTED) {
		ret = -EISCONN;
		goto error;
	}
	if (sk->sk_state == LLCP_CONNECTING) {
		ret = -EINPROGRESS;
		goto error;
	}

	dev = nfc_get_device(addr->dev_idx);
	if (dev == NULL) {
		ret = -ENODEV;
		goto error;
	}

	local = nfc_llcp_find_local(dev);
	if (local == NULL) {
		ret = -ENODEV;
		goto put_dev;
	}

	device_lock(&dev->dev);
	if (dev->dep_link_up == false) {
		ret = -ENOLINK;
		device_unlock(&dev->dev);
		goto sock_llcp_put_local;
	}
	device_unlock(&dev->dev);

	if (local->rf_mode == NFC_RF_INITIATOR &&
	    addr->target_idx != local->target_idx) {
		ret = -ENOLINK;
		goto sock_llcp_put_local;
	}

	llcp_sock->dev = dev;
	llcp_sock->local = local;
	llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
	if (llcp_sock->ssap == LLCP_SAP_MAX) {
		ret = -ENOMEM;
		goto sock_llcp_nullify;
	}

	llcp_sock->reserved_ssap = llcp_sock->ssap;

	if (addr->service_name_len == 0)
		llcp_sock->dsap = addr->dsap;
	else
		llcp_sock->dsap = LLCP_SAP_SDP;
	llcp_sock->nfc_protocol = addr->nfc_protocol;
	llcp_sock->service_name_len = min_t(unsigned int,
					    addr->service_name_len,
					    NFC_LLCP_MAX_SERVICE_NAME);
	llcp_sock->service_name = kmemdup(addr->service_name,
					  llcp_sock->service_name_len,
					  GFP_KERNEL);
	if (!llcp_sock->service_name) {
		ret = -ENOMEM;
		goto sock_llcp_release;
	}

	nfc_llcp_sock_link(&local->connecting_sockets, sk);

	ret = nfc_llcp_send_connect(llcp_sock);
	if (ret)
		goto sock_unlink;

	sk->sk_state = LLCP_CONNECTING;

	ret = sock_wait_state(sk, LLCP_CONNECTED,
			      sock_sndtimeo(sk, flags & O_NONBLOCK));
	if (ret && ret != -EINPROGRESS)
		goto sock_unlink;

	release_sock(sk);

	return ret;

sock_unlink:
	nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
	kfree(llcp_sock->service_name);
	llcp_sock->service_name = NULL;

sock_llcp_release:
	nfc_llcp_put_ssap(local, llcp_sock->ssap);

sock_llcp_nullify:
	llcp_sock->local = NULL;
	llcp_sock->dev = NULL;

sock_llcp_put_local:
	nfc_llcp_local_put(local);

put_dev:
	nfc_put_device(dev);

error:
	release_sock(sk);
	return ret;
}

static int llcp_sock_sendmsg(struct socket *sock, struct msghdr *msg,
			     size_t len)
{
	struct sock *sk = sock->sk;
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
	int ret;

	pr_debug("sock %p sk %p", sock, sk);

	ret = sock_error(sk);
	if (ret)
		return ret;

	if (msg->msg_flags & MSG_OOB)
		return -EOPNOTSUPP;

	lock_sock(sk);

	if (!llcp_sock->local) {
		release_sock(sk);
		return -ENODEV;
	}

	if (sk->sk_type == SOCK_DGRAM) {
		if (sk->sk_state != LLCP_BOUND) {
			release_sock(sk);
			return -ENOTCONN;
		}

		DECLARE_SOCKADDR(struct sockaddr_nfc_llcp *, addr,
				 msg->msg_name);

		if (msg->msg_namelen < sizeof(*addr)) {
			release_sock(sk);
			return -EINVAL;
		}

		release_sock(sk);

		return nfc_llcp_send_ui_frame(llcp_sock, addr->dsap, addr->ssap,
					      msg, len);
	}

	if (sk->sk_state != LLCP_CONNECTED) {
		release_sock(sk);
		return -ENOTCONN;
	}

	release_sock(sk);

	return nfc_llcp_send_i_frame(llcp_sock, msg, len);
}

static int llcp_sock_recvmsg(struct socket *sock, struct msghdr *msg,
			     size_t len, int flags)
{
	struct sock *sk = sock->sk;
	unsigned int copied, rlen;
	struct sk_buff *skb, *cskb;
	int err = 0;

	pr_debug("%p %zu\n", sk, len);

	lock_sock(sk);

	if (sk->sk_state == LLCP_CLOSED &&
	    skb_queue_empty(&sk->sk_receive_queue)) {
		release_sock(sk);
		return 0;
	}

	release_sock(sk);

	if (flags & (MSG_OOB))
		return -EOPNOTSUPP;

	skb = skb_recv_datagram(sk, flags, &err);
	if (!skb) {
		pr_err("Recv datagram failed state %d %d %d",
		       sk->sk_state, err, sock_error(sk));

		if (sk->sk_shutdown & RCV_SHUTDOWN)
			return 0;

		return err;
	}

	rlen = skb->len;		/* real length of skb */
	copied = min_t(unsigned int, rlen, len);

	cskb = skb;
	if (skb_copy_datagram_msg(cskb, 0, msg, copied)) {
		if (!(flags & MSG_PEEK))
			skb_queue_head(&sk->sk_receive_queue, skb);
		return -EFAULT;
	}

	sock_recv_timestamp(msg, sk, skb);

	if (sk->sk_type == SOCK_DGRAM && msg->msg_name) {
		struct nfc_llcp_ui_cb *ui_cb = nfc_llcp_ui_skb_cb(skb);
		DECLARE_SOCKADDR(struct sockaddr_nfc_llcp *, sockaddr,
				 msg->msg_name);

		msg->msg_namelen = sizeof(struct sockaddr_nfc_llcp);

		pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap);

		memset(sockaddr, 0, sizeof(*sockaddr));
		sockaddr->sa_family = AF_NFC;
		sockaddr->nfc_protocol = NFC_PROTO_NFC_DEP;
		sockaddr->dsap = ui_cb->dsap;
		sockaddr->ssap = ui_cb->ssap;
	}

	/* Mark read part of skb as used */
	if (!(flags & MSG_PEEK)) {

		/* SOCK_STREAM: re-queue skb if it contains unreceived data */
		if (sk->sk_type == SOCK_STREAM ||
		    sk->sk_type == SOCK_DGRAM ||
		    sk->sk_type == SOCK_RAW) {
			skb_pull(skb, copied);
			if (skb->len) {
				skb_queue_head(&sk->sk_receive_queue, skb);
				goto done;
			}
		}

		kfree_skb(skb);
	}

	/* XXX Queue backlogged skbs */

done:
	/* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
	if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
		copied = rlen;

	return copied;
}

static const struct proto_ops llcp_sock_ops = {
	.family         = PF_NFC,
	.owner          = THIS_MODULE,
	.bind           = llcp_sock_bind,
	.connect        = llcp_sock_connect,
	.release        = llcp_sock_release,
	.socketpair     = sock_no_socketpair,
	.accept         = llcp_sock_accept,
	.getname        = llcp_sock_getname,
	.poll           = llcp_sock_poll,
	.ioctl          = sock_no_ioctl,
	.listen         = llcp_sock_listen,
	.shutdown       = sock_no_shutdown,
	.setsockopt     = nfc_llcp_setsockopt,
	.getsockopt     = nfc_llcp_getsockopt,
	.sendmsg        = llcp_sock_sendmsg,
	.recvmsg        = llcp_sock_recvmsg,
	.mmap           = sock_no_mmap,
};

static const struct proto_ops llcp_rawsock_ops = {
	.family         = PF_NFC,
	.owner          = THIS_MODULE,
	.bind           = llcp_raw_sock_bind,
	.connect        = sock_no_connect,
	.release        = llcp_sock_release,
	.socketpair     = sock_no_socketpair,
	.accept         = sock_no_accept,
	.getname        = llcp_sock_getname,
	.poll           = llcp_sock_poll,
	.ioctl          = sock_no_ioctl,
	.listen         = sock_no_listen,
	.shutdown       = sock_no_shutdown,
	.sendmsg        = sock_no_sendmsg,
	.recvmsg        = llcp_sock_recvmsg,
	.mmap           = sock_no_mmap,
};

static void llcp_sock_destruct(struct sock *sk)
{
	struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);

	pr_debug("%p\n", sk);

	if (sk->sk_state == LLCP_CONNECTED)
		nfc_put_device(llcp_sock->dev);

	skb_queue_purge(&sk->sk_receive_queue);

	nfc_llcp_sock_free(llcp_sock);

	if (!sock_flag(sk, SOCK_DEAD)) {
		pr_err("Freeing alive NFC LLCP socket %p\n", sk);
		return;
	}
}

struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp, int kern)
{
	struct sock *sk;
	struct nfc_llcp_sock *llcp_sock;

	sk = sk_alloc(&init_net, PF_NFC, gfp, &llcp_sock_proto, kern);
	if (!sk)
		return NULL;

	llcp_sock = nfc_llcp_sock(sk);

	sock_init_data(sock, sk);
	sk->sk_state = LLCP_CLOSED;
	sk->sk_protocol = NFC_SOCKPROTO_LLCP;
	sk->sk_type = type;
	sk->sk_destruct = llcp_sock_destruct;

	llcp_sock->ssap = 0;
	llcp_sock->dsap = LLCP_SAP_SDP;
	llcp_sock->rw = LLCP_MAX_RW + 1;
	llcp_sock->miux = cpu_to_be16(LLCP_MAX_MIUX + 1);
	llcp_sock->send_n = llcp_sock->send_ack_n = 0;
	llcp_sock->recv_n = llcp_sock->recv_ack_n = 0;
	llcp_sock->remote_ready = 1;
	llcp_sock->reserved_ssap = LLCP_SAP_MAX;
	nfc_llcp_socket_remote_param_init(llcp_sock);
	skb_queue_head_init(&llcp_sock->tx_queue);
	skb_queue_head_init(&llcp_sock->tx_pending_queue);
	INIT_LIST_HEAD(&llcp_sock->accept_queue);

	if (sock != NULL)
		sock->state = SS_UNCONNECTED;

	return sk;
}

void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
{
	kfree(sock->service_name);

	skb_queue_purge(&sock->tx_queue);
	skb_queue_purge(&sock->tx_pending_queue);

	list_del_init(&sock->accept_queue);

	sock->parent = NULL;

	nfc_llcp_local_put(sock->local);
}

static int llcp_sock_create(struct net *net, struct socket *sock,
			    const struct nfc_protocol *nfc_proto, int kern)
{
	struct sock *sk;

	pr_debug("%p\n", sock);

	if (sock->type != SOCK_STREAM &&
	    sock->type != SOCK_DGRAM &&
	    sock->type != SOCK_RAW)
		return -ESOCKTNOSUPPORT;

	if (sock->type == SOCK_RAW) {
		if (!capable(CAP_NET_RAW))
			return -EPERM;
		sock->ops = &llcp_rawsock_ops;
	} else {
		sock->ops = &llcp_sock_ops;
	}

	sk = nfc_llcp_sock_alloc(sock, sock->type, GFP_ATOMIC, kern);
	if (sk == NULL)
		return -ENOMEM;

	return 0;
}

static const struct nfc_protocol llcp_nfc_proto = {
	.id	  = NFC_SOCKPROTO_LLCP,
	.proto    = &llcp_sock_proto,
	.owner    = THIS_MODULE,
	.create   = llcp_sock_create
};

int __init nfc_llcp_sock_init(void)
{
	return nfc_proto_register(&llcp_nfc_proto);
}

void nfc_llcp_sock_exit(void)
{
	nfc_proto_unregister(&llcp_nfc_proto);
}
