pn544.c 24.0 KB
Newer Older
E
Eric Lapuyade 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * HCI based Driver for NXP PN544 NFC Chip
 *
 * Copyright (C) 2012  Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
E
Eric Lapuyade 已提交
17 18
 */

J
Joe Perches 已提交
19 20
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

E
Eric Lapuyade 已提交
21 22
#include <linux/delay.h>
#include <linux/slab.h>
23
#include <linux/module.h>
E
Eric Lapuyade 已提交
24 25 26

#include <linux/nfc.h>
#include <net/nfc/hci.h>
27
#include <net/nfc/llc.h>
E
Eric Lapuyade 已提交
28

29
#include "pn544.h"
E
Eric Lapuyade 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43

/* Timing restrictions (ms) */
#define PN544_HCI_RESETVEN_TIME		30

enum pn544_state {
	PN544_ST_COLD,
	PN544_ST_FW_READY,
	PN544_ST_READY,
};

#define FULL_VERSION_LEN 11

/* Proprietary commands */
#define PN544_WRITE		0x3f
44
#define PN544_TEST_SWP		0x21
E
Eric Lapuyade 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

/* Proprietary gates, events, commands and registers */

/* NFC_HCI_RF_READER_A_GATE additional registers and commands */
#define PN544_RF_READER_A_AUTO_ACTIVATION			0x10
#define PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION		0x12
#define PN544_MIFARE_CMD					0x21

/* Commands that apply to all RF readers */
#define PN544_RF_READER_CMD_PRESENCE_CHECK	0x30
#define PN544_RF_READER_CMD_ACTIVATE_NEXT	0x32

/* NFC_HCI_ID_MGMT_GATE additional registers */
#define PN544_ID_MGMT_FULL_VERSION_SW		0x10

#define PN544_RF_READER_ISO15693_GATE		0x12

#define PN544_RF_READER_F_GATE			0x14
#define PN544_FELICA_ID				0x04
#define PN544_FELICA_RAW			0x20

#define PN544_RF_READER_JEWEL_GATE		0x15
#define PN544_JEWEL_RAW_CMD			0x23

#define PN544_RF_READER_NFCIP1_INITIATOR_GATE	0x30
#define PN544_RF_READER_NFCIP1_TARGET_GATE	0x31

#define PN544_SYS_MGMT_GATE			0x90
#define PN544_SYS_MGMT_INFO_NOTIFICATION	0x02

#define PN544_POLLING_LOOP_MGMT_GATE		0x94
A
Arron Wang 已提交
76 77 78 79
#define PN544_DEP_MODE				0x01
#define PN544_DEP_ATR_REQ			0x02
#define PN544_DEP_ATR_RES			0x03
#define PN544_DEP_MERGE				0x0D
E
Eric Lapuyade 已提交
80 81 82 83 84
#define PN544_PL_RDPHASES			0x06
#define PN544_PL_EMULATION			0x07
#define PN544_PL_NFCT_DEACTIVATED		0x09

#define PN544_SWP_MGMT_GATE			0xA0
85
#define PN544_SWP_DEFAULT_MODE			0x01
E
Eric Lapuyade 已提交
86 87

#define PN544_NFC_WI_MGMT_GATE			0xA1
88
#define PN544_NFC_ESE_DEFAULT_MODE		0x01
E
Eric Lapuyade 已提交
89

90 91 92 93 94
#define PN544_HCI_EVT_SND_DATA			0x01
#define PN544_HCI_EVT_ACTIVATED			0x02
#define PN544_HCI_EVT_DEACTIVATED		0x03
#define PN544_HCI_EVT_RCV_DATA			0x04
#define PN544_HCI_EVT_CONTINUE_MI		0x05
95
#define PN544_HCI_EVT_SWITCH_MODE		0x03
96

97
#define PN544_HCI_CMD_ATTREQUEST		0x12
A
Arron Wang 已提交
98 99
#define PN544_HCI_CMD_CONTINUE_ACTIVATION	0x13

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
static struct nfc_hci_gate pn544_gates[] = {
	{NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_LINK_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE},
	{NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_SYS_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_SWP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_POLLING_LOOP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_NFC_WI_MGMT_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_RF_READER_JEWEL_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_INVALID_PIPE},
	{PN544_RF_READER_NFCIP1_TARGET_GATE, NFC_HCI_INVALID_PIPE}
E
Eric Lapuyade 已提交
116 117 118 119 120 121
};

/* Largest headroom needed for outgoing custom commands */
#define PN544_CMDS_HEADROOM	2

struct pn544_hci_info {
122 123 124
	struct nfc_phy_ops *phy_ops;
	void *phy_id;

125
	struct nfc_hci_dev *hdev;
E
Eric Lapuyade 已提交
126 127 128 129 130

	enum pn544_state state;

	struct mutex info_lock;

131 132 133
	int async_cb_type;
	data_exchange_cb_t async_cb;
	void *async_cb_context;
134 135

	fw_download_t fw_download;
E
Eric Lapuyade 已提交
136 137
};

138
static int pn544_hci_open(struct nfc_hci_dev *hdev)
E
Eric Lapuyade 已提交
139
{
140
	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
E
Eric Lapuyade 已提交
141 142 143 144 145 146 147 148 149
	int r = 0;

	mutex_lock(&info->info_lock);

	if (info->state != PN544_ST_COLD) {
		r = -EBUSY;
		goto out;
	}

150
	r = info->phy_ops->enable(info->phy_id);
E
Eric Lapuyade 已提交
151

152 153 154
	if (r == 0)
		info->state = PN544_ST_READY;

E
Eric Lapuyade 已提交
155 156 157 158 159
out:
	mutex_unlock(&info->info_lock);
	return r;
}

160
static void pn544_hci_close(struct nfc_hci_dev *hdev)
E
Eric Lapuyade 已提交
161
{
162
	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
E
Eric Lapuyade 已提交
163 164 165 166 167 168

	mutex_lock(&info->info_lock);

	if (info->state == PN544_ST_COLD)
		goto out;

169
	info->phy_ops->disable(info->phy_id);
E
Eric Lapuyade 已提交
170

171 172
	info->state = PN544_ST_COLD;

E
Eric Lapuyade 已提交
173 174 175 176
out:
	mutex_unlock(&info->info_lock);
}

177
static int pn544_hci_ready(struct nfc_hci_dev *hdev)
E
Eric Lapuyade 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
{
	struct sk_buff *skb;
	static struct hw_config {
		u8 adr[2];
		u8 value;
	} hw_config[] = {
		{{0x9f, 0x9a}, 0x00},

		{{0x98, 0x10}, 0xbc},

		{{0x9e, 0x71}, 0x00},

		{{0x98, 0x09}, 0x00},

		{{0x9e, 0xb4}, 0x00},

		{{0x9c, 0x01}, 0x08},

		{{0x9e, 0xaa}, 0x01},

198 199 200 201 202 203 204 205 206 207 208
		{{0x9b, 0xd1}, 0x17},
		{{0x9b, 0xd2}, 0x58},
		{{0x9b, 0xd3}, 0x10},
		{{0x9b, 0xd4}, 0x47},
		{{0x9b, 0xd5}, 0x0c},
		{{0x9b, 0xd6}, 0x37},
		{{0x9b, 0xdd}, 0x33},

		{{0x9b, 0x84}, 0x00},
		{{0x99, 0x81}, 0x79},
		{{0x99, 0x31}, 0x79},
E
Eric Lapuyade 已提交
209 210 211

		{{0x98, 0x00}, 0x3f},

212
		{{0x9f, 0x09}, 0x02},
E
Eric Lapuyade 已提交
213 214 215 216

		{{0x9f, 0x0a}, 0x05},

		{{0x9e, 0xd1}, 0xa1},
217
		{{0x99, 0x23}, 0x01},
E
Eric Lapuyade 已提交
218

219 220
		{{0x9e, 0x74}, 0x00},
		{{0x9e, 0x90}, 0x00},
E
Eric Lapuyade 已提交
221 222
		{{0x9f, 0x28}, 0x10},

223
		{{0x9f, 0x35}, 0x04},
E
Eric Lapuyade 已提交
224

225
		{{0x9f, 0x36}, 0x11},
E
Eric Lapuyade 已提交
226 227 228

		{{0x9c, 0x31}, 0x00},

229
		{{0x9c, 0x32}, 0x00},
E
Eric Lapuyade 已提交
230

231
		{{0x9c, 0x19}, 0x0a},
E
Eric Lapuyade 已提交
232

233
		{{0x9c, 0x1a}, 0x0a},
E
Eric Lapuyade 已提交
234 235 236 237 238 239 240 241 242

		{{0x9c, 0x0c}, 0x00},

		{{0x9c, 0x0d}, 0x00},

		{{0x9c, 0x12}, 0x00},

		{{0x9c, 0x13}, 0x00},

243
		{{0x98, 0xa2}, 0x09},
E
Eric Lapuyade 已提交
244

245
		{{0x98, 0x93}, 0x00},
E
Eric Lapuyade 已提交
246

247
		{{0x98, 0x7d}, 0x08},
E
Eric Lapuyade 已提交
248
		{{0x98, 0x7e}, 0x00},
249
		{{0x9f, 0xc8}, 0x00},
E
Eric Lapuyade 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
	};
	struct hw_config *p = hw_config;
	int count = ARRAY_SIZE(hw_config);
	struct sk_buff *res_skb;
	u8 param[4];
	int r;

	param[0] = 0;
	while (count--) {
		param[1] = p->adr[0];
		param[2] = p->adr[1];
		param[3] = p->value;

		r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_WRITE,
				     param, 4, &res_skb);
		if (r < 0)
			return r;

		if (res_skb->len != 1) {
			kfree_skb(res_skb);
			return -EPROTO;
		}

		if (res_skb->data[0] != p->value) {
			kfree_skb(res_skb);
			return -EIO;
		}

		kfree_skb(res_skb);

		p++;
	}

	param[0] = NFC_HCI_UICC_HOST_ID;
	r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE,
			      NFC_HCI_ADMIN_WHITELIST, param, 1);
	if (r < 0)
		return r;

	param[0] = 0x3d;
	r = nfc_hci_set_param(hdev, PN544_SYS_MGMT_GATE,
			      PN544_SYS_MGMT_INFO_NOTIFICATION, param, 1);
	if (r < 0)
		return r;

	param[0] = 0x0;
	r = nfc_hci_set_param(hdev, NFC_HCI_RF_READER_A_GATE,
			      PN544_RF_READER_A_AUTO_ACTIVATION, param, 1);
	if (r < 0)
		return r;

	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
			       NFC_HCI_EVT_END_OPERATION, NULL, 0);
	if (r < 0)
		return r;

	param[0] = 0x1;
	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
			      PN544_PL_NFCT_DEACTIVATED, param, 1);
	if (r < 0)
		return r;

	param[0] = 0x0;
	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
			      PN544_PL_RDPHASES, param, 1);
	if (r < 0)
		return r;

	r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
			      PN544_ID_MGMT_FULL_VERSION_SW, &skb);
	if (r < 0)
		return r;

	if (skb->len != FULL_VERSION_LEN) {
		kfree_skb(skb);
		return -EINVAL;
	}

	print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ",
		       DUMP_PREFIX_NONE, 16, 1,
		       skb->data, FULL_VERSION_LEN, false);

	kfree_skb(skb);

	return 0;
}

337
static int pn544_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb)
E
Eric Lapuyade 已提交
338
{
339
	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
340

341
	return info->phy_ops->write(info->phy_id, skb);
E
Eric Lapuyade 已提交
342 343
}

344
static int pn544_hci_start_poll(struct nfc_hci_dev *hdev,
345
				u32 im_protocols, u32 tm_protocols)
E
Eric Lapuyade 已提交
346 347 348 349 350
{
	u8 phases = 0;
	int r;
	u8 duration[2];
	u8 activated;
A
Arron Wang 已提交
351 352 353
	u8 i_mode = 0x3f; /* Enable all supported modes */
	u8 t_mode = 0x0f;
	u8 t_merge = 0x01; /* Enable merge by default */
E
Eric Lapuyade 已提交
354

355 356
	pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n",
		__func__, im_protocols, tm_protocols);
E
Eric Lapuyade 已提交
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375

	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
			       NFC_HCI_EVT_END_OPERATION, NULL, 0);
	if (r < 0)
		return r;

	duration[0] = 0x18;
	duration[1] = 0x6a;
	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
			      PN544_PL_EMULATION, duration, 2);
	if (r < 0)
		return r;

	activated = 0;
	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
			      PN544_PL_NFCT_DEACTIVATED, &activated, 1);
	if (r < 0)
		return r;

376
	if (im_protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK |
E
Eric Lapuyade 已提交
377 378
			 NFC_PROTO_JEWEL_MASK))
		phases |= 1;		/* Type A */
379
	if (im_protocols & NFC_PROTO_FELICA_MASK) {
E
Eric Lapuyade 已提交
380 381 382 383 384 385 386 387 388 389 390
		phases |= (1 << 2);	/* Type F 212 */
		phases |= (1 << 3);	/* Type F 424 */
	}

	phases |= (1 << 5);		/* NFC active */

	r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE,
			      PN544_PL_RDPHASES, &phases, 1);
	if (r < 0)
		return r;

A
Arron Wang 已提交
391 392 393
	if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
		hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
							&hdev->gb_len);
J
Joe Perches 已提交
394
		pr_debug("generate local bytes %p\n", hdev->gb);
A
Arron Wang 已提交
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
		if (hdev->gb == NULL || hdev->gb_len == 0) {
			im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
			tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
		}
	}

	if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
		r = nfc_hci_send_event(hdev,
				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
				NFC_HCI_EVT_END_OPERATION, NULL, 0);
		if (r < 0)
			return r;

		r = nfc_hci_set_param(hdev,
				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
				PN544_DEP_MODE, &i_mode, 1);
		if (r < 0)
			return r;

		r = nfc_hci_set_param(hdev,
				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
				PN544_DEP_ATR_REQ, hdev->gb, hdev->gb_len);
		if (r < 0)
			return r;

		r = nfc_hci_send_event(hdev,
				PN544_RF_READER_NFCIP1_INITIATOR_GATE,
				NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
		if (r < 0)
			nfc_hci_send_event(hdev,
					PN544_RF_READER_NFCIP1_INITIATOR_GATE,
					NFC_HCI_EVT_END_OPERATION, NULL, 0);
	}

	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
		r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
				PN544_DEP_MODE, &t_mode, 1);
		if (r < 0)
			return r;

		r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
				PN544_DEP_ATR_RES, hdev->gb, hdev->gb_len);
		if (r < 0)
			return r;

		r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
				PN544_DEP_MERGE, &t_merge, 1);
		if (r < 0)
			return r;
	}

E
Eric Lapuyade 已提交
446 447 448 449 450 451 452 453 454
	r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
			       NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
	if (r < 0)
		nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
				   NFC_HCI_EVT_END_OPERATION, NULL, 0);

	return r;
}

455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
static int pn544_hci_dep_link_up(struct nfc_hci_dev *hdev,
				struct nfc_target *target, u8 comm_mode,
				u8 *gb, size_t gb_len)
{
	struct sk_buff *rgb_skb = NULL;
	int r;

	r = nfc_hci_get_param(hdev, target->hci_reader_gate,
				PN544_DEP_ATR_RES, &rgb_skb);
	if (r < 0)
		return r;

	if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) {
		r = -EPROTO;
		goto exit;
	}
	print_hex_dump(KERN_DEBUG, "remote gb: ", DUMP_PREFIX_OFFSET,
			16, 1, rgb_skb->data, rgb_skb->len, true);

	r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data,
						rgb_skb->len);

	if (r == 0)
		r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode,
					NFC_RF_INITIATOR);
exit:
	kfree_skb(rgb_skb);
	return r;
}

static int pn544_hci_dep_link_down(struct nfc_hci_dev *hdev)
{

	return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE,
					NFC_HCI_EVT_END_OPERATION, NULL, 0);
}

492
static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
E
Eric Lapuyade 已提交
493 494 495 496 497 498 499 500 501 502
				      struct nfc_target *target)
{
	switch (gate) {
	case PN544_RF_READER_F_GATE:
		target->supported_protocols = NFC_PROTO_FELICA_MASK;
		break;
	case PN544_RF_READER_JEWEL_GATE:
		target->supported_protocols = NFC_PROTO_JEWEL_MASK;
		target->sens_res = 0x0c00;
		break;
A
Arron Wang 已提交
503 504 505
	case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
		target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
		break;
E
Eric Lapuyade 已提交
506 507 508 509 510 511 512
	default:
		return -EPROTO;
	}

	return 0;
}

513
static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev,
E
Eric Lapuyade 已提交
514 515 516 517 518 519
						u8 gate,
						struct nfc_target *target)
{
	struct sk_buff *uid_skb;
	int r = 0;

A
Arron Wang 已提交
520 521 522 523 524 525 526 527 528 529 530 531
	if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE)
		return r;

	if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) {
		r = nfc_hci_send_cmd(hdev,
			PN544_RF_READER_NFCIP1_INITIATOR_GATE,
			PN544_HCI_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL);
		if (r < 0)
			return r;

		target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE;
	} else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
E
Eric Lapuyade 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
		if (target->nfcid1_len != 4 && target->nfcid1_len != 7 &&
		    target->nfcid1_len != 10)
			return -EPROTO;

		r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
				     PN544_RF_READER_CMD_ACTIVATE_NEXT,
				     target->nfcid1, target->nfcid1_len, NULL);
	} else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) {
		r = nfc_hci_get_param(hdev, PN544_RF_READER_F_GATE,
				      PN544_FELICA_ID, &uid_skb);
		if (r < 0)
			return r;

		if (uid_skb->len != 8) {
			kfree_skb(uid_skb);
			return -EPROTO;
		}

550 551 552 553
		/* Type F NFC-DEP IDm has prefix 0x01FE */
		if ((uid_skb->data[0] == 0x01) && (uid_skb->data[1] == 0xfe)) {
			kfree_skb(uid_skb);
			r = nfc_hci_send_cmd(hdev,
A
Arron Wang 已提交
554 555 556
					PN544_RF_READER_NFCIP1_INITIATOR_GATE,
					PN544_HCI_CMD_CONTINUE_ACTIVATION,
					NULL, 0, NULL);
557 558 559 560 561 562 563 564 565 566 567 568
			if (r < 0)
				return r;

			target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
			target->hci_reader_gate =
				PN544_RF_READER_NFCIP1_INITIATOR_GATE;
		} else {
			r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE,
					     PN544_RF_READER_CMD_ACTIVATE_NEXT,
					     uid_skb->data, uid_skb->len, NULL);
			kfree_skb(uid_skb);
		}
E
Eric Lapuyade 已提交
569 570 571 572 573 574 575 576 577 578 579 580 581 582
	} else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) {
		/*
		 * TODO: maybe other ISO 14443 require some kind of continue
		 * activation, but for now we've seen only this one below.
		 */
		if (target->sens_res == 0x4403)	/* Type 4 Mifare DESFire */
			r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
			      PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION,
			      NULL, 0, NULL);
	}

	return r;
}

583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
#define PN544_CB_TYPE_READER_F 1

static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb,
				       int err)
{
	struct pn544_hci_info *info = context;

	switch (info->async_cb_type) {
	case PN544_CB_TYPE_READER_F:
		if (err == 0)
			skb_pull(skb, 1);
		info->async_cb(info->async_cb_context, skb, err);
		break;
	default:
		if (err == 0)
			kfree_skb(skb);
		break;
	}
}

E
Eric Lapuyade 已提交
603 604 605 606 607 608 609 610 611 612 613
#define MIFARE_CMD_AUTH_KEY_A	0x60
#define MIFARE_CMD_AUTH_KEY_B	0x61
#define MIFARE_CMD_HEADER	2
#define MIFARE_UID_LEN		4
#define MIFARE_KEY_LEN		6
#define MIFARE_CMD_LEN		12
/*
 * Returns:
 * <= 0: driver handled the data exchange
 *    1: driver doesn't especially handle, please do standard processing
 */
614
static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev,
E
Eric Lapuyade 已提交
615
				   struct nfc_target *target,
616 617
				   struct sk_buff *skb, data_exchange_cb_t cb,
				   void *cb_context)
E
Eric Lapuyade 已提交
618
{
619
	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
E
Eric Lapuyade 已提交
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643

	pr_info(DRIVER_DESC ": %s for gate=%d\n", __func__,
		target->hci_reader_gate);

	switch (target->hci_reader_gate) {
	case NFC_HCI_RF_READER_A_GATE:
		if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
			/*
			 * It seems that pn544 is inverting key and UID for
			 * MIFARE authentication commands.
			 */
			if (skb->len == MIFARE_CMD_LEN &&
			    (skb->data[0] == MIFARE_CMD_AUTH_KEY_A ||
			     skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) {
				u8 uid[MIFARE_UID_LEN];
				u8 *data = skb->data + MIFARE_CMD_HEADER;

				memcpy(uid, data + MIFARE_KEY_LEN,
				       MIFARE_UID_LEN);
				memmove(data + MIFARE_UID_LEN, data,
					MIFARE_KEY_LEN);
				memcpy(data, uid, MIFARE_UID_LEN);
			}

644 645 646 647 648
			return nfc_hci_send_cmd_async(hdev,
						      target->hci_reader_gate,
						      PN544_MIFARE_CMD,
						      skb->data, skb->len,
						      cb, cb_context);
E
Eric Lapuyade 已提交
649 650 651 652 653 654
		} else
			return 1;
	case PN544_RF_READER_F_GATE:
		*skb_push(skb, 1) = 0;
		*skb_push(skb, 1) = 0;

655 656 657 658 659 660 661 662
		info->async_cb_type = PN544_CB_TYPE_READER_F;
		info->async_cb = cb;
		info->async_cb_context = cb_context;

		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
					      PN544_FELICA_RAW, skb->data,
					      skb->len,
					      pn544_hci_data_exchange_cb, info);
E
Eric Lapuyade 已提交
663
	case PN544_RF_READER_JEWEL_GATE:
664 665 666
		return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
					      PN544_JEWEL_RAW_CMD, skb->data,
					      skb->len, cb, cb_context);
667 668 669 670 671 672
	case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
		*skb_push(skb, 1) = 0;

		return nfc_hci_send_event(hdev, target->hci_reader_gate,
					PN544_HCI_EVT_SND_DATA, skb->data,
					skb->len);
E
Eric Lapuyade 已提交
673 674 675 676 677
	default:
		return 1;
	}
}

678 679
static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
{
680 681
	int r;

682 683 684
	/* Set default false for multiple information chaining */
	*skb_push(skb, 1) = 0;

685 686 687 688 689 690
	r = nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
			       PN544_HCI_EVT_SND_DATA, skb->data, skb->len);

	kfree_skb(skb);

	return r;
691 692
}

693
static int pn544_hci_check_presence(struct nfc_hci_dev *hdev,
E
Eric Lapuyade 已提交
694 695
				   struct nfc_target *target)
{
J
Joe Perches 已提交
696
	pr_debug("supported protocol %d\b", target->supported_protocols);
697 698 699 700 701 702 703 704
	if (target->supported_protocols & (NFC_PROTO_ISO14443_MASK |
					NFC_PROTO_ISO14443_B_MASK)) {
		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
					PN544_RF_READER_CMD_PRESENCE_CHECK,
					NULL, 0, NULL);
	} else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) {
		if (target->nfcid1_len != 4 && target->nfcid1_len != 7 &&
		    target->nfcid1_len != 10)
705
			return -EOPNOTSUPP;
706 707 708 709

		 return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
				     PN544_RF_READER_CMD_ACTIVATE_NEXT,
				     target->nfcid1, target->nfcid1_len, NULL);
710 711 712
	} else if (target->supported_protocols & (NFC_PROTO_JEWEL_MASK |
						NFC_PROTO_FELICA_MASK)) {
		return -EOPNOTSUPP;
713 714 715 716 717 718 719
	} else if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) {
		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
					PN544_HCI_CMD_ATTREQUEST,
					NULL, 0, NULL);
	}

	return 0;
E
Eric Lapuyade 已提交
720 721
}

722 723 724 725 726
/*
 * Returns:
 * <= 0: driver handled the event, skb consumed
 *    1: driver does not handle the event, please do standard processing
 */
727 728
static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event,
				    struct sk_buff *skb)
729 730
{
	struct sk_buff *rgb_skb = NULL;
731
	int r;
732

J
Joe Perches 已提交
733
	pr_debug("hci event %d\n", event);
734 735
	switch (event) {
	case PN544_HCI_EVT_ACTIVATED:
736
		if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) {
737
			r = nfc_hci_target_discovered(hdev, gate);
738
		} else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) {
739
			r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ,
740
					      &rgb_skb);
741 742 743
			if (r < 0)
				goto exit;

744 745 746
			r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
					     NFC_COMM_PASSIVE, rgb_skb->data,
					     rgb_skb->len);
747 748

			kfree_skb(rgb_skb);
749 750
		} else {
			r = -EINVAL;
751 752 753
		}
		break;
	case PN544_HCI_EVT_DEACTIVATED:
754 755
		r = nfc_hci_send_event(hdev, gate, NFC_HCI_EVT_END_OPERATION,
				       NULL, 0);
756
		break;
757 758 759 760 761 762 763
	case PN544_HCI_EVT_RCV_DATA:
		if (skb->len < 2) {
			r = -EPROTO;
			goto exit;
		}

		if (skb->data[0] != 0) {
J
Joe Perches 已提交
764
			pr_debug("data0 %d\n", skb->data[0]);
765 766 767 768 769
			r = -EPROTO;
			goto exit;
		}

		skb_pull(skb, 2);
770
		return nfc_tm_data_received(hdev->ndev, skb);
771
	default:
772
		return 1;
773 774 775 776
	}

exit:
	kfree_skb(skb);
777 778

	return r;
779 780
}

781 782 783 784 785 786 787 788 789 790 791
static int pn544_hci_fw_download(struct nfc_hci_dev *hdev,
				 const char *firmware_name)
{
	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);

	if (info->fw_download == NULL)
		return -ENOTSUPP;

	return info->fw_download(info->phy_id, firmware_name);
}

792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817
static int pn544_hci_discover_se(struct nfc_hci_dev *hdev)
{
	u32 se_idx = 0;
	u8 ese_mode = 0x01; /* Default mode */
	struct sk_buff *res_skb;
	int r;

	r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_TEST_SWP,
			     NULL, 0, &res_skb);

	if (r == 0) {
		if (res_skb->len == 2 && res_skb->data[0] == 0x00)
			nfc_add_se(hdev->ndev, se_idx++, NFC_SE_UICC);

		kfree_skb(res_skb);
	}

	r = nfc_hci_send_event(hdev, PN544_NFC_WI_MGMT_GATE,
				PN544_HCI_EVT_SWITCH_MODE,
				&ese_mode, 1);
	if (r == 0)
		nfc_add_se(hdev->ndev, se_idx++, NFC_SE_EMBEDDED);

	return !se_idx;
}

818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
#define PN544_SE_MODE_OFF	0x00
#define PN544_SE_MODE_ON	0x01
static int pn544_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx)
{
	struct nfc_se *se;
	u8 enable = PN544_SE_MODE_ON;
	static struct uicc_gatelist {
		u8 head;
		u8 adr[2];
		u8 value;
	} uicc_gatelist[] = {
		{0x00, {0x9e, 0xd9}, 0x23},
		{0x00, {0x9e, 0xda}, 0x21},
		{0x00, {0x9e, 0xdb}, 0x22},
		{0x00, {0x9e, 0xdc}, 0x24},
	};
	struct uicc_gatelist *p = uicc_gatelist;
	int count = ARRAY_SIZE(uicc_gatelist);
	struct sk_buff *res_skb;
	int r;

	se = nfc_find_se(hdev->ndev, se_idx);

	switch (se->type) {
	case NFC_SE_UICC:
		while (count--) {
			r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE,
					PN544_WRITE, (u8 *)p, 4, &res_skb);
			if (r < 0)
				return r;

			if (res_skb->len != 1) {
				kfree_skb(res_skb);
				return -EPROTO;
			}

			if (res_skb->data[0] != p->value) {
				kfree_skb(res_skb);
				return -EIO;
			}

			kfree_skb(res_skb);

			p++;
		}

		return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
			      PN544_SWP_DEFAULT_MODE, &enable, 1);
	case NFC_SE_EMBEDDED:
		return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
			      PN544_NFC_ESE_DEFAULT_MODE, &enable, 1);

	default:
		return -EINVAL;
	}
}

static int pn544_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx)
{
	struct nfc_se *se;
	u8 disable = PN544_SE_MODE_OFF;

	se = nfc_find_se(hdev->ndev, se_idx);

	switch (se->type) {
	case NFC_SE_UICC:
		return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
			      PN544_SWP_DEFAULT_MODE, &disable, 1);
	case NFC_SE_EMBEDDED:
		return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
			      PN544_NFC_ESE_DEFAULT_MODE, &disable, 1);
	default:
		return -EINVAL;
	}
}

894
static struct nfc_hci_ops pn544_hci_ops = {
E
Eric Lapuyade 已提交
895 896 897 898 899
	.open = pn544_hci_open,
	.close = pn544_hci_close,
	.hci_ready = pn544_hci_ready,
	.xmit = pn544_hci_xmit,
	.start_poll = pn544_hci_start_poll,
900 901
	.dep_link_up = pn544_hci_dep_link_up,
	.dep_link_down = pn544_hci_dep_link_down,
E
Eric Lapuyade 已提交
902 903
	.target_from_gate = pn544_hci_target_from_gate,
	.complete_target_discovered = pn544_hci_complete_target_discovered,
904 905
	.im_transceive = pn544_hci_im_transceive,
	.tm_send = pn544_hci_tm_send,
E
Eric Lapuyade 已提交
906
	.check_presence = pn544_hci_check_presence,
907
	.event_received = pn544_hci_event_received,
908
	.fw_download = pn544_hci_fw_download,
909
	.discover_se = pn544_hci_discover_se,
910 911
	.enable_se = pn544_hci_enable_se,
	.disable_se = pn544_hci_disable_se,
E
Eric Lapuyade 已提交
912 913
};

914 915
int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
		    int phy_headroom, int phy_tailroom, int phy_payload,
916
		    fw_download_t fw_download, struct nfc_hci_dev **hdev)
E
Eric Lapuyade 已提交
917 918
{
	struct pn544_hci_info *info;
919
	u32 protocols;
E
Eric Lapuyade 已提交
920
	struct nfc_hci_init_data init_data;
921
	int r;
E
Eric Lapuyade 已提交
922 923 924 925 926 927 928

	info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL);
	if (!info) {
		r = -ENOMEM;
		goto err_info_alloc;
	}

929 930
	info->phy_ops = phy_ops;
	info->phy_id = phy_id;
931
	info->fw_download = fw_download;
E
Eric Lapuyade 已提交
932 933 934
	info->state = PN544_ST_COLD;
	mutex_init(&info->info_lock);

935
	init_data.gate_count = ARRAY_SIZE(pn544_gates);
E
Eric Lapuyade 已提交
936

937
	memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates));
E
Eric Lapuyade 已提交
938 939 940 941 942 943 944 945 946 947 948

	/*
	 * TODO: Session id must include the driver name + some bus addr
	 * persistent info to discriminate 2 identical chips
	 */
	strcpy(init_data.session_id, "ID544HCI");

	protocols = NFC_PROTO_JEWEL_MASK |
		    NFC_PROTO_MIFARE_MASK |
		    NFC_PROTO_FELICA_MASK |
		    NFC_PROTO_ISO14443_MASK |
949
		    NFC_PROTO_ISO14443_B_MASK |
E
Eric Lapuyade 已提交
950 951
		    NFC_PROTO_NFC_DEP_MASK;

952
	info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0,
953
					     protocols, llc_name,
954 955
					     phy_headroom + PN544_CMDS_HEADROOM,
					     phy_tailroom, phy_payload);
956
	if (!info->hdev) {
J
Joe Perches 已提交
957
		pr_err("Cannot allocate nfc hdev\n");
E
Eric Lapuyade 已提交
958
		r = -ENOMEM;
959
		goto err_alloc_hdev;
E
Eric Lapuyade 已提交
960 961
	}

962 963 964 965 966
	nfc_hci_set_clientdata(info->hdev, info);

	r = nfc_hci_register_device(info->hdev);
	if (r)
		goto err_regdev;
E
Eric Lapuyade 已提交
967

968 969
	*hdev = info->hdev;

E
Eric Lapuyade 已提交
970 971
	return 0;

972 973 974 975
err_regdev:
	nfc_hci_free_device(info->hdev);

err_alloc_hdev:
E
Eric Lapuyade 已提交
976 977 978 979 980
	kfree(info);

err_info_alloc:
	return r;
}
981
EXPORT_SYMBOL(pn544_hci_probe);
E
Eric Lapuyade 已提交
982

983
void pn544_hci_remove(struct nfc_hci_dev *hdev)
E
Eric Lapuyade 已提交
984
{
985
	struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev);
E
Eric Lapuyade 已提交
986

987 988
	nfc_hci_unregister_device(hdev);
	nfc_hci_free_device(hdev);
E
Eric Lapuyade 已提交
989 990
	kfree(info);
}
991 992 993 994
EXPORT_SYMBOL(pn544_hci_remove);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DRIVER_DESC);