aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Lapuyade <eric.lapuyade@linux.intel.com>2012-06-05 08:42:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-09 16:42:12 -0400
commita10d595b1074d04446f77161eea165e5809e163c (patch)
tree4ba305673685b1602cc4ec66083a7c06a1d0b06e
parenteae202aa2083eb6f7fdb686e2c42d7db4ef63632 (diff)
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>
-rw-r--r--drivers/nfc/pn544_hci.c31
-rw-r--r--include/net/nfc/hci.h17
-rw-r--r--net/nfc/hci/command.c8
-rw-r--r--net/nfc/hci/core.c23
-rw-r--r--net/nfc/hci/hci.h5
5 files changed, 47 insertions, 37 deletions
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c
index 69df6fecb847..c67b55e224e0 100644
--- a/drivers/nfc/pn544_hci.c
+++ b/drivers/nfc/pn544_hci.c
@@ -108,16 +108,22 @@ enum pn544_state {
108 108
109#define PN544_NFC_WI_MGMT_GATE 0xA1 109#define PN544_NFC_WI_MGMT_GATE 0xA1
110 110
111static u8 pn544_custom_gates[] = { 111static struct nfc_hci_gate pn544_gates[] = {
112 PN544_SYS_MGMT_GATE, 112 {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE},
113 PN544_SWP_MGMT_GATE, 113 {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE},
114 PN544_POLLING_LOOP_MGMT_GATE, 114 {NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE},
115 PN544_NFC_WI_MGMT_GATE, 115 {NFC_HCI_LINK_MGMT_GATE, NFC_HCI_INVALID_PIPE},
116 PN544_RF_READER_F_GATE, 116 {NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE},
117 PN544_RF_READER_JEWEL_GATE, 117 {NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE},
118 PN544_RF_READER_ISO15693_GATE, 118 {PN544_SYS_MGMT_GATE, NFC_HCI_INVALID_PIPE},
119 PN544_RF_READER_NFCIP1_INITIATOR_GATE, 119 {PN544_SWP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
120 PN544_RF_READER_NFCIP1_TARGET_GATE 120 {PN544_POLLING_LOOP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
121 {PN544_NFC_WI_MGMT_GATE, NFC_HCI_INVALID_PIPE},
122 {PN544_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
123 {PN544_RF_READER_JEWEL_GATE, NFC_HCI_INVALID_PIPE},
124 {PN544_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
125 {PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_INVALID_PIPE},
126 {PN544_RF_READER_NFCIP1_TARGET_GATE, NFC_HCI_INVALID_PIPE}
121}; 127};
122 128
123/* Largest headroom needed for outgoing custom commands */ 129/* Largest headroom needed for outgoing custom commands */
@@ -849,10 +855,9 @@ static int __devinit pn544_hci_probe(struct i2c_client *client,
849 goto err_rti; 855 goto err_rti;
850 } 856 }
851 857
852 init_data.gate_count = ARRAY_SIZE(pn544_custom_gates); 858 init_data.gate_count = ARRAY_SIZE(pn544_gates);
853 859
854 memcpy(init_data.gates, pn544_custom_gates, 860 memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates));
855 ARRAY_SIZE(pn544_custom_gates));
856 861
857 /* 862 /*
858 * TODO: Session id must include the driver name + some bus addr 863 * TODO: Session id must include the driver name + some bus addr
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h
index d25dd9b99877..f5169b04f082 100644
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -44,10 +44,20 @@ struct nfc_hci_ops {
44 struct nfc_target *target); 44 struct nfc_target *target);
45}; 45};
46 46
47#define NFC_HCI_MAX_CUSTOM_GATES 15 47/* Pipes */
48#define NFC_HCI_INVALID_PIPE 0x80
49#define NFC_HCI_LINK_MGMT_PIPE 0x00
50#define NFC_HCI_ADMIN_PIPE 0x01
51
52struct nfc_hci_gate {
53 u8 gate;
54 u8 pipe;
55};
56
57#define NFC_HCI_MAX_CUSTOM_GATES 50
48struct nfc_hci_init_data { 58struct nfc_hci_init_data {
49 u8 gate_count; 59 u8 gate_count;
50 u8 gates[NFC_HCI_MAX_CUSTOM_GATES]; 60 struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES];
51 char session_id[9]; 61 char session_id[9];
52}; 62};
53 63
@@ -182,7 +192,8 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
182void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb); 192void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb);
183 193
184/* connecting to gates and sending hci instructions */ 194/* connecting to gates and sending hci instructions */
185int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate); 195int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
196 u8 pipe);
186int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate); 197int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate);
187int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev); 198int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev);
188int nfc_hci_get_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx, 199int nfc_hci_get_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx,
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c
index 12cd6f3f77ec..46362ef979db 100644
--- a/net/nfc/hci/command.c
+++ b/net/nfc/hci/command.c
@@ -299,9 +299,9 @@ int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev)
299} 299}
300EXPORT_SYMBOL(nfc_hci_disconnect_all_gates); 300EXPORT_SYMBOL(nfc_hci_disconnect_all_gates);
301 301
302int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate) 302int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
303 u8 pipe)
303{ 304{
304 u8 pipe = NFC_HCI_INVALID_PIPE;
305 bool pipe_created = false; 305 bool pipe_created = false;
306 int r; 306 int r;
307 307
@@ -310,6 +310,9 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate)
310 if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE) 310 if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE)
311 return -EADDRINUSE; 311 return -EADDRINUSE;
312 312
313 if (pipe != NFC_HCI_INVALID_PIPE)
314 goto pipe_is_open;
315
313 switch (dest_gate) { 316 switch (dest_gate) {
314 case NFC_HCI_LINK_MGMT_GATE: 317 case NFC_HCI_LINK_MGMT_GATE:
315 pipe = NFC_HCI_LINK_MGMT_PIPE; 318 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)
335 return r; 338 return r;
336 } 339 }
337 340
341pipe_is_open:
338 hdev->gate2pipe[dest_gate] = pipe; 342 hdev->gate2pipe[dest_gate] = pipe;
339 343
340 return 0; 344 return 0;
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index e6b2df3981b6..4ccc518f56eb 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -315,15 +315,15 @@ static void nfc_hci_cmd_timeout(unsigned long data)
315} 315}
316 316
317static int hci_dev_connect_gates(struct nfc_hci_dev *hdev, u8 gate_count, 317static int hci_dev_connect_gates(struct nfc_hci_dev *hdev, u8 gate_count,
318 u8 gates[]) 318 struct nfc_hci_gate *gates)
319{ 319{
320 int r; 320 int r;
321 u8 *p = gates;
322 while (gate_count--) { 321 while (gate_count--) {
323 r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, *p); 322 r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
323 gates->gate, gates->pipe);
324 if (r < 0) 324 if (r < 0)
325 return r; 325 return r;
326 p++; 326 gates++;
327 } 327 }
328 328
329 return 0; 329 return 0;
@@ -333,14 +333,13 @@ static int hci_dev_session_init(struct nfc_hci_dev *hdev)
333{ 333{
334 struct sk_buff *skb = NULL; 334 struct sk_buff *skb = NULL;
335 int r; 335 int r;
336 u8 hci_gates[] = { /* NFC_HCI_ADMIN_GATE MUST be first */ 336
337 NFC_HCI_ADMIN_GATE, NFC_HCI_LOOPBACK_GATE, 337 if (hdev->init_data.gates[0].gate != NFC_HCI_ADMIN_GATE)
338 NFC_HCI_ID_MGMT_GATE, NFC_HCI_LINK_MGMT_GATE, 338 return -EPROTO;
339 NFC_HCI_RF_READER_B_GATE, NFC_HCI_RF_READER_A_GATE
340 };
341 339
342 r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, 340 r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
343 NFC_HCI_ADMIN_GATE); 341 hdev->init_data.gates[0].gate,
342 hdev->init_data.gates[0].pipe);
344 if (r < 0) 343 if (r < 0)
345 goto exit; 344 goto exit;
346 345
@@ -368,10 +367,6 @@ static int hci_dev_session_init(struct nfc_hci_dev *hdev)
368 if (r < 0) 367 if (r < 0)
369 goto exit; 368 goto exit;
370 369
371 r = hci_dev_connect_gates(hdev, sizeof(hci_gates), hci_gates);
372 if (r < 0)
373 goto disconnect_all;
374
375 r = hci_dev_connect_gates(hdev, hdev->init_data.gate_count, 370 r = hci_dev_connect_gates(hdev, hdev->init_data.gate_count,
376 hdev->init_data.gates); 371 hdev->init_data.gates);
377 if (r < 0) 372 if (r < 0)
diff --git a/net/nfc/hci/hci.h b/net/nfc/hci/hci.h
index d3cde075ba60..fa9a21e92239 100644
--- a/net/nfc/hci/hci.h
+++ b/net/nfc/hci/hci.h
@@ -132,9 +132,4 @@ void nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type,
132#define NFC_HCI_ANY_E_REG_ACCESS_DENIED 0x0a 132#define NFC_HCI_ANY_E_REG_ACCESS_DENIED 0x0a
133#define NFC_HCI_ANY_E_PIPE_ACCESS_DENIED 0x0b 133#define NFC_HCI_ANY_E_PIPE_ACCESS_DENIED 0x0b
134 134
135/* Pipes */
136#define NFC_HCI_INVALID_PIPE 0x80
137#define NFC_HCI_LINK_MGMT_PIPE 0x00
138#define NFC_HCI_ADMIN_PIPE 0x01
139
140#endif /* __LOCAL_HCI_H */ 135#endif /* __LOCAL_HCI_H */