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: Eric Lapuyade <eric.lapuyade@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c
index 12cd6f3..46362ef 100644
--- a/net/nfc/hci/command.c
+++ b/net/nfc/hci/command.c
@@ -299,9 +299,9 @@
 }
 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 @@
 	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 @@
 		return r;
 	}
 
+pipe_is_open:
 	hdev->gate2pipe[dest_gate] = pipe;
 
 	return 0;
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index e6b2df3..4ccc518 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -315,15 +315,15 @@
 }
 
 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 @@
 {
 	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 @@
 	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)
diff --git a/net/nfc/hci/hci.h b/net/nfc/hci/hci.h
index d3cde07..fa9a21e 100644
--- a/net/nfc/hci/hci.h
+++ b/net/nfc/hci/hci.h
@@ -132,9 +132,4 @@
 #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 */