diff options
-rw-r--r-- | drivers/nfc/st21nfca/Makefile | 2 | ||||
-rw-r--r-- | drivers/nfc/st21nfca/i2c.c | 17 | ||||
-rw-r--r-- | drivers/nfc/st21nfca/st21nfca.c | 134 | ||||
-rw-r--r-- | drivers/nfc/st21nfca/st21nfca.h | 21 | ||||
-rw-r--r-- | drivers/nfc/st21nfca/st21nfca_se.c | 390 | ||||
-rw-r--r-- | drivers/nfc/st21nfca/st21nfca_se.h | 63 | ||||
-rw-r--r-- | include/linux/platform_data/st21nfca.h | 2 |
7 files changed, 608 insertions, 21 deletions
diff --git a/drivers/nfc/st21nfca/Makefile b/drivers/nfc/st21nfca/Makefile index 7d688f97aa27..97edab4bbdf8 100644 --- a/drivers/nfc/st21nfca/Makefile +++ b/drivers/nfc/st21nfca/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for ST21NFCA HCI based NFC driver | 2 | # Makefile for ST21NFCA HCI based NFC driver |
3 | # | 3 | # |
4 | 4 | ||
5 | st21nfca_hci-objs = st21nfca.o st21nfca_dep.o | 5 | st21nfca_hci-objs = st21nfca.o st21nfca_dep.o st21nfca_se.o |
6 | obj-$(CONFIG_NFC_ST21NFCA) += st21nfca_hci.o | 6 | obj-$(CONFIG_NFC_ST21NFCA) += st21nfca_hci.o |
7 | 7 | ||
8 | st21nfca_i2c-objs = i2c.o | 8 | st21nfca_i2c-objs = i2c.o |
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 82b82dbd2997..a32143951616 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c | |||
@@ -74,6 +74,8 @@ struct st21nfca_i2c_phy { | |||
74 | unsigned int gpio_ena; | 74 | unsigned int gpio_ena; |
75 | unsigned int irq_polarity; | 75 | unsigned int irq_polarity; |
76 | 76 | ||
77 | struct st21nfca_se_status se_status; | ||
78 | |||
77 | struct sk_buff *pending_skb; | 79 | struct sk_buff *pending_skb; |
78 | int current_read_len; | 80 | int current_read_len; |
79 | /* | 81 | /* |
@@ -537,6 +539,11 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) | |||
537 | 539 | ||
538 | phy->irq_polarity = irq_get_trigger_type(client->irq); | 540 | phy->irq_polarity = irq_get_trigger_type(client->irq); |
539 | 541 | ||
542 | phy->se_status.is_ese_present = | ||
543 | of_property_read_bool(pp, "ese-present"); | ||
544 | phy->se_status.is_uicc_present = | ||
545 | of_property_read_bool(pp, "uicc-present"); | ||
546 | |||
540 | return 0; | 547 | return 0; |
541 | } | 548 | } |
542 | #else | 549 | #else |
@@ -571,6 +578,9 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) | |||
571 | } | 578 | } |
572 | } | 579 | } |
573 | 580 | ||
581 | phy->se_status.is_ese_present = pdata->is_ese_present; | ||
582 | phy->se_status.is_uicc_present = pdata->is_uicc_present; | ||
583 | |||
574 | return 0; | 584 | return 0; |
575 | } | 585 | } |
576 | 586 | ||
@@ -638,8 +648,11 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, | |||
638 | } | 648 | } |
639 | 649 | ||
640 | return st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, | 650 | return st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, |
641 | ST21NFCA_FRAME_HEADROOM, ST21NFCA_FRAME_TAILROOM, | 651 | ST21NFCA_FRAME_HEADROOM, |
642 | ST21NFCA_HCI_LLC_MAX_PAYLOAD, &phy->hdev); | 652 | ST21NFCA_FRAME_TAILROOM, |
653 | ST21NFCA_HCI_LLC_MAX_PAYLOAD, | ||
654 | &phy->hdev, | ||
655 | &phy->se_status); | ||
643 | } | 656 | } |
644 | 657 | ||
645 | static int st21nfca_hci_i2c_remove(struct i2c_client *client) | 658 | static int st21nfca_hci_i2c_remove(struct i2c_client *client) |
diff --git a/drivers/nfc/st21nfca/st21nfca.c b/drivers/nfc/st21nfca/st21nfca.c index 7cb7ce47d2af..24d3d240d5f4 100644 --- a/drivers/nfc/st21nfca/st21nfca.c +++ b/drivers/nfc/st21nfca/st21nfca.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "st21nfca.h" | 24 | #include "st21nfca.h" |
25 | #include "st21nfca_dep.h" | 25 | #include "st21nfca_dep.h" |
26 | #include "st21nfca_se.h" | ||
26 | 27 | ||
27 | #define DRIVER_DESC "HCI NFC driver for ST21NFCA" | 28 | #define DRIVER_DESC "HCI NFC driver for ST21NFCA" |
28 | 29 | ||
@@ -62,7 +63,6 @@ | |||
62 | #define ST21NFCA_RF_CARD_F_DATARATE 0x08 | 63 | #define ST21NFCA_RF_CARD_F_DATARATE 0x08 |
63 | #define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01 | 64 | #define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01 |
64 | 65 | ||
65 | #define ST21NFCA_DEVICE_MGNT_GATE 0x01 | ||
66 | #define ST21NFCA_DEVICE_MGNT_PIPE 0x02 | 66 | #define ST21NFCA_DEVICE_MGNT_PIPE 0x02 |
67 | 67 | ||
68 | #define ST21NFCA_DM_GETINFO 0x13 | 68 | #define ST21NFCA_DM_GETINFO 0x13 |
@@ -78,6 +78,11 @@ | |||
78 | 78 | ||
79 | #define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/ | 79 | #define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/ |
80 | 80 | ||
81 | #define ST21NFCA_EVT_HOT_PLUG 0x03 | ||
82 | #define ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80) | ||
83 | |||
84 | #define ST21NFCA_SE_TO_PIPES 2000 | ||
85 | |||
81 | static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES); | 86 | static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES); |
82 | 87 | ||
83 | static struct nfc_hci_gate st21nfca_gates[] = { | 88 | static struct nfc_hci_gate st21nfca_gates[] = { |
@@ -92,6 +97,10 @@ static struct nfc_hci_gate st21nfca_gates[] = { | |||
92 | {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, | 97 | {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, |
93 | {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, | 98 | {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, |
94 | {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE}, | 99 | {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE}, |
100 | |||
101 | /* Secure element pipes are created by secure element host */ | ||
102 | {ST21NFCA_CONNECTIVITY_GATE, NFC_HCI_DO_NOT_CREATE_PIPE}, | ||
103 | {ST21NFCA_APDU_READER_GATE, NFC_HCI_DO_NOT_CREATE_PIPE}, | ||
95 | }; | 104 | }; |
96 | 105 | ||
97 | struct st21nfca_pipe_info { | 106 | struct st21nfca_pipe_info { |
@@ -136,7 +145,8 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
136 | * Pipe can be closed and need to be open. | 145 | * Pipe can be closed and need to be open. |
137 | */ | 146 | */ |
138 | r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, | 147 | r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, |
139 | ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE); | 148 | ST21NFCA_DEVICE_MGNT_GATE, |
149 | ST21NFCA_DEVICE_MGNT_PIPE); | ||
140 | if (r < 0) | 150 | if (r < 0) |
141 | goto free_info; | 151 | goto free_info; |
142 | 152 | ||
@@ -167,17 +177,28 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
167 | * - destination gid (1byte) | 177 | * - destination gid (1byte) |
168 | */ | 178 | */ |
169 | info = (struct st21nfca_pipe_info *) skb_pipe_info->data; | 179 | info = (struct st21nfca_pipe_info *) skb_pipe_info->data; |
180 | if (info->dst_gate_id == ST21NFCA_APDU_READER_GATE && | ||
181 | info->src_host_id != ST21NFCA_ESE_HOST_ID) { | ||
182 | pr_err("Unexpected apdu_reader pipe on host %x\n", | ||
183 | info->src_host_id); | ||
184 | continue; | ||
185 | } | ||
186 | |||
170 | for (j = 0; (j < ARRAY_SIZE(st21nfca_gates)) && | 187 | for (j = 0; (j < ARRAY_SIZE(st21nfca_gates)) && |
171 | (st21nfca_gates[j].gate != info->dst_gate_id); | 188 | (st21nfca_gates[j].gate != info->dst_gate_id) ; j++) |
172 | j++) | ||
173 | ; | 189 | ; |
174 | 190 | ||
175 | if (j < ARRAY_SIZE(st21nfca_gates) && | 191 | if (j < ARRAY_SIZE(st21nfca_gates) && |
176 | st21nfca_gates[j].gate == info->dst_gate_id && | 192 | st21nfca_gates[j].gate == info->dst_gate_id && |
177 | ST21NFCA_DM_IS_PIPE_OPEN(info->pipe_state)) { | 193 | ST21NFCA_DM_IS_PIPE_OPEN(info->pipe_state)) { |
178 | st21nfca_gates[j].pipe = pipe_info[2]; | 194 | st21nfca_gates[j].pipe = pipe_info[2]; |
195 | |||
179 | hdev->gate2pipe[st21nfca_gates[j].gate] = | 196 | hdev->gate2pipe[st21nfca_gates[j].gate] = |
180 | st21nfca_gates[j].pipe; | 197 | st21nfca_gates[j].pipe; |
198 | hdev->pipes[st21nfca_gates[j].pipe].gate = | ||
199 | st21nfca_gates[j].gate; | ||
200 | hdev->pipes[st21nfca_gates[j].pipe].dest_host = | ||
201 | info->src_host_id; | ||
181 | } | 202 | } |
182 | } | 203 | } |
183 | 204 | ||
@@ -187,7 +208,7 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
187 | */ | 208 | */ |
188 | if (skb_pipe_list->len + 3 < ARRAY_SIZE(st21nfca_gates)) { | 209 | if (skb_pipe_list->len + 3 < ARRAY_SIZE(st21nfca_gates)) { |
189 | for (i = skb_pipe_list->len + 3; | 210 | for (i = skb_pipe_list->len + 3; |
190 | i < ARRAY_SIZE(st21nfca_gates); i++) { | 211 | i < ARRAY_SIZE(st21nfca_gates) - 2; i++) { |
191 | r = nfc_hci_connect_gate(hdev, | 212 | r = nfc_hci_connect_gate(hdev, |
192 | NFC_HCI_HOST_CONTROLLER_ID, | 213 | NFC_HCI_HOST_CONTROLLER_ID, |
193 | st21nfca_gates[i].gate, | 214 | st21nfca_gates[i].gate, |
@@ -244,16 +265,33 @@ out: | |||
244 | 265 | ||
245 | static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) | 266 | static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) |
246 | { | 267 | { |
268 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
247 | struct sk_buff *skb; | 269 | struct sk_buff *skb; |
248 | 270 | ||
249 | u8 param; | 271 | u8 param; |
272 | u8 white_list[2]; | ||
273 | int wl_size = 0; | ||
250 | int r; | 274 | int r; |
251 | 275 | ||
252 | param = NFC_HCI_UICC_HOST_ID; | 276 | if (info->se_status->is_ese_present && |
253 | r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, | 277 | info->se_status->is_uicc_present) { |
254 | NFC_HCI_ADMIN_WHITELIST, ¶m, 1); | 278 | white_list[wl_size++] = NFC_HCI_UICC_HOST_ID; |
255 | if (r < 0) | 279 | white_list[wl_size++] = ST21NFCA_ESE_HOST_ID; |
256 | return r; | 280 | } else if (!info->se_status->is_ese_present && |
281 | info->se_status->is_uicc_present) { | ||
282 | white_list[wl_size++] = NFC_HCI_UICC_HOST_ID; | ||
283 | } else if (info->se_status->is_ese_present && | ||
284 | !info->se_status->is_uicc_present) { | ||
285 | white_list[wl_size++] = ST21NFCA_ESE_HOST_ID; | ||
286 | } | ||
287 | |||
288 | if (wl_size) { | ||
289 | r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, | ||
290 | NFC_HCI_ADMIN_WHITELIST, | ||
291 | (u8 *) &white_list, wl_size); | ||
292 | if (r < 0) | ||
293 | return r; | ||
294 | } | ||
257 | 295 | ||
258 | /* Set NFC_MODE in device management gate to enable */ | 296 | /* Set NFC_MODE in device management gate to enable */ |
259 | r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, | 297 | r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, |
@@ -821,19 +859,79 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev, | |||
821 | } | 859 | } |
822 | } | 860 | } |
823 | 861 | ||
862 | static void st21nfca_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, | ||
863 | struct sk_buff *skb) | ||
864 | { | ||
865 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
866 | u8 gate = hdev->pipes[pipe].gate; | ||
867 | |||
868 | pr_debug("cmd: %x\n", cmd); | ||
869 | |||
870 | switch (cmd) { | ||
871 | case NFC_HCI_ANY_OPEN_PIPE: | ||
872 | if (gate != ST21NFCA_APDU_READER_GATE && | ||
873 | hdev->pipes[pipe].dest_host != NFC_HCI_UICC_HOST_ID) | ||
874 | info->se_info.count_pipes++; | ||
875 | |||
876 | if (info->se_info.count_pipes == info->se_info.expected_pipes) { | ||
877 | del_timer_sync(&info->se_info.se_active_timer); | ||
878 | info->se_info.se_active = false; | ||
879 | info->se_info.count_pipes = 0; | ||
880 | complete(&info->se_info.req_completion); | ||
881 | } | ||
882 | break; | ||
883 | } | ||
884 | } | ||
885 | |||
886 | static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event, | ||
887 | struct sk_buff *skb) | ||
888 | { | ||
889 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
890 | |||
891 | pr_debug("admin event: %x\n", event); | ||
892 | |||
893 | switch (event) { | ||
894 | case ST21NFCA_EVT_HOT_PLUG: | ||
895 | if (info->se_info.se_active) { | ||
896 | if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) { | ||
897 | del_timer_sync(&info->se_info.se_active_timer); | ||
898 | info->se_info.se_active = false; | ||
899 | complete(&info->se_info.req_completion); | ||
900 | } else { | ||
901 | mod_timer(&info->se_info.se_active_timer, | ||
902 | jiffies + | ||
903 | msecs_to_jiffies(ST21NFCA_SE_TO_PIPES)); | ||
904 | } | ||
905 | } | ||
906 | break; | ||
907 | } | ||
908 | kfree_skb(skb); | ||
909 | return 0; | ||
910 | } | ||
911 | |||
824 | /* | 912 | /* |
825 | * Returns: | 913 | * Returns: |
826 | * <= 0: driver handled the event, skb consumed | 914 | * <= 0: driver handled the event, skb consumed |
827 | * 1: driver does not handle the event, please do standard processing | 915 | * 1: driver does not handle the event, please do standard processing |
828 | */ | 916 | */ |
829 | static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, | 917 | static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, |
830 | u8 event, struct sk_buff *skb) | 918 | u8 event, struct sk_buff *skb) |
831 | { | 919 | { |
920 | u8 gate = hdev->pipes[pipe].gate; | ||
921 | u8 host = hdev->pipes[pipe].dest_host; | ||
922 | |||
832 | pr_debug("hci event: %d gate: %x\n", event, gate); | 923 | pr_debug("hci event: %d gate: %x\n", event, gate); |
833 | 924 | ||
834 | switch (gate) { | 925 | switch (gate) { |
926 | case NFC_HCI_ADMIN_GATE: | ||
927 | return st21nfca_admin_event_received(hdev, event, skb); | ||
835 | case ST21NFCA_RF_CARD_F_GATE: | 928 | case ST21NFCA_RF_CARD_F_GATE: |
836 | return st21nfca_dep_event_received(hdev, event, skb); | 929 | return st21nfca_dep_event_received(hdev, event, skb); |
930 | case ST21NFCA_CONNECTIVITY_GATE: | ||
931 | return st21nfca_connectivity_event_received(hdev, host, | ||
932 | event, skb); | ||
933 | case ST21NFCA_APDU_READER_GATE: | ||
934 | return st21nfca_apdu_reader_event_received(hdev, event, skb); | ||
837 | default: | 935 | default: |
838 | return 1; | 936 | return 1; |
839 | } | 937 | } |
@@ -855,11 +953,17 @@ static struct nfc_hci_ops st21nfca_hci_ops = { | |||
855 | .tm_send = st21nfca_hci_tm_send, | 953 | .tm_send = st21nfca_hci_tm_send, |
856 | .check_presence = st21nfca_hci_check_presence, | 954 | .check_presence = st21nfca_hci_check_presence, |
857 | .event_received = st21nfca_hci_event_received, | 955 | .event_received = st21nfca_hci_event_received, |
956 | .cmd_received = st21nfca_hci_cmd_received, | ||
957 | .discover_se = st21nfca_hci_discover_se, | ||
958 | .enable_se = st21nfca_hci_enable_se, | ||
959 | .disable_se = st21nfca_hci_disable_se, | ||
960 | .se_io = st21nfca_hci_se_io, | ||
858 | }; | 961 | }; |
859 | 962 | ||
860 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | 963 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, |
861 | char *llc_name, int phy_headroom, int phy_tailroom, | 964 | char *llc_name, int phy_headroom, int phy_tailroom, |
862 | int phy_payload, struct nfc_hci_dev **hdev) | 965 | int phy_payload, struct nfc_hci_dev **hdev, |
966 | struct st21nfca_se_status *se_status) | ||
863 | { | 967 | { |
864 | struct st21nfca_hci_info *info; | 968 | struct st21nfca_hci_info *info; |
865 | int r = 0; | 969 | int r = 0; |
@@ -919,6 +1023,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | |||
919 | goto err_alloc_hdev; | 1023 | goto err_alloc_hdev; |
920 | } | 1024 | } |
921 | 1025 | ||
1026 | info->se_status = se_status; | ||
1027 | |||
922 | nfc_hci_set_clientdata(info->hdev, info); | 1028 | nfc_hci_set_clientdata(info->hdev, info); |
923 | 1029 | ||
924 | r = nfc_hci_register_device(info->hdev); | 1030 | r = nfc_hci_register_device(info->hdev); |
@@ -927,6 +1033,7 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | |||
927 | 1033 | ||
928 | *hdev = info->hdev; | 1034 | *hdev = info->hdev; |
929 | st21nfca_dep_init(info->hdev); | 1035 | st21nfca_dep_init(info->hdev); |
1036 | st21nfca_se_init(info->hdev); | ||
930 | 1037 | ||
931 | return 0; | 1038 | return 0; |
932 | 1039 | ||
@@ -945,6 +1052,7 @@ void st21nfca_hci_remove(struct nfc_hci_dev *hdev) | |||
945 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | 1052 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
946 | 1053 | ||
947 | st21nfca_dep_deinit(hdev); | 1054 | st21nfca_dep_deinit(hdev); |
1055 | st21nfca_se_deinit(hdev); | ||
948 | nfc_hci_unregister_device(hdev); | 1056 | nfc_hci_unregister_device(hdev); |
949 | nfc_hci_free_device(hdev); | 1057 | nfc_hci_free_device(hdev); |
950 | kfree(info); | 1058 | kfree(info); |
diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h index 7c2a85292230..15a78d330a9f 100644 --- a/drivers/nfc/st21nfca/st21nfca.h +++ b/drivers/nfc/st21nfca/st21nfca.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <net/nfc/hci.h> | 20 | #include <net/nfc/hci.h> |
21 | 21 | ||
22 | #include "st21nfca_dep.h" | 22 | #include "st21nfca_dep.h" |
23 | #include "st21nfca_se.h" | ||
23 | 24 | ||
24 | #define HCI_MODE 0 | 25 | #define HCI_MODE 0 |
25 | 26 | ||
@@ -51,9 +52,15 @@ | |||
51 | 52 | ||
52 | #define ST21NFCA_NUM_DEVICES 256 | 53 | #define ST21NFCA_NUM_DEVICES 256 |
53 | 54 | ||
55 | struct st21nfca_se_status { | ||
56 | bool is_ese_present; | ||
57 | bool is_uicc_present; | ||
58 | }; | ||
59 | |||
54 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | 60 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, |
55 | char *llc_name, int phy_headroom, int phy_tailroom, | 61 | char *llc_name, int phy_headroom, int phy_tailroom, |
56 | int phy_payload, struct nfc_hci_dev **hdev); | 62 | int phy_payload, struct nfc_hci_dev **hdev, |
63 | struct st21nfca_se_status *se_status); | ||
57 | void st21nfca_hci_remove(struct nfc_hci_dev *hdev); | 64 | void st21nfca_hci_remove(struct nfc_hci_dev *hdev); |
58 | 65 | ||
59 | enum st21nfca_state { | 66 | enum st21nfca_state { |
@@ -66,6 +73,7 @@ struct st21nfca_hci_info { | |||
66 | void *phy_id; | 73 | void *phy_id; |
67 | 74 | ||
68 | struct nfc_hci_dev *hdev; | 75 | struct nfc_hci_dev *hdev; |
76 | struct st21nfca_se_status *se_status; | ||
69 | 77 | ||
70 | enum st21nfca_state state; | 78 | enum st21nfca_state state; |
71 | 79 | ||
@@ -76,13 +84,16 @@ struct st21nfca_hci_info { | |||
76 | void *async_cb_context; | 84 | void *async_cb_context; |
77 | 85 | ||
78 | struct st21nfca_dep_info dep_info; | 86 | struct st21nfca_dep_info dep_info; |
87 | struct st21nfca_se_info se_info; | ||
79 | }; | 88 | }; |
80 | 89 | ||
81 | /* Reader RF commands */ | 90 | /* Reader RF commands */ |
82 | #define ST21NFCA_WR_XCHG_DATA 0x10 | 91 | #define ST21NFCA_WR_XCHG_DATA 0x10 |
83 | |||
84 | #define ST21NFCA_RF_READER_F_GATE 0x14 | ||
85 | 92 | ||
86 | #define ST21NFCA_RF_CARD_F_GATE 0x24 | 93 | #define ST21NFCA_DEVICE_MGNT_GATE 0x01 |
94 | #define ST21NFCA_RF_READER_F_GATE 0x14 | ||
95 | #define ST21NFCA_RF_CARD_F_GATE 0x24 | ||
96 | #define ST21NFCA_APDU_READER_GATE 0xf0 | ||
97 | #define ST21NFCA_CONNECTIVITY_GATE 0x41 | ||
87 | 98 | ||
88 | #endif /* __LOCAL_ST21NFCA_H_ */ | 99 | #endif /* __LOCAL_ST21NFCA_H_ */ |
diff --git a/drivers/nfc/st21nfca/st21nfca_se.c b/drivers/nfc/st21nfca/st21nfca_se.c new file mode 100644 index 000000000000..9b93d3904ab5 --- /dev/null +++ b/drivers/nfc/st21nfca/st21nfca_se.c | |||
@@ -0,0 +1,390 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <net/nfc/hci.h> | ||
18 | |||
19 | #include "st21nfca.h" | ||
20 | #include "st21nfca_se.h" | ||
21 | |||
22 | #define ST21NFCA_EVT_UICC_ACTIVATE 0x10 | ||
23 | #define ST21NFCA_EVT_UICC_DEACTIVATE 0x13 | ||
24 | #define ST21NFCA_EVT_SE_HARD_RESET 0x20 | ||
25 | #define ST21NFCA_EVT_SE_SOFT_RESET 0x11 | ||
26 | #define ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER 0x21 | ||
27 | #define ST21NFCA_EVT_SE_ACTIVATE 0x22 | ||
28 | #define ST21NFCA_EVT_SE_DEACTIVATE 0x23 | ||
29 | |||
30 | #define ST21NFCA_EVT_TRANSMIT_DATA 0x10 | ||
31 | #define ST21NFCA_EVT_WTX_REQUEST 0x11 | ||
32 | |||
33 | #define ST21NFCA_EVT_CONNECTIVITY 0x10 | ||
34 | #define ST21NFCA_EVT_TRANSACTION 0x12 | ||
35 | |||
36 | #define ST21NFCA_ESE_HOST_ID 0xc0 | ||
37 | |||
38 | #define ST21NFCA_SE_TO_HOT_PLUG 1000 | ||
39 | /* Connectivity pipe only */ | ||
40 | #define ST21NFCA_SE_COUNT_PIPE_UICC 0x01 | ||
41 | /* Connectivity + APDU Reader pipe */ | ||
42 | #define ST21NFCA_SE_COUNT_PIPE_EMBEDDED 0x02 | ||
43 | |||
44 | #define ST21NFCA_SE_MODE_OFF 0x00 | ||
45 | #define ST21NFCA_SE_MODE_ON 0x01 | ||
46 | |||
47 | #define ST21NFCA_PARAM_ATR 0x01 | ||
48 | #define ST21NFCA_ATR_DEFAULT_BWI 0x04 | ||
49 | |||
50 | /* | ||
51 | * WT = 2^BWI/10[s], convert into msecs and add a secure | ||
52 | * room by increasing by 2 this timeout | ||
53 | */ | ||
54 | #define ST21NFCA_BWI_TO_TIMEOUT(x) ((1 << x) * 200) | ||
55 | #define ST21NFCA_ATR_GET_Y_FROM_TD(x) (x >> 4) | ||
56 | |||
57 | /* If TA is present bit 0 is set */ | ||
58 | #define ST21NFCA_ATR_TA_PRESENT(x) (x & 0x01) | ||
59 | /* If TB is present bit 1 is set */ | ||
60 | #define ST21NFCA_ATR_TB_PRESENT(x) (x & 0x02) | ||
61 | |||
62 | static u8 st21nfca_se_get_bwi(struct nfc_hci_dev *hdev) | ||
63 | { | ||
64 | int i; | ||
65 | u8 td; | ||
66 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
67 | |||
68 | /* Bits 8 to 5 of the first TB for T=1 encode BWI from zero to nine */ | ||
69 | for (i = 1; i < ST21NFCA_ESE_MAX_LENGTH; i++) { | ||
70 | td = ST21NFCA_ATR_GET_Y_FROM_TD(info->se_info.atr[i]); | ||
71 | if (ST21NFCA_ATR_TA_PRESENT(td)) | ||
72 | i++; | ||
73 | if (ST21NFCA_ATR_TB_PRESENT(td)) { | ||
74 | i++; | ||
75 | return info->se_info.atr[i] >> 4; | ||
76 | } | ||
77 | } | ||
78 | return ST21NFCA_ATR_DEFAULT_BWI; | ||
79 | } | ||
80 | |||
81 | static void st21nfca_se_get_atr(struct nfc_hci_dev *hdev) | ||
82 | { | ||
83 | int r; | ||
84 | struct sk_buff *skb; | ||
85 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
86 | |||
87 | r = nfc_hci_get_param(hdev, ST21NFCA_APDU_READER_GATE, | ||
88 | ST21NFCA_PARAM_ATR, &skb); | ||
89 | if (r < 0) | ||
90 | return; | ||
91 | |||
92 | if (skb->len <= ST21NFCA_ESE_MAX_LENGTH) { | ||
93 | memcpy(info->se_info.atr, skb->data, skb->len); | ||
94 | info->se_info.wt_timeout = | ||
95 | ST21NFCA_BWI_TO_TIMEOUT(st21nfca_se_get_bwi(hdev)); | ||
96 | } | ||
97 | kfree_skb(skb); | ||
98 | } | ||
99 | |||
100 | static int st21nfca_hci_control_se(struct nfc_hci_dev *hdev, u32 se_idx, | ||
101 | u8 state) | ||
102 | { | ||
103 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
104 | int r; | ||
105 | struct sk_buff *sk_host_list; | ||
106 | u8 se_event, host_id; | ||
107 | |||
108 | switch (se_idx) { | ||
109 | case NFC_HCI_UICC_HOST_ID: | ||
110 | se_event = (state == ST21NFCA_SE_MODE_ON ? | ||
111 | ST21NFCA_EVT_UICC_ACTIVATE : | ||
112 | ST21NFCA_EVT_UICC_DEACTIVATE); | ||
113 | |||
114 | info->se_info.count_pipes = 0; | ||
115 | info->se_info.expected_pipes = ST21NFCA_SE_COUNT_PIPE_UICC; | ||
116 | break; | ||
117 | case ST21NFCA_ESE_HOST_ID: | ||
118 | se_event = (state == ST21NFCA_SE_MODE_ON ? | ||
119 | ST21NFCA_EVT_SE_ACTIVATE : | ||
120 | ST21NFCA_EVT_SE_DEACTIVATE); | ||
121 | |||
122 | info->se_info.count_pipes = 0; | ||
123 | info->se_info.expected_pipes = ST21NFCA_SE_COUNT_PIPE_EMBEDDED; | ||
124 | break; | ||
125 | default: | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Wait for an EVT_HOT_PLUG in order to | ||
131 | * retrieve a relevant host list. | ||
132 | */ | ||
133 | reinit_completion(&info->se_info.req_completion); | ||
134 | r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, se_event, | ||
135 | NULL, 0); | ||
136 | if (r < 0) | ||
137 | return r; | ||
138 | |||
139 | mod_timer(&info->se_info.se_active_timer, jiffies + | ||
140 | msecs_to_jiffies(ST21NFCA_SE_TO_HOT_PLUG)); | ||
141 | info->se_info.se_active = true; | ||
142 | |||
143 | /* Ignore return value and check in any case the host_list */ | ||
144 | wait_for_completion_interruptible(&info->se_info.req_completion); | ||
145 | |||
146 | r = nfc_hci_get_param(hdev, NFC_HCI_ADMIN_GATE, | ||
147 | NFC_HCI_ADMIN_HOST_LIST, | ||
148 | &sk_host_list); | ||
149 | if (r < 0) | ||
150 | return r; | ||
151 | |||
152 | host_id = sk_host_list->data[sk_host_list->len - 1]; | ||
153 | kfree_skb(sk_host_list); | ||
154 | |||
155 | if (state == ST21NFCA_SE_MODE_ON && host_id == se_idx) | ||
156 | return se_idx; | ||
157 | else if (state == ST21NFCA_SE_MODE_OFF && host_id != se_idx) | ||
158 | return se_idx; | ||
159 | |||
160 | return -1; | ||
161 | } | ||
162 | |||
163 | int st21nfca_hci_discover_se(struct nfc_hci_dev *hdev) | ||
164 | { | ||
165 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
166 | int se_count = 0; | ||
167 | |||
168 | if (info->se_status->is_uicc_present) { | ||
169 | nfc_add_se(hdev->ndev, NFC_HCI_UICC_HOST_ID, NFC_SE_UICC); | ||
170 | se_count++; | ||
171 | } | ||
172 | |||
173 | if (info->se_status->is_ese_present) { | ||
174 | nfc_add_se(hdev->ndev, ST21NFCA_ESE_HOST_ID, NFC_SE_EMBEDDED); | ||
175 | se_count++; | ||
176 | } | ||
177 | |||
178 | return !se_count; | ||
179 | } | ||
180 | EXPORT_SYMBOL(st21nfca_hci_discover_se); | ||
181 | |||
182 | int st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx) | ||
183 | { | ||
184 | int r; | ||
185 | |||
186 | /* | ||
187 | * According to upper layer, se_idx == NFC_SE_UICC when | ||
188 | * info->se_status->is_uicc_enable is true should never happen. | ||
189 | * Same for eSE. | ||
190 | */ | ||
191 | r = st21nfca_hci_control_se(hdev, se_idx, ST21NFCA_SE_MODE_ON); | ||
192 | |||
193 | if (r == ST21NFCA_ESE_HOST_ID) { | ||
194 | st21nfca_se_get_atr(hdev); | ||
195 | r = nfc_hci_send_event(hdev, ST21NFCA_APDU_READER_GATE, | ||
196 | ST21NFCA_EVT_SE_SOFT_RESET, NULL, 0); | ||
197 | if (r < 0) | ||
198 | return r; | ||
199 | } else if (r < 0) { | ||
200 | /* | ||
201 | * The activation tentative failed, the secure element | ||
202 | * is not connected. Remove from the list. | ||
203 | */ | ||
204 | nfc_remove_se(hdev->ndev, se_idx); | ||
205 | return r; | ||
206 | } | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | EXPORT_SYMBOL(st21nfca_hci_enable_se); | ||
211 | |||
212 | int st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx) | ||
213 | { | ||
214 | int r; | ||
215 | |||
216 | /* | ||
217 | * According to upper layer, se_idx == NFC_SE_UICC when | ||
218 | * info->se_status->is_uicc_enable is true should never happen | ||
219 | * Same for eSE. | ||
220 | */ | ||
221 | r = st21nfca_hci_control_se(hdev, se_idx, ST21NFCA_SE_MODE_OFF); | ||
222 | if (r < 0) | ||
223 | return r; | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | EXPORT_SYMBOL(st21nfca_hci_disable_se); | ||
228 | |||
229 | int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, | ||
230 | u8 *apdu, size_t apdu_length, | ||
231 | se_io_cb_t cb, void *cb_context) | ||
232 | { | ||
233 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
234 | |||
235 | pr_debug("se_io %x\n", se_idx); | ||
236 | |||
237 | switch (se_idx) { | ||
238 | case ST21NFCA_ESE_HOST_ID: | ||
239 | info->se_info.cb = cb; | ||
240 | info->se_info.cb_context = cb_context; | ||
241 | mod_timer(&info->se_info.bwi_timer, jiffies + | ||
242 | msecs_to_jiffies(info->se_info.wt_timeout)); | ||
243 | info->se_info.bwi_active = true; | ||
244 | return nfc_hci_send_event(hdev, ST21NFCA_APDU_READER_GATE, | ||
245 | ST21NFCA_EVT_TRANSMIT_DATA, | ||
246 | apdu, apdu_length); | ||
247 | default: | ||
248 | return -ENODEV; | ||
249 | } | ||
250 | } | ||
251 | EXPORT_SYMBOL(st21nfca_hci_se_io); | ||
252 | |||
253 | static void st21nfca_se_wt_timeout(unsigned long data) | ||
254 | { | ||
255 | /* | ||
256 | * No answer from the secure element | ||
257 | * within the defined timeout. | ||
258 | * Let's send a reset request as recovery procedure. | ||
259 | * According to the situation, we first try to send a software reset | ||
260 | * to the secure element. If the next command is still not | ||
261 | * answering in time, we send to the CLF a secure element hardware | ||
262 | * reset request. | ||
263 | */ | ||
264 | /* hardware reset managed through VCC_UICC_OUT power supply */ | ||
265 | u8 param = 0x01; | ||
266 | struct st21nfca_hci_info *info = (struct st21nfca_hci_info *) data; | ||
267 | |||
268 | pr_debug("\n"); | ||
269 | |||
270 | info->se_info.bwi_active = false; | ||
271 | |||
272 | if (!info->se_info.xch_error) { | ||
273 | info->se_info.xch_error = true; | ||
274 | nfc_hci_send_event(info->hdev, ST21NFCA_APDU_READER_GATE, | ||
275 | ST21NFCA_EVT_SE_SOFT_RESET, NULL, 0); | ||
276 | } else { | ||
277 | info->se_info.xch_error = false; | ||
278 | nfc_hci_send_event(info->hdev, ST21NFCA_DEVICE_MGNT_GATE, | ||
279 | ST21NFCA_EVT_SE_HARD_RESET, ¶m, 1); | ||
280 | } | ||
281 | info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); | ||
282 | } | ||
283 | |||
284 | static void st21nfca_se_activation_timeout(unsigned long data) | ||
285 | { | ||
286 | struct st21nfca_hci_info *info = (struct st21nfca_hci_info *) data; | ||
287 | |||
288 | pr_debug("\n"); | ||
289 | |||
290 | info->se_info.se_active = false; | ||
291 | |||
292 | complete(&info->se_info.req_completion); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Returns: | ||
297 | * <= 0: driver handled the event, skb consumed | ||
298 | * 1: driver does not handle the event, please do standard processing | ||
299 | */ | ||
300 | int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, | ||
301 | u8 event, struct sk_buff *skb) | ||
302 | { | ||
303 | int r = 0; | ||
304 | |||
305 | pr_debug("connectivity gate event: %x\n", event); | ||
306 | |||
307 | switch (event) { | ||
308 | case ST21NFCA_EVT_CONNECTIVITY: | ||
309 | break; | ||
310 | case ST21NFCA_EVT_TRANSACTION: | ||
311 | break; | ||
312 | default: | ||
313 | return 1; | ||
314 | } | ||
315 | kfree_skb(skb); | ||
316 | return r; | ||
317 | } | ||
318 | EXPORT_SYMBOL(st21nfca_connectivity_event_received); | ||
319 | |||
320 | int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, | ||
321 | u8 event, struct sk_buff *skb) | ||
322 | { | ||
323 | int r = 0; | ||
324 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
325 | |||
326 | pr_debug("apdu reader gate event: %x\n", event); | ||
327 | |||
328 | switch (event) { | ||
329 | case ST21NFCA_EVT_TRANSMIT_DATA: | ||
330 | del_timer_sync(&info->se_info.bwi_timer); | ||
331 | info->se_info.bwi_active = false; | ||
332 | r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, | ||
333 | ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); | ||
334 | if (r < 0) | ||
335 | goto exit; | ||
336 | |||
337 | info->se_info.cb(info->se_info.cb_context, | ||
338 | skb->data, skb->len, 0); | ||
339 | break; | ||
340 | case ST21NFCA_EVT_WTX_REQUEST: | ||
341 | mod_timer(&info->se_info.bwi_timer, jiffies + | ||
342 | msecs_to_jiffies(info->se_info.wt_timeout)); | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | exit: | ||
347 | kfree_skb(skb); | ||
348 | return r; | ||
349 | } | ||
350 | EXPORT_SYMBOL(st21nfca_apdu_reader_event_received); | ||
351 | |||
352 | void st21nfca_se_init(struct nfc_hci_dev *hdev) | ||
353 | { | ||
354 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
355 | |||
356 | init_completion(&info->se_info.req_completion); | ||
357 | /* initialize timers */ | ||
358 | init_timer(&info->se_info.bwi_timer); | ||
359 | info->se_info.bwi_timer.data = (unsigned long)info; | ||
360 | info->se_info.bwi_timer.function = st21nfca_se_wt_timeout; | ||
361 | info->se_info.bwi_active = false; | ||
362 | |||
363 | init_timer(&info->se_info.se_active_timer); | ||
364 | info->se_info.se_active_timer.data = (unsigned long)info; | ||
365 | info->se_info.se_active_timer.function = st21nfca_se_activation_timeout; | ||
366 | info->se_info.se_active = false; | ||
367 | |||
368 | info->se_info.count_pipes = 0; | ||
369 | info->se_info.expected_pipes = 0; | ||
370 | |||
371 | info->se_info.xch_error = false; | ||
372 | |||
373 | info->se_info.wt_timeout = | ||
374 | ST21NFCA_BWI_TO_TIMEOUT(ST21NFCA_ATR_DEFAULT_BWI); | ||
375 | } | ||
376 | EXPORT_SYMBOL(st21nfca_se_init); | ||
377 | |||
378 | void st21nfca_se_deinit(struct nfc_hci_dev *hdev) | ||
379 | { | ||
380 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
381 | |||
382 | if (info->se_info.bwi_active) | ||
383 | del_timer_sync(&info->se_info.bwi_timer); | ||
384 | if (info->se_info.se_active) | ||
385 | del_timer_sync(&info->se_info.se_active_timer); | ||
386 | |||
387 | info->se_info.bwi_active = false; | ||
388 | info->se_info.se_active = false; | ||
389 | } | ||
390 | EXPORT_SYMBOL(st21nfca_se_deinit); | ||
diff --git a/drivers/nfc/st21nfca/st21nfca_se.h b/drivers/nfc/st21nfca/st21nfca_se.h new file mode 100644 index 000000000000..b172cfcaeb90 --- /dev/null +++ b/drivers/nfc/st21nfca/st21nfca_se.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __ST21NFCA_SE_H | ||
18 | #define __ST21NFCA_SE_H | ||
19 | |||
20 | #include <linux/skbuff.h> | ||
21 | #include <linux/workqueue.h> | ||
22 | |||
23 | /* | ||
24 | * ref ISO7816-3 chap 8.1. the initial character TS is followed by a | ||
25 | * sequence of at most 32 characters. | ||
26 | */ | ||
27 | #define ST21NFCA_ESE_MAX_LENGTH 33 | ||
28 | #define ST21NFCA_ESE_HOST_ID 0xc0 | ||
29 | |||
30 | struct st21nfca_se_info { | ||
31 | u8 atr[ST21NFCA_ESE_MAX_LENGTH]; | ||
32 | struct completion req_completion; | ||
33 | |||
34 | struct timer_list bwi_timer; | ||
35 | int wt_timeout; /* in msecs */ | ||
36 | bool bwi_active; | ||
37 | |||
38 | struct timer_list se_active_timer; | ||
39 | bool se_active; | ||
40 | int expected_pipes; | ||
41 | int count_pipes; | ||
42 | |||
43 | bool xch_error; | ||
44 | |||
45 | se_io_cb_t cb; | ||
46 | void *cb_context; | ||
47 | }; | ||
48 | |||
49 | int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, | ||
50 | u8 event, struct sk_buff *skb); | ||
51 | int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, | ||
52 | u8 event, struct sk_buff *skb); | ||
53 | |||
54 | int st21nfca_hci_discover_se(struct nfc_hci_dev *hdev); | ||
55 | int st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx); | ||
56 | int st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx); | ||
57 | int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, | ||
58 | u8 *apdu, size_t apdu_length, | ||
59 | se_io_cb_t cb, void *cb_context); | ||
60 | |||
61 | void st21nfca_se_init(struct nfc_hci_dev *hdev); | ||
62 | void st21nfca_se_deinit(struct nfc_hci_dev *hdev); | ||
63 | #endif /* __ST21NFCA_SE_H */ | ||
diff --git a/include/linux/platform_data/st21nfca.h b/include/linux/platform_data/st21nfca.h index 5087fff96d86..cc2bdafb0c69 100644 --- a/include/linux/platform_data/st21nfca.h +++ b/include/linux/platform_data/st21nfca.h | |||
@@ -26,6 +26,8 @@ | |||
26 | struct st21nfca_nfc_platform_data { | 26 | struct st21nfca_nfc_platform_data { |
27 | unsigned int gpio_ena; | 27 | unsigned int gpio_ena; |
28 | unsigned int irq_polarity; | 28 | unsigned int irq_polarity; |
29 | bool is_ese_present; | ||
30 | bool is_uicc_present; | ||
29 | }; | 31 | }; |
30 | 32 | ||
31 | #endif /* _ST21NFCA_HCI_H_ */ | 33 | #endif /* _ST21NFCA_HCI_H_ */ |