linux/net/nfc/nci/ntf.c
<<
>>
Prefs
   1/*
   2 *  The NFC Controller Interface is the communication protocol between an
   3 *  NFC Controller (NFCC) and a Device Host (DH).
   4 *
   5 *  Copyright (C) 2011 Texas Instruments, Inc.
   6 *
   7 *  Written by Ilan Elias <ilane@ti.com>
   8 *
   9 *  Acknowledgements:
  10 *  This file is based on hci_event.c, which was written
  11 *  by Maxim Krasnyansky.
  12 *
  13 *  This program is free software; you can redistribute it and/or modify
  14 *  it under the terms of the GNU General Public License version 2
  15 *  as published by the Free Software Foundation
  16 *
  17 *  This program is distributed in the hope that it will be useful,
  18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 *  GNU General Public License for more details.
  21 *
  22 *  You should have received a copy of the GNU General Public License
  23 *  along with this program; if not, write to the Free Software
  24 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  25 *
  26 */
  27
  28#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
  29
  30#include <linux/types.h>
  31#include <linux/interrupt.h>
  32#include <linux/bitops.h>
  33#include <linux/skbuff.h>
  34
  35#include "../nfc.h"
  36#include <net/nfc/nci.h>
  37#include <net/nfc/nci_core.h>
  38#include <linux/nfc.h>
  39
  40/* Handle NCI Notification packets */
  41
  42static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
  43                                             struct sk_buff *skb)
  44{
  45        struct nci_core_conn_credit_ntf *ntf = (void *) skb->data;
  46        int i;
  47
  48        pr_debug("num_entries %d\n", ntf->num_entries);
  49
  50        if (ntf->num_entries > NCI_MAX_NUM_CONN)
  51                ntf->num_entries = NCI_MAX_NUM_CONN;
  52
  53        /* update the credits */
  54        for (i = 0; i < ntf->num_entries; i++) {
  55                ntf->conn_entries[i].conn_id =
  56                        nci_conn_id(&ntf->conn_entries[i].conn_id);
  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);
  61
  62                if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
  63                        /* found static rf connection */
  64                        atomic_add(ntf->conn_entries[i].credits,
  65                                   &ndev->credits_cnt);
  66                }
  67        }
  68
  69        /* trigger the next tx */
  70        if (!skb_queue_empty(&ndev->tx_q))
  71                queue_work(ndev->tx_wq, &ndev->tx_work);
  72}
  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
  88static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
  89                                                struct sk_buff *skb)
  90{
  91        struct nci_core_intf_error_ntf *ntf = (void *) skb->data;
  92
  93        ntf->conn_id = nci_conn_id(&ntf->conn_id);
  94
  95        pr_debug("status 0x%x, conn_id %d\n", ntf->status, ntf->conn_id);
  96
  97        /* complete the data exchange transaction, if exists */
  98        if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
  99                nci_data_exchange_complete(ndev, NULL, -EIO);
 100}
 101
 102static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
 103                        struct rf_tech_specific_params_nfca_poll *nfca_poll,
 104                                                     __u8 *data)
 105{
 106        nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
 107        data += 2;
 108
 109        nfca_poll->nfcid1_len = min_t(__u8, *data++, NFC_NFCID1_MAXSIZE);
 110
 111        pr_debug("sens_res 0x%x, nfcid1_len %d\n",
 112                 nfca_poll->sens_res, nfca_poll->nfcid1_len);
 113
 114        memcpy(nfca_poll->nfcid1, data, nfca_poll->nfcid1_len);
 115        data += nfca_poll->nfcid1_len;
 116
 117        nfca_poll->sel_res_len = *data++;
 118
 119        if (nfca_poll->sel_res_len != 0)
 120                nfca_poll->sel_res = *data++;
 121
 122        pr_debug("sel_res_len %d, sel_res 0x%x\n",
 123                 nfca_poll->sel_res_len,
 124                 nfca_poll->sel_res);
 125
 126        return data;
 127}
 128
 129static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
 130                        struct rf_tech_specific_params_nfcb_poll *nfcb_poll,
 131                                                     __u8 *data)
 132{
 133        nfcb_poll->sensb_res_len = min_t(__u8, *data++, NFC_SENSB_RES_MAXSIZE);
 134
 135        pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len);
 136
 137        memcpy(nfcb_poll->sensb_res, data, nfcb_poll->sensb_res_len);
 138        data += nfcb_poll->sensb_res_len;
 139
 140        return data;
 141}
 142
 143static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
 144                        struct rf_tech_specific_params_nfcf_poll *nfcf_poll,
 145                                                     __u8 *data)
 146{
 147        nfcf_poll->bit_rate = *data++;
 148        nfcf_poll->sensf_res_len = min_t(__u8, *data++, NFC_SENSF_RES_MAXSIZE);
 149
 150        pr_debug("bit_rate %d, sensf_res_len %d\n",
 151                 nfcf_poll->bit_rate, nfcf_poll->sensf_res_len);
 152
 153        memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len);
 154        data += nfcf_poll->sensf_res_len;
 155
 156        return data;
 157}
 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                if (rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE)
 174                        protocol = NFC_PROTO_ISO14443_MASK;
 175                else
 176                        protocol = NFC_PROTO_ISO14443_B_MASK;
 177        else if (rf_protocol == NCI_RF_PROTOCOL_T3T)
 178                protocol = NFC_PROTO_FELICA_MASK;
 179        else if (rf_protocol == NCI_RF_PROTOCOL_NFC_DEP)
 180                protocol = NFC_PROTO_NFC_DEP_MASK;
 181        else
 182                protocol = 0;
 183
 184        if (!(protocol & ndev->poll_prots)) {
 185                pr_err("the target found does not have the desired protocol\n");
 186                return -EPROTO;
 187        }
 188
 189        if (rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) {
 190                nfca_poll = (struct rf_tech_specific_params_nfca_poll *)params;
 191
 192                target->sens_res = nfca_poll->sens_res;
 193                target->sel_res = nfca_poll->sel_res;
 194                target->nfcid1_len = nfca_poll->nfcid1_len;
 195                if (target->nfcid1_len > 0) {
 196                        memcpy(target->nfcid1, nfca_poll->nfcid1,
 197                               target->nfcid1_len);
 198                }
 199        } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) {
 200                nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
 201
 202                target->sensb_res_len = nfcb_poll->sensb_res_len;
 203                if (target->sensb_res_len > 0) {
 204                        memcpy(target->sensb_res, nfcb_poll->sensb_res,
 205                               target->sensb_res_len);
 206                }
 207        } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) {
 208                nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
 209
 210                target->sensf_res_len = nfcf_poll->sensf_res_len;
 211                if (target->sensf_res_len > 0) {
 212                        memcpy(target->sensf_res, nfcf_poll->sensf_res,
 213                               target->sensf_res_len);
 214                }
 215        } else {
 216                pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
 217                return -EPROTO;
 218        }
 219
 220        target->supported_protocols |= protocol;
 221
 222        pr_debug("protocol 0x%x\n", protocol);
 223
 224        return 0;
 225}
 226
 227static void nci_add_new_target(struct nci_dev *ndev,
 228                               struct nci_rf_discover_ntf *ntf)
 229{
 230        struct nfc_target *target;
 231        int i, rc;
 232
 233        for (i = 0; i < ndev->n_targets; i++) {
 234                target = &ndev->targets[i];
 235                if (target->logical_idx == ntf->rf_discovery_id) {
 236                        /* This target already exists, add the new protocol */
 237                        nci_add_new_protocol(ndev, target, ntf->rf_protocol,
 238                                             ntf->rf_tech_and_mode,
 239                                             &ntf->rf_tech_specific_params);
 240                        return;
 241                }
 242        }
 243
 244        /* This is a new target, check if we've enough room */
 245        if (ndev->n_targets == NCI_MAX_DISCOVERED_TARGETS) {
 246                pr_debug("not enough room, ignoring new target...\n");
 247                return;
 248        }
 249
 250        target = &ndev->targets[ndev->n_targets];
 251
 252        rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
 253                                  ntf->rf_tech_and_mode,
 254                                  &ntf->rf_tech_specific_params);
 255        if (!rc) {
 256                target->logical_idx = ntf->rf_discovery_id;
 257                ndev->n_targets++;
 258
 259                pr_debug("logical idx %d, n_targets %d\n", target->logical_idx,
 260                         ndev->n_targets);
 261        }
 262}
 263
 264void nci_clear_target_list(struct nci_dev *ndev)
 265{
 266        memset(ndev->targets, 0,
 267               (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS));
 268
 269        ndev->n_targets = 0;
 270}
 271
 272static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
 273                                       struct sk_buff *skb)
 274{
 275        struct nci_rf_discover_ntf ntf;
 276        __u8 *data = skb->data;
 277        bool add_target = true;
 278
 279        ntf.rf_discovery_id = *data++;
 280        ntf.rf_protocol = *data++;
 281        ntf.rf_tech_and_mode = *data++;
 282        ntf.rf_tech_specific_params_len = *data++;
 283
 284        pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);
 285        pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
 286        pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode);
 287        pr_debug("rf_tech_specific_params_len %d\n",
 288                 ntf.rf_tech_specific_params_len);
 289
 290        if (ntf.rf_tech_specific_params_len > 0) {
 291                switch (ntf.rf_tech_and_mode) {
 292                case NCI_NFC_A_PASSIVE_POLL_MODE:
 293                        data = nci_extract_rf_params_nfca_passive_poll(ndev,
 294                                &(ntf.rf_tech_specific_params.nfca_poll), data);
 295                        break;
 296
 297                case NCI_NFC_B_PASSIVE_POLL_MODE:
 298                        data = nci_extract_rf_params_nfcb_passive_poll(ndev,
 299                                &(ntf.rf_tech_specific_params.nfcb_poll), data);
 300                        break;
 301
 302                case NCI_NFC_F_PASSIVE_POLL_MODE:
 303                        data = nci_extract_rf_params_nfcf_passive_poll(ndev,
 304                                &(ntf.rf_tech_specific_params.nfcf_poll), data);
 305                        break;
 306
 307                default:
 308                        pr_err("unsupported rf_tech_and_mode 0x%x\n",
 309                               ntf.rf_tech_and_mode);
 310                        data += ntf.rf_tech_specific_params_len;
 311                        add_target = false;
 312                }
 313        }
 314
 315        ntf.ntf_type = *data++;
 316        pr_debug("ntf_type %d\n", ntf.ntf_type);
 317
 318        if (add_target == true)
 319                nci_add_new_target(ndev, &ntf);
 320
 321        if (ntf.ntf_type == NCI_DISCOVER_NTF_TYPE_MORE) {
 322                atomic_set(&ndev->state, NCI_W4_ALL_DISCOVERIES);
 323        } else {
 324                atomic_set(&ndev->state, NCI_W4_HOST_SELECT);
 325                nfc_targets_found(ndev->nfc_dev, ndev->targets,
 326                                  ndev->n_targets);
 327        }
 328}
 329
 330static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
 331                        struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
 332{
 333        struct activation_params_nfca_poll_iso_dep *nfca_poll;
 334        struct activation_params_nfcb_poll_iso_dep *nfcb_poll;
 335
 336        switch (ntf->activation_rf_tech_and_mode) {
 337        case NCI_NFC_A_PASSIVE_POLL_MODE:
 338                nfca_poll = &ntf->activation_params.nfca_poll_iso_dep;
 339                nfca_poll->rats_res_len = min_t(__u8, *data++, 20);
 340                pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len);
 341                if (nfca_poll->rats_res_len > 0) {
 342                        memcpy(nfca_poll->rats_res,
 343                               data, nfca_poll->rats_res_len);
 344                }
 345                break;
 346
 347        case NCI_NFC_B_PASSIVE_POLL_MODE:
 348                nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep;
 349                nfcb_poll->attrib_res_len = min_t(__u8, *data++, 50);
 350                pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len);
 351                if (nfcb_poll->attrib_res_len > 0) {
 352                        memcpy(nfcb_poll->attrib_res,
 353                               data, nfcb_poll->attrib_res_len);
 354                }
 355                break;
 356
 357        default:
 358                pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
 359                       ntf->activation_rf_tech_and_mode);
 360                return NCI_STATUS_RF_PROTOCOL_ERROR;
 361        }
 362
 363        return NCI_STATUS_OK;
 364}
 365
 366static int nci_extract_activation_params_nfc_dep(struct nci_dev *ndev,
 367                        struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
 368{
 369        struct activation_params_poll_nfc_dep *poll;
 370        int i;
 371
 372        switch (ntf->activation_rf_tech_and_mode) {
 373        case NCI_NFC_A_PASSIVE_POLL_MODE:
 374        case NCI_NFC_F_PASSIVE_POLL_MODE:
 375                poll = &ntf->activation_params.poll_nfc_dep;
 376                poll->atr_res_len = min_t(__u8, *data++, 63);
 377                pr_debug("atr_res_len %d\n", poll->atr_res_len);
 378                if (poll->atr_res_len > 0) {
 379                        for (i = 0; i < poll->atr_res_len; i++)
 380                                poll->atr_res[poll->atr_res_len-1-i] = data[i];
 381                }
 382                break;
 383
 384        default:
 385                pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
 386                       ntf->activation_rf_tech_and_mode);
 387                return NCI_STATUS_RF_PROTOCOL_ERROR;
 388        }
 389
 390        return NCI_STATUS_OK;
 391}
 392
 393static void nci_target_auto_activated(struct nci_dev *ndev,
 394                                      struct nci_rf_intf_activated_ntf *ntf)
 395{
 396        struct nfc_target *target;
 397        int rc;
 398
 399        target = &ndev->targets[ndev->n_targets];
 400
 401        rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
 402                                  ntf->activation_rf_tech_and_mode,
 403                                  &ntf->rf_tech_specific_params);
 404        if (rc)
 405                return;
 406
 407        target->logical_idx = ntf->rf_discovery_id;
 408        ndev->n_targets++;
 409
 410        pr_debug("logical idx %d, n_targets %d\n",
 411                 target->logical_idx, ndev->n_targets);
 412
 413        nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets);
 414}
 415
 416static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 417                                             struct sk_buff *skb)
 418{
 419        struct nci_rf_intf_activated_ntf ntf;
 420        __u8 *data = skb->data;
 421        int err = NCI_STATUS_OK;
 422
 423        ntf.rf_discovery_id = *data++;
 424        ntf.rf_interface = *data++;
 425        ntf.rf_protocol = *data++;
 426        ntf.activation_rf_tech_and_mode = *data++;
 427        ntf.max_data_pkt_payload_size = *data++;
 428        ntf.initial_num_credits = *data++;
 429        ntf.rf_tech_specific_params_len = *data++;
 430
 431        pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);
 432        pr_debug("rf_interface 0x%x\n", ntf.rf_interface);
 433        pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
 434        pr_debug("activation_rf_tech_and_mode 0x%x\n",
 435                 ntf.activation_rf_tech_and_mode);
 436        pr_debug("max_data_pkt_payload_size 0x%x\n",
 437                 ntf.max_data_pkt_payload_size);
 438        pr_debug("initial_num_credits 0x%x\n",
 439                 ntf.initial_num_credits);
 440        pr_debug("rf_tech_specific_params_len %d\n",
 441                 ntf.rf_tech_specific_params_len);
 442
 443        if (ntf.rf_tech_specific_params_len > 0) {
 444                switch (ntf.activation_rf_tech_and_mode) {
 445                case NCI_NFC_A_PASSIVE_POLL_MODE:
 446                        data = nci_extract_rf_params_nfca_passive_poll(ndev,
 447                                &(ntf.rf_tech_specific_params.nfca_poll), data);
 448                        break;
 449
 450                case NCI_NFC_B_PASSIVE_POLL_MODE:
 451                        data = nci_extract_rf_params_nfcb_passive_poll(ndev,
 452                                &(ntf.rf_tech_specific_params.nfcb_poll), data);
 453                        break;
 454
 455                case NCI_NFC_F_PASSIVE_POLL_MODE:
 456                        data = nci_extract_rf_params_nfcf_passive_poll(ndev,
 457                                &(ntf.rf_tech_specific_params.nfcf_poll), data);
 458                        break;
 459
 460                default:
 461                        pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
 462                               ntf.activation_rf_tech_and_mode);
 463                        err = NCI_STATUS_RF_PROTOCOL_ERROR;
 464                        goto exit;
 465                }
 466        }
 467
 468        ntf.data_exch_rf_tech_and_mode = *data++;
 469        ntf.data_exch_tx_bit_rate = *data++;
 470        ntf.data_exch_rx_bit_rate = *data++;
 471        ntf.activation_params_len = *data++;
 472
 473        pr_debug("data_exch_rf_tech_and_mode 0x%x\n",
 474                 ntf.data_exch_rf_tech_and_mode);
 475        pr_debug("data_exch_tx_bit_rate 0x%x\n", ntf.data_exch_tx_bit_rate);
 476        pr_debug("data_exch_rx_bit_rate 0x%x\n", ntf.data_exch_rx_bit_rate);
 477        pr_debug("activation_params_len %d\n", ntf.activation_params_len);
 478
 479        if (ntf.activation_params_len > 0) {
 480                switch (ntf.rf_interface) {
 481                case NCI_RF_INTERFACE_ISO_DEP:
 482                        err = nci_extract_activation_params_iso_dep(ndev,
 483                                                                    &ntf, data);
 484                        break;
 485
 486                case NCI_RF_INTERFACE_NFC_DEP:
 487                        err = nci_extract_activation_params_nfc_dep(ndev,
 488                                                                    &ntf, data);
 489                        break;
 490
 491                case NCI_RF_INTERFACE_FRAME:
 492                        /* no activation params */
 493                        break;
 494
 495                default:
 496                        pr_err("unsupported rf_interface 0x%x\n",
 497                               ntf.rf_interface);
 498                        err = NCI_STATUS_RF_PROTOCOL_ERROR;
 499                        break;
 500                }
 501        }
 502
 503exit:
 504        if (err == NCI_STATUS_OK) {
 505                ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size;
 506                ndev->initial_num_credits = ntf.initial_num_credits;
 507
 508                /* set the available credits to initial value */
 509                atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
 510
 511                /* store general bytes to be reported later in dep_link_up */
 512                if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) {
 513                        ndev->remote_gb_len = 0;
 514
 515                        if (ntf.activation_params_len > 0) {
 516                                /* ATR_RES general bytes at offset 15 */
 517                                ndev->remote_gb_len = min_t(__u8,
 518                                        (ntf.activation_params
 519                                        .poll_nfc_dep.atr_res_len
 520                                        - NFC_ATR_RES_GT_OFFSET),
 521                                        NFC_MAX_GT_LEN);
 522                                memcpy(ndev->remote_gb,
 523                                       (ntf.activation_params.poll_nfc_dep
 524                                       .atr_res + NFC_ATR_RES_GT_OFFSET),
 525                                       ndev->remote_gb_len);
 526                        }
 527                }
 528        }
 529
 530        if (atomic_read(&ndev->state) == NCI_DISCOVERY) {
 531                /* A single target was found and activated automatically */
 532                atomic_set(&ndev->state, NCI_POLL_ACTIVE);
 533                if (err == NCI_STATUS_OK)
 534                        nci_target_auto_activated(ndev, &ntf);
 535        } else {        /* ndev->state == NCI_W4_HOST_SELECT */
 536                /* A selected target was activated, so complete the request */
 537                atomic_set(&ndev->state, NCI_POLL_ACTIVE);
 538                nci_req_complete(ndev, err);
 539        }
 540}
 541
 542static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
 543                                         struct sk_buff *skb)
 544{
 545        struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
 546
 547        pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
 548
 549        /* drop tx data queue */
 550        skb_queue_purge(&ndev->tx_q);
 551
 552        /* drop partial rx data packet */
 553        if (ndev->rx_data_reassembly) {
 554                kfree_skb(ndev->rx_data_reassembly);
 555                ndev->rx_data_reassembly = NULL;
 556        }
 557
 558        /* complete the data exchange transaction, if exists */
 559        if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
 560                nci_data_exchange_complete(ndev, NULL, -EIO);
 561
 562        nci_clear_target_list(ndev);
 563        atomic_set(&ndev->state, NCI_IDLE);
 564        nci_req_complete(ndev, NCI_STATUS_OK);
 565}
 566
 567void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
 568{
 569        __u16 ntf_opcode = nci_opcode(skb->data);
 570
 571        pr_debug("NCI RX: MT=ntf, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
 572                 nci_pbf(skb->data),
 573                 nci_opcode_gid(ntf_opcode),
 574                 nci_opcode_oid(ntf_opcode),
 575                 nci_plen(skb->data));
 576
 577        /* strip the nci control header */
 578        skb_pull(skb, NCI_CTRL_HDR_SIZE);
 579
 580        switch (ntf_opcode) {
 581        case NCI_OP_CORE_CONN_CREDITS_NTF:
 582                nci_core_conn_credits_ntf_packet(ndev, skb);
 583                break;
 584
 585        case NCI_OP_CORE_GENERIC_ERROR_NTF:
 586                nci_core_generic_error_ntf_packet(ndev, skb);
 587                break;
 588
 589        case NCI_OP_CORE_INTF_ERROR_NTF:
 590                nci_core_conn_intf_error_ntf_packet(ndev, skb);
 591                break;
 592
 593        case NCI_OP_RF_DISCOVER_NTF:
 594                nci_rf_discover_ntf_packet(ndev, skb);
 595                break;
 596
 597        case NCI_OP_RF_INTF_ACTIVATED_NTF:
 598                nci_rf_intf_activated_ntf_packet(ndev, skb);
 599                break;
 600
 601        case NCI_OP_RF_DEACTIVATE_NTF:
 602                nci_rf_deactivate_ntf_packet(ndev, skb);
 603                break;
 604
 605        default:
 606                pr_err("unknown ntf opcode 0x%x\n", ntf_opcode);
 607                break;
 608        }
 609
 610        kfree_skb(skb);
 611}
 612