static int nfcwilink_send(struct sk_buff *skb) { struct nci_dev *ndev = (struct nci_dev *)skb->dev; struct nfcwilink *drv = nci_get_drvdata(ndev); struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000}; long len; nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len); if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { kfree_skb(skb); return -EINVAL; } hdr.len = cpu_to_le16(skb->len); memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); /* Insert skb to shared transport layer's transmit queue. * Freeing skb memory is taken care in shared transport layer, * so don't free skb memory here. */ len = drv->st_write(skb); if (len < 0) { kfree_skb(skb); nfc_dev_err(&drv->pdev->dev, "st_write failed %ld", len); return -EFAULT; } return 0; }
void st21nfcb_nci_remove(struct nci_dev *ndev) { struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); nci_unregister_device(ndev); nci_free_device(ndev); kfree(info); }
int st_nci_vendor_cmds_init(struct nci_dev *ndev) { struct st_nci_info *info = nci_get_drvdata(ndev); init_completion(&info->vendor_info.req_completion); return nfc_set_vendor_cmds(ndev->nfc_dev, st_nci_vendor_cmds, sizeof(st_nci_vendor_cmds)); }
void st_nci_remove(struct nci_dev *ndev) { struct st_nci_info *info = nci_get_drvdata(ndev); ndlc_close(info->ndlc); nci_unregister_device(ndev); nci_free_device(ndev); }
static int st21nfcb_nci_close(struct nci_dev *ndev) { struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); if (!test_and_clear_bit(ST21NFCB_NCI_RUNNING, &info->flags)) return 0; ndlc_close(info->ndlc); return 0; }
static int st21nfcb_nci_send(struct nci_dev *ndev, struct sk_buff *skb) { struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); skb->dev = (void *)ndev; if (!test_bit(ST21NFCB_NCI_RUNNING, &info->flags)) return -EBUSY; return ndlc_send(info->ndlc, skb); }
static int nfcmrvl_nci_close(struct nci_dev *ndev) { struct nfcmrvl_private *priv = nci_get_drvdata(ndev); if (!test_and_clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) return 0; priv->if_ops->nci_close(priv); return 0; }
static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb) { struct nfcmrvl_private *priv = nci_get_drvdata(ndev); nfc_info(priv->dev, "send entry, len %d\n", skb->len); skb->dev = (void *)ndev; if (!test_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) return -EBUSY; return priv->if_ops->nci_send(priv, skb); }
static int st_nci_hci_loopback(struct nfc_dev *dev, void *data, size_t data_len) { int r; struct sk_buff *msg; struct nci_dev *ndev = nfc_get_drvdata(dev); struct st_nci_info *info = nci_get_drvdata(ndev); if (data_len <= 0) return -EPROTO; reinit_completion(&info->vendor_info.req_completion); info->vendor_info.rx_skb = NULL; r = nci_hci_send_event(ndev, NCI_HCI_LOOPBACK_GATE, ST_NCI_EVT_POST_DATA, data, data_len); if (r != data_len) { r = -EPROTO; goto exit; } wait_for_completion_interruptible(&info->vendor_info.req_completion); if (!info->vendor_info.rx_skb || info->vendor_info.rx_skb->len != data_len) { r = -EPROTO; goto exit; } msg = nfc_vendor_cmd_alloc_reply_skb(ndev->nfc_dev, ST_NCI_VENDOR_OUI, HCI_LOOPBACK, info->vendor_info.rx_skb->len); if (!msg) { r = -ENOMEM; goto free_skb; } if (nla_put(msg, NFC_ATTR_VENDOR_DATA, info->vendor_info.rx_skb->len, info->vendor_info.rx_skb->data)) { kfree_skb(msg); r = -ENOBUFS; goto free_skb; } r = nfc_vendor_cmd_reply(msg); free_skb: kfree_skb(info->vendor_info.rx_skb); exit: return r; }
static int st21nfcb_nci_open(struct nci_dev *ndev) { struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); int r; if (test_and_set_bit(ST21NFCB_NCI_RUNNING, &info->flags)) return 0; r = ndlc_open(info->ndlc); if (r) clear_bit(ST21NFCB_NCI_RUNNING, &info->flags); return r; }
void st_nci_hci_loopback_event_received(struct nci_dev *ndev, u8 event, struct sk_buff *skb) { struct st_nci_info *info = nci_get_drvdata(ndev); switch (event) { case ST_NCI_EVT_POST_DATA: info->vendor_info.rx_skb = skb; break; default: nfc_err(&ndev->nfc_dev->dev, "Unexpected event on loopback gate\n"); } complete(&info->vendor_info.req_completion); }
static int nfcmrvl_nci_open(struct nci_dev *ndev) { struct nfcmrvl_private *priv = nci_get_drvdata(ndev); int err; if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) return 0; err = priv->if_ops->nci_open(priv); if (err) clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags); return err; }
static int nfcwilink_close(struct nci_dev *ndev) { struct nfcwilink *drv = nci_get_drvdata(ndev); int rc; if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags)) return 0; rc = st_unregister(&nfcwilink_proto); if (rc) nfc_err(&drv->pdev->dev, "st_unregister failed %d\n", rc); drv->st_write = NULL; return rc; }
static void nfcmrvl_tx_complete(struct urb *urb) { struct sk_buff *skb = urb->context; struct nci_dev *ndev = (struct nci_dev *)skb->dev; struct nfcmrvl_private *priv = nci_get_drvdata(ndev); struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data; nfc_info(priv->dev, "urb %p status %d count %d", urb, urb->status, urb->actual_length); spin_lock(&drv_data->txlock); drv_data->tx_in_flight--; spin_unlock(&drv_data->txlock); kfree(urb->setup_packet); kfree_skb(skb); }
static int st_nci_factory_mode(struct nfc_dev *dev, void *data, size_t data_len) { struct nci_dev *ndev = nfc_get_drvdata(dev); struct st_nci_info *info = nci_get_drvdata(ndev); if (data_len != 1) return -EINVAL; pr_debug("factory mode: %x\n", ((u8 *)data)[0]); switch (((u8 *)data)[0]) { case ST_NCI_FACTORY_MODE_ON: test_and_set_bit(ST_NCI_FACTORY_MODE, &info->flags); break; case ST_NCI_FACTORY_MODE_OFF: clear_bit(ST_NCI_FACTORY_MODE, &info->flags); break; default: return -EINVAL; } return 0; }
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; }
static int nfcwilink_open(struct nci_dev *ndev) { struct nfcwilink *drv = nci_get_drvdata(ndev); unsigned long comp_ret; int rc; nfc_dev_dbg(&drv->pdev->dev, "open entry"); if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) { rc = -EBUSY; goto exit; } nfcwilink_proto.priv_data = drv; init_completion(&drv->completed); drv->st_register_cb_status = -EINPROGRESS; rc = st_register(&nfcwilink_proto); if (rc < 0) { if (rc == -EINPROGRESS) { comp_ret = wait_for_completion_timeout( &drv->completed, msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", comp_ret); if (comp_ret == 0) { /* timeout */ rc = -ETIMEDOUT; goto clear_exit; } else if (drv->st_register_cb_status != 0) { rc = drv->st_register_cb_status; nfc_dev_err(&drv->pdev->dev, "st_register_cb failed %d", rc); goto clear_exit; } } else { nfc_dev_err(&drv->pdev->dev, "st_register failed %d", rc); goto clear_exit; } } /* st_register MUST fill the write callback */ BUG_ON(nfcwilink_proto.write == NULL); drv->st_write = nfcwilink_proto.write; if (nfcwilink_download_fw(drv)) { nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d", rc); /* open should succeed, even if the FW download failed */ } goto exit; clear_exit: clear_bit(NFCWILINK_RUNNING, &drv->flags); exit: return rc; }