linux/net/nfc/nci/hci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  The NFC Controller Interface is the communication protocol between an
   4 *  NFC Controller (NFCC) and a Device Host (DH).
   5 *  This is the HCI over NCI implementation, as specified in the 10.2
   6 *  section of the NCI 1.1 specification.
   7 *
   8 *  Copyright (C) 2014  STMicroelectronics SAS. All rights reserved.
   9 */
  10
  11#include <linux/skbuff.h>
  12
  13#include "../nfc.h"
  14#include <net/nfc/nci.h>
  15#include <net/nfc/nci_core.h>
  16#include <linux/nfc.h>
  17
  18struct nci_data {
  19        u8              conn_id;
  20        u8              pipe;
  21        u8              cmd;
  22        const u8        *data;
  23        u32             data_len;
  24} __packed;
  25
  26struct nci_hci_create_pipe_params {
  27        u8 src_gate;
  28        u8 dest_host;
  29        u8 dest_gate;
  30} __packed;
  31
  32struct nci_hci_create_pipe_resp {
  33        u8 src_host;
  34        u8 src_gate;
  35        u8 dest_host;
  36        u8 dest_gate;
  37        u8 pipe;
  38} __packed;
  39
  40struct nci_hci_delete_pipe_noti {
  41        u8 pipe;
  42} __packed;
  43
  44struct nci_hci_all_pipe_cleared_noti {
  45        u8 host;
  46} __packed;
  47
  48struct nci_hcp_message {
  49        u8 header;      /* type -cmd,evt,rsp- + instruction */
  50        u8 data[];
  51} __packed;
  52
  53struct nci_hcp_packet {
  54        u8 header;      /* cbit+pipe */
  55        struct nci_hcp_message message;
  56} __packed;
  57
  58#define NCI_HCI_ANY_SET_PARAMETER  0x01
  59#define NCI_HCI_ANY_GET_PARAMETER  0x02
  60#define NCI_HCI_ANY_CLOSE_PIPE     0x04
  61#define NCI_HCI_ADM_CLEAR_ALL_PIPE 0x14
  62
  63#define NCI_HFP_NO_CHAINING        0x80
  64
  65#define NCI_NFCEE_ID_HCI                0x80
  66
  67#define NCI_EVT_HOT_PLUG           0x03
  68
  69#define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY       0x01
  70#define NCI_HCI_ADM_CREATE_PIPE                 0x10
  71#define NCI_HCI_ADM_DELETE_PIPE                 0x11
  72
  73/* HCP headers */
  74#define NCI_HCI_HCP_PACKET_HEADER_LEN      1
  75#define NCI_HCI_HCP_MESSAGE_HEADER_LEN     1
  76#define NCI_HCI_HCP_HEADER_LEN             2
  77
  78/* HCP types */
  79#define NCI_HCI_HCP_COMMAND        0x00
  80#define NCI_HCI_HCP_EVENT          0x01
  81#define NCI_HCI_HCP_RESPONSE       0x02
  82
  83#define NCI_HCI_ADM_NOTIFY_PIPE_CREATED     0x12
  84#define NCI_HCI_ADM_NOTIFY_PIPE_DELETED     0x13
  85#define NCI_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
  86
  87#define NCI_HCI_FRAGMENT           0x7f
  88#define NCI_HCP_HEADER(type, instr) ((((type) & 0x03) << 6) |\
  89                                      ((instr) & 0x3f))
  90
  91#define NCI_HCP_MSG_GET_TYPE(header) ((header & 0xc0) >> 6)
  92#define NCI_HCP_MSG_GET_CMD(header)  (header & 0x3f)
  93#define NCI_HCP_MSG_GET_PIPE(header) (header & 0x7f)
  94
  95static int nci_hci_result_to_errno(u8 result)
  96{
  97        switch (result) {
  98        case NCI_HCI_ANY_OK:
  99                return 0;
 100        case NCI_HCI_ANY_E_REG_PAR_UNKNOWN:
 101                return -EOPNOTSUPP;
 102        case NCI_HCI_ANY_E_TIMEOUT:
 103                return -ETIME;
 104        default:
 105                return -1;
 106        }
 107}
 108
 109/* HCI core */
 110static void nci_hci_reset_pipes(struct nci_hci_dev *hdev)
 111{
 112        int i;
 113
 114        for (i = 0; i < NCI_HCI_MAX_PIPES; i++) {
 115                hdev->pipes[i].gate = NCI_HCI_INVALID_GATE;
 116                hdev->pipes[i].host = NCI_HCI_INVALID_HOST;
 117        }
 118        memset(hdev->gate2pipe, NCI_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe));
 119}
 120
 121static void nci_hci_reset_pipes_per_host(struct nci_dev *ndev, u8 host)
 122{
 123        int i;
 124
 125        for (i = 0; i < NCI_HCI_MAX_PIPES; i++) {
 126                if (ndev->hci_dev->pipes[i].host == host) {
 127                        ndev->hci_dev->pipes[i].gate = NCI_HCI_INVALID_GATE;
 128                        ndev->hci_dev->pipes[i].host = NCI_HCI_INVALID_HOST;
 129                }
 130        }
 131}
 132
 133/* Fragment HCI data over NCI packet.
 134 * NFC Forum NCI 10.2.2 Data Exchange:
 135 * The payload of the Data Packets sent on the Logical Connection SHALL be
 136 * valid HCP packets, as defined within [ETSI_102622]. Each Data Packet SHALL
 137 * contain a single HCP packet. NCI Segmentation and Reassembly SHALL NOT be
 138 * applied to Data Messages in either direction. The HCI fragmentation mechanism
 139 * is used if required.
 140 */
 141static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
 142                             const u8 data_type, const u8 *data,
 143                             size_t data_len)
 144{
 145        struct nci_conn_info    *conn_info;
 146        struct sk_buff *skb;
 147        int len, i, r;
 148        u8 cb = pipe;
 149
 150        conn_info = ndev->hci_dev->conn_info;
 151        if (!conn_info)
 152                return -EPROTO;
 153
 154        i = 0;
 155        skb = nci_skb_alloc(ndev, conn_info->max_pkt_payload_len +
 156                            NCI_DATA_HDR_SIZE, GFP_KERNEL);
 157        if (!skb)
 158                return -ENOMEM;
 159
 160        skb_reserve(skb, NCI_DATA_HDR_SIZE + 2);
 161        *(u8 *)skb_push(skb, 1) = data_type;
 162
 163        do {
 164                len = conn_info->max_pkt_payload_len;
 165
 166                /* If last packet add NCI_HFP_NO_CHAINING */
 167                if (i + conn_info->max_pkt_payload_len -
 168                    (skb->len + 1) >= data_len) {
 169                        cb |= NCI_HFP_NO_CHAINING;
 170                        len = data_len - i;
 171                } else {
 172                        len = conn_info->max_pkt_payload_len - skb->len - 1;
 173                }
 174
 175                *(u8 *)skb_push(skb, 1) = cb;
 176
 177                if (len > 0)
 178                        skb_put_data(skb, data + i, len);
 179
 180                r = nci_send_data(ndev, conn_info->conn_id, skb);
 181                if (r < 0)
 182                        return r;
 183
 184                i += len;
 185
 186                if (i < data_len) {
 187                        skb = nci_skb_alloc(ndev,
 188                                            conn_info->max_pkt_payload_len +
 189                                            NCI_DATA_HDR_SIZE, GFP_KERNEL);
 190                        if (!skb)
 191                                return -ENOMEM;
 192
 193                        skb_reserve(skb, NCI_DATA_HDR_SIZE + 1);
 194                }
 195        } while (i < data_len);
 196
 197        return i;
 198}
 199
 200static void nci_hci_send_data_req(struct nci_dev *ndev, unsigned long opt)
 201{
 202        struct nci_data *data = (struct nci_data *)opt;
 203
 204        nci_hci_send_data(ndev, data->pipe, data->cmd,
 205                          data->data, data->data_len);
 206}
 207
 208int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event,
 209                       const u8 *param, size_t param_len)
 210{
 211        u8 pipe = ndev->hci_dev->gate2pipe[gate];
 212
 213        if (pipe == NCI_HCI_INVALID_PIPE)
 214                return -EADDRNOTAVAIL;
 215
 216        return nci_hci_send_data(ndev, pipe,
 217                        NCI_HCP_HEADER(NCI_HCI_HCP_EVENT, event),
 218                        param, param_len);
 219}
 220EXPORT_SYMBOL(nci_hci_send_event);
 221
 222int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate, u8 cmd,
 223                     const u8 *param, size_t param_len,
 224                     struct sk_buff **skb)
 225{
 226        struct nci_hcp_message *message;
 227        struct nci_conn_info   *conn_info;
 228        struct nci_data data;
 229        int r;
 230        u8 pipe = ndev->hci_dev->gate2pipe[gate];
 231
 232        if (pipe == NCI_HCI_INVALID_PIPE)
 233                return -EADDRNOTAVAIL;
 234
 235        conn_info = ndev->hci_dev->conn_info;
 236        if (!conn_info)
 237                return -EPROTO;
 238
 239        data.conn_id = conn_info->conn_id;
 240        data.pipe = pipe;
 241        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND, cmd);
 242        data.data = param;
 243        data.data_len = param_len;
 244
 245        r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
 246                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 247        if (r == NCI_STATUS_OK) {
 248                message = (struct nci_hcp_message *)conn_info->rx_skb->data;
 249                r = nci_hci_result_to_errno(
 250                        NCI_HCP_MSG_GET_CMD(message->header));
 251                skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 252
 253                if (!r && skb)
 254                        *skb = conn_info->rx_skb;
 255        }
 256
 257        return r;
 258}
 259EXPORT_SYMBOL(nci_hci_send_cmd);
 260
 261int nci_hci_clear_all_pipes(struct nci_dev *ndev)
 262{
 263        int r;
 264
 265        r = nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
 266                             NCI_HCI_ADM_CLEAR_ALL_PIPE, NULL, 0, NULL);
 267        if (r < 0)
 268                return r;
 269
 270        nci_hci_reset_pipes(ndev->hci_dev);
 271        return r;
 272}
 273EXPORT_SYMBOL(nci_hci_clear_all_pipes);
 274
 275static void nci_hci_event_received(struct nci_dev *ndev, u8 pipe,
 276                                   u8 event, struct sk_buff *skb)
 277{
 278        if (ndev->ops->hci_event_received)
 279                ndev->ops->hci_event_received(ndev, pipe, event, skb);
 280}
 281
 282static void nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe,
 283                                 u8 cmd, struct sk_buff *skb)
 284{
 285        u8 gate = ndev->hci_dev->pipes[pipe].gate;
 286        u8 status = NCI_HCI_ANY_OK | ~NCI_HCI_FRAGMENT;
 287        u8 dest_gate, new_pipe;
 288        struct nci_hci_create_pipe_resp *create_info;
 289        struct nci_hci_delete_pipe_noti *delete_info;
 290        struct nci_hci_all_pipe_cleared_noti *cleared_info;
 291
 292        pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd);
 293
 294        switch (cmd) {
 295        case NCI_HCI_ADM_NOTIFY_PIPE_CREATED:
 296                if (skb->len != 5) {
 297                        status = NCI_HCI_ANY_E_NOK;
 298                        goto exit;
 299                }
 300                create_info = (struct nci_hci_create_pipe_resp *)skb->data;
 301                dest_gate = create_info->dest_gate;
 302                new_pipe = create_info->pipe;
 303                if (new_pipe >= NCI_HCI_MAX_PIPES) {
 304                        status = NCI_HCI_ANY_E_NOK;
 305                        goto exit;
 306                }
 307
 308                /* Save the new created pipe and bind with local gate,
 309                 * the description for skb->data[3] is destination gate id
 310                 * but since we received this cmd from host controller, we
 311                 * are the destination and it is our local gate
 312                 */
 313                ndev->hci_dev->gate2pipe[dest_gate] = new_pipe;
 314                ndev->hci_dev->pipes[new_pipe].gate = dest_gate;
 315                ndev->hci_dev->pipes[new_pipe].host =
 316                                                create_info->src_host;
 317                break;
 318        case NCI_HCI_ANY_OPEN_PIPE:
 319                /* If the pipe is not created report an error */
 320                if (gate == NCI_HCI_INVALID_GATE) {
 321                        status = NCI_HCI_ANY_E_NOK;
 322                        goto exit;
 323                }
 324                break;
 325        case NCI_HCI_ADM_NOTIFY_PIPE_DELETED:
 326                if (skb->len != 1) {
 327                        status = NCI_HCI_ANY_E_NOK;
 328                        goto exit;
 329                }
 330                delete_info = (struct nci_hci_delete_pipe_noti *)skb->data;
 331                if (delete_info->pipe >= NCI_HCI_MAX_PIPES) {
 332                        status = NCI_HCI_ANY_E_NOK;
 333                        goto exit;
 334                }
 335
 336                ndev->hci_dev->pipes[delete_info->pipe].gate =
 337                                                NCI_HCI_INVALID_GATE;
 338                ndev->hci_dev->pipes[delete_info->pipe].host =
 339                                                NCI_HCI_INVALID_HOST;
 340                break;
 341        case NCI_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
 342                if (skb->len != 1) {
 343                        status = NCI_HCI_ANY_E_NOK;
 344                        goto exit;
 345                }
 346
 347                cleared_info =
 348                        (struct nci_hci_all_pipe_cleared_noti *)skb->data;
 349                nci_hci_reset_pipes_per_host(ndev, cleared_info->host);
 350                break;
 351        default:
 352                pr_debug("Discarded unknown cmd %x to gate %x\n", cmd, gate);
 353                break;
 354        }
 355
 356        if (ndev->ops->hci_cmd_received)
 357                ndev->ops->hci_cmd_received(ndev, pipe, cmd, skb);
 358
 359exit:
 360        nci_hci_send_data(ndev, pipe, status, NULL, 0);
 361
 362        kfree_skb(skb);
 363}
 364
 365static void nci_hci_resp_received(struct nci_dev *ndev, u8 pipe,
 366                                  u8 result, struct sk_buff *skb)
 367{
 368        struct nci_conn_info    *conn_info;
 369        u8 status = result;
 370
 371        conn_info = ndev->hci_dev->conn_info;
 372        if (!conn_info) {
 373                status = NCI_STATUS_REJECTED;
 374                goto exit;
 375        }
 376
 377        conn_info->rx_skb = skb;
 378
 379exit:
 380        nci_req_complete(ndev, NCI_STATUS_OK);
 381}
 382
 383/* Receive hcp message for pipe, with type and cmd.
 384 * skb contains optional message data only.
 385 */
 386static void nci_hci_hcp_message_rx(struct nci_dev *ndev, u8 pipe,
 387                                   u8 type, u8 instruction, struct sk_buff *skb)
 388{
 389        switch (type) {
 390        case NCI_HCI_HCP_RESPONSE:
 391                nci_hci_resp_received(ndev, pipe, instruction, skb);
 392                break;
 393        case NCI_HCI_HCP_COMMAND:
 394                nci_hci_cmd_received(ndev, pipe, instruction, skb);
 395                break;
 396        case NCI_HCI_HCP_EVENT:
 397                nci_hci_event_received(ndev, pipe, instruction, skb);
 398                break;
 399        default:
 400                pr_err("UNKNOWN MSG Type %d, instruction=%d\n",
 401                       type, instruction);
 402                kfree_skb(skb);
 403                break;
 404        }
 405
 406        nci_req_complete(ndev, NCI_STATUS_OK);
 407}
 408
 409static void nci_hci_msg_rx_work(struct work_struct *work)
 410{
 411        struct nci_hci_dev *hdev =
 412                container_of(work, struct nci_hci_dev, msg_rx_work);
 413        struct sk_buff *skb;
 414        struct nci_hcp_message *message;
 415        u8 pipe, type, instruction;
 416
 417        while ((skb = skb_dequeue(&hdev->msg_rx_queue)) != NULL) {
 418                pipe = NCI_HCP_MSG_GET_PIPE(skb->data[0]);
 419                skb_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
 420                message = (struct nci_hcp_message *)skb->data;
 421                type = NCI_HCP_MSG_GET_TYPE(message->header);
 422                instruction = NCI_HCP_MSG_GET_CMD(message->header);
 423                skb_pull(skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 424
 425                nci_hci_hcp_message_rx(hdev->ndev, pipe,
 426                                       type, instruction, skb);
 427        }
 428}
 429
 430void nci_hci_data_received_cb(void *context,
 431                              struct sk_buff *skb, int err)
 432{
 433        struct nci_dev *ndev = (struct nci_dev *)context;
 434        struct nci_hcp_packet *packet;
 435        u8 pipe, type;
 436        struct sk_buff *hcp_skb;
 437        struct sk_buff *frag_skb;
 438        int msg_len;
 439
 440        pr_debug("\n");
 441
 442        if (err) {
 443                nci_req_complete(ndev, err);
 444                return;
 445        }
 446
 447        packet = (struct nci_hcp_packet *)skb->data;
 448        if ((packet->header & ~NCI_HCI_FRAGMENT) == 0) {
 449                skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
 450                return;
 451        }
 452
 453        /* it's the last fragment. Does it need re-aggregation? */
 454        if (skb_queue_len(&ndev->hci_dev->rx_hcp_frags)) {
 455                pipe = NCI_HCP_MSG_GET_PIPE(packet->header);
 456                skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
 457
 458                msg_len = 0;
 459                skb_queue_walk(&ndev->hci_dev->rx_hcp_frags, frag_skb) {
 460                        msg_len += (frag_skb->len -
 461                                    NCI_HCI_HCP_PACKET_HEADER_LEN);
 462                }
 463
 464                hcp_skb = nfc_alloc_recv_skb(NCI_HCI_HCP_PACKET_HEADER_LEN +
 465                                             msg_len, GFP_KERNEL);
 466                if (!hcp_skb) {
 467                        nci_req_complete(ndev, -ENOMEM);
 468                        return;
 469                }
 470
 471                skb_put_u8(hcp_skb, pipe);
 472
 473                skb_queue_walk(&ndev->hci_dev->rx_hcp_frags, frag_skb) {
 474                        msg_len = frag_skb->len - NCI_HCI_HCP_PACKET_HEADER_LEN;
 475                        skb_put_data(hcp_skb,
 476                                     frag_skb->data + NCI_HCI_HCP_PACKET_HEADER_LEN,
 477                                     msg_len);
 478                }
 479
 480                skb_queue_purge(&ndev->hci_dev->rx_hcp_frags);
 481        } else {
 482                packet->header &= NCI_HCI_FRAGMENT;
 483                hcp_skb = skb;
 484        }
 485
 486        /* if this is a response, dispatch immediately to
 487         * unblock waiting cmd context. Otherwise, enqueue to dispatch
 488         * in separate context where handler can also execute command.
 489         */
 490        packet = (struct nci_hcp_packet *)hcp_skb->data;
 491        type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
 492        if (type == NCI_HCI_HCP_RESPONSE) {
 493                pipe = NCI_HCP_MSG_GET_PIPE(packet->header);
 494                skb_pull(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
 495                nci_hci_hcp_message_rx(ndev, pipe, type,
 496                                       NCI_STATUS_OK, hcp_skb);
 497        } else {
 498                skb_queue_tail(&ndev->hci_dev->msg_rx_queue, hcp_skb);
 499                schedule_work(&ndev->hci_dev->msg_rx_work);
 500        }
 501}
 502
 503int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe)
 504{
 505        struct nci_data data;
 506        struct nci_conn_info    *conn_info;
 507
 508        conn_info = ndev->hci_dev->conn_info;
 509        if (!conn_info)
 510                return -EPROTO;
 511
 512        data.conn_id = conn_info->conn_id;
 513        data.pipe = pipe;
 514        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
 515                                       NCI_HCI_ANY_OPEN_PIPE);
 516        data.data = NULL;
 517        data.data_len = 0;
 518
 519        return nci_request(ndev, nci_hci_send_data_req,
 520                        (unsigned long)&data,
 521                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 522}
 523EXPORT_SYMBOL(nci_hci_open_pipe);
 524
 525static u8 nci_hci_create_pipe(struct nci_dev *ndev, u8 dest_host,
 526                              u8 dest_gate, int *result)
 527{
 528        u8 pipe;
 529        struct sk_buff *skb;
 530        struct nci_hci_create_pipe_params params;
 531        struct nci_hci_create_pipe_resp *resp;
 532
 533        pr_debug("gate=%d\n", dest_gate);
 534
 535        params.src_gate = NCI_HCI_ADMIN_GATE;
 536        params.dest_host = dest_host;
 537        params.dest_gate = dest_gate;
 538
 539        *result = nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
 540                                   NCI_HCI_ADM_CREATE_PIPE,
 541                                   (u8 *)&params, sizeof(params), &skb);
 542        if (*result < 0)
 543                return NCI_HCI_INVALID_PIPE;
 544
 545        resp = (struct nci_hci_create_pipe_resp *)skb->data;
 546        pipe = resp->pipe;
 547        kfree_skb(skb);
 548
 549        pr_debug("pipe created=%d\n", pipe);
 550
 551        return pipe;
 552}
 553
 554static int nci_hci_delete_pipe(struct nci_dev *ndev, u8 pipe)
 555{
 556        pr_debug("\n");
 557
 558        return nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
 559                                NCI_HCI_ADM_DELETE_PIPE, &pipe, 1, NULL);
 560}
 561
 562int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
 563                      const u8 *param, size_t param_len)
 564{
 565        struct nci_hcp_message *message;
 566        struct nci_conn_info *conn_info;
 567        struct nci_data data;
 568        int r;
 569        u8 *tmp;
 570        u8 pipe = ndev->hci_dev->gate2pipe[gate];
 571
 572        pr_debug("idx=%d to gate %d\n", idx, gate);
 573
 574        if (pipe == NCI_HCI_INVALID_PIPE)
 575                return -EADDRNOTAVAIL;
 576
 577        conn_info = ndev->hci_dev->conn_info;
 578        if (!conn_info)
 579                return -EPROTO;
 580
 581        tmp = kmalloc(1 + param_len, GFP_KERNEL);
 582        if (!tmp)
 583                return -ENOMEM;
 584
 585        *tmp = idx;
 586        memcpy(tmp + 1, param, param_len);
 587
 588        data.conn_id = conn_info->conn_id;
 589        data.pipe = pipe;
 590        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
 591                                       NCI_HCI_ANY_SET_PARAMETER);
 592        data.data = tmp;
 593        data.data_len = param_len + 1;
 594
 595        r = nci_request(ndev, nci_hci_send_data_req,
 596                        (unsigned long)&data,
 597                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 598        if (r == NCI_STATUS_OK) {
 599                message = (struct nci_hcp_message *)conn_info->rx_skb->data;
 600                r = nci_hci_result_to_errno(
 601                        NCI_HCP_MSG_GET_CMD(message->header));
 602                skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 603        }
 604
 605        kfree(tmp);
 606        return r;
 607}
 608EXPORT_SYMBOL(nci_hci_set_param);
 609
 610int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx,
 611                      struct sk_buff **skb)
 612{
 613        struct nci_hcp_message *message;
 614        struct nci_conn_info    *conn_info;
 615        struct nci_data data;
 616        int r;
 617        u8 pipe = ndev->hci_dev->gate2pipe[gate];
 618
 619        pr_debug("idx=%d to gate %d\n", idx, gate);
 620
 621        if (pipe == NCI_HCI_INVALID_PIPE)
 622                return -EADDRNOTAVAIL;
 623
 624        conn_info = ndev->hci_dev->conn_info;
 625        if (!conn_info)
 626                return -EPROTO;
 627
 628        data.conn_id = conn_info->conn_id;
 629        data.pipe = pipe;
 630        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
 631                                  NCI_HCI_ANY_GET_PARAMETER);
 632        data.data = &idx;
 633        data.data_len = 1;
 634
 635        r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
 636                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 637
 638        if (r == NCI_STATUS_OK) {
 639                message = (struct nci_hcp_message *)conn_info->rx_skb->data;
 640                r = nci_hci_result_to_errno(
 641                        NCI_HCP_MSG_GET_CMD(message->header));
 642                skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 643
 644                if (!r && skb)
 645                        *skb = conn_info->rx_skb;
 646        }
 647
 648        return r;
 649}
 650EXPORT_SYMBOL(nci_hci_get_param);
 651
 652int nci_hci_connect_gate(struct nci_dev *ndev,
 653                         u8 dest_host, u8 dest_gate, u8 pipe)
 654{
 655        bool pipe_created = false;
 656        int r;
 657
 658        if (pipe == NCI_HCI_DO_NOT_OPEN_PIPE)
 659                return 0;
 660
 661        if (ndev->hci_dev->gate2pipe[dest_gate] != NCI_HCI_INVALID_PIPE)
 662                return -EADDRINUSE;
 663
 664        if (pipe != NCI_HCI_INVALID_PIPE)
 665                goto open_pipe;
 666
 667        switch (dest_gate) {
 668        case NCI_HCI_LINK_MGMT_GATE:
 669                pipe = NCI_HCI_LINK_MGMT_PIPE;
 670        break;
 671        case NCI_HCI_ADMIN_GATE:
 672                pipe = NCI_HCI_ADMIN_PIPE;
 673        break;
 674        default:
 675                pipe = nci_hci_create_pipe(ndev, dest_host, dest_gate, &r);
 676                if (pipe == NCI_HCI_INVALID_PIPE)
 677                        return r;
 678                pipe_created = true;
 679                break;
 680        }
 681
 682open_pipe:
 683        r = nci_hci_open_pipe(ndev, pipe);
 684        if (r < 0) {
 685                if (pipe_created) {
 686                        if (nci_hci_delete_pipe(ndev, pipe) < 0) {
 687                                /* TODO: Cannot clean by deleting pipe...
 688                                 * -> inconsistent state
 689                                 */
 690                        }
 691                }
 692                return r;
 693        }
 694
 695        ndev->hci_dev->pipes[pipe].gate = dest_gate;
 696        ndev->hci_dev->pipes[pipe].host = dest_host;
 697        ndev->hci_dev->gate2pipe[dest_gate] = pipe;
 698
 699        return 0;
 700}
 701EXPORT_SYMBOL(nci_hci_connect_gate);
 702
 703static int nci_hci_dev_connect_gates(struct nci_dev *ndev,
 704                                     u8 gate_count,
 705                                     struct nci_hci_gate *gates)
 706{
 707        int r;
 708
 709        while (gate_count--) {
 710                r = nci_hci_connect_gate(ndev, gates->dest_host,
 711                                         gates->gate, gates->pipe);
 712                if (r < 0)
 713                        return r;
 714                gates++;
 715        }
 716
 717        return 0;
 718}
 719
 720int nci_hci_dev_session_init(struct nci_dev *ndev)
 721{
 722        struct nci_conn_info    *conn_info;
 723        struct sk_buff *skb;
 724        int r;
 725
 726        ndev->hci_dev->count_pipes = 0;
 727        ndev->hci_dev->expected_pipes = 0;
 728
 729        conn_info = ndev->hci_dev->conn_info;
 730        if (!conn_info)
 731                return -EPROTO;
 732
 733        conn_info->data_exchange_cb = nci_hci_data_received_cb;
 734        conn_info->data_exchange_cb_context = ndev;
 735
 736        nci_hci_reset_pipes(ndev->hci_dev);
 737
 738        if (ndev->hci_dev->init_data.gates[0].gate != NCI_HCI_ADMIN_GATE)
 739                return -EPROTO;
 740
 741        r = nci_hci_connect_gate(ndev,
 742                                 ndev->hci_dev->init_data.gates[0].dest_host,
 743                                 ndev->hci_dev->init_data.gates[0].gate,
 744                                 ndev->hci_dev->init_data.gates[0].pipe);
 745        if (r < 0)
 746                return r;
 747
 748        r = nci_hci_get_param(ndev, NCI_HCI_ADMIN_GATE,
 749                              NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY, &skb);
 750        if (r < 0)
 751                return r;
 752
 753        if (skb->len &&
 754            skb->len == strlen(ndev->hci_dev->init_data.session_id) &&
 755            !memcmp(ndev->hci_dev->init_data.session_id, skb->data, skb->len) &&
 756            ndev->ops->hci_load_session) {
 757                /* Restore gate<->pipe table from some proprietary location. */
 758                r = ndev->ops->hci_load_session(ndev);
 759        } else {
 760                r = nci_hci_clear_all_pipes(ndev);
 761                if (r < 0)
 762                        goto exit;
 763
 764                r = nci_hci_dev_connect_gates(ndev,
 765                                              ndev->hci_dev->init_data.gate_count,
 766                                              ndev->hci_dev->init_data.gates);
 767                if (r < 0)
 768                        goto exit;
 769
 770                r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE,
 771                                      NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY,
 772                                      ndev->hci_dev->init_data.session_id,
 773                                      strlen(ndev->hci_dev->init_data.session_id));
 774        }
 775
 776exit:
 777        kfree_skb(skb);
 778
 779        return r;
 780}
 781EXPORT_SYMBOL(nci_hci_dev_session_init);
 782
 783struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev)
 784{
 785        struct nci_hci_dev *hdev;
 786
 787        hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
 788        if (!hdev)
 789                return NULL;
 790
 791        skb_queue_head_init(&hdev->rx_hcp_frags);
 792        INIT_WORK(&hdev->msg_rx_work, nci_hci_msg_rx_work);
 793        skb_queue_head_init(&hdev->msg_rx_queue);
 794        hdev->ndev = ndev;
 795
 796        return hdev;
 797}
 798