Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ilan Elias and committed by
John W. Linville
019c4fba 25a1d9dc

+378 -96
+33 -1
include/net/nfc/nci.h
··· 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 ··· 212 207 struct disc_config disc_configs[NCI_MAX_NUM_RF_CONFIGS]; 213 208 } __packed; 214 209 210 + #define NCI_OP_RF_DISCOVER_SELECT_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x04) 211 + struct nci_rf_discover_select_cmd { 212 + __u8 rf_discovery_id; 213 + __u8 rf_protocol; 214 + __u8 rf_interface; 215 + } __packed; 216 + 215 217 #define NCI_OP_RF_DEACTIVATE_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) 216 218 struct nci_rf_deactivate_cmd { 217 219 __u8 type; ··· 256 244 257 245 #define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03) 258 246 247 + #define NCI_OP_RF_DISCOVER_SELECT_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x04) 248 + 259 249 #define NCI_OP_RF_DEACTIVATE_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) 260 250 261 251 /* --------------------------- */ ··· 274 260 struct conn_credit_entry conn_entries[NCI_MAX_NUM_CONN]; 275 261 } __packed; 276 262 263 + #define NCI_OP_CORE_GENERIC_ERROR_NTF nci_opcode_pack(NCI_GID_CORE, 0x07) 264 + 277 265 #define NCI_OP_CORE_INTF_ERROR_NTF nci_opcode_pack(NCI_GID_CORE, 0x08) 278 266 struct nci_core_intf_error_ntf { 279 267 __u8 status; 280 268 __u8 conn_id; 281 269 } __packed; 282 270 283 - #define NCI_OP_RF_INTF_ACTIVATED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05) 271 + #define NCI_OP_RF_DISCOVER_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x03) 284 272 struct rf_tech_specific_params_nfca_poll { 285 273 __u16 sens_res; 286 274 __u8 nfcid1_len; /* 0, 4, 7, or 10 Bytes */ ··· 302 286 __u8 sensf_res[18]; /* 16 or 18 Bytes */ 303 287 } __packed; 304 288 289 + struct nci_rf_discover_ntf { 290 + __u8 rf_discovery_id; 291 + __u8 rf_protocol; 292 + __u8 rf_tech_and_mode; 293 + __u8 rf_tech_specific_params_len; 294 + 295 + union { 296 + struct rf_tech_specific_params_nfca_poll nfca_poll; 297 + struct rf_tech_specific_params_nfcb_poll nfcb_poll; 298 + struct rf_tech_specific_params_nfcf_poll nfcf_poll; 299 + } rf_tech_specific_params; 300 + 301 + __u8 ntf_type; 302 + } __packed; 303 + 304 + #define NCI_OP_RF_INTF_ACTIVATED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05) 305 305 struct activation_params_nfca_poll_iso_dep { 306 306 __u8 rats_res_len; 307 307 __u8 rats_res[20];
+8 -1
include/net/nfc/nci_core.h
··· 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 ··· 55 53 #define NCI_RESET_TIMEOUT 5000 56 54 #define NCI_INIT_TIMEOUT 5000 57 55 #define NCI_RF_DISC_TIMEOUT 5000 56 + #define NCI_RF_DISC_SELECT_TIMEOUT 5000 58 57 #define NCI_RF_DEACTIVATE_TIMEOUT 30000 59 58 #define NCI_CMD_TIMEOUT 5000 60 59 #define NCI_DATA_TIMEOUT 700 ··· 69 66 }; 70 67 71 68 #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 69 + #define NCI_MAX_DISCOVERED_TARGETS 10 72 70 73 71 /* NCI Core structures */ 74 72 struct nci_dev { ··· 109 105 void *driver_data; 110 106 111 107 __u32 poll_prots; 112 - __u32 target_available_prots; 113 108 __u32 target_active_prot; 109 + 110 + struct nfc_target targets[NCI_MAX_DISCOVERED_TARGETS]; 111 + int n_targets; 114 112 115 113 /* received during NCI_OP_CORE_RESET_RSP */ 116 114 __u8 nci_ver; ··· 184 178 int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); 185 179 void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, 186 180 int err); 181 + void nci_clear_target_list(struct nci_dev *ndev); 187 182 188 183 /* ----- NCI requests ----- */ 189 184 #define NCI_REQ_DONE 0
+82 -9
net/nfc/nci/core.c
··· 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; ··· 297 264 298 265 if (!rc) { 299 266 set_bit(NCI_UP, &ndev->flags); 267 + nci_clear_target_list(ndev); 300 268 atomic_set(&ndev->state, NCI_IDLE); 301 269 } else { 302 270 /* Init failed, cleanup */ ··· 395 361 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 396 362 int rc; 397 363 398 - if (atomic_read(&ndev->state) == NCI_DISCOVERY) { 364 + if ((atomic_read(&ndev->state) == NCI_DISCOVERY) || 365 + (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) { 399 366 pr_err("unable to start poll, since poll is already active\n"); 400 367 return -EBUSY; 401 368 } ··· 406 371 return -EBUSY; 407 372 } 408 373 409 - if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) { 410 - pr_debug("target is active, implicitly deactivate...\n"); 374 + if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) || 375 + (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) { 376 + pr_debug("target active or w4 select, implicitly deactivate\n"); 411 377 412 378 rc = nci_request(ndev, nci_rf_deactivate_req, 0, 413 379 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); ··· 429 393 { 430 394 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 431 395 432 - if (atomic_read(&ndev->state) != NCI_DISCOVERY) { 396 + if ((atomic_read(&ndev->state) != NCI_DISCOVERY) && 397 + (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) { 433 398 pr_err("unable to stop poll, since poll is not active\n"); 434 399 return; 435 400 } ··· 443 406 __u32 protocol) 444 407 { 445 408 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 409 + struct nci_rf_discover_select_param param; 410 + struct nfc_target *target = 0; 411 + int i; 412 + int rc = 0; 446 413 447 414 pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol); 448 415 449 - if (atomic_read(&ndev->state) != NCI_POLL_ACTIVE) { 416 + if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) && 417 + (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { 450 418 pr_err("there is no available target to activate\n"); 451 419 return -EINVAL; 452 420 } ··· 461 419 return -EBUSY; 462 420 } 463 421 464 - if (!(ndev->target_available_prots & (1 << protocol))) { 422 + for (i = 0; i < ndev->n_targets; i++) { 423 + if (ndev->targets[i].idx == target_idx) { 424 + target = &ndev->targets[i]; 425 + break; 426 + } 427 + } 428 + 429 + if (!target) { 430 + pr_err("unable to find the selected target\n"); 431 + return -EINVAL; 432 + } 433 + 434 + if (!(target->supported_protocols & (1 << protocol))) { 465 435 pr_err("target does not support the requested protocol 0x%x\n", 466 436 protocol); 467 437 return -EINVAL; 468 438 } 469 439 470 - ndev->target_active_prot = protocol; 471 - ndev->target_available_prots = 0; 440 + if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) { 441 + param.rf_discovery_id = target->idx; 472 442 473 - return 0; 443 + if (protocol == NFC_PROTO_JEWEL) 444 + param.rf_protocol = NCI_RF_PROTOCOL_T1T; 445 + else if (protocol == NFC_PROTO_MIFARE) 446 + param.rf_protocol = NCI_RF_PROTOCOL_T2T; 447 + else if (protocol == NFC_PROTO_FELICA) 448 + param.rf_protocol = NCI_RF_PROTOCOL_T3T; 449 + else if (protocol == NFC_PROTO_ISO14443) 450 + param.rf_protocol = NCI_RF_PROTOCOL_ISO_DEP; 451 + else 452 + param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; 453 + 454 + rc = nci_request(ndev, nci_rf_discover_select_req, 455 + (unsigned long)&param, 456 + msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT)); 457 + } 458 + 459 + if (!rc) 460 + ndev->target_active_prot = protocol; 461 + 462 + return rc; 474 463 } 475 464 476 465 static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
+238 -85
net/nfc/nci/ntf.c
··· 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 { ··· 100 86 } 101 87 102 88 static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, 103 - struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 89 + struct rf_tech_specific_params_nfca_poll *nfca_poll, 90 + __u8 *data) 104 91 { 105 - struct rf_tech_specific_params_nfca_poll *nfca_poll; 106 - 107 - nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; 108 - 109 92 nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); 110 93 data += 2; 111 94 ··· 127 116 } 128 117 129 118 static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, 130 - struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 119 + struct rf_tech_specific_params_nfcb_poll *nfcb_poll, 120 + __u8 *data) 131 121 { 132 - struct rf_tech_specific_params_nfcb_poll *nfcb_poll; 133 - 134 - nfcb_poll = &ntf->rf_tech_specific_params.nfcb_poll; 135 - 136 122 nfcb_poll->sensb_res_len = *data++; 137 123 138 124 pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); ··· 141 133 } 142 134 143 135 static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, 144 - struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 136 + struct rf_tech_specific_params_nfcf_poll *nfcf_poll, 137 + __u8 *data) 145 138 { 146 - struct rf_tech_specific_params_nfcf_poll *nfcf_poll; 147 - 148 - nfcf_poll = &ntf->rf_tech_specific_params.nfcf_poll; 149 - 150 139 nfcf_poll->bit_rate = *data++; 151 140 nfcf_poll->sensf_res_len = *data++; 152 141 ··· 154 149 data += nfcf_poll->sensf_res_len; 155 150 156 151 return data; 152 + } 153 + 154 + static int nci_add_new_protocol(struct nci_dev *ndev, 155 + struct nfc_target *target, 156 + __u8 rf_protocol, 157 + __u8 rf_tech_and_mode, 158 + void *params) 159 + { 160 + struct rf_tech_specific_params_nfca_poll *nfca_poll; 161 + struct rf_tech_specific_params_nfcb_poll *nfcb_poll; 162 + struct rf_tech_specific_params_nfcf_poll *nfcf_poll; 163 + __u32 protocol; 164 + 165 + if (rf_protocol == NCI_RF_PROTOCOL_T2T) 166 + protocol = NFC_PROTO_MIFARE_MASK; 167 + else if (rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) 168 + protocol = NFC_PROTO_ISO14443_MASK; 169 + else if (rf_protocol == NCI_RF_PROTOCOL_T3T) 170 + protocol = NFC_PROTO_FELICA_MASK; 171 + else 172 + protocol = 0; 173 + 174 + if (!(protocol & ndev->poll_prots)) { 175 + pr_err("the target found does not have the desired protocol\n"); 176 + return -EPROTO; 177 + } 178 + 179 + if (rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) { 180 + nfca_poll = (struct rf_tech_specific_params_nfca_poll *)params; 181 + 182 + target->sens_res = nfca_poll->sens_res; 183 + target->sel_res = nfca_poll->sel_res; 184 + target->nfcid1_len = nfca_poll->nfcid1_len; 185 + if (target->nfcid1_len > 0) { 186 + memcpy(target->nfcid1, nfca_poll->nfcid1, 187 + target->nfcid1_len); 188 + } 189 + } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) { 190 + nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params; 191 + 192 + target->sensb_res_len = nfcb_poll->sensb_res_len; 193 + if (target->sensb_res_len > 0) { 194 + memcpy(target->sensb_res, nfcb_poll->sensb_res, 195 + target->sensb_res_len); 196 + } 197 + } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) { 198 + nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params; 199 + 200 + target->sensf_res_len = nfcf_poll->sensf_res_len; 201 + if (target->sensf_res_len > 0) { 202 + memcpy(target->sensf_res, nfcf_poll->sensf_res, 203 + target->sensf_res_len); 204 + } 205 + } else { 206 + pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode); 207 + return -EPROTO; 208 + } 209 + 210 + target->supported_protocols |= protocol; 211 + 212 + pr_debug("protocol 0x%x\n", protocol); 213 + 214 + return 0; 215 + } 216 + 217 + static void nci_add_new_target(struct nci_dev *ndev, 218 + struct nci_rf_discover_ntf *ntf) 219 + { 220 + struct nfc_target *target; 221 + int i, rc; 222 + 223 + for (i = 0; i < ndev->n_targets; i++) { 224 + target = &ndev->targets[i]; 225 + if (target->idx == ntf->rf_discovery_id) { 226 + /* This target already exists, add the new protocol */ 227 + nci_add_new_protocol(ndev, target, ntf->rf_protocol, 228 + ntf->rf_tech_and_mode, 229 + &ntf->rf_tech_specific_params); 230 + return; 231 + } 232 + } 233 + 234 + /* This is a new target, check if we've enough room */ 235 + if (ndev->n_targets == NCI_MAX_DISCOVERED_TARGETS) { 236 + pr_debug("not enough room, ignoring new target...\n"); 237 + return; 238 + } 239 + 240 + target = &ndev->targets[ndev->n_targets]; 241 + 242 + rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, 243 + ntf->rf_tech_and_mode, 244 + &ntf->rf_tech_specific_params); 245 + if (!rc) { 246 + target->idx = ntf->rf_discovery_id; 247 + ndev->n_targets++; 248 + 249 + pr_debug("target_idx %d, n_targets %d\n", target->idx, 250 + ndev->n_targets); 251 + } 252 + } 253 + 254 + void nci_clear_target_list(struct nci_dev *ndev) 255 + { 256 + memset(ndev->targets, 0, 257 + (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS)); 258 + 259 + ndev->n_targets = 0; 260 + } 261 + 262 + static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, 263 + struct sk_buff *skb) 264 + { 265 + struct nci_rf_discover_ntf ntf; 266 + __u8 *data = skb->data; 267 + bool add_target = true; 268 + 269 + ntf.rf_discovery_id = *data++; 270 + ntf.rf_protocol = *data++; 271 + ntf.rf_tech_and_mode = *data++; 272 + ntf.rf_tech_specific_params_len = *data++; 273 + 274 + pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id); 275 + pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol); 276 + pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode); 277 + pr_debug("rf_tech_specific_params_len %d\n", 278 + ntf.rf_tech_specific_params_len); 279 + 280 + if (ntf.rf_tech_specific_params_len > 0) { 281 + switch (ntf.rf_tech_and_mode) { 282 + case NCI_NFC_A_PASSIVE_POLL_MODE: 283 + data = nci_extract_rf_params_nfca_passive_poll(ndev, 284 + &(ntf.rf_tech_specific_params.nfca_poll), data); 285 + break; 286 + 287 + case NCI_NFC_B_PASSIVE_POLL_MODE: 288 + data = nci_extract_rf_params_nfcb_passive_poll(ndev, 289 + &(ntf.rf_tech_specific_params.nfcb_poll), data); 290 + break; 291 + 292 + case NCI_NFC_F_PASSIVE_POLL_MODE: 293 + data = nci_extract_rf_params_nfcf_passive_poll(ndev, 294 + &(ntf.rf_tech_specific_params.nfcf_poll), data); 295 + break; 296 + 297 + default: 298 + pr_err("unsupported rf_tech_and_mode 0x%x\n", 299 + ntf.rf_tech_and_mode); 300 + data += ntf.rf_tech_specific_params_len; 301 + add_target = false; 302 + } 303 + } 304 + 305 + ntf.ntf_type = *data++; 306 + pr_debug("ntf_type %d\n", ntf.ntf_type); 307 + 308 + if (add_target == true) 309 + nci_add_new_target(ndev, &ntf); 310 + 311 + if (ntf.ntf_type == NCI_DISCOVER_NTF_TYPE_MORE) { 312 + atomic_set(&ndev->state, NCI_W4_ALL_DISCOVERIES); 313 + } else { 314 + atomic_set(&ndev->state, NCI_W4_HOST_SELECT); 315 + nfc_targets_found(ndev->nfc_dev, ndev->targets, 316 + ndev->n_targets); 317 + } 157 318 } 158 319 159 320 static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, ··· 355 184 default: 356 185 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", 357 186 ntf->activation_rf_tech_and_mode); 358 - return -EPROTO; 187 + return NCI_STATUS_RF_PROTOCOL_ERROR; 359 188 } 360 189 361 - return 0; 190 + return NCI_STATUS_OK; 362 191 } 363 192 364 - static void nci_target_found(struct nci_dev *ndev, 365 - struct nci_rf_intf_activated_ntf *ntf) 193 + static void nci_target_auto_activated(struct nci_dev *ndev, 194 + struct nci_rf_intf_activated_ntf *ntf) 366 195 { 367 - struct nfc_target nfc_tgt; 196 + struct nfc_target *target; 197 + int rc; 368 198 369 - memset(&nfc_tgt, 0, sizeof(nfc_tgt)); 199 + target = &ndev->targets[ndev->n_targets]; 370 200 371 - if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T) 372 - nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; 373 - else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) 374 - nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; 375 - else if (ntf->rf_protocol == NCI_RF_PROTOCOL_T3T) 376 - nfc_tgt.supported_protocols = NFC_PROTO_FELICA_MASK; 377 - 378 - if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) { 379 - pr_debug("the target found does not have the desired protocol\n"); 201 + rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, 202 + ntf->activation_rf_tech_and_mode, 203 + &ntf->rf_tech_specific_params); 204 + if (rc) 380 205 return; 381 - } 382 206 383 - pr_debug("new target found, supported_protocols 0x%x\n", 384 - nfc_tgt.supported_protocols); 207 + target->idx = ntf->rf_discovery_id; 208 + ndev->n_targets++; 385 209 386 - if (ntf->activation_rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) { 387 - nfc_tgt.sens_res = 388 - ntf->rf_tech_specific_params.nfca_poll.sens_res; 389 - nfc_tgt.sel_res = 390 - ntf->rf_tech_specific_params.nfca_poll.sel_res; 391 - nfc_tgt.nfcid1_len = 392 - ntf->rf_tech_specific_params.nfca_poll.nfcid1_len; 393 - if (nfc_tgt.nfcid1_len > 0) { 394 - memcpy(nfc_tgt.nfcid1, 395 - ntf->rf_tech_specific_params.nfca_poll.nfcid1, 396 - nfc_tgt.nfcid1_len); 397 - } 398 - } else if (ntf->activation_rf_tech_and_mode == 399 - NCI_NFC_B_PASSIVE_POLL_MODE) { 400 - nfc_tgt.sensb_res_len = 401 - ntf->rf_tech_specific_params.nfcb_poll.sensb_res_len; 402 - if (nfc_tgt.sensb_res_len > 0) { 403 - memcpy(nfc_tgt.sensb_res, 404 - ntf->rf_tech_specific_params.nfcb_poll.sensb_res, 405 - nfc_tgt.sensb_res_len); 406 - } 407 - } else if (ntf->activation_rf_tech_and_mode == 408 - NCI_NFC_F_PASSIVE_POLL_MODE) { 409 - nfc_tgt.sensf_res_len = 410 - ntf->rf_tech_specific_params.nfcf_poll.sensf_res_len; 411 - if (nfc_tgt.sensf_res_len > 0) { 412 - memcpy(nfc_tgt.sensf_res, 413 - ntf->rf_tech_specific_params.nfcf_poll.sensf_res, 414 - nfc_tgt.sensf_res_len); 415 - } 416 - } 210 + pr_debug("target_idx %d, n_targets %d\n", target->idx, ndev->n_targets); 417 211 418 - ndev->target_available_prots = nfc_tgt.supported_protocols; 419 - ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size; 420 - ndev->initial_num_credits = ntf->initial_num_credits; 421 - 422 - /* set the available credits to initial value */ 423 - atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); 424 - 425 - nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); 212 + nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets); 426 213 } 427 214 428 215 static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, ··· 388 259 { 389 260 struct nci_rf_intf_activated_ntf ntf; 390 261 __u8 *data = skb->data; 391 - int err = 0; 392 - 393 - atomic_set(&ndev->state, NCI_POLL_ACTIVE); 262 + int err = NCI_STATUS_OK; 394 263 395 264 ntf.rf_discovery_id = *data++; 396 265 ntf.rf_interface = *data++; ··· 413 286 switch (ntf.activation_rf_tech_and_mode) { 414 287 case NCI_NFC_A_PASSIVE_POLL_MODE: 415 288 data = nci_extract_rf_params_nfca_passive_poll(ndev, 416 - &ntf, data); 289 + &(ntf.rf_tech_specific_params.nfca_poll), data); 417 290 break; 418 291 419 292 case NCI_NFC_B_PASSIVE_POLL_MODE: 420 293 data = nci_extract_rf_params_nfcb_passive_poll(ndev, 421 - &ntf, data); 294 + &(ntf.rf_tech_specific_params.nfcb_poll), data); 422 295 break; 423 296 424 297 case NCI_NFC_F_PASSIVE_POLL_MODE: 425 298 data = nci_extract_rf_params_nfcf_passive_poll(ndev, 426 - &ntf, data); 299 + &(ntf.rf_tech_specific_params.nfcf_poll), data); 427 300 break; 428 301 429 302 default: 430 303 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", 431 304 ntf.activation_rf_tech_and_mode); 432 - return; 305 + err = NCI_STATUS_RF_PROTOCOL_ERROR; 306 + goto exit; 433 307 } 434 308 } 435 309 ··· 462 334 default: 463 335 pr_err("unsupported rf_interface 0x%x\n", 464 336 ntf.rf_interface); 465 - return; 337 + err = NCI_STATUS_RF_PROTOCOL_ERROR; 338 + break; 466 339 } 467 340 } 468 341 469 - if (!err) 470 - nci_target_found(ndev, &ntf); 342 + exit: 343 + if (err == NCI_STATUS_OK) { 344 + ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size; 345 + ndev->initial_num_credits = ntf.initial_num_credits; 346 + 347 + /* set the available credits to initial value */ 348 + atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); 349 + } 350 + 351 + if (atomic_read(&ndev->state) == NCI_DISCOVERY) { 352 + /* A single target was found and activated automatically */ 353 + atomic_set(&ndev->state, NCI_POLL_ACTIVE); 354 + if (err == NCI_STATUS_OK) 355 + nci_target_auto_activated(ndev, &ntf); 356 + } else { /* ndev->state == NCI_W4_HOST_SELECT */ 357 + /* A selected target was activated, so complete the request */ 358 + atomic_set(&ndev->state, NCI_POLL_ACTIVE); 359 + nci_req_complete(ndev, err); 360 + } 471 361 } 472 362 473 363 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, ··· 494 348 struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; 495 349 496 350 pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason); 497 - 498 - atomic_set(&ndev->state, NCI_IDLE); 499 - ndev->target_active_prot = 0; 500 351 501 352 /* drop tx data queue */ 502 353 skb_queue_purge(&ndev->tx_q); ··· 508 365 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) 509 366 nci_data_exchange_complete(ndev, NULL, -EIO); 510 367 368 + nci_clear_target_list(ndev); 369 + atomic_set(&ndev->state, NCI_IDLE); 511 370 nci_req_complete(ndev, NCI_STATUS_OK); 512 371 } 513 372 ··· 531 386 nci_core_conn_credits_ntf_packet(ndev, skb); 532 387 break; 533 388 389 + case NCI_OP_CORE_GENERIC_ERROR_NTF: 390 + nci_core_generic_error_ntf_packet(ndev, skb); 391 + break; 392 + 534 393 case NCI_OP_CORE_INTF_ERROR_NTF: 535 394 nci_core_conn_intf_error_ntf_packet(ndev, skb); 395 + break; 396 + 397 + case NCI_OP_RF_DISCOVER_NTF: 398 + nci_rf_discover_ntf_packet(ndev, skb); 536 399 break; 537 400 538 401 case NCI_OP_RF_INTF_ACTIVATED_NTF:
+17
net/nfc/nci/rsp.c
··· 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 { ··· 164 152 /* If target was active, complete the request only in deactivate_ntf */ 165 153 if ((status != NCI_STATUS_OK) || 166 154 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { 155 + nci_clear_target_list(ndev); 167 156 atomic_set(&ndev->state, NCI_IDLE); 168 157 nci_req_complete(ndev, status); 169 158 } ··· 201 188 202 189 case NCI_OP_RF_DISCOVER_RSP: 203 190 nci_rf_disc_rsp_packet(ndev, skb); 191 + break; 192 + 193 + case NCI_OP_RF_DISCOVER_SELECT_RSP: 194 + nci_rf_disc_select_rsp_packet(ndev, skb); 204 195 break; 205 196 206 197 case NCI_OP_RF_DEACTIVATE_RSP: