Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: chromeos/drivers/ath6kl/os/linux/hci_bridge.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //------------------------------------------------------------------------------
2 // <copyright file="hci_bridge.c" company="Atheros">
3 // Copyright (c) 2009 Atheros Corporation. All rights reserved.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // Software distributed under the License is distributed on an "AS
10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 // implied. See the License for the specific language governing
12 // rights and limitations under the License.
13 //
14 //
15 //------------------------------------------------------------------------------
16 //==============================================================================
17 // HCI bridge implementation
18 //
19 // Author(s): ="Atheros"
20 //==============================================================================
21
22 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
23 #include <linux/etherdevice.h>
24 #include <a_config.h>
25 #include <athdefs.h>
26 #include "a_types.h"
27 #include "a_osapi.h"
28 #include "htc_api.h"
29 #include "wmi.h"
30 #include "a_drv.h"
31 #include "hif.h"
32 #include "common_drv.h"
33 #include "a_debug.h"
34 #define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
35 #define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
36 #define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
37 #define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
38 #else
39 #include "ar6000_drv.h"
40 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
41
42 #ifdef ATH_AR6K_ENABLE_GMBOX
43 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
44 #include "export_hci_transport.h"
45 #else
46 #include "hci_transport_api.h"
47 #endif
48 #include "epping_test.h"
49 #include "gmboxif.h"
50 #include "ar3kconfig.h"
51 #include <net/bluetooth/bluetooth.h>
52 #include <net/bluetooth/hci_core.h>
53
54 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
55 /* only build on newer kernels which have BT configured */
56 #if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
57 #define CONFIG_BLUEZ_HCI_BRIDGE
58 #endif
59 #endif
60
61 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
62 unsigned int ar3khcibaud = 0;
63 unsigned int hciuartscale = 0;
64 unsigned int hciuartstep = 0;
65
66 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
67 module_param(ar3khcibaud, int, 0644);
68 module_param(hciuartscale, int, 0644);
69 module_param(hciuartstep, int, 0644);
70 #else
71
72 #define __user
73 /* for linux 2.4 and lower */
74 MODULE_PARM(ar3khcibaud, "i");
75 MODULE_PARM(hciuartscale, "i");
76 MODULE_PARM(hciuartstep, "i");
77 #endif
78 #else
79 extern unsigned int ar3khcibaud;
80 extern unsigned int hciuartscale;
81 extern unsigned int hciuartstep;
82 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
83
84 typedef struct {
85 void *pHCIDev; /* HCI bridge device */
86 HCI_TRANSPORT_PROPERTIES HCIProps; /* HCI bridge props */
87 struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
88 A_BOOL HciNormalMode; /* Actual HCI mode enabled (non-T EST)*/
89 A_BOOL HciRegistered; /* HCI device registered with sta ck */
90 HTC_PACKET_QUEUE HTCPacketStructHead;
91 A_UINT8 *pHTCStructAlloc;
92 spinlock_t BridgeLock;
93 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
94 HCI_TRANSPORT_MISC_HANDLES HCITransHdl;
95 #else
96 AR_SOFTC_T *ar;
97 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
98 } AR6K_HCI_BRIDGE_INFO;
99
100 #define MAX_ACL_RECV_BUFS 16
101 #define MAX_EVT_RECV_BUFS 8
102 #define MAX_HCI_WRITE_QUEUE_DEPTH 32
103 #define MAX_ACL_RECV_LENGTH 1200
104 #define MAX_EVT_RECV_LENGTH 257
105 #define TX_PACKET_RSV_OFFSET 32
106 #define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX _HCI_WRITE_QUEUE_DEPTH) * 2)
107
108 #define HCI_GET_OP_CODE(p) (((A_UINT16)((p)[1])) << 8) | ((A_UINT16)((p )[0]))
109
110 extern unsigned int setupbtdev;
111
112 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
113 AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo;
114 #endif
115
116 static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo);
117 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo);
118 static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo);
119 static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
120 HCI_TRANSPORT_PACKET_TYPE Type,
121 struct sk_buff *skb);
122 static struct sk_buff *bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Le ngth);
123 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb);
124
125 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
126 A_STATUS ar6000_setup_hci(void *ar);
127 void ar6000_cleanup_hci(void *ar);
128 A_STATUS hci_test_send(void *ar, struct sk_buff *skb);
129 #else
130 A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar);
131 void ar6000_cleanup_hci(AR_SOFTC_T *ar);
132 /* HCI bridge testing */
133 A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb);
134 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
135
136 #define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
137 #define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
138
139 static inline void FreeBtOsBuf(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, void *osbuf)
140 {
141 if (pHcidevInfo->HciNormalMode) {
142 bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
143 } else {
144 /* in test mode, these are just ordinary netbuf allocations */
145 A_NETBUF_FREE(osbuf);
146 }
147 }
148
149 static void FreeHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HTC_PACKET *pPacket )
150 {
151 LOCK_BRIDGE(pHcidevInfo);
152 HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
153 UNLOCK_BRIDGE(pHcidevInfo);
154 }
155
156 static HTC_PACKET * AllocHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
157 {
158 HTC_PACKET *pPacket = NULL;
159 LOCK_BRIDGE(pHcidevInfo);
160 pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
161 UNLOCK_BRIDGE(pHcidevInfo);
162 return pPacket;
163 }
164
165 #define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)- 1))
166
167 static void RefillRecvBuffers(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
168 HCI_TRANSPORT_PACKET_TYPE Type,
169 int NumBuffers)
170 {
171 int length, i;
172 void *osBuf = NULL;
173 HTC_PACKET_QUEUE queue;
174 HTC_PACKET *pPacket;
175
176 INIT_HTC_PACKET_QUEUE(&queue);
177
178 if (Type == HCI_ACL_TYPE) {
179 if (pHcidevInfo->HciNormalMode) {
180 length = HCI_MAX_FRAME_SIZE;
181 } else {
182 length = MAX_ACL_RECV_LENGTH;
183 }
184 } else {
185 length = MAX_EVT_RECV_LENGTH;
186 }
187
188 /* add on transport head and tail room */
189 length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
190 /* round up to the required I/O padding */
191 length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
192
193 for (i = 0; i < NumBuffers; i++) {
194
195 if (pHcidevInfo->HciNormalMode) {
196 osBuf = bt_alloc_buffer(pHcidevInfo,length);
197 } else {
198 osBuf = A_NETBUF_ALLOC(length);
199 }
200
201 if (NULL == osBuf) {
202 break;
203 }
204
205 pPacket = AllocHTCStruct(pHcidevInfo);
206 if (NULL == pPacket) {
207 FreeBtOsBuf(pHcidevInfo,osBuf);
208 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
209 break;
210 }
211
212 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length, Type);
213 /* add to queue */
214 HTC_PACKET_ENQUEUE(&queue,pPacket);
215 }
216
217 if (i > 0) {
218 HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);
219 }
220 }
221
222 static A_STATUS ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle,
223 HCI_TRANSPORT_PROPERTIES *pProps,
224 void *pContext)
225 {
226 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
227 A_STATUS status;
228 AR3K_CONFIG_INFO ar3kconfig;
229
230 pHcidevInfo->pHCIDev = HCIHandle;
231
232 A_MEMCPY(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
233
234 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%X, headroom:%d, tai lroom:%d blockpad:%d) \n",
235 (A_UINT32)HCIHandle,
236 pHcidevInfo->HCIProps.HeadRoom,
237 pHcidevInfo->HCIProps.TailRoom,
238 pHcidevInfo->HCIProps.IOBlockPad));
239
240 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
241 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHci devInfo->HCITransHdl.netDevice)->hard_header_len);
242 #else
243 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev- >hard_header_len);
244 #endif
245
246 /* provide buffers */
247 RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
248 RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
249
250 do {
251 /* start transport */
252 status = HCI_TransportStart(pHcidevInfo->pHCIDev);
253
254 if (A_FAILED(status)) {
255 break;
256 }
257
258 if (!pHcidevInfo->HciNormalMode) {
259 /* in test mode, no need to go any further */
260 break;
261 }
262
263 A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
264 ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
265 ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
266 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
267 ar3kconfig.pHIFDevice = (HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevic e);
268 #else
269 ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
270 #endif
271 ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
272
273 if (ar3khcibaud != 0) {
274 /* user wants ar3k baud rate change */
275 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
276 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
277 ar3kconfig.AR3KBaudRate = ar3khcibaud;
278 }
279
280 if ((hciuartscale != 0) || (hciuartstep != 0)) {
281 /* user wants to tune HCI bridge UART scale/step values */
282 ar3kconfig.AR6KScale = (A_UINT16)hciuartscale;
283 ar3kconfig.AR6KStep = (A_UINT16)hciuartstep;
284 ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
285 }
286
287 /* configure the AR3K device */
288 status = AR3KConfigure(&ar3kconfig);
289 if (A_FAILED(status)) {
290 break;
291 }
292
293 status = bt_register_hci(pHcidevInfo);
294
295 } while (FALSE);
296
297 return status;
298 }
299
300 static void ar6000_hci_transport_failure(void *pContext, A_STATUS Status)
301 {
302 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
303
304 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
305
306 if (pHcidevInfo->HciNormalMode) {
307 /* TODO .. */
308 }
309 }
310
311 static void ar6000_hci_transport_removed(void *pContext)
312 {
313 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
314
315 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n")) ;
316
317 A_ASSERT(pHcidevInfo->pHCIDev != NULL);
318
319 HCI_TransportDetach(pHcidevInfo->pHCIDev);
320 bt_cleanup_hci(pHcidevInfo);
321 pHcidevInfo->pHCIDev = NULL;
322 }
323
324 static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket)
325 {
326 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
327 void *osbuf = pPacket->pPktContext;
328 A_ASSERT(osbuf != NULL);
329 A_ASSERT(pHcidevInfo != NULL);
330
331 if (A_FAILED(pPacket->Status)) {
332 if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURC E)) {
333 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status));
334 }
335 }
336
337 FreeHTCStruct(pHcidevInfo,pPacket);
338 FreeBtOsBuf(pHcidevInfo,osbuf);
339
340 }
341
342 static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket)
343 {
344 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
345 struct sk_buff *skb;
346
347 A_ASSERT(pHcidevInfo != NULL);
348 skb = (struct sk_buff *)pPacket->pPktContext;
349 A_ASSERT(skb != NULL);
350
351 do {
352
353 if (A_FAILED(pPacket->Status)) {
354 break;
355 }
356
357 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
358 ("HCI Bridge, packet received type : %d len:%d \n",
359 HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength));
360
361 /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
362 * to fill the front of the buffer */
363 A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom) ;
364 A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom);
365
366 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
367 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n",
368 (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVEN T" : "ACL",
369 skb->len));
370 AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
371 }
372
373 if (pHcidevInfo->HciNormalMode) {
374 /* indicate the packet */
375 if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) {
376 /* bt stack accepted the packet */
377 skb = NULL;
378 }
379 break;
380 }
381
382 /* for testing, indicate packet to the network stack */
383 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
384 skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice);
385 if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) {
386 skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInf o->HCITransHdl.netDevice));
387 #else
388 skb->dev = pHcidevInfo->ar->arNetDev;
389 if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) {
390 skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev);
391 #endif
392 netif_rx(skb);
393 skb = NULL;
394 }
395
396 } while (FALSE);
397
398 FreeHTCStruct(pHcidevInfo,pPacket);
399
400 if (skb != NULL) {
401 /* packet was not accepted, free it */
402 FreeBtOsBuf(pHcidevInfo,skb);
403 }
404
405 }
406
407 static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Typ e, int BuffersAvailable)
408 {
409 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
410 int refillCount;
411
412 if (Type == HCI_ACL_TYPE) {
413 refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable;
414 } else {
415 refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable;
416 }
417
418 if (refillCount > 0) {
419 RefillRecvBuffers(pHcidevInfo,Type,refillCount);
420 }
421
422 }
423
424 static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, HTC_PACKET *pPacket)
425 {
426 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
427 HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP;
428
429 if (!pHcidevInfo->HciNormalMode) {
430 /* for epping testing, check packet tag, some epping packets are
431 * special and cannot be dropped */
432 if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) {
433 action = HCI_SEND_FULL_DROP;
434 }
435 }
436
437 return action;
438 }
439
440 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
441 A_STATUS ar6000_setup_hci(void *ar)
442 #else
443 A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar)
444 #endif
445 {
446 HCI_TRANSPORT_CONFIG_INFO config;
447 A_STATUS status = A_OK;
448 int i;
449 HTC_PACKET *pPacket;
450 AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
451
452
453 do {
454
455 pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_IN FO));
456
457 if (NULL == pHcidevInfo) {
458 status = A_NO_MEMORY;
459 break;
460 }
461
462 A_MEMZERO(pHcidevInfo, sizeof(AR6K_HCI_BRIDGE_INFO));
463 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
464 g_pHcidevInfo = pHcidevInfo;
465 pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar;
466 #else
467 ar->hcidev_info = pHcidevInfo;
468 pHcidevInfo->ar = ar;
469 #endif
470 spin_lock_init(&pHcidevInfo->BridgeLock);
471 INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
472
473 ar->exitCallback = AR3KConfigureExit;
474
475 status = bt_setup_hci(pHcidevInfo);
476 if (A_FAILED(status)) {
477 break;
478 }
479
480 if (pHcidevInfo->HciNormalMode) {
481 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in norma l mode... \n"));
482 } else {
483 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));
484 }
485
486 pHcidevInfo->pHTCStructAlloc = (A_UINT8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS);
487
488 if (NULL == pHcidevInfo->pHTCStructAlloc) {
489 status = A_NO_MEMORY;
490 break;
491 }
492
493 pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc;
494 for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
495 FreeHTCStruct(pHcidevInfo,pPacket);
496 }
497
498 A_MEMZERO(&config,sizeof(HCI_TRANSPORT_CONFIG_INFO));
499 config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
500 config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
501 config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
502 config.pContext = pHcidevInfo;
503 config.TransportFailure = ar6000_hci_transport_failure;
504 config.TransportReady = ar6000_hci_transport_ready;
505 config.TransportRemoved = ar6000_hci_transport_removed;
506 config.pHCISendComplete = ar6000_hci_send_complete;
507 config.pHCIPktRecv = ar6000_hci_pkt_recv;
508 config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
509 config.pHCISendFull = ar6000_hci_pkt_send_full;
510
511 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
512 pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcH andle, &config);
513 #else
514 pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
515 #endif
516
517 if (NULL == pHcidevInfo->pHCIDev) {
518 status = A_ERROR;
519 }
520
521 } while (FALSE);
522
523 if (A_FAILED(status)) {
524 if (pHcidevInfo != NULL) {
525 if (NULL == pHcidevInfo->pHCIDev) {
526 /* GMBOX may not be present in older chips */
527 /* just return success */
528 status = A_OK;
529 }
530 }
531 ar6000_cleanup_hci(ar);
532 }
533
534 return status;
535 }
536
537 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
538 void ar6000_cleanup_hci(void *ar)
539 #else
540 void ar6000_cleanup_hci(AR_SOFTC_T *ar)
541 #endif
542 {
543 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
544 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo;
545 #else
546 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
547 #endif
548
549 if (pHcidevInfo != NULL) {
550 bt_cleanup_hci(pHcidevInfo);
551
552 if (pHcidevInfo->pHCIDev != NULL) {
553 HCI_TransportStop(pHcidevInfo->pHCIDev);
554 HCI_TransportDetach(pHcidevInfo->pHCIDev);
555 pHcidevInfo->pHCIDev = NULL;
556 }
557
558 if (pHcidevInfo->pHTCStructAlloc != NULL) {
559 A_FREE(pHcidevInfo->pHTCStructAlloc);
560 pHcidevInfo->pHTCStructAlloc = NULL;
561 }
562
563 A_FREE(pHcidevInfo);
564 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
565 ar->hcidev_info = NULL;
566 #endif
567 }
568
569
570 }
571
572 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
573 A_STATUS hci_test_send(void *ar, struct sk_buff *skb)
574 #else
575 A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb)
576 #endif
577 {
578 int status = A_OK;
579 int length;
580 EPPING_HEADER *pHeader;
581 HTC_PACKET *pPacket;
582 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
583 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
584 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo;
585 #else
586 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
587 #endif
588
589 do {
590
591 if (NULL == pHcidevInfo) {
592 status = A_ERROR;
593 break;
594 }
595
596 if (NULL == pHcidevInfo->pHCIDev) {
597 status = A_ERROR;
598 break;
599 }
600
601 if (pHcidevInfo->HciNormalMode) {
602 /* this interface cannot run when normal WMI is running */
603 status = A_ERROR;
604 break;
605 }
606
607 pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
608
609 if (!IS_EPPING_PACKET(pHeader)) {
610 status = A_EINVAL;
611 break;
612 }
613
614 if (IS_EPING_PACKET_NO_DROP(pHeader)) {
615 htc_tag = AR6K_CONTROL_PKT_TAG;
616 }
617
618 length = sizeof(EPPING_HEADER) + pHeader->DataLength;
619
620 pPacket = AllocHTCStruct(pHcidevInfo);
621 if (NULL == pPacket) {
622 status = A_NO_MEMORY;
623 break;
624 }
625
626 SET_HTC_PACKET_INFO_TX(pPacket,
627 skb,
628 A_NETBUF_DATA(skb),
629 length,
630 HCI_ACL_TYPE, /* send every thing out as ACL */
631 htc_tag);
632
633 HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,FALSE);
634 pPacket = NULL;
635
636 } while (FALSE);
637
638 return status;
639 }
640
641 void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig)
642 {
643 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
644 AR3K_CONFIG_INFO *config = (AR3K_CONFIG_INFO *)ar3kconfig;
645
646 config->pHCIDev = pHcidevInfo->pHCIDev;
647 config->pHCIProps = &pHcidevInfo->HCIProps;
648 config->pHIFDevice = ar->arHifDevice;
649 config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
650 config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
651 config->AR3KBaudRate = 115200;
652 }
653
654 #ifdef CONFIG_BLUEZ_HCI_BRIDGE
655 /*** BT Stack Entrypoints *******/
656
657 /*
658 * bt_open - open a handle to the device
659 */
660 static int bt_open(struct hci_dev *hdev)
661 {
662
663 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n"));
664 set_bit(HCI_RUNNING, &hdev->flags);
665 set_bit(HCI_UP, &hdev->flags);
666 set_bit(HCI_INIT, &hdev->flags);
667 return 0;
668 }
669
670 /*
671 * bt_close - close handle to the device
672 */
673 static int bt_close(struct hci_dev *hdev)
674 {
675 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
676 clear_bit(HCI_RUNNING, &hdev->flags);
677 return 0;
678 }
679
680 /*
681 * bt_send_frame - send data frames
682 */
683 static int bt_send_frame(struct sk_buff *skb)
684 {
685 struct hci_dev *hdev = (struct hci_dev *)skb->dev;
686 HCI_TRANSPORT_PACKET_TYPE type;
687 AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
688 A_UINT8 *pTemp;
689 HTC_PACKET *pPacket;
690 A_STATUS status = A_OK;
691 struct sk_buff *txSkb = NULL;
692
693 if (!hdev) {
694 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\ n"));
695 return -ENODEV;
696 }
697
698 if (!test_bit(HCI_RUNNING, &hdev->flags)) {
699 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n" ));
700 return -EBUSY;
701 }
702
703 pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;
704 A_ASSERT(pHcidevInfo != NULL);
705
706 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb) ->pkt_type));
707 type = HCI_COMMAND_TYPE;
708
709 switch (bt_cb(skb)->pkt_type) {
710 case HCI_COMMAND_PKT:
711 type = HCI_COMMAND_TYPE;
712 hdev->stat.cmd_tx++;
713 break;
714
715 case HCI_ACLDATA_PKT:
716 type = HCI_ACL_TYPE;
717 hdev->stat.acl_tx++;
718 break;
719
720 case HCI_SCODATA_PKT:
721 /* we don't support SCO over the bridge */
722 kfree_skb(skb);
723 return 0;
724 default:
725 A_ASSERT(FALSE);
726 kfree_skb(skb);
727 return 0;
728 }
729
730 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
731 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
732 (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
733 skb->len));
734 if (type == HCI_COMMAND_TYPE) {
735 A_UINT16 opcode = HCI_GET_OP_CODE(skb->data);
736 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \ r\n",
737 opcode >> 10, opcode & 0x3FF));
738 }
739 AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
740 }
741
742 do {
743
744 txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRo om +
745 pHcidevInfo->HCIProps.TailRoom + skb->len,
746 GFP_ATOMIC);
747
748 if (txSkb == NULL) {
749 status = A_NO_MEMORY;
750 break;
751 }
752
753 bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
754 txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
755 skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom );
756 A_MEMCPY(txSkb->data, skb->data, skb->len);
757 skb_put(txSkb,skb->len);
758
759 /* push on header transport space */
760 pTemp = (A_UINT8 *)skb_push(txSkb, pHcidevInfo->HCIProps.HeadRoom);
761 pPacket = AllocHTCStruct(pHcidevInfo);
762 if (NULL == pPacket) {
763 status = A_NO_MEMORY;
764 break;
765 }
766
767 SET_HTC_PACKET_INFO_TX(pPacket,
768 txSkb,
769 pTemp + pHcidevInfo->HCIProps.HeadRoom,
770 txSkb->len,
771 type,
772 AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be d ropped */
773
774 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%X \n",(A_UINT32)txSkb));
775 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length: %d Bytes \n",
776 type, txSkb->len));
777
778 status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,FALSE);
779 pPacket = NULL;
780 txSkb = NULL;
781
782 } while (FALSE);
783
784 if (txSkb != NULL) {
785 kfree_skb(txSkb);
786 }
787
788 kfree_skb(skb);
789
790 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n"));
791 return 0;
792 }
793
794 /*
795 * bt_ioctl - ioctl processing
796 */
797 static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
798 {
799 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
800 return -ENOIOCTLCMD;
801 }
802
803 /*
804 * bt_flush - flush outstandingbpackets
805 */
806 static int bt_flush(struct hci_dev *hdev)
807 {
808 AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
809
810 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
811
812 pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;
813
814 /* TODO??? */
815
816 return 0;
817 }
818
819
820 /*
821 * bt_destruct -
822 */
823 static void bt_destruct(struct hci_dev *hdev)
824 {
825 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
826 /* nothing to do here */
827 }
828
829 static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
830 {
831 A_STATUS status = A_OK;
832 struct hci_dev *pHciDev = NULL;
833 HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
834
835 if (!setupbtdev) {
836 return A_OK;
837 }
838
839 do {
840
841 A_MEMZERO(&osDevInfo,sizeof(osDevInfo));
842 /* get the underlying OS device */
843 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
844 status = ar6000_get_hif_dev((HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifD evice),
845 &osDevInfo);
846 #else
847 status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice,
848 HIF_DEVICE_GET_OS_DEVICE,
849 &osDevInfo,
850 sizeof(osDevInfo));
851 #endif
852
853 if (A_FAILED(status)) {
854 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n" ));
855 break;
856 }
857
858 /* allocate a BT HCI struct for this device */
859 pHciDev = hci_alloc_dev();
860 if (NULL == pHciDev) {
861 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n"));
862 status = A_NO_MEMORY;
863 break;
864 }
865 /* save the device, we'll register this later */
866 pHcidevInfo->pBtStackHCIDev = pHciDev;
867 SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice);
868 pHciDev->type = HCI_VIRTUAL;
869 pHciDev->driver_data = pHcidevInfo;
870 pHciDev->open = bt_open;
871 pHciDev->close = bt_close;
872 pHciDev->send = bt_send_frame;
873 pHciDev->ioctl = bt_ioctl;
874 pHciDev->flush = bt_flush;
875 pHciDev->destruct = bt_destruct;
876 pHciDev->owner = THIS_MODULE;
877 /* driver is running in normal BT mode */
878 pHcidevInfo->HciNormalMode = TRUE;
879
880 } while (FALSE);
881
882 if (A_FAILED(status)) {
883 bt_cleanup_hci(pHcidevInfo);
884 }
885
886 return status;
887 }
888
889 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
890 {
891 int err;
892
893 if (pHcidevInfo->HciRegistered) {
894 pHcidevInfo->HciRegistered = FALSE;
895 clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags);
896 clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags);
897 clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags);
898 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
899 /* unregister */
900 if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
901 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister wi th bluetooth %d\n",err));
902 }
903 }
904
905 if (pHcidevInfo->pBtStackHCIDev != NULL) {
906 kfree(pHcidevInfo->pBtStackHCIDev);
907 pHcidevInfo->pBtStackHCIDev = NULL;
908 }
909 }
910
911 static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
912 {
913 int err;
914 A_STATUS status = A_OK;
915
916 do {
917 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \ n"));
918 A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
919 /* mark that we are registered */
920 pHcidevInfo->HciRegistered = TRUE;
921 if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
922 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err));
923 pHcidevInfo->HciRegistered = FALSE;
924 status = A_ERROR;
925 break;
926 }
927
928 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n")) ;
929
930 } while (FALSE);
931
932 return status;
933 }
934
935 static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
936 HCI_TRANSPORT_PACKET_TYPE Type,
937 struct sk_buff *skb)
938 {
939 A_UINT8 btType;
940 int len;
941 A_BOOL success = FALSE;
942 BT_HCI_EVENT_HEADER *pEvent;
943
944 do {
945
946 if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
947 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
948 break;
949 }
950
951 switch (Type) {
952 case HCI_ACL_TYPE:
953 btType = HCI_ACLDATA_PKT;
954 break;
955 case HCI_EVENT_TYPE:
956 btType = HCI_EVENT_PKT;
957 break;
958 default:
959 btType = 0;
960 A_ASSERT(FALSE);
961 break;
962 }
963
964 if (0 == btType) {
965 break;
966 }
967
968 /* set the final type */
969 bt_cb(skb)->pkt_type = btType;
970 /* set dev */
971 skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
972 len = skb->len;
973
974 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) {
975 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
976 pEvent = (BT_HCI_EVENT_HEADER *)skb->data;
977 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len: %d \n",
978 pEvent->EventCode, pEvent->ParamLength));
979 }
980 }
981
982 /* pass receive packet up the stack */
983 if (hci_recv_frame(skb) != 0) {
984 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \ n"));
985 break;
986 } else {
987 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
988 ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType ,len));
989 }
990
991 success = TRUE;
992
993 } while (FALSE);
994
995 return success;
996 }
997
998 static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Le ngth)
999 {
1000 struct sk_buff *skb;
1001 /* in normal HCI mode we need to alloc from the bt core APIs */
1002 skb = bt_skb_alloc(Length, GFP_ATOMIC);
1003 if (NULL == skb) {
1004 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
1005 }
1006 return skb;
1007 }
1008
1009 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *sk b)
1010 {
1011 kfree_skb(skb);
1012 }
1013
1014 #else // { CONFIG_BLUEZ_HCI_BRIDGE
1015
1016 /* stubs when we only want to test the HCI bridging Interface without the HT stack */
1017 static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
1018 {
1019 return A_OK;
1020 }
1021 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
1022 {
1023
1024 }
1025 static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
1026 {
1027 A_ASSERT(FALSE);
1028 return A_ERROR;
1029 }
1030
1031 static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
1032 HCI_TRANSPORT_PACKET_TYPE Type,
1033 struct sk_buff *skb)
1034 {
1035 A_ASSERT(FALSE);
1036 return FALSE;
1037 }
1038
1039 static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Le ngth)
1040 {
1041 A_ASSERT(FALSE);
1042 return NULL;
1043 }
1044 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *sk b)
1045 {
1046 A_ASSERT(FALSE);
1047 }
1048
1049 #endif // } CONFIG_BLUEZ_HCI_BRIDGE
1050
1051 #else // { ATH_AR6K_ENABLE_GMBOX
1052
1053 /* stubs when GMBOX support is not needed */
1054
1055 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1056 A_STATUS ar6000_setup_hci(void *ar)
1057 #else
1058 A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar)
1059 #endif
1060 {
1061 return A_OK;
1062 }
1063
1064 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1065 void ar6000_cleanup_hci(void *ar)
1066 #else
1067 void ar6000_cleanup_hci(AR_SOFTC_T *ar)
1068 #endif
1069 {
1070 return;
1071 }
1072
1073 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
1074 void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig)
1075 {
1076 return;
1077 }
1078 #endif
1079
1080 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1081 int hci_test_send(void *ar, struct sk_buff *skb)
1082 #else
1083 int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb)
1084 #endif
1085 {
1086 return -EOPNOTSUPP;
1087 }
1088
1089 #endif // } ATH_AR6K_ENABLE_GMBOX
1090
1091
1092 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1093 static int __init
1094 hcibridge_init_module(void)
1095 {
1096 A_STATUS status;
1097 HCI_TRANSPORT_CALLBACKS hciTransCallbacks;
1098
1099 hciTransCallbacks.setupTransport = ar6000_setup_hci;
1100 hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
1101
1102 status = ar6000_register_hci_transport(&hciTransCallbacks);
1103 if(status != A_OK)
1104 return -ENODEV;
1105
1106 return 0;
1107 }
1108
1109 static void __exit
1110 hcibridge_cleanup_module(void)
1111 {
1112 }
1113
1114 module_init(hcibridge_init_module);
1115 module_exit(hcibridge_cleanup_module);
1116 MODULE_LICENSE("GPL and additional rights");
1117 #endif
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/os/linux/export_hci_transport.c ('k') | chromeos/drivers/ath6kl/os/linux/include/ar6000_drv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698