Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a10d595b authored by Eric Lapuyade's avatar Eric Lapuyade Committed by John W. Linville
Browse files

NFC: Allow HCI driver to pre-open pipes to some gates



Some NFC chips will statically create and open pipes for both standard
and proprietary gates. The driver can now pass this information to HCI
such that HCI will not attempt to create and open them, but will instead
directly use the passed pipe ids.

Signed-off-by: default avatarEric Lapuyade <eric.lapuyade@intel.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent eae202aa
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -108,16 +108,22 @@ enum pn544_state {

#define PN544_NFC_WI_MGMT_GATE			0xA1

static u8 pn544_custom_gates[] = {
	PN544_SYS_MGMT_GATE,
	PN544_SWP_MGMT_GATE,
	PN544_POLLING_LOOP_MGMT_GATE,
	PN544_NFC_WI_MGMT_GATE,
	PN544_RF_READER_F_GATE,
	PN544_RF_READER_JEWEL_GATE,
	PN544_RF_READER_ISO15693_GATE,
	PN544_RF_READER_NFCIP1_INITIATOR_GATE,
	PN544_RF_READER_NFCIP1_TARGET_GATE
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}
};

/* Largest headroom needed for outgoing custom commands */
@@ -849,10 +855,9 @@ static int __devinit pn544_hci_probe(struct i2c_client *client,
		goto err_rti;
	}

	init_data.gate_count = ARRAY_SIZE(pn544_custom_gates);
	init_data.gate_count = ARRAY_SIZE(pn544_gates);

	memcpy(init_data.gates, pn544_custom_gates,
	       ARRAY_SIZE(pn544_custom_gates));
	memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates));

	/*
	 * TODO: Session id must include the driver name + some bus addr
+14 −3
Original line number Diff line number Diff line
@@ -44,10 +44,20 @@ struct nfc_hci_ops {
			      struct nfc_target *target);
};

#define NFC_HCI_MAX_CUSTOM_GATES	15
/* Pipes */
#define NFC_HCI_INVALID_PIPE	0x80
#define NFC_HCI_LINK_MGMT_PIPE	0x00
#define NFC_HCI_ADMIN_PIPE	0x01

struct nfc_hci_gate {
	u8 gate;
	u8 pipe;
};

#define NFC_HCI_MAX_CUSTOM_GATES	50
struct nfc_hci_init_data {
	u8 gate_count;
	u8 gates[NFC_HCI_MAX_CUSTOM_GATES];
	struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES];
	char session_id[9];
};

@@ -182,7 +192,8 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb);

/* connecting to gates and sending hci instructions */
int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate);
int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
			 u8 pipe);
int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate);
int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev);
int nfc_hci_get_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx,
+6 −2
Original line number Diff line number Diff line
@@ -299,9 +299,9 @@ int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev)
}
EXPORT_SYMBOL(nfc_hci_disconnect_all_gates);

int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate)
int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
			 u8 pipe)
{
	u8 pipe = NFC_HCI_INVALID_PIPE;
	bool pipe_created = false;
	int r;

@@ -310,6 +310,9 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate)
	if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE)
		return -EADDRINUSE;

	if (pipe != NFC_HCI_INVALID_PIPE)
		goto pipe_is_open;

	switch (dest_gate) {
	case NFC_HCI_LINK_MGMT_GATE:
		pipe = NFC_HCI_LINK_MGMT_PIPE;
@@ -335,6 +338,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate)
		return r;
	}

pipe_is_open:
	hdev->gate2pipe[dest_gate] = pipe;

	return 0;
+9 −14
Original line number Diff line number Diff line
@@ -315,15 +315,15 @@ static void nfc_hci_cmd_timeout(unsigned long data)
}

static int hci_dev_connect_gates(struct nfc_hci_dev *hdev, u8 gate_count,
				 u8 gates[])
				 struct nfc_hci_gate *gates)
{
	int r;
	u8 *p = gates;
	while (gate_count--) {
		r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, *p);
		r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
					 gates->gate, gates->pipe);
		if (r < 0)
			return r;
		p++;
		gates++;
	}

	return 0;
@@ -333,14 +333,13 @@ static int hci_dev_session_init(struct nfc_hci_dev *hdev)
{
	struct sk_buff *skb = NULL;
	int r;
	u8 hci_gates[] = {	/* NFC_HCI_ADMIN_GATE MUST be first */
		NFC_HCI_ADMIN_GATE, NFC_HCI_LOOPBACK_GATE,
		NFC_HCI_ID_MGMT_GATE, NFC_HCI_LINK_MGMT_GATE,
		NFC_HCI_RF_READER_B_GATE, NFC_HCI_RF_READER_A_GATE
	};

	if (hdev->init_data.gates[0].gate != NFC_HCI_ADMIN_GATE)
		return -EPROTO;

	r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
				 NFC_HCI_ADMIN_GATE);
				 hdev->init_data.gates[0].gate,
				 hdev->init_data.gates[0].pipe);
	if (r < 0)
		goto exit;

@@ -368,10 +367,6 @@ static int hci_dev_session_init(struct nfc_hci_dev *hdev)
	if (r < 0)
		goto exit;

	r = hci_dev_connect_gates(hdev, sizeof(hci_gates), hci_gates);
	if (r < 0)
		goto disconnect_all;

	r = hci_dev_connect_gates(hdev, hdev->init_data.gate_count,
				  hdev->init_data.gates);
	if (r < 0)
+0 −5
Original line number Diff line number Diff line
@@ -132,9 +132,4 @@ void nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type,
#define NFC_HCI_ANY_E_REG_ACCESS_DENIED		0x0a
#define NFC_HCI_ANY_E_PIPE_ACCESS_DENIED	0x0b

/* Pipes */
#define NFC_HCI_INVALID_PIPE	0x80
#define NFC_HCI_LINK_MGMT_PIPE	0x00
#define NFC_HCI_ADMIN_PIPE	0x01

#endif /* __LOCAL_HCI_H */