static irqreturn_t microread_i2c_irq_thread_fn(int irq, void *phy_id) { struct microread_i2c_phy *phy = phy_id; struct sk_buff *skb = NULL; int r; if (!phy || irq != phy->i2c_dev->irq) { WARN_ON_ONCE(1); return IRQ_NONE; } if (phy->hard_fault != 0) return IRQ_HANDLED; r = microread_i2c_read(phy, &skb); if (r == -EREMOTEIO) { phy->hard_fault = r; nfc_hci_recv_frame(phy->hdev, NULL); return IRQ_HANDLED; } else if ((r == -ENOMEM) || (r == -EBADMSG)) { return IRQ_HANDLED; } nfc_hci_recv_frame(phy->hdev, skb); return IRQ_HANDLED; }
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); } }
/* * Receive validated frames from lower layer. skb contains HCI payload only. * Handle according to algorithm at spec:10.8.2 */ static void nfc_shdlc_rcv_i_frame(struct nfc_shdlc *shdlc, struct sk_buff *skb, int ns, int nr) { int x_ns = ns; int y_nr = nr; pr_debug("recvd I-frame %d, remote waiting frame %d\n", ns, nr); if (shdlc->state != SHDLC_CONNECTED) goto exit; if (x_ns != shdlc->nr) { nfc_shdlc_send_s_frame(shdlc, S_FRAME_REJ, shdlc->nr); goto exit; } if (shdlc->t1_active == false) { shdlc->t1_active = true; mod_timer(&shdlc->t1_timer, msecs_to_jiffies(SHDLC_T1_VALUE_MS(shdlc->w))); pr_debug("(re)Start T1(send ack)\n"); } if (skb->len) { nfc_hci_recv_frame(shdlc->hdev, skb); skb = NULL; } shdlc->nr = (shdlc->nr + 1) % 8; if (nfc_shdlc_x_lt_y_lteq_z(shdlc->dnr, y_nr, shdlc->ns)) { nfc_shdlc_reset_t2(shdlc, y_nr); shdlc->dnr = y_nr; } exit: if (skb) kfree_skb(skb); }