/* There is no sequence with UI frames */
        skb_pull(skb, LLCP_HEADER_SIZE);
-       if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
-               pr_err("receive queue is full\n");
+       if (!sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
+               /*
+                * UI frames will be freed from the socket layer, so we
+                * need to keep them alive until someone receives them.
+                */
+               skb_get(skb);
+       } else {
+               pr_err("Receive queue is full\n");
                kfree_skb(skb);
        }
 
                        pr_err("Received out of sequence I PDU\n");
 
                skb_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
-               if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
-                       pr_err("receive queue is full\n");
+               if (!sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
+                       /*
+                        * I frames will be freed from the socket layer, so we
+                        * need to keep them alive until someone receives them.
+                        */
+                       skb_get(skb);
+               } else {
+                       pr_err("Receive queue is full\n");
                        kfree_skb(skb);
                }
        }
        local->rx_pending = NULL;
 }
 
+static void __nfc_llcp_recv(struct nfc_llcp_local *local, struct sk_buff *skb)
+{
+       local->rx_pending = skb;
+       del_timer(&local->link_timer);
+       schedule_work(&local->rx_work);
+}
+
 void nfc_llcp_recv(void *data, struct sk_buff *skb, int err)
 {
        struct nfc_llcp_local *local = (struct nfc_llcp_local *) data;
                return;
        }
 
-       local->rx_pending = skb_get(skb);
-       del_timer(&local->link_timer);
-       schedule_work(&local->rx_work);
+       __nfc_llcp_recv(local, skb);
 }
 
 int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
        if (local == NULL)
                return -ENODEV;
 
-       local->rx_pending = skb_get(skb);
-       del_timer(&local->link_timer);
-       schedule_work(&local->rx_work);
+       __nfc_llcp_recv(local, skb);
 
        return 0;
 }