162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __LOCAL_ST21NFCA_H_ 762306a36Sopenharmony_ci#define __LOCAL_ST21NFCA_H_ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <net/nfc/hci.h> 1062306a36Sopenharmony_ci#include <linux/skbuff.h> 1162306a36Sopenharmony_ci#include <linux/workqueue.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define HCI_MODE 0 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* framing in HCI mode */ 1662306a36Sopenharmony_ci#define ST21NFCA_SOF_EOF_LEN 2 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Almost every time value is 0 */ 1962306a36Sopenharmony_ci#define ST21NFCA_HCI_LLC_LEN 1 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* Size in worst case : 2262306a36Sopenharmony_ci * In normal case CRC len = 2 but byte stuffing 2362306a36Sopenharmony_ci * may appear in case one CRC byte = ST21NFCA_SOF_EOF 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci#define ST21NFCA_HCI_LLC_CRC 4 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define ST21NFCA_HCI_LLC_LEN_CRC (ST21NFCA_SOF_EOF_LEN + \ 2862306a36Sopenharmony_ci ST21NFCA_HCI_LLC_LEN + \ 2962306a36Sopenharmony_ci ST21NFCA_HCI_LLC_CRC) 3062306a36Sopenharmony_ci#define ST21NFCA_HCI_LLC_MIN_SIZE (1 + ST21NFCA_HCI_LLC_LEN_CRC) 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* Worst case when adding byte stuffing between each byte */ 3362306a36Sopenharmony_ci#define ST21NFCA_HCI_LLC_MAX_PAYLOAD 29 3462306a36Sopenharmony_ci#define ST21NFCA_HCI_LLC_MAX_SIZE (ST21NFCA_HCI_LLC_LEN_CRC + 1 + \ 3562306a36Sopenharmony_ci ST21NFCA_HCI_LLC_MAX_PAYLOAD) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* Reader RF commands */ 3862306a36Sopenharmony_ci#define ST21NFCA_WR_XCHG_DATA 0x10 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define ST21NFCA_DEVICE_MGNT_GATE 0x01 4162306a36Sopenharmony_ci#define ST21NFCA_RF_READER_F_GATE 0x14 4262306a36Sopenharmony_ci#define ST21NFCA_RF_CARD_F_GATE 0x24 4362306a36Sopenharmony_ci#define ST21NFCA_APDU_READER_GATE 0xf0 4462306a36Sopenharmony_ci#define ST21NFCA_CONNECTIVITY_GATE 0x41 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* 4762306a36Sopenharmony_ci * ref ISO7816-3 chap 8.1. the initial character TS is followed by a 4862306a36Sopenharmony_ci * sequence of at most 32 characters. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci#define ST21NFCA_ESE_MAX_LENGTH 33 5162306a36Sopenharmony_ci#define ST21NFCA_ESE_HOST_ID 0xc0 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define DRIVER_DESC "HCI NFC driver for ST21NFCA" 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define ST21NFCA_HCI_MODE 0 5662306a36Sopenharmony_ci#define ST21NFCA_NUM_DEVICES 256 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define ST21NFCA_VENDOR_OUI 0x0080E1 /* STMicroelectronics */ 5962306a36Sopenharmony_ci#define ST21NFCA_FACTORY_MODE 2 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistruct st21nfca_se_status { 6262306a36Sopenharmony_ci bool is_ese_present; 6362306a36Sopenharmony_ci bool is_uicc_present; 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cienum st21nfca_state { 6762306a36Sopenharmony_ci ST21NFCA_ST_COLD, 6862306a36Sopenharmony_ci ST21NFCA_ST_READY, 6962306a36Sopenharmony_ci}; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/** 7262306a36Sopenharmony_ci * enum nfc_vendor_cmds - supported nfc vendor commands 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * @FACTORY_MODE: Allow to set the driver into a mode where no secure element 7562306a36Sopenharmony_ci * are activated. It does not consider any NFC_ATTR_VENDOR_DATA. 7662306a36Sopenharmony_ci * @HCI_CLEAR_ALL_PIPES: Allow to execute a HCI clear all pipes command. 7762306a36Sopenharmony_ci * It does not consider any NFC_ATTR_VENDOR_DATA. 7862306a36Sopenharmony_ci * @HCI_DM_PUT_DATA: Allow to configure specific CLF registry as for example 7962306a36Sopenharmony_ci * RF trimmings or low level drivers configurations (I2C, SPI, SWP). 8062306a36Sopenharmony_ci * @HCI_DM_UPDATE_AID: Allow to configure an AID routing into the CLF routing 8162306a36Sopenharmony_ci * table following RF technology, CLF mode or protocol. 8262306a36Sopenharmony_ci * @HCI_DM_GET_INFO: Allow to retrieve CLF information. 8362306a36Sopenharmony_ci * @HCI_DM_GET_DATA: Allow to retrieve CLF configurable data such as low 8462306a36Sopenharmony_ci * level drivers configurations or RF trimmings. 8562306a36Sopenharmony_ci * @HCI_DM_LOAD: Allow to load a firmware into the CLF. A complete 8662306a36Sopenharmony_ci * packet can be more than 8KB. 8762306a36Sopenharmony_ci * @HCI_DM_RESET: Allow to run a CLF reset in order to "commit" CLF 8862306a36Sopenharmony_ci * configuration changes without CLF power off. 8962306a36Sopenharmony_ci * @HCI_GET_PARAM: Allow to retrieve an HCI CLF parameter (for example the 9062306a36Sopenharmony_ci * white list). 9162306a36Sopenharmony_ci * @HCI_DM_FIELD_GENERATOR: Allow to generate different kind of RF 9262306a36Sopenharmony_ci * technology. When using this command to anti-collision is done. 9362306a36Sopenharmony_ci * @HCI_LOOPBACK: Allow to echo a command and test the Dh to CLF 9462306a36Sopenharmony_ci * connectivity. 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_cienum nfc_vendor_cmds { 9762306a36Sopenharmony_ci FACTORY_MODE, 9862306a36Sopenharmony_ci HCI_CLEAR_ALL_PIPES, 9962306a36Sopenharmony_ci HCI_DM_PUT_DATA, 10062306a36Sopenharmony_ci HCI_DM_UPDATE_AID, 10162306a36Sopenharmony_ci HCI_DM_GET_INFO, 10262306a36Sopenharmony_ci HCI_DM_GET_DATA, 10362306a36Sopenharmony_ci HCI_DM_LOAD, 10462306a36Sopenharmony_ci HCI_DM_RESET, 10562306a36Sopenharmony_ci HCI_GET_PARAM, 10662306a36Sopenharmony_ci HCI_DM_FIELD_GENERATOR, 10762306a36Sopenharmony_ci HCI_LOOPBACK, 10862306a36Sopenharmony_ci}; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistruct st21nfca_vendor_info { 11162306a36Sopenharmony_ci struct completion req_completion; 11262306a36Sopenharmony_ci struct sk_buff *rx_skb; 11362306a36Sopenharmony_ci}; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistruct st21nfca_dep_info { 11662306a36Sopenharmony_ci struct sk_buff *tx_pending; 11762306a36Sopenharmony_ci struct work_struct tx_work; 11862306a36Sopenharmony_ci u8 curr_nfc_dep_pni; 11962306a36Sopenharmony_ci u32 idx; 12062306a36Sopenharmony_ci u8 to; 12162306a36Sopenharmony_ci u8 did; 12262306a36Sopenharmony_ci u8 bsi; 12362306a36Sopenharmony_ci u8 bri; 12462306a36Sopenharmony_ci u8 lri; 12562306a36Sopenharmony_ci} __packed; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistruct st21nfca_se_info { 12862306a36Sopenharmony_ci u8 atr[ST21NFCA_ESE_MAX_LENGTH]; 12962306a36Sopenharmony_ci struct completion req_completion; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci struct timer_list bwi_timer; 13262306a36Sopenharmony_ci int wt_timeout; /* in msecs */ 13362306a36Sopenharmony_ci bool bwi_active; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci struct timer_list se_active_timer; 13662306a36Sopenharmony_ci bool se_active; 13762306a36Sopenharmony_ci int expected_pipes; 13862306a36Sopenharmony_ci int count_pipes; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci bool xch_error; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci se_io_cb_t cb; 14362306a36Sopenharmony_ci void *cb_context; 14462306a36Sopenharmony_ci struct work_struct timeout_work; 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistruct st21nfca_hci_info { 14862306a36Sopenharmony_ci const struct nfc_phy_ops *phy_ops; 14962306a36Sopenharmony_ci void *phy_id; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci struct nfc_hci_dev *hdev; 15262306a36Sopenharmony_ci struct st21nfca_se_status *se_status; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci enum st21nfca_state state; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci struct mutex info_lock; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci int async_cb_type; 15962306a36Sopenharmony_ci data_exchange_cb_t async_cb; 16062306a36Sopenharmony_ci void *async_cb_context; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci struct st21nfca_dep_info dep_info; 16362306a36Sopenharmony_ci struct st21nfca_se_info se_info; 16462306a36Sopenharmony_ci struct st21nfca_vendor_info vendor_info; 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ciint st21nfca_hci_probe(void *phy_id, const struct nfc_phy_ops *phy_ops, 16862306a36Sopenharmony_ci char *llc_name, int phy_headroom, int phy_tailroom, 16962306a36Sopenharmony_ci int phy_payload, struct nfc_hci_dev **hdev, 17062306a36Sopenharmony_ci struct st21nfca_se_status *se_status); 17162306a36Sopenharmony_civoid st21nfca_hci_remove(struct nfc_hci_dev *hdev); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ciint st21nfca_dep_event_received(struct nfc_hci_dev *hdev, 17462306a36Sopenharmony_ci u8 event, struct sk_buff *skb); 17562306a36Sopenharmony_ciint st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ciint st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len); 17862306a36Sopenharmony_ciint st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb); 17962306a36Sopenharmony_civoid st21nfca_dep_init(struct nfc_hci_dev *hdev); 18062306a36Sopenharmony_civoid st21nfca_dep_deinit(struct nfc_hci_dev *hdev); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ciint st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, 18362306a36Sopenharmony_ci u8 event, struct sk_buff *skb); 18462306a36Sopenharmony_ciint st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, 18562306a36Sopenharmony_ci u8 event, struct sk_buff *skb); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ciint st21nfca_hci_discover_se(struct nfc_hci_dev *hdev); 18862306a36Sopenharmony_ciint st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx); 18962306a36Sopenharmony_ciint st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx); 19062306a36Sopenharmony_ciint st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, 19162306a36Sopenharmony_ci u8 *apdu, size_t apdu_length, 19262306a36Sopenharmony_ci se_io_cb_t cb, void *cb_context); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_civoid st21nfca_se_init(struct nfc_hci_dev *hdev); 19562306a36Sopenharmony_civoid st21nfca_se_deinit(struct nfc_hci_dev *hdev); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ciint st21nfca_hci_loopback_event_received(struct nfc_hci_dev *ndev, u8 event, 19862306a36Sopenharmony_ci struct sk_buff *skb); 19962306a36Sopenharmony_ciint st21nfca_vendor_cmds_init(struct nfc_hci_dev *ndev); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci#endif /* __LOCAL_ST21NFCA_H_ */ 202