Commit 019c4fbaa790e2b3f11dab0c8b7d9896d77db3e5

Authored by Ilan Elias
Committed by John W. Linville
1 parent 25a1d9dc85

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>

Showing 5 changed files with 378 additions and 96 deletions Side-by-side Diff

include/net/nfc/nci.h
... ... @@ -116,6 +116,11 @@
116 116 #define NCI_DISC_MAP_MODE_POLL 0x01
117 117 #define NCI_DISC_MAP_MODE_LISTEN 0x02
118 118  
  119 +/* NCI Discover Notification Type */
  120 +#define NCI_DISCOVER_NTF_TYPE_LAST 0x00
  121 +#define NCI_DISCOVER_NTF_TYPE_LAST_NFCC 0x01
  122 +#define NCI_DISCOVER_NTF_TYPE_MORE 0x02
  123 +
119 124 /* NCI Deactivation Type */
120 125 #define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00
121 126 #define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01
... ... @@ -207,6 +212,13 @@
207 212 struct disc_config disc_configs[NCI_MAX_NUM_RF_CONFIGS];
208 213 } __packed;
209 214  
  215 +#define NCI_OP_RF_DISCOVER_SELECT_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x04)
  216 +struct nci_rf_discover_select_cmd {
  217 + __u8 rf_discovery_id;
  218 + __u8 rf_protocol;
  219 + __u8 rf_interface;
  220 +} __packed;
  221 +
210 222 #define NCI_OP_RF_DEACTIVATE_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
211 223 struct nci_rf_deactivate_cmd {
212 224 __u8 type;
... ... @@ -244,6 +256,8 @@
244 256  
245 257 #define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
246 258  
  259 +#define NCI_OP_RF_DISCOVER_SELECT_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x04)
  260 +
247 261 #define NCI_OP_RF_DEACTIVATE_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
248 262  
249 263 /* --------------------------- */
250 264  
... ... @@ -260,13 +274,15 @@
260 274 struct conn_credit_entry conn_entries[NCI_MAX_NUM_CONN];
261 275 } __packed;
262 276  
  277 +#define NCI_OP_CORE_GENERIC_ERROR_NTF nci_opcode_pack(NCI_GID_CORE, 0x07)
  278 +
263 279 #define NCI_OP_CORE_INTF_ERROR_NTF nci_opcode_pack(NCI_GID_CORE, 0x08)
264 280 struct nci_core_intf_error_ntf {
265 281 __u8 status;
266 282 __u8 conn_id;
267 283 } __packed;
268 284  
269   -#define NCI_OP_RF_INTF_ACTIVATED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
  285 +#define NCI_OP_RF_DISCOVER_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
270 286 struct rf_tech_specific_params_nfca_poll {
271 287 __u16 sens_res;
272 288 __u8 nfcid1_len; /* 0, 4, 7, or 10 Bytes */
... ... @@ -286,6 +302,22 @@
286 302 __u8 sensf_res[18]; /* 16 or 18 Bytes */
287 303 } __packed;
288 304  
  305 +struct nci_rf_discover_ntf {
  306 + __u8 rf_discovery_id;
  307 + __u8 rf_protocol;
  308 + __u8 rf_tech_and_mode;
  309 + __u8 rf_tech_specific_params_len;
  310 +
  311 + union {
  312 + struct rf_tech_specific_params_nfca_poll nfca_poll;
  313 + struct rf_tech_specific_params_nfcb_poll nfcb_poll;
  314 + struct rf_tech_specific_params_nfcf_poll nfcf_poll;
  315 + } rf_tech_specific_params;
  316 +
  317 + __u8 ntf_type;
  318 +} __packed;
  319 +
  320 +#define NCI_OP_RF_INTF_ACTIVATED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
289 321 struct activation_params_nfca_poll_iso_dep {
290 322 __u8 rats_res_len;
291 323 __u8 rats_res[20];
include/net/nfc/nci_core.h
... ... @@ -46,6 +46,8 @@
46 46 enum nci_state {
47 47 NCI_IDLE,
48 48 NCI_DISCOVERY,
  49 + NCI_W4_ALL_DISCOVERIES,
  50 + NCI_W4_HOST_SELECT,
49 51 NCI_POLL_ACTIVE,
50 52 };
51 53  
... ... @@ -53,6 +55,7 @@
53 55 #define NCI_RESET_TIMEOUT 5000
54 56 #define NCI_INIT_TIMEOUT 5000
55 57 #define NCI_RF_DISC_TIMEOUT 5000
  58 +#define NCI_RF_DISC_SELECT_TIMEOUT 5000
56 59 #define NCI_RF_DEACTIVATE_TIMEOUT 30000
57 60 #define NCI_CMD_TIMEOUT 5000
58 61 #define NCI_DATA_TIMEOUT 700
... ... @@ -66,6 +69,7 @@
66 69 };
67 70  
68 71 #define NCI_MAX_SUPPORTED_RF_INTERFACES 4
  72 +#define NCI_MAX_DISCOVERED_TARGETS 10
69 73  
70 74 /* NCI Core structures */
71 75 struct nci_dev {
72 76  
... ... @@ -105,9 +109,11 @@
105 109 void *driver_data;
106 110  
107 111 __u32 poll_prots;
108   - __u32 target_available_prots;
109 112 __u32 target_active_prot;
110 113  
  114 + struct nfc_target targets[NCI_MAX_DISCOVERED_TARGETS];
  115 + int n_targets;
  116 +
111 117 /* received during NCI_OP_CORE_RESET_RSP */
112 118 __u8 nci_ver;
113 119  
... ... @@ -178,6 +184,7 @@
178 184 int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb);
179 185 void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
180 186 int err);
  187 +void nci_clear_target_list(struct nci_dev *ndev);
181 188  
182 189 /* ----- NCI requests ----- */
183 190 #define NCI_REQ_DONE 0
... ... @@ -216,6 +216,39 @@
216 216 &cmd);
217 217 }
218 218  
  219 +struct nci_rf_discover_select_param {
  220 + __u8 rf_discovery_id;
  221 + __u8 rf_protocol;
  222 +};
  223 +
  224 +static 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 +
219 252 static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
220 253 {
221 254 struct nci_rf_deactivate_cmd cmd;
... ... @@ -264,6 +297,7 @@
264 297  
265 298 if (!rc) {
266 299 set_bit(NCI_UP, &ndev->flags);
  300 + nci_clear_target_list(ndev);
267 301 atomic_set(&ndev->state, NCI_IDLE);
268 302 } else {
269 303 /* Init failed, cleanup */
... ... @@ -361,7 +395,8 @@
361 395 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
362 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 400 pr_err("unable to start poll, since poll is already active\n");
366 401 return -EBUSY;
367 402 }
... ... @@ -371,8 +406,9 @@
371 406 return -EBUSY;
372 407 }
373 408  
374   - if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) {
375   - pr_debug("target is active, implicitly deactivate...\n");
  409 + if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
  410 + (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
  411 + pr_debug("target active or w4 select, implicitly deactivate\n");
376 412  
377 413 rc = nci_request(ndev, nci_rf_deactivate_req, 0,
378 414 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
... ... @@ -393,7 +429,8 @@
393 429 {
394 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 434 pr_err("unable to stop poll, since poll is not active\n");
398 435 return;
399 436 }
400 437  
... ... @@ -406,10 +443,15 @@
406 443 __u32 protocol)
407 444 {
408 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 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 455 pr_err("there is no available target to activate\n");
414 456 return -EINVAL;
415 457 }
416 458  
417 459  
... ... @@ -419,16 +461,47 @@
419 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 477 pr_err("target does not support the requested protocol 0x%x\n",
424 478 protocol);
425 479 return -EINVAL;
426 480 }
427 481  
428   - ndev->target_active_prot = protocol;
429   - ndev->target_available_prots = 0;
  482 + if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
  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  
434 507 static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
... ... @@ -71,6 +71,20 @@
71 71 queue_work(ndev->tx_wq, &ndev->tx_work);
72 72 }
73 73  
  74 +static 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 +
74 88 static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
75 89 struct sk_buff *skb)
76 90 {
77 91  
... ... @@ -86,12 +100,9 @@
86 100 }
87 101  
88 102 static __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 106 nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
96 107 data += 2;
97 108  
98 109  
... ... @@ -116,12 +127,9 @@
116 127 }
117 128  
118 129 static __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 133 nfcb_poll->sensb_res_len = *data++;
126 134  
127 135 pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len);
128 136  
... ... @@ -133,12 +141,9 @@
133 141 }
134 142  
135 143 static __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 147 nfcf_poll->bit_rate = *data++;
143 148 nfcf_poll->sensf_res_len = *data++;
144 149  
... ... @@ -151,6 +156,172 @@
151 156 return data;
152 157 }
153 158  
  159 +static 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 +
  222 +static 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 +
  259 +void 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 +
  267 +static 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 +
154 325 static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
155 326 struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
156 327 {
157 328  
158 329  
159 330  
160 331  
161 332  
162 333  
163 334  
164 335  
165 336  
... ... @@ -184,74 +355,32 @@
184 355 default:
185 356 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
186 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  
193   -static void nci_target_found(struct nci_dev *ndev,
194   - struct nci_rf_intf_activated_ntf *ntf)
  364 +static void nci_target_auto_activated(struct nci_dev *ndev,
  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)
201   - nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK;
202   - else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)
203   - nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK;
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");
  372 + rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
  373 + ntf->activation_rf_tech_and_mode,
  374 + &ntf->rf_tech_specific_params);
  375 + if (rc)
209 376 return;
210   - }
211 377  
212   - pr_debug("new target found, supported_protocols 0x%x\n",
213   - nfc_tgt.supported_protocols);
  378 + target->idx = ntf->rf_discovery_id;
  379 + ndev->n_targets++;
214 380  
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   - }
  381 + pr_debug("target_idx %d, n_targets %d\n", target->idx, ndev->n_targets);
246 382  
247   - ndev->target_available_prots = nfc_tgt.supported_protocols;
248   - ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size;
249   - ndev->initial_num_credits = ntf->initial_num_credits;
250   -
251   - /* set the available credits to initial value */
252   - atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
253   -
254   - nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
  383 + nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets);
255 384 }
256 385  
257 386 static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
258 387  
... ... @@ -259,10 +388,8 @@
259 388 {
260 389 struct nci_rf_intf_activated_ntf ntf;
261 390 __u8 *data = skb->data;
262   - int err = 0;
  391 + int err = NCI_STATUS_OK;
263 392  
264   - atomic_set(&ndev->state, NCI_POLL_ACTIVE);
265   -
266 393 ntf.rf_discovery_id = *data++;
267 394 ntf.rf_interface = *data++;
268 395 ntf.rf_protocol = *data++;
269 396  
270 397  
271 398  
... ... @@ -286,23 +413,24 @@
286 413 switch (ntf.activation_rf_tech_and_mode) {
287 414 case NCI_NFC_A_PASSIVE_POLL_MODE:
288 415 data = nci_extract_rf_params_nfca_passive_poll(ndev,
289   - &ntf, data);
  416 + &(ntf.rf_tech_specific_params.nfca_poll), data);
290 417 break;
291 418  
292 419 case NCI_NFC_B_PASSIVE_POLL_MODE:
293 420 data = nci_extract_rf_params_nfcb_passive_poll(ndev,
294   - &ntf, data);
  421 + &(ntf.rf_tech_specific_params.nfcb_poll), data);
295 422 break;
296 423  
297 424 case NCI_NFC_F_PASSIVE_POLL_MODE:
298 425 data = nci_extract_rf_params_nfcf_passive_poll(ndev,
299   - &ntf, data);
  426 + &(ntf.rf_tech_specific_params.nfcf_poll), data);
300 427 break;
301 428  
302 429 default:
303 430 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
304 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  
309 437  
... ... @@ -334,12 +462,30 @@
334 462 default:
335 463 pr_err("unsupported rf_interface 0x%x\n",
336 464 ntf.rf_interface);
337   - return;
  465 + err = NCI_STATUS_RF_PROTOCOL_ERROR;
  466 + break;
338 467 }
339 468 }
340 469  
341   - if (!err)
342   - nci_target_found(ndev, &ntf);
  470 +exit:
  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  
345 491 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
... ... @@ -349,9 +495,6 @@
349 495  
350 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 498 /* drop tx data queue */
356 499 skb_queue_purge(&ndev->tx_q);
357 500  
... ... @@ -365,6 +508,8 @@
365 508 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
366 509 nci_data_exchange_complete(ndev, NULL, -EIO);
367 510  
  511 + nci_clear_target_list(ndev);
  512 + atomic_set(&ndev->state, NCI_IDLE);
368 513 nci_req_complete(ndev, NCI_STATUS_OK);
369 514 }
370 515  
371 516  
... ... @@ -386,8 +531,16 @@
386 531 nci_core_conn_credits_ntf_packet(ndev, skb);
387 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 538 case NCI_OP_CORE_INTF_ERROR_NTF:
390 539 nci_core_conn_intf_error_ntf_packet(ndev, skb);
  540 + break;
  541 +
  542 + case NCI_OP_RF_DISCOVER_NTF:
  543 + nci_rf_discover_ntf_packet(ndev, skb);
391 544 break;
392 545  
393 546 case NCI_OP_RF_INTF_ACTIVATED_NTF:
... ... @@ -142,6 +142,18 @@
142 142 nci_req_complete(ndev, status);
143 143 }
144 144  
  145 +static 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 +
145 157 static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
146 158 struct sk_buff *skb)
147 159 {
... ... @@ -152,6 +164,7 @@
152 164 /* If target was active, complete the request only in deactivate_ntf */
153 165 if ((status != NCI_STATUS_OK) ||
154 166 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
  167 + nci_clear_target_list(ndev);
155 168 atomic_set(&ndev->state, NCI_IDLE);
156 169 nci_req_complete(ndev, status);
157 170 }
... ... @@ -188,6 +201,10 @@
188 201  
189 202 case NCI_OP_RF_DISCOVER_RSP:
190 203 nci_rf_disc_rsp_packet(ndev, skb);
  204 + break;
  205 +
  206 + case NCI_OP_RF_DISCOVER_SELECT_RSP:
  207 + nci_rf_disc_select_rsp_packet(ndev, skb);
191 208 break;
192 209  
193 210 case NCI_OP_RF_DEACTIVATE_RSP: