18b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade/* 28b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Copyright (C) 2012 Intel Corporation. All rights reserved. 38b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * 48b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * This program is free software; you can redistribute it and/or modify 58b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * it under the terms of the GNU General Public License as published by 68b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * the Free Software Foundation; either version 2 of the License, or 78b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * (at your option) any later version. 88b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * 98b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * This program is distributed in the hope that it will be useful, 108b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * but WITHOUT ANY WARRANTY; without even the implied warranty of 118b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * GNU General Public License for more details. 138b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * 148b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * You should have received a copy of the GNU General Public License 1598b32decc83ed3137e3ddbc918b102f8fc406b6dJeff Kirsher * along with this program; if not, see <http://www.gnu.org/licenses/>. 168b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade */ 178b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 188b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#define pr_fmt(fmt) "hci: %s: " fmt, __func__ 198b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 208b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <linux/init.h> 218b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <linux/kernel.h> 228b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <linux/module.h> 238b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 248b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <net/nfc/hci.h> 258b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 268b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include "hci.h" 278b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 288b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade/* 298b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Payload is the HCP message data only. Instruction will be prepended. 308b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Guarantees that cb will be called upon completion or timeout delay 318b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * counted from the moment the cmd is sent to the transport. 328b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade */ 338b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadeint nfc_hci_hcp_message_tx(struct nfc_hci_dev *hdev, u8 pipe, 348b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade u8 type, u8 instruction, 358b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade const u8 *payload, size_t payload_len, 36b5faa648faf974b58e5a79eafa9a97e1deed7a8aEric Lapuyade data_exchange_cb_t cb, void *cb_context, 378b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade unsigned long completion_delay) 388b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade{ 398b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct nfc_dev *ndev = hdev->ndev; 408b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct hci_msg *cmd; 418b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade const u8 *ptr = payload; 428b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade int hci_len, err; 438b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade bool firstfrag = true; 448b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 458b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd = kzalloc(sizeof(struct hci_msg), GFP_KERNEL); 468b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (cmd == NULL) 478b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return -ENOMEM; 488b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 498b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade INIT_LIST_HEAD(&cmd->msg_l); 508b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_queue_head_init(&cmd->msg_frags); 518b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd->wait_response = (type == NFC_HCI_HCP_COMMAND) ? true : false; 528b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd->cb = cb; 53b5faa648faf974b58e5a79eafa9a97e1deed7a8aEric Lapuyade cmd->cb_context = cb_context; 548b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd->completion_delay = completion_delay; 558b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 568b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade hci_len = payload_len + 1; 578b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade while (hci_len > 0) { 588b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct sk_buff *skb; 598b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade int skb_len, data_link_len; 608b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct hcp_packet *packet; 618b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 628b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (NFC_HCI_HCP_PACKET_HEADER_LEN + hci_len <= 638b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade hdev->max_data_link_payload) 648b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len = hci_len; 658b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade else 668b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len = hdev->max_data_link_payload - 678b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade NFC_HCI_HCP_PACKET_HEADER_LEN; 688b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 698b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_len = ndev->tx_headroom + NFC_HCI_HCP_PACKET_HEADER_LEN + 708b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len + ndev->tx_tailroom; 718b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade hci_len -= data_link_len; 728b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 738b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb = alloc_skb(skb_len, GFP_KERNEL); 748b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (skb == NULL) { 758b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade err = -ENOMEM; 768b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade goto out_skb_err; 778b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 788b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_reserve(skb, ndev->tx_headroom); 798b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 808b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_put(skb, NFC_HCI_HCP_PACKET_HEADER_LEN + data_link_len); 818b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 828b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade /* Only the last fragment will have the cb bit set to 1 */ 838b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet = (struct hcp_packet *)skb->data; 848b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet->header = pipe; 858b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (firstfrag) { 868b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade firstfrag = false; 878b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet->message.header = HCP_HEADER(type, instruction); 888b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (ptr) { 898b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade memcpy(packet->message.data, ptr, 908b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len - 1); 918b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade ptr += data_link_len - 1; 928b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 938b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } else { 948b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade memcpy(&packet->message, ptr, data_link_len); 958b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade ptr += data_link_len; 968b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 978b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 988b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade /* This is the last fragment, set the cb bit */ 998b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (hci_len == 0) 1008b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet->header |= ~NFC_HCI_FRAGMENT; 1018b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1028b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_queue_tail(&cmd->msg_frags, skb); 1038b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 1048b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1058b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade mutex_lock(&hdev->msg_tx_mutex); 106f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade 107f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade if (hdev->shutting_down) { 108f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade err = -ESHUTDOWN; 109f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade mutex_unlock(&hdev->msg_tx_mutex); 110f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade goto out_skb_err; 111f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade } 112f0c9103813b3045bd5b43220b6a78c9908a45d24Eric Lapuyade 113f8bf65bf3688835f95f7c74f5c844a64b2743a42Mathias Jeppsson list_add_tail(&cmd->msg_l, &hdev->msg_tx_queue); 1148b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade mutex_unlock(&hdev->msg_tx_mutex); 1158b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 116916082b073ebb7f4e064cebce0768e34cacde508Linus Torvalds schedule_work(&hdev->msg_tx_work); 1178b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1188b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return 0; 1198b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1208b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadeout_skb_err: 1218b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_queue_purge(&cmd->msg_frags); 1228b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade kfree(cmd); 1238b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1248b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return err; 1258b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade} 1268b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1278b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadeu8 nfc_hci_pipe2gate(struct nfc_hci_dev *hdev, u8 pipe) 1288b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade{ 1298b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade int gate; 1308b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1318b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade for (gate = 0; gate < NFC_HCI_MAX_GATES; gate++) 1328b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (hdev->gate2pipe[gate] == pipe) 1338b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return gate; 1348b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1358b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return 0xff; 1368b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade} 1378b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1388b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade/* 1398b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Receive hcp message for pipe, with type and cmd. 1408b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * skb contains optional message data only. 1418b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade */ 1428b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadevoid nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type, 1438b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade u8 instruction, struct sk_buff *skb) 1448b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade{ 1458b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade switch (type) { 1468b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade case NFC_HCI_HCP_RESPONSE: 1478b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade nfc_hci_resp_received(hdev, instruction, skb); 1488b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1498b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade case NFC_HCI_HCP_COMMAND: 1508b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade nfc_hci_cmd_received(hdev, pipe, instruction, skb); 1518b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1528b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade case NFC_HCI_HCP_EVENT: 1538b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade nfc_hci_event_received(hdev, pipe, instruction, skb); 1548b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1558b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade default: 1568b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade pr_err("UNKNOWN MSG Type %d, instruction=%d\n", 1578b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade type, instruction); 1588b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade kfree_skb(skb); 1598b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1608b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 1618b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade} 162