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        *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                *skb_push(skb, 1) = cb;
 188
 189                if (len > 0)
 190                        memcpy(skb_put(skb, len), 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(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN) = 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                        memcpy(skb_put(hcp_skb, msg_len), frag_skb->data +
 480                               NCI_HCI_HCP_PACKET_HEADER_LEN, msg_len);
 481                }
 482
 483                skb_queue_purge(&ndev->hci_dev->rx_hcp_frags);
 484        } else {
 485                packet->header &= NCI_HCI_FRAGMENT;
 486                hcp_skb = skb;
 487        }
 488
 489        /* if this is a response, dispatch immediately to
 490         * unblock waiting cmd context. Otherwise, enqueue to dispatch
 491         * in separate context where handler can also execute command.
 492         */
 493        packet = (struct nci_hcp_packet *)hcp_skb->data;
 494        type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
 495        if (type == NCI_HCI_HCP_RESPONSE) {
 496                pipe = NCI_HCP_MSG_GET_PIPE(packet->header);
 497                skb_pull(hcp_skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
 498                nci_hci_hcp_message_rx(ndev, pipe, type,
 499                                       NCI_STATUS_OK, hcp_skb);
 500        } else {
 501                skb_queue_tail(&ndev->hci_dev->msg_rx_queue, hcp_skb);
 502                schedule_work(&ndev->hci_dev->msg_rx_work);
 503        }
 504}
 505
 506int nci_hci_open_pipe(struct nci_dev *ndev, u8 pipe)
 507{
 508        struct nci_data data;
 509        struct nci_conn_info    *conn_info;
 510
 511        conn_info = ndev->hci_dev->conn_info;
 512        if (!conn_info)
 513                return -EPROTO;
 514
 515        data.conn_id = conn_info->conn_id;
 516        data.pipe = pipe;
 517        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
 518                                       NCI_HCI_ANY_OPEN_PIPE);
 519        data.data = NULL;
 520        data.data_len = 0;
 521
 522        return nci_request(ndev, nci_hci_send_data_req,
 523                        (unsigned long)&data,
 524                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 525}
 526EXPORT_SYMBOL(nci_hci_open_pipe);
 527
 528static u8 nci_hci_create_pipe(struct nci_dev *ndev, u8 dest_host,
 529                              u8 dest_gate, int *result)
 530{
 531        u8 pipe;
 532        struct sk_buff *skb;
 533        struct nci_hci_create_pipe_params params;
 534        struct nci_hci_create_pipe_resp *resp;
 535
 536        pr_debug("gate=%d\n", dest_gate);
 537
 538        params.src_gate = NCI_HCI_ADMIN_GATE;
 539        params.dest_host = dest_host;
 540        params.dest_gate = dest_gate;
 541
 542        *result = nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
 543                                   NCI_HCI_ADM_CREATE_PIPE,
 544                                   (u8 *)&params, sizeof(params), &skb);
 545        if (*result < 0)
 546                return NCI_HCI_INVALID_PIPE;
 547
 548        resp = (struct nci_hci_create_pipe_resp *)skb->data;
 549        pipe = resp->pipe;
 550        kfree_skb(skb);
 551
 552        pr_debug("pipe created=%d\n", pipe);
 553
 554        return pipe;
 555}
 556
 557static int nci_hci_delete_pipe(struct nci_dev *ndev, u8 pipe)
 558{
 559        pr_debug("\n");
 560
 561        return nci_hci_send_cmd(ndev, NCI_HCI_ADMIN_GATE,
 562                                NCI_HCI_ADM_DELETE_PIPE, &pipe, 1, NULL);
 563}
 564
 565int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
 566                      const u8 *param, size_t param_len)
 567{
 568        struct nci_hcp_message *message;
 569        struct nci_conn_info *conn_info;
 570        struct nci_data data;
 571        int r;
 572        u8 *tmp;
 573        u8 pipe = ndev->hci_dev->gate2pipe[gate];
 574
 575        pr_debug("idx=%d to gate %d\n", idx, gate);
 576
 577        if (pipe == NCI_HCI_INVALID_PIPE)
 578                return -EADDRNOTAVAIL;
 579
 580        conn_info = ndev->hci_dev->conn_info;
 581        if (!conn_info)
 582                return -EPROTO;
 583
 584        tmp = kmalloc(1 + param_len, GFP_KERNEL);
 585        if (!tmp)
 586                return -ENOMEM;
 587
 588        *tmp = idx;
 589        memcpy(tmp + 1, param, param_len);
 590
 591        data.conn_id = conn_info->conn_id;
 592        data.pipe = pipe;
 593        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
 594                                       NCI_HCI_ANY_SET_PARAMETER);
 595        data.data = tmp;
 596        data.data_len = param_len + 1;
 597
 598        r = nci_request(ndev, nci_hci_send_data_req,
 599                        (unsigned long)&data,
 600                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 601        if (r == NCI_STATUS_OK) {
 602                message = (struct nci_hcp_message *)conn_info->rx_skb->data;
 603                r = nci_hci_result_to_errno(
 604                        NCI_HCP_MSG_GET_CMD(message->header));
 605                skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 606        }
 607
 608        kfree(tmp);
 609        return r;
 610}
 611EXPORT_SYMBOL(nci_hci_set_param);
 612
 613int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx,
 614                      struct sk_buff **skb)
 615{
 616        struct nci_hcp_message *message;
 617        struct nci_conn_info    *conn_info;
 618        struct nci_data data;
 619        int r;
 620        u8 pipe = ndev->hci_dev->gate2pipe[gate];
 621
 622        pr_debug("idx=%d to gate %d\n", idx, gate);
 623
 624        if (pipe == NCI_HCI_INVALID_PIPE)
 625                return -EADDRNOTAVAIL;
 626
 627        conn_info = ndev->hci_dev->conn_info;
 628        if (!conn_info)
 629                return -EPROTO;
 630
 631        data.conn_id = conn_info->conn_id;
 632        data.pipe = pipe;
 633        data.cmd = NCI_HCP_HEADER(NCI_HCI_HCP_COMMAND,
 634                                  NCI_HCI_ANY_GET_PARAMETER);
 635        data.data = &idx;
 636        data.data_len = 1;
 637
 638        r = nci_request(ndev, nci_hci_send_data_req, (unsigned long)&data,
 639                        msecs_to_jiffies(NCI_DATA_TIMEOUT));
 640
 641        if (r == NCI_STATUS_OK) {
 642                message = (struct nci_hcp_message *)conn_info->rx_skb->data;
 643                r = nci_hci_result_to_errno(
 644                        NCI_HCP_MSG_GET_CMD(message->header));
 645                skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
 646
 647                if (!r && skb)
 648                        *skb = conn_info->rx_skb;
 649        }
 650
 651        return r;
 652}
 653EXPORT_SYMBOL(nci_hci_get_param);
 654
 655int nci_hci_connect_gate(struct nci_dev *ndev,
 656                         u8 dest_host, u8 dest_gate, u8 pipe)
 657{
 658        bool pipe_created = false;
 659        int r;
 660
 661        if (pipe == NCI_HCI_DO_NOT_OPEN_PIPE)
 662                return 0;
 663
 664        if (ndev->hci_dev->gate2pipe[dest_gate] != NCI_HCI_INVALID_PIPE)
 665                return -EADDRINUSE;
 666
 667        if (pipe != NCI_HCI_INVALID_PIPE)
 668                goto open_pipe;
 669
 670        switch (dest_gate) {
 671        case NCI_HCI_LINK_MGMT_GATE:
 672                pipe = NCI_HCI_LINK_MGMT_PIPE;
 673        break;
 674        case NCI_HCI_ADMIN_GATE:
 675                pipe = NCI_HCI_ADMIN_PIPE;
 676        break;
 677        default:
 678                pipe = nci_hci_create_pipe(ndev, dest_host, dest_gate, &r);
 679                if (pipe == NCI_HCI_INVALID_PIPE)
 680                        return r;
 681                pipe_created = true;
 682                break;
 683        }
 684
 685open_pipe:
 686        r = nci_hci_open_pipe(ndev, pipe);
 687        if (r < 0) {
 688                if (pipe_created) {
 689                        if (nci_hci_delete_pipe(ndev, pipe) < 0) {
 690                                /* TODO: Cannot clean by deleting pipe...
 691                                 * -> inconsistent state
 692                                 */
 693                        }
 694                }
 695                return r;
 696        }
 697
 698        ndev->hci_dev->pipes[pipe].gate = dest_gate;
 699        ndev->hci_dev->pipes[pipe].host = dest_host;
 700        ndev->hci_dev->gate2pipe[dest_gate] = pipe;
 701
 702        return 0;
 703}
 704EXPORT_SYMBOL(nci_hci_connect_gate);
 705
 706static int nci_hci_dev_connect_gates(struct nci_dev *ndev,
 707                                     u8 gate_count,
 708                                     struct nci_hci_gate *gates)
 709{
 710        int r;
 711
 712        while (gate_count--) {
 713                r = nci_hci_connect_gate(ndev, gates->dest_host,
 714                                         gates->gate, gates->pipe);
 715                if (r < 0)
 716                        return r;
 717                gates++;
 718        }
 719
 720        return 0;
 721}
 722
 723int nci_hci_dev_session_init(struct nci_dev *ndev)
 724{
 725        struct nci_conn_info    *conn_info;
 726        struct sk_buff *skb;
 727        int r;
 728
 729        ndev->hci_dev->count_pipes = 0;
 730        ndev->hci_dev->expected_pipes = 0;
 731
 732        conn_info = ndev->hci_dev->conn_info;
 733        if (!conn_info)
 734                return -EPROTO;
 735
 736        conn_info->data_exchange_cb = nci_hci_data_received_cb;
 737        conn_info->data_exchange_cb_context = ndev;
 738
 739        nci_hci_reset_pipes(ndev->hci_dev);
 740
 741        if (ndev->hci_dev->init_data.gates[0].gate != NCI_HCI_ADMIN_GATE)
 742                return -EPROTO;
 743
 744        r = nci_hci_connect_gate(ndev,
 745                                 ndev->hci_dev->init_data.gates[0].dest_host,
 746                                 ndev->hci_dev->init_data.gates[0].gate,
 747                                 ndev->hci_dev->init_data.gates[0].pipe);
 748        if (r < 0)
 749                return r;
 750
 751        r = nci_hci_get_param(ndev, NCI_HCI_ADMIN_GATE,
 752                              NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY, &skb);
 753        if (r < 0)
 754                return r;
 755
 756        if (skb->len &&
 757            skb->len == strlen(ndev->hci_dev->init_data.session_id) &&
 758            !memcmp(ndev->hci_dev->init_data.session_id, skb->data, skb->len) &&
 759            ndev->ops->hci_load_session) {
 760                /* Restore gate<->pipe table from some proprietary location. */
 761                r = ndev->ops->hci_load_session(ndev);
 762        } else {
 763                r = nci_hci_clear_all_pipes(ndev);
 764                if (r < 0)
 765                        goto exit;
 766
 767                r = nci_hci_dev_connect_gates(ndev,
 768                                              ndev->hci_dev->init_data.gate_count,
 769                                              ndev->hci_dev->init_data.gates);
 770                if (r < 0)
 771                        goto exit;
 772
 773                r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE,
 774                                      NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY,
 775                                      ndev->hci_dev->init_data.session_id,
 776                                      strlen(ndev->hci_dev->init_data.session_id));
 777        }
 778
 779exit:
 780        kfree_skb(skb);
 781
 782        return r;
 783}
 784EXPORT_SYMBOL(nci_hci_dev_session_init);
 785
 786struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev)
 787{
 788        struct nci_hci_dev *hdev;
 789
 790        hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
 791        if (!hdev)
 792                return NULL;
 793
 794        skb_queue_head_init(&hdev->rx_hcp_frags);
 795        INIT_WORK(&hdev->msg_rx_work, nci_hci_msg_rx_work);
 796        skb_queue_head_init(&hdev->msg_rx_queue);
 797        hdev->ndev = ndev;
 798
 799        return hdev;
 800}
 801