18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef __LOCAL_ST21NFCA_H_ 78c2ecf20Sopenharmony_ci#define __LOCAL_ST21NFCA_H_ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <net/nfc/hci.h> 108c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 118c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define HCI_MODE 0 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* framing in HCI mode */ 168c2ecf20Sopenharmony_ci#define ST21NFCA_SOF_EOF_LEN 2 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* Almost every time value is 0 */ 198c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_LLC_LEN 1 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* Size in worst case : 228c2ecf20Sopenharmony_ci * In normal case CRC len = 2 but byte stuffing 238c2ecf20Sopenharmony_ci * may appear in case one CRC byte = ST21NFCA_SOF_EOF 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_LLC_CRC 4 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_LLC_LEN_CRC (ST21NFCA_SOF_EOF_LEN + \ 288c2ecf20Sopenharmony_ci ST21NFCA_HCI_LLC_LEN + \ 298c2ecf20Sopenharmony_ci ST21NFCA_HCI_LLC_CRC) 308c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_LLC_MIN_SIZE (1 + ST21NFCA_HCI_LLC_LEN_CRC) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* Worst case when adding byte stuffing between each byte */ 338c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_LLC_MAX_PAYLOAD 29 348c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_LLC_MAX_SIZE (ST21NFCA_HCI_LLC_LEN_CRC + 1 + \ 358c2ecf20Sopenharmony_ci ST21NFCA_HCI_LLC_MAX_PAYLOAD) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* Reader RF commands */ 388c2ecf20Sopenharmony_ci#define ST21NFCA_WR_XCHG_DATA 0x10 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define ST21NFCA_DEVICE_MGNT_GATE 0x01 418c2ecf20Sopenharmony_ci#define ST21NFCA_RF_READER_F_GATE 0x14 428c2ecf20Sopenharmony_ci#define ST21NFCA_RF_CARD_F_GATE 0x24 438c2ecf20Sopenharmony_ci#define ST21NFCA_APDU_READER_GATE 0xf0 448c2ecf20Sopenharmony_ci#define ST21NFCA_CONNECTIVITY_GATE 0x41 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* 478c2ecf20Sopenharmony_ci * ref ISO7816-3 chap 8.1. the initial character TS is followed by a 488c2ecf20Sopenharmony_ci * sequence of at most 32 characters. 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci#define ST21NFCA_ESE_MAX_LENGTH 33 518c2ecf20Sopenharmony_ci#define ST21NFCA_ESE_HOST_ID 0xc0 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define DRIVER_DESC "HCI NFC driver for ST21NFCA" 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define ST21NFCA_HCI_MODE 0 568c2ecf20Sopenharmony_ci#define ST21NFCA_NUM_DEVICES 256 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define ST21NFCA_VENDOR_OUI 0x0080E1 /* STMicroelectronics */ 598c2ecf20Sopenharmony_ci#define ST21NFCA_FACTORY_MODE 2 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistruct st21nfca_se_status { 628c2ecf20Sopenharmony_ci bool is_ese_present; 638c2ecf20Sopenharmony_ci bool is_uicc_present; 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cienum st21nfca_state { 678c2ecf20Sopenharmony_ci ST21NFCA_ST_COLD, 688c2ecf20Sopenharmony_ci ST21NFCA_ST_READY, 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/** 728c2ecf20Sopenharmony_ci * enum nfc_vendor_cmds - supported nfc vendor commands 738c2ecf20Sopenharmony_ci * 748c2ecf20Sopenharmony_ci * @FACTORY_MODE: Allow to set the driver into a mode where no secure element 758c2ecf20Sopenharmony_ci * are activated. It does not consider any NFC_ATTR_VENDOR_DATA. 768c2ecf20Sopenharmony_ci * @HCI_CLEAR_ALL_PIPES: Allow to execute a HCI clear all pipes command. 778c2ecf20Sopenharmony_ci * It does not consider any NFC_ATTR_VENDOR_DATA. 788c2ecf20Sopenharmony_ci * @HCI_DM_PUT_DATA: Allow to configure specific CLF registry as for example 798c2ecf20Sopenharmony_ci * RF trimmings or low level drivers configurations (I2C, SPI, SWP). 808c2ecf20Sopenharmony_ci * @HCI_DM_UPDATE_AID: Allow to configure an AID routing into the CLF routing 818c2ecf20Sopenharmony_ci * table following RF technology, CLF mode or protocol. 828c2ecf20Sopenharmony_ci * @HCI_DM_GET_INFO: Allow to retrieve CLF information. 838c2ecf20Sopenharmony_ci * @HCI_DM_GET_DATA: Allow to retrieve CLF configurable data such as low 848c2ecf20Sopenharmony_ci * level drivers configurations or RF trimmings. 858c2ecf20Sopenharmony_ci * @HCI_DM_LOAD: Allow to load a firmware into the CLF. A complete 868c2ecf20Sopenharmony_ci * packet can be more than 8KB. 878c2ecf20Sopenharmony_ci * @HCI_DM_RESET: Allow to run a CLF reset in order to "commit" CLF 888c2ecf20Sopenharmony_ci * configuration changes without CLF power off. 898c2ecf20Sopenharmony_ci * @HCI_GET_PARAM: Allow to retrieve an HCI CLF parameter (for example the 908c2ecf20Sopenharmony_ci * white list). 918c2ecf20Sopenharmony_ci * @HCI_DM_FIELD_GENERATOR: Allow to generate different kind of RF 928c2ecf20Sopenharmony_ci * technology. When using this command to anti-collision is done. 938c2ecf20Sopenharmony_ci * @HCI_LOOPBACK: Allow to echo a command and test the Dh to CLF 948c2ecf20Sopenharmony_ci * connectivity. 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_cienum nfc_vendor_cmds { 978c2ecf20Sopenharmony_ci FACTORY_MODE, 988c2ecf20Sopenharmony_ci HCI_CLEAR_ALL_PIPES, 998c2ecf20Sopenharmony_ci HCI_DM_PUT_DATA, 1008c2ecf20Sopenharmony_ci HCI_DM_UPDATE_AID, 1018c2ecf20Sopenharmony_ci HCI_DM_GET_INFO, 1028c2ecf20Sopenharmony_ci HCI_DM_GET_DATA, 1038c2ecf20Sopenharmony_ci HCI_DM_LOAD, 1048c2ecf20Sopenharmony_ci HCI_DM_RESET, 1058c2ecf20Sopenharmony_ci HCI_GET_PARAM, 1068c2ecf20Sopenharmony_ci HCI_DM_FIELD_GENERATOR, 1078c2ecf20Sopenharmony_ci HCI_LOOPBACK, 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistruct st21nfca_vendor_info { 1118c2ecf20Sopenharmony_ci struct completion req_completion; 1128c2ecf20Sopenharmony_ci struct sk_buff *rx_skb; 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistruct st21nfca_dep_info { 1168c2ecf20Sopenharmony_ci struct sk_buff *tx_pending; 1178c2ecf20Sopenharmony_ci struct work_struct tx_work; 1188c2ecf20Sopenharmony_ci u8 curr_nfc_dep_pni; 1198c2ecf20Sopenharmony_ci u32 idx; 1208c2ecf20Sopenharmony_ci u8 to; 1218c2ecf20Sopenharmony_ci u8 did; 1228c2ecf20Sopenharmony_ci u8 bsi; 1238c2ecf20Sopenharmony_ci u8 bri; 1248c2ecf20Sopenharmony_ci u8 lri; 1258c2ecf20Sopenharmony_ci} __packed; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistruct st21nfca_se_info { 1288c2ecf20Sopenharmony_ci u8 atr[ST21NFCA_ESE_MAX_LENGTH]; 1298c2ecf20Sopenharmony_ci struct completion req_completion; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci struct timer_list bwi_timer; 1328c2ecf20Sopenharmony_ci int wt_timeout; /* in msecs */ 1338c2ecf20Sopenharmony_ci bool bwi_active; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci struct timer_list se_active_timer; 1368c2ecf20Sopenharmony_ci bool se_active; 1378c2ecf20Sopenharmony_ci int expected_pipes; 1388c2ecf20Sopenharmony_ci int count_pipes; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci bool xch_error; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci se_io_cb_t cb; 1438c2ecf20Sopenharmony_ci void *cb_context; 1448c2ecf20Sopenharmony_ci struct work_struct timeout_work; 1458c2ecf20Sopenharmony_ci}; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistruct st21nfca_hci_info { 1488c2ecf20Sopenharmony_ci struct nfc_phy_ops *phy_ops; 1498c2ecf20Sopenharmony_ci void *phy_id; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci struct nfc_hci_dev *hdev; 1528c2ecf20Sopenharmony_ci struct st21nfca_se_status *se_status; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci enum st21nfca_state state; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci struct mutex info_lock; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci int async_cb_type; 1598c2ecf20Sopenharmony_ci data_exchange_cb_t async_cb; 1608c2ecf20Sopenharmony_ci void *async_cb_context; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci struct st21nfca_dep_info dep_info; 1638c2ecf20Sopenharmony_ci struct st21nfca_se_info se_info; 1648c2ecf20Sopenharmony_ci struct st21nfca_vendor_info vendor_info; 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ciint st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, 1688c2ecf20Sopenharmony_ci char *llc_name, int phy_headroom, int phy_tailroom, 1698c2ecf20Sopenharmony_ci int phy_payload, struct nfc_hci_dev **hdev, 1708c2ecf20Sopenharmony_ci struct st21nfca_se_status *se_status); 1718c2ecf20Sopenharmony_civoid st21nfca_hci_remove(struct nfc_hci_dev *hdev); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ciint st21nfca_dep_event_received(struct nfc_hci_dev *hdev, 1748c2ecf20Sopenharmony_ci u8 event, struct sk_buff *skb); 1758c2ecf20Sopenharmony_ciint st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ciint st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len); 1788c2ecf20Sopenharmony_ciint st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb); 1798c2ecf20Sopenharmony_civoid st21nfca_dep_init(struct nfc_hci_dev *hdev); 1808c2ecf20Sopenharmony_civoid st21nfca_dep_deinit(struct nfc_hci_dev *hdev); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ciint st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, 1838c2ecf20Sopenharmony_ci u8 event, struct sk_buff *skb); 1848c2ecf20Sopenharmony_ciint st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, 1858c2ecf20Sopenharmony_ci u8 event, struct sk_buff *skb); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ciint st21nfca_hci_discover_se(struct nfc_hci_dev *hdev); 1888c2ecf20Sopenharmony_ciint st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx); 1898c2ecf20Sopenharmony_ciint st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx); 1908c2ecf20Sopenharmony_ciint st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, 1918c2ecf20Sopenharmony_ci u8 *apdu, size_t apdu_length, 1928c2ecf20Sopenharmony_ci se_io_cb_t cb, void *cb_context); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_civoid st21nfca_se_init(struct nfc_hci_dev *hdev); 1958c2ecf20Sopenharmony_civoid st21nfca_se_deinit(struct nfc_hci_dev *hdev); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ciint st21nfca_hci_loopback_event_received(struct nfc_hci_dev *ndev, u8 event, 1988c2ecf20Sopenharmony_ci struct sk_buff *skb); 1998c2ecf20Sopenharmony_ciint st21nfca_vendor_cmds_init(struct nfc_hci_dev *ndev); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci#endif /* __LOCAL_ST21NFCA_H_ */ 202