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