hcp.c revision 916082b073ebb7f4e064cebce0768e34cacde508
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 158b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * along with this program; if not, write to the 168b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Free Software Foundation, Inc., 178b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 188b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade */ 198b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 208b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#define pr_fmt(fmt) "hci: %s: " fmt, __func__ 218b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 228b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <linux/init.h> 238b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <linux/kernel.h> 248b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <linux/module.h> 258b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 268b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include <net/nfc/hci.h> 278b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 288b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade#include "hci.h" 298b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 308b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade/* 318b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Payload is the HCP message data only. Instruction will be prepended. 328b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Guarantees that cb will be called upon completion or timeout delay 338b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * counted from the moment the cmd is sent to the transport. 348b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade */ 358b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadeint nfc_hci_hcp_message_tx(struct nfc_hci_dev *hdev, u8 pipe, 368b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade u8 type, u8 instruction, 378b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade const u8 *payload, size_t payload_len, 38b5faa648faf974b58e5a79eafa9a97e1deed7a8aEric Lapuyade data_exchange_cb_t cb, void *cb_context, 398b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade unsigned long completion_delay) 408b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade{ 418b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct nfc_dev *ndev = hdev->ndev; 428b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct hci_msg *cmd; 438b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade const u8 *ptr = payload; 448b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade int hci_len, err; 458b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade bool firstfrag = true; 468b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 478b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd = kzalloc(sizeof(struct hci_msg), GFP_KERNEL); 488b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (cmd == NULL) 498b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return -ENOMEM; 508b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 518b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade INIT_LIST_HEAD(&cmd->msg_l); 528b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_queue_head_init(&cmd->msg_frags); 538b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd->wait_response = (type == NFC_HCI_HCP_COMMAND) ? true : false; 548b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd->cb = cb; 55b5faa648faf974b58e5a79eafa9a97e1deed7a8aEric Lapuyade cmd->cb_context = cb_context; 568b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade cmd->completion_delay = completion_delay; 578b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 588b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade hci_len = payload_len + 1; 598b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade while (hci_len > 0) { 608b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct sk_buff *skb; 618b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade int skb_len, data_link_len; 628b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade struct hcp_packet *packet; 638b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 648b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (NFC_HCI_HCP_PACKET_HEADER_LEN + hci_len <= 658b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade hdev->max_data_link_payload) 668b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len = hci_len; 678b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade else 688b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len = hdev->max_data_link_payload - 698b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade NFC_HCI_HCP_PACKET_HEADER_LEN; 708b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 718b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_len = ndev->tx_headroom + NFC_HCI_HCP_PACKET_HEADER_LEN + 728b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len + ndev->tx_tailroom; 738b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade hci_len -= data_link_len; 748b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 758b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb = alloc_skb(skb_len, GFP_KERNEL); 768b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (skb == NULL) { 778b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade err = -ENOMEM; 788b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade goto out_skb_err; 798b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 808b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_reserve(skb, ndev->tx_headroom); 818b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 828b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_put(skb, NFC_HCI_HCP_PACKET_HEADER_LEN + data_link_len); 838b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 848b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade /* Only the last fragment will have the cb bit set to 1 */ 858b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet = (struct hcp_packet *)skb->data; 868b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet->header = pipe; 878b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (firstfrag) { 888b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade firstfrag = false; 898b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet->message.header = HCP_HEADER(type, instruction); 908b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (ptr) { 918b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade memcpy(packet->message.data, ptr, 928b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade data_link_len - 1); 938b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade ptr += data_link_len - 1; 948b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 958b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } else { 968b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade memcpy(&packet->message, ptr, data_link_len); 978b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade ptr += data_link_len; 988b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 998b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1008b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade /* This is the last fragment, set the cb bit */ 1018b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (hci_len == 0) 1028b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade packet->header |= ~NFC_HCI_FRAGMENT; 1038b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1048b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_queue_tail(&cmd->msg_frags, skb); 1058b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 1068b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1078b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade mutex_lock(&hdev->msg_tx_mutex); 108f8bf65bf3688835f95f7c74f5c844a64b2743a42Mathias Jeppsson list_add_tail(&cmd->msg_l, &hdev->msg_tx_queue); 1098b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade mutex_unlock(&hdev->msg_tx_mutex); 1108b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 111916082b073ebb7f4e064cebce0768e34cacde508Linus Torvalds schedule_work(&hdev->msg_tx_work); 1128b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1138b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return 0; 1148b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1158b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadeout_skb_err: 1168b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade skb_queue_purge(&cmd->msg_frags); 1178b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade kfree(cmd); 1188b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1198b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return err; 1208b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade} 1218b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1228b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadeu8 nfc_hci_pipe2gate(struct nfc_hci_dev *hdev, u8 pipe) 1238b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade{ 1248b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade int gate; 1258b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1268b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade for (gate = 0; gate < NFC_HCI_MAX_GATES; gate++) 1278b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade if (hdev->gate2pipe[gate] == pipe) 1288b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return gate; 1298b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1308b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade return 0xff; 1318b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade} 1328b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade 1338b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade/* 1348b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * Receive hcp message for pipe, with type and cmd. 1358b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade * skb contains optional message data only. 1368b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade */ 1378b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyadevoid nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type, 1388b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade u8 instruction, struct sk_buff *skb) 1398b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade{ 1408b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade switch (type) { 1418b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade case NFC_HCI_HCP_RESPONSE: 1428b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade nfc_hci_resp_received(hdev, instruction, skb); 1438b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1448b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade case NFC_HCI_HCP_COMMAND: 1458b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade nfc_hci_cmd_received(hdev, pipe, instruction, skb); 1468b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1478b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade case NFC_HCI_HCP_EVENT: 1488b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade nfc_hci_event_received(hdev, pipe, instruction, skb); 1498b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1508b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade default: 1518b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade pr_err("UNKNOWN MSG Type %d, instruction=%d\n", 1528b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade type, instruction); 1538b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade kfree_skb(skb); 1548b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade break; 1558b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade } 1568b8d2e08bf0d50193931afd27482a59376b66b2bEric Lapuyade} 157