static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event, struct sk_buff *skb) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); pr_debug("admin event: %x\n", event); switch (event) { case ST21NFCA_EVT_HOT_PLUG: if (info->se_info.se_active) { if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) { del_timer_sync(&info->se_info.se_active_timer); info->se_info.se_active = false; complete(&info->se_info.req_completion); } else { mod_timer(&info->se_info.se_active_timer, jiffies + msecs_to_jiffies(ST21NFCA_SE_TO_PIPES)); } } break; default: nfc_err(&hdev->ndev->dev, "Unexpected event on admin gate\n"); } kfree_skb(skb); return 0; }
void microread_remove(struct nfc_hci_dev *hdev) { struct microread_info *info = nfc_hci_get_clientdata(hdev); nfc_hci_unregister_device(hdev); nfc_hci_free_device(hdev); kfree(info); }
void pn544_hci_remove(struct nfc_hci_dev *hdev) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); nfc_hci_unregister_device(hdev); nfc_hci_free_device(hdev); kfree(info); }
void st21nfca_hci_remove(struct nfc_hci_dev *hdev) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); st21nfca_dep_deinit(hdev); nfc_hci_unregister_device(hdev); nfc_hci_free_device(hdev); kfree(info); }
static int st21nfca_hci_dep_link_up(struct nfc_hci_dev *hdev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); info->dep_info.idx = target->idx; return st21nfca_im_send_atr_req(hdev, gb, gb_len); }
/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int microread_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct microread_info *info = nfc_hci_get_clientdata(hdev); u8 control_bits; u16 crc; pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate); if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) { *skb_push(skb, 1) = 0; return nfc_hci_send_event(hdev, target->hci_reader_gate, MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF, skb->data, skb->len); } switch (target->hci_reader_gate) { case MICROREAD_GATE_ID_MREAD_ISO_A: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_ISO_A_3: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_ISO_B: control_bits = 0xCB; break; case MICROREAD_GATE_ID_MREAD_NFC_T1: control_bits = 0x1B; crc = crc_ccitt(0xffff, skb->data, skb->len); crc = ~crc; *skb_put(skb, 1) = crc & 0xff; *skb_put(skb, 1) = crc >> 8; break; case MICROREAD_GATE_ID_MREAD_NFC_T3: control_bits = 0xDB; break; default: pr_info("Abort im_transceive to invalid gate 0x%x\n", target->hci_reader_gate); return 1; } *skb_push(skb, 1) = control_bits; info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL; info->async_cb = cb; info->async_cb_context = cb_context; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, MICROREAD_CMD_MREAD_EXCHANGE, skb->data, skb->len, microread_im_transceive_cb, info); }
static int st21nfca_hci_dep_link_down(struct nfc_hci_dev *hdev) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); info->state = ST21NFCA_ST_READY; return nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DM_DISCONNECT, NULL, 0, NULL); }
static int pn544_hci_fw_download(struct nfc_hci_dev *hdev, const char *firmware_name) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); if (info->fw_download == NULL) return -ENOTSUPP; return info->fw_download(info->phy_id, firmware_name); }
static int nfc_shdlc_check_presence(struct nfc_hci_dev *hdev, struct nfc_target *target) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); if (shdlc->ops->check_presence) return shdlc->ops->check_presence(shdlc, target); return 0; }
static int nfc_shdlc_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); if (shdlc->ops->target_from_gate) return shdlc->ops->target_from_gate(shdlc, gate, target); return -EPERM; }
static void nfc_shdlc_close(struct nfc_hci_dev *hdev) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); pr_debug("\n"); nfc_shdlc_disconnect(shdlc); if (shdlc->ops->close) shdlc->ops->close(shdlc); }
static int nfc_shdlc_hci_ready(struct nfc_hci_dev *hdev) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); int r = 0; pr_debug("\n"); if (shdlc->ops->hci_ready) r = shdlc->ops->hci_ready(shdlc); return r; }
static int nfc_shdlc_data_exchange(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, struct sk_buff **res_skb) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); if (shdlc->ops->data_exchange) return shdlc->ops->data_exchange(shdlc, target, skb, res_skb); return -EPERM; }
static int nfc_shdlc_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); SHDLC_DUMP_SKB("queuing HCP packet to shdlc", skb); skb_queue_tail(&shdlc->send_q, skb); queue_work(shdlc->sm_wq, &shdlc->sm_work); return 0; }
static int nfc_shdlc_start_poll(struct nfc_hci_dev *hdev, u32 im_protocols, u32 tm_protocols) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); pr_debug("\n"); if (shdlc->ops->start_poll) return shdlc->ops->start_poll(shdlc, im_protocols, tm_protocols); return 0; }
static int nfc_shdlc_complete_target_discovered(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); pr_debug("\n"); if (shdlc->ops->complete_target_discovered) return shdlc->ops->complete_target_discovered(shdlc, gate, target); return 0; }
static void st21nfca_hci_close(struct nfc_hci_dev *hdev) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); mutex_lock(&info->info_lock); if (info->state == ST21NFCA_ST_COLD) goto out; info->phy_ops->disable(info->phy_id); info->state = ST21NFCA_ST_COLD; out: mutex_unlock(&info->info_lock); }
static int nfc_shdlc_open(struct nfc_hci_dev *hdev) { struct nfc_shdlc *shdlc = nfc_hci_get_clientdata(hdev); int r; pr_debug("\n"); if (shdlc->ops->open) { r = shdlc->ops->open(shdlc); if (r < 0) return r; } r = nfc_shdlc_connect(shdlc); if (r < 0 && shdlc->ops->close) shdlc->ops->close(shdlc); return r; }
/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__, target->hci_reader_gate, skb->len); switch (target->hci_reader_gate) { case ST21NFCA_RF_READER_F_GATE: if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK) return st21nfca_im_send_dep_req(hdev, skb); *(u8 *)skb_push(skb, 1) = 0x1a; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len, cb, cb_context); case ST21NFCA_RF_READER_14443_3_A_GATE: *(u8 *)skb_push(skb, 1) = 0x1a; /* CTR, see spec:10.2.2.1 */ return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len, cb, cb_context); case ST21NFCA_RF_READER_ISO15693_GATE: info->async_cb_type = ST21NFCA_CB_TYPE_READER_ISO15693; info->async_cb = cb; info->async_cb_context = cb_context; *(u8 *)skb_push(skb, 1) = 0x17; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, ST21NFCA_WR_XCHG_DATA, skb->data, skb->len, st21nfca_hci_data_exchange_cb, info); break; default: return 1; } }
static int st21nfca_hci_open(struct nfc_hci_dev *hdev) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); int r; mutex_lock(&info->info_lock); if (info->state != ST21NFCA_ST_COLD) { r = -EBUSY; goto out; } r = info->phy_ops->enable(info->phy_id); if (r == 0) info->state = ST21NFCA_ST_READY; out: mutex_unlock(&info->info_lock); return r; }
/* * Returns: * <= 0: driver handled the event, skb consumed * 1: driver does not handle the event, please do standard processing */ static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, struct sk_buff *skb) { int r; struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); pr_debug("hci event: %d\n", event); switch (event) { case ST21NFCA_EVT_CARD_ACTIVATED: if (gate == ST21NFCA_RF_CARD_F_GATE) info->dep_info.curr_nfc_dep_pni = 0; break; case ST21NFCA_EVT_CARD_DEACTIVATED: break; case ST21NFCA_EVT_FIELD_ON: break; case ST21NFCA_EVT_FIELD_OFF: break; case ST21NFCA_EVT_SEND_DATA: if (gate == ST21NFCA_RF_CARD_F_GATE) { r = st21nfca_tm_event_send_data(hdev, skb, gate); if (r < 0) goto exit; return 0; } else { info->dep_info.curr_nfc_dep_pni = 0; return 1; } break; default: return 1; } kfree_skb(skb); return 0; exit: return r; }
static void st21nfca_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, struct sk_buff *skb) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); u8 gate = hdev->pipes[pipe].gate; pr_debug("cmd: %x\n", cmd); switch (cmd) { case NFC_HCI_ANY_OPEN_PIPE: if (gate != ST21NFCA_APDU_READER_GATE && hdev->pipes[pipe].dest_host != NFC_HCI_UICC_HOST_ID) info->se_info.count_pipes++; if (info->se_info.count_pipes == info->se_info.expected_pipes) { del_timer_sync(&info->se_info.se_active_timer); info->se_info.se_active = false; info->se_info.count_pipes = 0; complete(&info->se_info.req_completion); } break; } }
static void microread_close(struct nfc_hci_dev *hdev) { struct microread_info *info = nfc_hci_get_clientdata(hdev); info->phy_ops->disable(info->phy_id); }
/* * Returns: * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); pr_debug(DRIVER_DESC ": %s for gate=%d\n", __func__, target->hci_reader_gate); switch (target->hci_reader_gate) { case NFC_HCI_RF_READER_A_GATE: if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { /* * It seems that pn544 is inverting key and UID for * MIFARE authentication commands. */ if (skb->len == MIFARE_CMD_LEN && (skb->data[0] == MIFARE_CMD_AUTH_KEY_A || skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) { u8 uid[MIFARE_UID_LEN]; u8 *data = skb->data + MIFARE_CMD_HEADER; memcpy(uid, data + MIFARE_KEY_LEN, MIFARE_UID_LEN); memmove(data + MIFARE_UID_LEN, data, MIFARE_KEY_LEN); memcpy(data, uid, MIFARE_UID_LEN); } return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_MIFARE_CMD, skb->data, skb->len, cb, cb_context); } else return 1; case PN544_RF_READER_F_GATE: *skb_push(skb, 1) = 0; *skb_push(skb, 1) = 0; info->async_cb_type = PN544_CB_TYPE_READER_F; info->async_cb = cb; info->async_cb_context = cb_context; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_FELICA_RAW, skb->data, skb->len, pn544_hci_data_exchange_cb, info); case PN544_RF_READER_JEWEL_GATE: return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_JEWEL_RAW_CMD, skb->data, skb->len, cb, cb_context); case PN544_RF_READER_NFCIP1_INITIATOR_GATE: *skb_push(skb, 1) = 0; return nfc_hci_send_event(hdev, target->hci_reader_gate, PN544_HCI_EVT_SND_DATA, skb->data, skb->len); default: return 1; } }
static int microread_open(struct nfc_hci_dev *hdev) { struct microread_info *info = nfc_hci_get_clientdata(hdev); return info->phy_ops->enable(info->phy_id); }
static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); struct sk_buff *skb; u8 param; u8 white_list[2]; int wl_size = 0; int r; if (info->se_status->is_uicc_present) white_list[wl_size++] = NFC_HCI_UICC_HOST_ID; if (info->se_status->is_ese_present) white_list[wl_size++] = ST21NFCA_ESE_HOST_ID; if (wl_size) { r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, NFC_HCI_ADMIN_WHITELIST, (u8 *) &white_list, wl_size); if (r < 0) return r; } /* Set NFC_MODE in device management gate to enable */ r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_NFC_MODE, &skb); if (r < 0) return r; param = skb->data[0]; kfree_skb(skb); if (param == 0) { param = 1; r = nfc_hci_set_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_NFC_MODE, ¶m, 1); if (r < 0) return r; } r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); if (r < 0) return r; r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, NFC_HCI_ID_MGMT_VERSION_SW, &skb); if (r < 0) return r; if (skb->len != FULL_VERSION_LEN) { kfree_skb(skb); return -EINVAL; } print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ", DUMP_PREFIX_NONE, 16, 1, skb->data, FULL_VERSION_LEN, false); kfree_skb(skb); return 0; }
static int st21nfca_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); return info->phy_ops->write(info->phy_id, skb); }