/* Called by ST when receive data is available */ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) { struct nfcwilink *drv = priv_data; int rc; if (!skb) return -EFAULT; if (!drv) { kfree_skb(skb); return -EFAULT; } nfc_dev_dbg(&drv->pdev->dev, "receive entry, len %d", skb->len); /* strip the ST header (apart for the chnl byte, which is not received in the hdr) */ skb_pull(skb, (NFCWILINK_HDR_LEN-1)); if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) { nfcwilink_fw_download_receive(drv, skb); return 0; } skb->dev = (void *) drv->ndev; /* Forward skb to NCI core layer */ rc = nci_recv_frame(skb); if (rc < 0) { nfc_dev_err(&drv->pdev->dev, "nci_recv_frame failed %d", rc); return rc; } return 0; }
int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, void *data, int count) { struct sk_buff *skb; skb = nci_skb_alloc(priv->ndev, count, GFP_ATOMIC); if (!skb) return -ENOMEM; memcpy(skb_put(skb, count), data, count); nci_recv_frame(priv->ndev, skb); return count; }
static void llt_ndlc_rcv_queue(struct llt_ndlc *ndlc) { struct sk_buff *skb; u8 pcb; unsigned long time_sent; if (ndlc->rcv_q.qlen) pr_debug("rcvQlen=%d\n", ndlc->rcv_q.qlen); while ((skb = skb_dequeue(&ndlc->rcv_q)) != NULL) { pcb = skb->data[0]; skb_pull(skb, 1); if ((pcb & PCB_TYPE_MASK) == PCB_TYPE_SUPERVISOR) { switch (pcb & PCB_SYNC_MASK) { case PCB_SYNC_ACK: del_timer_sync(&ndlc->t1_timer); del_timer_sync(&ndlc->t2_timer); ndlc->t2_active = false; ndlc->t1_active = false; break; case PCB_SYNC_NACK: llt_ndlc_requeue_data_pending(ndlc); llt_ndlc_send_queue(ndlc); /* start timer t1 for ndlc aknowledge */ time_sent = jiffies; ndlc->t1_active = true; mod_timer(&ndlc->t1_timer, time_sent + msecs_to_jiffies(NDLC_TIMER_T1)); break; case PCB_SYNC_WAIT: time_sent = jiffies; ndlc->t1_active = true; mod_timer(&ndlc->t1_timer, time_sent + msecs_to_jiffies(NDLC_TIMER_T1_WAIT)); break; default: pr_err("UNKNOWN Packet Control Byte=%d\n", pcb); kfree_skb(skb); break; } } else { nci_recv_frame(ndlc->ndev, skb); } } }
/* -- Default recv handler -- */ static int nci_uart_default_recv(struct nci_uart *nu, struct sk_buff *skb) { return nci_recv_frame(nu->ndev, skb); }
static irqreturn_t nxp_nci_i2c_irq_thread_fn(int irq, void *phy_id) { struct nxp_nci_i2c_phy *phy = phy_id; struct i2c_client *client; struct nxp_nci_info *info; struct sk_buff *skb = NULL; int r = 0; if (!phy || !phy->ndev) goto exit_irq_none; client = phy->i2c_dev; if (!client || irq != client->irq) goto exit_irq_none; info = nci_get_drvdata(phy->ndev); if (!info) goto exit_irq_none; mutex_lock(&info->info_lock); if (phy->hard_fault != 0) goto exit_irq_handled; switch (info->mode) { case NXP_NCI_MODE_NCI: r = nxp_nci_i2c_nci_read(phy, &skb); break; case NXP_NCI_MODE_FW: r = nxp_nci_i2c_fw_read(phy, &skb); break; case NXP_NCI_MODE_COLD: r = -EREMOTEIO; break; } if (r == -EREMOTEIO) { phy->hard_fault = r; skb = NULL; } else if (r < 0) { nfc_err(&client->dev, "Read failed with error %d\n", r); goto exit_irq_handled; } switch (info->mode) { case NXP_NCI_MODE_NCI: nci_recv_frame(phy->ndev, skb); break; case NXP_NCI_MODE_FW: nxp_nci_fw_recv_frame(phy->ndev, skb); break; case NXP_NCI_MODE_COLD: break; } exit_irq_handled: mutex_unlock(&info->info_lock); return IRQ_HANDLED; exit_irq_none: WARN_ON_ONCE(1); return IRQ_NONE; }