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