aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/nci/ntf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/nci/ntf.c')
-rw-r--r--net/nfc/nci/ntf.c209
1 files changed, 136 insertions, 73 deletions
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 96633f5cda4f..b16a8dc2afbe 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -25,6 +25,8 @@
25 * 25 *
26 */ 26 */
27 27
28#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
29
28#include <linux/types.h> 30#include <linux/types.h>
29#include <linux/interrupt.h> 31#include <linux/interrupt.h>
30#include <linux/bitops.h> 32#include <linux/bitops.h>
@@ -43,18 +45,21 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
43 struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; 45 struct nci_core_conn_credit_ntf *ntf = (void *) skb->data;
44 int i; 46 int i;
45 47
46 nfc_dbg("entry, num_entries %d", ntf->num_entries); 48 pr_debug("num_entries %d\n", ntf->num_entries);
47 49
48 if (ntf->num_entries > NCI_MAX_NUM_CONN) 50 if (ntf->num_entries > NCI_MAX_NUM_CONN)
49 ntf->num_entries = NCI_MAX_NUM_CONN; 51 ntf->num_entries = NCI_MAX_NUM_CONN;
50 52
51 /* update the credits */ 53 /* update the credits */
52 for (i = 0; i < ntf->num_entries; i++) { 54 for (i = 0; i < ntf->num_entries; i++) {
53 nfc_dbg("entry[%d]: conn_id %d, credits %d", i, 55 ntf->conn_entries[i].conn_id =
54 ntf->conn_entries[i].conn_id, 56 nci_conn_id(&ntf->conn_entries[i].conn_id);
55 ntf->conn_entries[i].credits); 57
58 pr_debug("entry[%d]: conn_id %d, credits %d\n",
59 i, ntf->conn_entries[i].conn_id,
60 ntf->conn_entries[i].credits);
56 61
57 if (ntf->conn_entries[i].conn_id == ndev->conn_id) { 62 if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
58 /* found static rf connection */ 63 /* found static rf connection */
59 atomic_add(ntf->conn_entries[i].credits, 64 atomic_add(ntf->conn_entries[i].credits,
60 &ndev->credits_cnt); 65 &ndev->credits_cnt);
@@ -66,31 +71,34 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
66 queue_work(ndev->tx_wq, &ndev->tx_work); 71 queue_work(ndev->tx_wq, &ndev->tx_work);
67} 72}
68 73
69static void nci_rf_field_info_ntf_packet(struct nci_dev *ndev, 74static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
70 struct sk_buff *skb) 75 struct sk_buff *skb)
71{ 76{
72 struct nci_rf_field_info_ntf *ntf = (void *) skb->data; 77 struct nci_core_intf_error_ntf *ntf = (void *) skb->data;
73 78
74 nfc_dbg("entry, rf_field_status %d", ntf->rf_field_status); 79 ntf->conn_id = nci_conn_id(&ntf->conn_id);
80
81 pr_debug("status 0x%x, conn_id %d\n", ntf->status, ntf->conn_id);
82
83 /* complete the data exchange transaction, if exists */
84 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
85 nci_data_exchange_complete(ndev, NULL, -EIO);
75} 86}
76 87
77static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, 88static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
78 struct nci_rf_activate_ntf *ntf, __u8 *data) 89 struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
79{ 90{
80 struct rf_tech_specific_params_nfca_poll *nfca_poll; 91 struct rf_tech_specific_params_nfca_poll *nfca_poll;
81 struct activation_params_nfca_poll_iso_dep *nfca_poll_iso_dep;
82 92
83 nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; 93 nfca_poll = &ntf->rf_tech_specific_params.nfca_poll;
84 nfca_poll_iso_dep = &ntf->activation_params.nfca_poll_iso_dep;
85 94
86 nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); 95 nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
87 data += 2; 96 data += 2;
88 97
89 nfca_poll->nfcid1_len = *data++; 98 nfca_poll->nfcid1_len = *data++;
90 99
91 nfc_dbg("sens_res 0x%x, nfcid1_len %d", 100 pr_debug("sens_res 0x%x, nfcid1_len %d\n",
92 nfca_poll->sens_res, 101 nfca_poll->sens_res, nfca_poll->nfcid1_len);
93 nfca_poll->nfcid1_len);
94 102
95 memcpy(nfca_poll->nfcid1, data, nfca_poll->nfcid1_len); 103 memcpy(nfca_poll->nfcid1, data, nfca_poll->nfcid1_len);
96 data += nfca_poll->nfcid1_len; 104 data += nfca_poll->nfcid1_len;
@@ -100,32 +108,32 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
100 if (nfca_poll->sel_res_len != 0) 108 if (nfca_poll->sel_res_len != 0)
101 nfca_poll->sel_res = *data++; 109 nfca_poll->sel_res = *data++;
102 110
103 ntf->rf_interface_type = *data++; 111 pr_debug("sel_res_len %d, sel_res 0x%x\n",
104 ntf->activation_params_len = *data++; 112 nfca_poll->sel_res_len,
113 nfca_poll->sel_res);
105 114
106 nfc_dbg("sel_res_len %d, sel_res 0x%x, rf_interface_type %d, activation_params_len %d", 115 return data;
107 nfca_poll->sel_res_len, 116}
108 nfca_poll->sel_res,
109 ntf->rf_interface_type,
110 ntf->activation_params_len);
111 117
112 switch (ntf->rf_interface_type) { 118static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
113 case NCI_RF_INTERFACE_ISO_DEP: 119 struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
114 nfca_poll_iso_dep->rats_res_len = *data++; 120{
115 if (nfca_poll_iso_dep->rats_res_len > 0) { 121 struct activation_params_nfca_poll_iso_dep *nfca_poll;
116 memcpy(nfca_poll_iso_dep->rats_res, 122
123 switch (ntf->activation_rf_tech_and_mode) {
124 case NCI_NFC_A_PASSIVE_POLL_MODE:
125 nfca_poll = &ntf->activation_params.nfca_poll_iso_dep;
126 nfca_poll->rats_res_len = *data++;
127 if (nfca_poll->rats_res_len > 0) {
128 memcpy(nfca_poll->rats_res,
117 data, 129 data,
118 nfca_poll_iso_dep->rats_res_len); 130 nfca_poll->rats_res_len);
119 } 131 }
120 break; 132 break;
121 133
122 case NCI_RF_INTERFACE_FRAME:
123 /* no activation params */
124 break;
125
126 default: 134 default:
127 nfc_err("unsupported rf_interface_type 0x%x", 135 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
128 ntf->rf_interface_type); 136 ntf->activation_rf_tech_and_mode);
129 return -EPROTO; 137 return -EPROTO;
130 } 138 }
131 139
@@ -133,7 +141,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
133} 141}
134 142
135static void nci_target_found(struct nci_dev *ndev, 143static void nci_target_found(struct nci_dev *ndev,
136 struct nci_rf_activate_ntf *ntf) 144 struct nci_rf_intf_activated_ntf *ntf)
137{ 145{
138 struct nfc_target nfc_tgt; 146 struct nfc_target nfc_tgt;
139 147
@@ -141,66 +149,121 @@ static void nci_target_found(struct nci_dev *ndev,
141 nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; 149 nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK;
142 else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ 150 else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */
143 nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; 151 nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK;
152 else
153 nfc_tgt.supported_protocols = 0;
144 154
145 nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; 155 nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res;
146 nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; 156 nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res;
157 nfc_tgt.nfcid1_len = ntf->rf_tech_specific_params.nfca_poll.nfcid1_len;
158 if (nfc_tgt.nfcid1_len > 0) {
159 memcpy(nfc_tgt.nfcid1,
160 ntf->rf_tech_specific_params.nfca_poll.nfcid1,
161 nfc_tgt.nfcid1_len);
162 }
147 163
148 if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) { 164 if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) {
149 nfc_dbg("the target found does not have the desired protocol"); 165 pr_debug("the target found does not have the desired protocol\n");
150 return; 166 return;
151 } 167 }
152 168
153 nfc_dbg("new target found, supported_protocols 0x%x", 169 pr_debug("new target found, supported_protocols 0x%x\n",
154 nfc_tgt.supported_protocols); 170 nfc_tgt.supported_protocols);
155 171
156 ndev->target_available_prots = nfc_tgt.supported_protocols; 172 ndev->target_available_prots = nfc_tgt.supported_protocols;
173 ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size;
174 ndev->initial_num_credits = ntf->initial_num_credits;
175
176 /* set the available credits to initial value */
177 atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
157 178
158 nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); 179 nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
159} 180}
160 181
161static void nci_rf_activate_ntf_packet(struct nci_dev *ndev, 182static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
162 struct sk_buff *skb) 183 struct sk_buff *skb)
163{ 184{
164 struct nci_rf_activate_ntf ntf; 185 struct nci_rf_intf_activated_ntf ntf;
165 __u8 *data = skb->data; 186 __u8 *data = skb->data;
166 int rc = -1; 187 int err = 0;
167 188
168 clear_bit(NCI_DISCOVERY, &ndev->flags); 189 clear_bit(NCI_DISCOVERY, &ndev->flags);
169 set_bit(NCI_POLL_ACTIVE, &ndev->flags); 190 set_bit(NCI_POLL_ACTIVE, &ndev->flags);
170 191
171 ntf.target_handle = *data++; 192 ntf.rf_discovery_id = *data++;
193 ntf.rf_interface = *data++;
172 ntf.rf_protocol = *data++; 194 ntf.rf_protocol = *data++;
173 ntf.rf_tech_and_mode = *data++; 195 ntf.activation_rf_tech_and_mode = *data++;
196 ntf.max_data_pkt_payload_size = *data++;
197 ntf.initial_num_credits = *data++;
174 ntf.rf_tech_specific_params_len = *data++; 198 ntf.rf_tech_specific_params_len = *data++;
175 199
176 nfc_dbg("target_handle %d, rf_protocol 0x%x, rf_tech_and_mode 0x%x, rf_tech_specific_params_len %d", 200 pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);
177 ntf.target_handle, 201 pr_debug("rf_interface 0x%x\n", ntf.rf_interface);
178 ntf.rf_protocol, 202 pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
179 ntf.rf_tech_and_mode, 203 pr_debug("activation_rf_tech_and_mode 0x%x\n",
180 ntf.rf_tech_specific_params_len); 204 ntf.activation_rf_tech_and_mode);
181 205 pr_debug("max_data_pkt_payload_size 0x%x\n",
182 switch (ntf.rf_tech_and_mode) { 206 ntf.max_data_pkt_payload_size);
183 case NCI_NFC_A_PASSIVE_POLL_MODE: 207 pr_debug("initial_num_credits 0x%x\n", ntf.initial_num_credits);
184 rc = nci_rf_activate_nfca_passive_poll(ndev, &ntf, 208 pr_debug("rf_tech_specific_params_len %d\n",
185 data); 209 ntf.rf_tech_specific_params_len);
186 break; 210
211 if (ntf.rf_tech_specific_params_len > 0) {
212 switch (ntf.activation_rf_tech_and_mode) {
213 case NCI_NFC_A_PASSIVE_POLL_MODE:
214 data = nci_extract_rf_params_nfca_passive_poll(ndev,
215 &ntf, data);
216 break;
217
218 default:
219 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
220 ntf.activation_rf_tech_and_mode);
221 return;
222 }
223 }
187 224
188 default: 225 ntf.data_exch_rf_tech_and_mode = *data++;
189 nfc_err("unsupported rf_tech_and_mode 0x%x", 226 ntf.data_exch_tx_bit_rate = *data++;
190 ntf.rf_tech_and_mode); 227 ntf.data_exch_rx_bit_rate = *data++;
191 return; 228 ntf.activation_params_len = *data++;
229
230 pr_debug("data_exch_rf_tech_and_mode 0x%x\n",
231 ntf.data_exch_rf_tech_and_mode);
232 pr_debug("data_exch_tx_bit_rate 0x%x\n",
233 ntf.data_exch_tx_bit_rate);
234 pr_debug("data_exch_rx_bit_rate 0x%x\n",
235 ntf.data_exch_rx_bit_rate);
236 pr_debug("activation_params_len %d\n",
237 ntf.activation_params_len);
238
239 if (ntf.activation_params_len > 0) {
240 switch (ntf.rf_interface) {
241 case NCI_RF_INTERFACE_ISO_DEP:
242 err = nci_extract_activation_params_iso_dep(ndev,
243 &ntf, data);
244 break;
245
246 case NCI_RF_INTERFACE_FRAME:
247 /* no activation params */
248 break;
249
250 default:
251 pr_err("unsupported rf_interface 0x%x\n",
252 ntf.rf_interface);
253 return;
254 }
192 } 255 }
193 256
194 if (!rc) 257 if (!err)
195 nci_target_found(ndev, &ntf); 258 nci_target_found(ndev, &ntf);
196} 259}
197 260
198static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, 261static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
199 struct sk_buff *skb) 262 struct sk_buff *skb)
200{ 263{
201 __u8 type = skb->data[0]; 264 struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
202 265
203 nfc_dbg("entry, type 0x%x", type); 266 pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
204 267
205 clear_bit(NCI_POLL_ACTIVE, &ndev->flags); 268 clear_bit(NCI_POLL_ACTIVE, &ndev->flags);
206 ndev->target_active_prot = 0; 269 ndev->target_active_prot = 0;
@@ -223,11 +286,11 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
223{ 286{
224 __u16 ntf_opcode = nci_opcode(skb->data); 287 __u16 ntf_opcode = nci_opcode(skb->data);
225 288
226 nfc_dbg("NCI RX: MT=ntf, PBF=%d, GID=0x%x, OID=0x%x, plen=%d", 289 pr_debug("NCI RX: MT=ntf, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
227 nci_pbf(skb->data), 290 nci_pbf(skb->data),
228 nci_opcode_gid(ntf_opcode), 291 nci_opcode_gid(ntf_opcode),
229 nci_opcode_oid(ntf_opcode), 292 nci_opcode_oid(ntf_opcode),
230 nci_plen(skb->data)); 293 nci_plen(skb->data));
231 294
232 /* strip the nci control header */ 295 /* strip the nci control header */
233 skb_pull(skb, NCI_CTRL_HDR_SIZE); 296 skb_pull(skb, NCI_CTRL_HDR_SIZE);
@@ -237,12 +300,12 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
237 nci_core_conn_credits_ntf_packet(ndev, skb); 300 nci_core_conn_credits_ntf_packet(ndev, skb);
238 break; 301 break;
239 302
240 case NCI_OP_RF_FIELD_INFO_NTF: 303 case NCI_OP_CORE_INTF_ERROR_NTF:
241 nci_rf_field_info_ntf_packet(ndev, skb); 304 nci_core_conn_intf_error_ntf_packet(ndev, skb);
242 break; 305 break;
243 306
244 case NCI_OP_RF_ACTIVATE_NTF: 307 case NCI_OP_RF_INTF_ACTIVATED_NTF:
245 nci_rf_activate_ntf_packet(ndev, skb); 308 nci_rf_intf_activated_ntf_packet(ndev, skb);
246 break; 309 break;
247 310
248 case NCI_OP_RF_DEACTIVATE_NTF: 311 case NCI_OP_RF_DEACTIVATE_NTF:
@@ -250,7 +313,7 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
250 break; 313 break;
251 314
252 default: 315 default:
253 nfc_err("unknown ntf opcode 0x%x", ntf_opcode); 316 pr_err("unknown ntf opcode 0x%x\n", ntf_opcode);
254 break; 317 break;
255 } 318 }
256 319