aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlan Elias <ilane@ti.com>2012-01-18 06:16:14 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-24 14:32:29 -0500
commit019c4fbaa790e2b3f11dab0c8b7d9896d77db3e5 (patch)
tree593fc051bc96a40e48406f6cba883b1f95822422 /net
parent25a1d9dc850b1bdcc4760eb625f0a67057f54d26 (diff)
NFC: Add NCI multiple targets support
Add the ability to select between multiple targets in NCI. If only one target is found, it will be auto-activated. If more than one target is found, then DISCOVER_NTF will be generated for each target, and the host should select one by calling DISCOVER_SELECT_CMD. Then, the target will be activated. If the activation fails, GENERIC_ERROR_NTF is generated. Signed-off-by: Ilan Elias <ilane@ti.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/nfc/nci/core.c91
-rw-r--r--net/nfc/nci/ntf.c323
-rw-r--r--net/nfc/nci/rsp.c17
3 files changed, 337 insertions, 94 deletions
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index 629b7684597..12d1d4d6267 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -216,6 +216,39 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
216 &cmd); 216 &cmd);
217} 217}
218 218
219struct nci_rf_discover_select_param {
220 __u8 rf_discovery_id;
221 __u8 rf_protocol;
222};
223
224static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
225{
226 struct nci_rf_discover_select_param *param =
227 (struct nci_rf_discover_select_param *)opt;
228 struct nci_rf_discover_select_cmd cmd;
229
230 cmd.rf_discovery_id = param->rf_discovery_id;
231 cmd.rf_protocol = param->rf_protocol;
232
233 switch (cmd.rf_protocol) {
234 case NCI_RF_PROTOCOL_ISO_DEP:
235 cmd.rf_interface = NCI_RF_INTERFACE_ISO_DEP;
236 break;
237
238 case NCI_RF_PROTOCOL_NFC_DEP:
239 cmd.rf_interface = NCI_RF_INTERFACE_NFC_DEP;
240 break;
241
242 default:
243 cmd.rf_interface = NCI_RF_INTERFACE_FRAME;
244 break;
245 }
246
247 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD,
248 sizeof(struct nci_rf_discover_select_cmd),
249 &cmd);
250}
251
219static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) 252static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
220{ 253{
221 struct nci_rf_deactivate_cmd cmd; 254 struct nci_rf_deactivate_cmd cmd;
@@ -264,6 +297,7 @@ static int nci_open_device(struct nci_dev *ndev)
264 297
265 if (!rc) { 298 if (!rc) {
266 set_bit(NCI_UP, &ndev->flags); 299 set_bit(NCI_UP, &ndev->flags);
300 nci_clear_target_list(ndev);
267 atomic_set(&ndev->state, NCI_IDLE); 301 atomic_set(&ndev->state, NCI_IDLE);
268 } else { 302 } else {
269 /* Init failed, cleanup */ 303 /* Init failed, cleanup */
@@ -361,7 +395,8 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
361 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 395 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
362 int rc; 396 int rc;
363 397
364 if (atomic_read(&ndev->state) == NCI_DISCOVERY) { 398 if ((atomic_read(&ndev->state) == NCI_DISCOVERY) ||
399 (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
365 pr_err("unable to start poll, since poll is already active\n"); 400 pr_err("unable to start poll, since poll is already active\n");
366 return -EBUSY; 401 return -EBUSY;
367 } 402 }
@@ -371,8 +406,9 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
371 return -EBUSY; 406 return -EBUSY;
372 } 407 }
373 408
374 if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) { 409 if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
375 pr_debug("target is active, implicitly deactivate...\n"); 410 (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
411 pr_debug("target active or w4 select, implicitly deactivate\n");
376 412
377 rc = nci_request(ndev, nci_rf_deactivate_req, 0, 413 rc = nci_request(ndev, nci_rf_deactivate_req, 0,
378 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); 414 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
@@ -393,7 +429,8 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev)
393{ 429{
394 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 430 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
395 431
396 if (atomic_read(&ndev->state) != NCI_DISCOVERY) { 432 if ((atomic_read(&ndev->state) != NCI_DISCOVERY) &&
433 (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
397 pr_err("unable to stop poll, since poll is not active\n"); 434 pr_err("unable to stop poll, since poll is not active\n");
398 return; 435 return;
399 } 436 }
@@ -406,10 +443,15 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
406 __u32 protocol) 443 __u32 protocol)
407{ 444{
408 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 445 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
446 struct nci_rf_discover_select_param param;
447 struct nfc_target *target = 0;
448 int i;
449 int rc = 0;
409 450
410 pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol); 451 pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol);
411 452
412 if (atomic_read(&ndev->state) != NCI_POLL_ACTIVE) { 453 if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) &&
454 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
413 pr_err("there is no available target to activate\n"); 455 pr_err("there is no available target to activate\n");
414 return -EINVAL; 456 return -EINVAL;
415 } 457 }
@@ -419,16 +461,47 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
419 return -EBUSY; 461 return -EBUSY;
420 } 462 }
421 463
422 if (!(ndev->target_available_prots & (1 << protocol))) { 464 for (i = 0; i < ndev->n_targets; i++) {
465 if (ndev->targets[i].idx == target_idx) {
466 target = &ndev->targets[i];
467 break;
468 }
469 }
470
471 if (!target) {
472 pr_err("unable to find the selected target\n");
473 return -EINVAL;
474 }
475
476 if (!(target->supported_protocols & (1 << protocol))) {
423 pr_err("target does not support the requested protocol 0x%x\n", 477 pr_err("target does not support the requested protocol 0x%x\n",
424 protocol); 478 protocol);
425 return -EINVAL; 479 return -EINVAL;
426 } 480 }
427 481
428 ndev->target_active_prot = protocol; 482 if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
429 ndev->target_available_prots = 0; 483 param.rf_discovery_id = target->idx;
430 484
431 return 0; 485 if (protocol == NFC_PROTO_JEWEL)
486 param.rf_protocol = NCI_RF_PROTOCOL_T1T;
487 else if (protocol == NFC_PROTO_MIFARE)
488 param.rf_protocol = NCI_RF_PROTOCOL_T2T;
489 else if (protocol == NFC_PROTO_FELICA)
490 param.rf_protocol = NCI_RF_PROTOCOL_T3T;
491 else if (protocol == NFC_PROTO_ISO14443)
492 param.rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
493 else
494 param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
495
496 rc = nci_request(ndev, nci_rf_discover_select_req,
497 (unsigned long)&param,
498 msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
499 }
500
501 if (!rc)
502 ndev->target_active_prot = protocol;
503
504 return rc;
432} 505}
433 506
434static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx) 507static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 8ec39464cea..03e7b4626a3 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -71,6 +71,20 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
71 queue_work(ndev->tx_wq, &ndev->tx_work); 71 queue_work(ndev->tx_wq, &ndev->tx_work);
72} 72}
73 73
74static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev,
75 struct sk_buff *skb)
76{
77 __u8 status = skb->data[0];
78
79 pr_debug("status 0x%x\n", status);
80
81 if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
82 /* Activation failed, so complete the request
83 (the state remains the same) */
84 nci_req_complete(ndev, status);
85 }
86}
87
74static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, 88static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
75 struct sk_buff *skb) 89 struct sk_buff *skb)
76{ 90{
@@ -86,12 +100,9 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
86} 100}
87 101
88static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, 102static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
89 struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 103 struct rf_tech_specific_params_nfca_poll *nfca_poll,
104 __u8 *data)
90{ 105{
91 struct rf_tech_specific_params_nfca_poll *nfca_poll;
92
93 nfca_poll = &ntf->rf_tech_specific_params.nfca_poll;
94
95 nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); 106 nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
96 data += 2; 107 data += 2;
97 108
@@ -116,12 +127,9 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
116} 127}
117 128
118static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, 129static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
119 struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 130 struct rf_tech_specific_params_nfcb_poll *nfcb_poll,
131 __u8 *data)
120{ 132{
121 struct rf_tech_specific_params_nfcb_poll *nfcb_poll;
122
123 nfcb_poll = &ntf->rf_tech_specific_params.nfcb_poll;
124
125 nfcb_poll->sensb_res_len = *data++; 133 nfcb_poll->sensb_res_len = *data++;
126 134
127 pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); 135 pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len);
@@ -133,12 +141,9 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
133} 141}
134 142
135static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, 143static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
136 struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 144 struct rf_tech_specific_params_nfcf_poll *nfcf_poll,
145 __u8 *data)
137{ 146{
138 struct rf_tech_specific_params_nfcf_poll *nfcf_poll;
139
140 nfcf_poll = &ntf->rf_tech_specific_params.nfcf_poll;
141
142 nfcf_poll->bit_rate = *data++; 147 nfcf_poll->bit_rate = *data++;
143 nfcf_poll->sensf_res_len = *data++; 148 nfcf_poll->sensf_res_len = *data++;
144 149
@@ -151,6 +156,172 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
151 return data; 156 return data;
152} 157}
153 158
159static int nci_add_new_protocol(struct nci_dev *ndev,
160 struct nfc_target *target,
161 __u8 rf_protocol,
162 __u8 rf_tech_and_mode,
163 void *params)
164{
165 struct rf_tech_specific_params_nfca_poll *nfca_poll;
166 struct rf_tech_specific_params_nfcb_poll *nfcb_poll;
167 struct rf_tech_specific_params_nfcf_poll *nfcf_poll;
168 __u32 protocol;
169
170 if (rf_protocol == NCI_RF_PROTOCOL_T2T)
171 protocol = NFC_PROTO_MIFARE_MASK;
172 else if (rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)
173 protocol = NFC_PROTO_ISO14443_MASK;
174 else if (rf_protocol == NCI_RF_PROTOCOL_T3T)
175 protocol = NFC_PROTO_FELICA_MASK;
176 else
177 protocol = 0;
178
179 if (!(protocol & ndev->poll_prots)) {
180 pr_err("the target found does not have the desired protocol\n");
181 return -EPROTO;
182 }
183
184 if (rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) {
185 nfca_poll = (struct rf_tech_specific_params_nfca_poll *)params;
186
187 target->sens_res = nfca_poll->sens_res;
188 target->sel_res = nfca_poll->sel_res;
189 target->nfcid1_len = nfca_poll->nfcid1_len;
190 if (target->nfcid1_len > 0) {
191 memcpy(target->nfcid1, nfca_poll->nfcid1,
192 target->nfcid1_len);
193 }
194 } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) {
195 nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
196
197 target->sensb_res_len = nfcb_poll->sensb_res_len;
198 if (target->sensb_res_len > 0) {
199 memcpy(target->sensb_res, nfcb_poll->sensb_res,
200 target->sensb_res_len);
201 }
202 } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) {
203 nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
204
205 target->sensf_res_len = nfcf_poll->sensf_res_len;
206 if (target->sensf_res_len > 0) {
207 memcpy(target->sensf_res, nfcf_poll->sensf_res,
208 target->sensf_res_len);
209 }
210 } else {
211 pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
212 return -EPROTO;
213 }
214
215 target->supported_protocols |= protocol;
216
217 pr_debug("protocol 0x%x\n", protocol);
218
219 return 0;
220}
221
222static void nci_add_new_target(struct nci_dev *ndev,
223 struct nci_rf_discover_ntf *ntf)
224{
225 struct nfc_target *target;
226 int i, rc;
227
228 for (i = 0; i < ndev->n_targets; i++) {
229 target = &ndev->targets[i];
230 if (target->idx == ntf->rf_discovery_id) {
231 /* This target already exists, add the new protocol */
232 nci_add_new_protocol(ndev, target, ntf->rf_protocol,
233 ntf->rf_tech_and_mode,
234 &ntf->rf_tech_specific_params);
235 return;
236 }
237 }
238
239 /* This is a new target, check if we've enough room */
240 if (ndev->n_targets == NCI_MAX_DISCOVERED_TARGETS) {
241 pr_debug("not enough room, ignoring new target...\n");
242 return;
243 }
244
245 target = &ndev->targets[ndev->n_targets];
246
247 rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
248 ntf->rf_tech_and_mode,
249 &ntf->rf_tech_specific_params);
250 if (!rc) {
251 target->idx = ntf->rf_discovery_id;
252 ndev->n_targets++;
253
254 pr_debug("target_idx %d, n_targets %d\n", target->idx,
255 ndev->n_targets);
256 }
257}
258
259void nci_clear_target_list(struct nci_dev *ndev)
260{
261 memset(ndev->targets, 0,
262 (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS));
263
264 ndev->n_targets = 0;
265}
266
267static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
268 struct sk_buff *skb)
269{
270 struct nci_rf_discover_ntf ntf;
271 __u8 *data = skb->data;
272 bool add_target = true;
273
274 ntf.rf_discovery_id = *data++;
275 ntf.rf_protocol = *data++;
276 ntf.rf_tech_and_mode = *data++;
277 ntf.rf_tech_specific_params_len = *data++;
278
279 pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);
280 pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
281 pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode);
282 pr_debug("rf_tech_specific_params_len %d\n",
283 ntf.rf_tech_specific_params_len);
284
285 if (ntf.rf_tech_specific_params_len > 0) {
286 switch (ntf.rf_tech_and_mode) {
287 case NCI_NFC_A_PASSIVE_POLL_MODE:
288 data = nci_extract_rf_params_nfca_passive_poll(ndev,
289 &(ntf.rf_tech_specific_params.nfca_poll), data);
290 break;
291
292 case NCI_NFC_B_PASSIVE_POLL_MODE:
293 data = nci_extract_rf_params_nfcb_passive_poll(ndev,
294 &(ntf.rf_tech_specific_params.nfcb_poll), data);
295 break;
296
297 case NCI_NFC_F_PASSIVE_POLL_MODE:
298 data = nci_extract_rf_params_nfcf_passive_poll(ndev,
299 &(ntf.rf_tech_specific_params.nfcf_poll), data);
300 break;
301
302 default:
303 pr_err("unsupported rf_tech_and_mode 0x%x\n",
304 ntf.rf_tech_and_mode);
305 data += ntf.rf_tech_specific_params_len;
306 add_target = false;
307 }
308 }
309
310 ntf.ntf_type = *data++;
311 pr_debug("ntf_type %d\n", ntf.ntf_type);
312
313 if (add_target == true)
314 nci_add_new_target(ndev, &ntf);
315
316 if (ntf.ntf_type == NCI_DISCOVER_NTF_TYPE_MORE) {
317 atomic_set(&ndev->state, NCI_W4_ALL_DISCOVERIES);
318 } else {
319 atomic_set(&ndev->state, NCI_W4_HOST_SELECT);
320 nfc_targets_found(ndev->nfc_dev, ndev->targets,
321 ndev->n_targets);
322 }
323}
324
154static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, 325static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
155 struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 326 struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
156{ 327{
@@ -184,74 +355,32 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
184 default: 355 default:
185 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", 356 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
186 ntf->activation_rf_tech_and_mode); 357 ntf->activation_rf_tech_and_mode);
187 return -EPROTO; 358 return NCI_STATUS_RF_PROTOCOL_ERROR;
188 } 359 }
189 360
190 return 0; 361 return NCI_STATUS_OK;
191} 362}
192 363
193static void nci_target_found(struct nci_dev *ndev, 364static void nci_target_auto_activated(struct nci_dev *ndev,
194 struct nci_rf_intf_activated_ntf *ntf) 365 struct nci_rf_intf_activated_ntf *ntf)
195{ 366{
196 struct nfc_target nfc_tgt; 367 struct nfc_target *target;
368 int rc;
197 369
198 memset(&nfc_tgt, 0, sizeof(nfc_tgt)); 370 target = &ndev->targets[ndev->n_targets];
199 371
200 if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T) 372 rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
201 nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; 373 ntf->activation_rf_tech_and_mode,
202 else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) 374 &ntf->rf_tech_specific_params);
203 nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; 375 if (rc)
204 else if (ntf->rf_protocol == NCI_RF_PROTOCOL_T3T)
205 nfc_tgt.supported_protocols = NFC_PROTO_FELICA_MASK;
206
207 if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) {
208 pr_debug("the target found does not have the desired protocol\n");
209 return; 376 return;
210 }
211 377
212 pr_debug("new target found, supported_protocols 0x%x\n", 378 target->idx = ntf->rf_discovery_id;
213 nfc_tgt.supported_protocols); 379 ndev->n_targets++;
214
215 if (ntf->activation_rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) {
216 nfc_tgt.sens_res =
217 ntf->rf_tech_specific_params.nfca_poll.sens_res;
218 nfc_tgt.sel_res =
219 ntf->rf_tech_specific_params.nfca_poll.sel_res;
220 nfc_tgt.nfcid1_len =
221 ntf->rf_tech_specific_params.nfca_poll.nfcid1_len;
222 if (nfc_tgt.nfcid1_len > 0) {
223 memcpy(nfc_tgt.nfcid1,
224 ntf->rf_tech_specific_params.nfca_poll.nfcid1,
225 nfc_tgt.nfcid1_len);
226 }
227 } else if (ntf->activation_rf_tech_and_mode ==
228 NCI_NFC_B_PASSIVE_POLL_MODE) {
229 nfc_tgt.sensb_res_len =
230 ntf->rf_tech_specific_params.nfcb_poll.sensb_res_len;
231 if (nfc_tgt.sensb_res_len > 0) {
232 memcpy(nfc_tgt.sensb_res,
233 ntf->rf_tech_specific_params.nfcb_poll.sensb_res,
234 nfc_tgt.sensb_res_len);
235 }
236 } else if (ntf->activation_rf_tech_and_mode ==
237 NCI_NFC_F_PASSIVE_POLL_MODE) {
238 nfc_tgt.sensf_res_len =
239 ntf->rf_tech_specific_params.nfcf_poll.sensf_res_len;
240 if (nfc_tgt.sensf_res_len > 0) {
241 memcpy(nfc_tgt.sensf_res,
242 ntf->rf_tech_specific_params.nfcf_poll.sensf_res,
243 nfc_tgt.sensf_res_len);
244 }
245 }
246 380
247 ndev->target_available_prots = nfc_tgt.supported_protocols; 381 pr_debug("target_idx %d, n_targets %d\n", target->idx, ndev->n_targets);
248 ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size;
249 ndev->initial_num_credits = ntf->initial_num_credits;
250 382
251 /* set the available credits to initial value */ 383 nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets);
252 atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
253
254 nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
255} 384}
256 385
257static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, 386static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
@@ -259,9 +388,7 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
259{ 388{
260 struct nci_rf_intf_activated_ntf ntf; 389 struct nci_rf_intf_activated_ntf ntf;
261 __u8 *data = skb->data; 390 __u8 *data = skb->data;
262 int err = 0; 391 int err = NCI_STATUS_OK;
263
264 atomic_set(&ndev->state, NCI_POLL_ACTIVE);
265 392
266 ntf.rf_discovery_id = *data++; 393 ntf.rf_discovery_id = *data++;
267 ntf.rf_interface = *data++; 394 ntf.rf_interface = *data++;
@@ -286,23 +413,24 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
286 switch (ntf.activation_rf_tech_and_mode) { 413 switch (ntf.activation_rf_tech_and_mode) {
287 case NCI_NFC_A_PASSIVE_POLL_MODE: 414 case NCI_NFC_A_PASSIVE_POLL_MODE:
288 data = nci_extract_rf_params_nfca_passive_poll(ndev, 415 data = nci_extract_rf_params_nfca_passive_poll(ndev,
289 &ntf, data); 416 &(ntf.rf_tech_specific_params.nfca_poll), data);
290 break; 417 break;
291 418
292 case NCI_NFC_B_PASSIVE_POLL_MODE: 419 case NCI_NFC_B_PASSIVE_POLL_MODE:
293 data = nci_extract_rf_params_nfcb_passive_poll(ndev, 420 data = nci_extract_rf_params_nfcb_passive_poll(ndev,
294 &ntf, data); 421 &(ntf.rf_tech_specific_params.nfcb_poll), data);
295 break; 422 break;
296 423
297 case NCI_NFC_F_PASSIVE_POLL_MODE: 424 case NCI_NFC_F_PASSIVE_POLL_MODE:
298 data = nci_extract_rf_params_nfcf_passive_poll(ndev, 425 data = nci_extract_rf_params_nfcf_passive_poll(ndev,
299 &ntf, data); 426 &(ntf.rf_tech_specific_params.nfcf_poll), data);
300 break; 427 break;
301 428
302 default: 429 default:
303 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", 430 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
304 ntf.activation_rf_tech_and_mode); 431 ntf.activation_rf_tech_and_mode);
305 return; 432 err = NCI_STATUS_RF_PROTOCOL_ERROR;
433 goto exit;
306 } 434 }
307 } 435 }
308 436
@@ -334,12 +462,30 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
334 default: 462 default:
335 pr_err("unsupported rf_interface 0x%x\n", 463 pr_err("unsupported rf_interface 0x%x\n",
336 ntf.rf_interface); 464 ntf.rf_interface);
337 return; 465 err = NCI_STATUS_RF_PROTOCOL_ERROR;
466 break;
338 } 467 }
339 } 468 }
340 469
341 if (!err) 470exit:
342 nci_target_found(ndev, &ntf); 471 if (err == NCI_STATUS_OK) {
472 ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size;
473 ndev->initial_num_credits = ntf.initial_num_credits;
474
475 /* set the available credits to initial value */
476 atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
477 }
478
479 if (atomic_read(&ndev->state) == NCI_DISCOVERY) {
480 /* A single target was found and activated automatically */
481 atomic_set(&ndev->state, NCI_POLL_ACTIVE);
482 if (err == NCI_STATUS_OK)
483 nci_target_auto_activated(ndev, &ntf);
484 } else { /* ndev->state == NCI_W4_HOST_SELECT */
485 /* A selected target was activated, so complete the request */
486 atomic_set(&ndev->state, NCI_POLL_ACTIVE);
487 nci_req_complete(ndev, err);
488 }
343} 489}
344 490
345static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, 491static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
@@ -349,9 +495,6 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
349 495
350 pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason); 496 pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
351 497
352 atomic_set(&ndev->state, NCI_IDLE);
353 ndev->target_active_prot = 0;
354
355 /* drop tx data queue */ 498 /* drop tx data queue */
356 skb_queue_purge(&ndev->tx_q); 499 skb_queue_purge(&ndev->tx_q);
357 500
@@ -365,6 +508,8 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
365 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) 508 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
366 nci_data_exchange_complete(ndev, NULL, -EIO); 509 nci_data_exchange_complete(ndev, NULL, -EIO);
367 510
511 nci_clear_target_list(ndev);
512 atomic_set(&ndev->state, NCI_IDLE);
368 nci_req_complete(ndev, NCI_STATUS_OK); 513 nci_req_complete(ndev, NCI_STATUS_OK);
369} 514}
370 515
@@ -386,10 +531,18 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
386 nci_core_conn_credits_ntf_packet(ndev, skb); 531 nci_core_conn_credits_ntf_packet(ndev, skb);
387 break; 532 break;
388 533
534 case NCI_OP_CORE_GENERIC_ERROR_NTF:
535 nci_core_generic_error_ntf_packet(ndev, skb);
536 break;
537
389 case NCI_OP_CORE_INTF_ERROR_NTF: 538 case NCI_OP_CORE_INTF_ERROR_NTF:
390 nci_core_conn_intf_error_ntf_packet(ndev, skb); 539 nci_core_conn_intf_error_ntf_packet(ndev, skb);
391 break; 540 break;
392 541
542 case NCI_OP_RF_DISCOVER_NTF:
543 nci_rf_discover_ntf_packet(ndev, skb);
544 break;
545
393 case NCI_OP_RF_INTF_ACTIVATED_NTF: 546 case NCI_OP_RF_INTF_ACTIVATED_NTF:
394 nci_rf_intf_activated_ntf_packet(ndev, skb); 547 nci_rf_intf_activated_ntf_packet(ndev, skb);
395 break; 548 break;
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c
index cb8bce6899c..aa63b1e9918 100644
--- a/net/nfc/nci/rsp.c
+++ b/net/nfc/nci/rsp.c
@@ -142,6 +142,18 @@ static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
142 nci_req_complete(ndev, status); 142 nci_req_complete(ndev, status);
143} 143}
144 144
145static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev,
146 struct sk_buff *skb)
147{
148 __u8 status = skb->data[0];
149
150 pr_debug("status 0x%x\n", status);
151
152 /* Complete the request on intf_activated_ntf or generic_error_ntf */
153 if (status != NCI_STATUS_OK)
154 nci_req_complete(ndev, status);
155}
156
145static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, 157static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
146 struct sk_buff *skb) 158 struct sk_buff *skb)
147{ 159{
@@ -152,6 +164,7 @@ static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
152 /* If target was active, complete the request only in deactivate_ntf */ 164 /* If target was active, complete the request only in deactivate_ntf */
153 if ((status != NCI_STATUS_OK) || 165 if ((status != NCI_STATUS_OK) ||
154 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { 166 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
167 nci_clear_target_list(ndev);
155 atomic_set(&ndev->state, NCI_IDLE); 168 atomic_set(&ndev->state, NCI_IDLE);
156 nci_req_complete(ndev, status); 169 nci_req_complete(ndev, status);
157 } 170 }
@@ -190,6 +203,10 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
190 nci_rf_disc_rsp_packet(ndev, skb); 203 nci_rf_disc_rsp_packet(ndev, skb);
191 break; 204 break;
192 205
206 case NCI_OP_RF_DISCOVER_SELECT_RSP:
207 nci_rf_disc_select_rsp_packet(ndev, skb);
208 break;
209
193 case NCI_OP_RF_DEACTIVATE_RSP: 210 case NCI_OP_RF_DEACTIVATE_RSP:
194 nci_rf_deactivate_rsp_packet(ndev, skb); 211 nci_rf_deactivate_rsp_packet(ndev, skb);
195 break; 212 break;