1 //------------------------------------------------------------------------------
2 // Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
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.
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.
18 //------------------------------------------------------------------------------
19 //==============================================================================
20 // HCI bridge implementation
22 // Author(s): ="Atheros"
23 //==============================================================================
25 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
26 #include <linux/etherdevice.h>
35 #include "common_drv.h"
37 #define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
38 #define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
39 #define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
40 #define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
42 #include "ar6000_drv.h"
43 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
45 #ifdef ATH_AR6K_ENABLE_GMBOX
46 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
47 #include "export_hci_transport.h"
49 #include "hci_transport_api.h"
51 #include "epping_test.h"
53 #include "ar3kconfig.h"
54 #include <net/bluetooth/bluetooth.h>
55 #include <net/bluetooth/hci_core.h>
57 /* only build on newer kernels which have BT configured */
58 #if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
59 #define CONFIG_BLUEZ_HCI_BRIDGE
62 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
63 unsigned int ar3khcibaud
= 0;
64 unsigned int hciuartscale
= 0;
65 unsigned int hciuartstep
= 0;
67 module_param(ar3khcibaud
, int, 0644);
68 module_param(hciuartscale
, int, 0644);
69 module_param(hciuartstep
, int, 0644);
71 extern unsigned int ar3khcibaud
;
72 extern unsigned int hciuartscale
;
73 extern unsigned int hciuartstep
;
74 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
77 void *pHCIDev
; /* HCI bridge device */
78 HCI_TRANSPORT_PROPERTIES HCIProps
; /* HCI bridge props */
79 struct hci_dev
*pBtStackHCIDev
; /* BT Stack HCI dev */
80 bool HciNormalMode
; /* Actual HCI mode enabled (non-TEST)*/
81 bool HciRegistered
; /* HCI device registered with stack */
82 HTC_PACKET_QUEUE HTCPacketStructHead
;
84 spinlock_t BridgeLock
;
85 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
86 HCI_TRANSPORT_MISC_HANDLES HCITransHdl
;
89 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
90 } AR6K_HCI_BRIDGE_INFO
;
92 #define MAX_ACL_RECV_BUFS 16
93 #define MAX_EVT_RECV_BUFS 8
94 #define MAX_HCI_WRITE_QUEUE_DEPTH 32
95 #define MAX_ACL_RECV_LENGTH 1200
96 #define MAX_EVT_RECV_LENGTH 257
97 #define TX_PACKET_RSV_OFFSET 32
98 #define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2)
100 #define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
102 extern unsigned int setupbtdev
;
103 AR3K_CONFIG_INFO ar3kconfig
;
105 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
106 AR6K_HCI_BRIDGE_INFO
*g_pHcidevInfo
;
109 static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
);
110 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
);
111 static int bt_register_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
);
112 static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
,
113 HCI_TRANSPORT_PACKET_TYPE Type
,
114 struct sk_buff
*skb
);
115 static struct sk_buff
*bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, int Length
);
116 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, struct sk_buff
*skb
);
118 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
119 int ar6000_setup_hci(void *ar
);
120 void ar6000_cleanup_hci(void *ar
);
121 int hci_test_send(void *ar
, struct sk_buff
*skb
);
123 int ar6000_setup_hci(AR_SOFTC_T
*ar
);
124 void ar6000_cleanup_hci(AR_SOFTC_T
*ar
);
125 /* HCI bridge testing */
126 int hci_test_send(AR_SOFTC_T
*ar
, struct sk_buff
*skb
);
127 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
129 #define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
130 #define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
132 static inline void FreeBtOsBuf(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, void *osbuf
)
134 if (pHcidevInfo
->HciNormalMode
) {
135 bt_free_buffer(pHcidevInfo
, (struct sk_buff
*)osbuf
);
137 /* in test mode, these are just ordinary netbuf allocations */
138 A_NETBUF_FREE(osbuf
);
142 static void FreeHTCStruct(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, HTC_PACKET
*pPacket
)
144 LOCK_BRIDGE(pHcidevInfo
);
145 HTC_PACKET_ENQUEUE(&pHcidevInfo
->HTCPacketStructHead
,pPacket
);
146 UNLOCK_BRIDGE(pHcidevInfo
);
149 static HTC_PACKET
* AllocHTCStruct(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
151 HTC_PACKET
*pPacket
= NULL
;
152 LOCK_BRIDGE(pHcidevInfo
);
153 pPacket
= HTC_PACKET_DEQUEUE(&pHcidevInfo
->HTCPacketStructHead
);
154 UNLOCK_BRIDGE(pHcidevInfo
);
158 #define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
160 static void RefillRecvBuffers(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
,
161 HCI_TRANSPORT_PACKET_TYPE Type
,
166 HTC_PACKET_QUEUE queue
;
169 INIT_HTC_PACKET_QUEUE(&queue
);
171 if (Type
== HCI_ACL_TYPE
) {
172 if (pHcidevInfo
->HciNormalMode
) {
173 length
= HCI_MAX_FRAME_SIZE
;
175 length
= MAX_ACL_RECV_LENGTH
;
178 length
= MAX_EVT_RECV_LENGTH
;
181 /* add on transport head and tail room */
182 length
+= pHcidevInfo
->HCIProps
.HeadRoom
+ pHcidevInfo
->HCIProps
.TailRoom
;
183 /* round up to the required I/O padding */
184 length
= BLOCK_ROUND_UP_PWR2(length
,pHcidevInfo
->HCIProps
.IOBlockPad
);
186 for (i
= 0; i
< NumBuffers
; i
++) {
188 if (pHcidevInfo
->HciNormalMode
) {
189 osBuf
= bt_alloc_buffer(pHcidevInfo
,length
);
191 osBuf
= A_NETBUF_ALLOC(length
);
198 pPacket
= AllocHTCStruct(pHcidevInfo
);
199 if (NULL
== pPacket
) {
200 FreeBtOsBuf(pHcidevInfo
,osBuf
);
201 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("Failed to alloc HTC struct \n"));
205 SET_HTC_PACKET_INFO_RX_REFILL(pPacket
,osBuf
,A_NETBUF_DATA(osBuf
),length
,Type
);
207 HTC_PACKET_ENQUEUE(&queue
,pPacket
);
211 HCI_TransportAddReceivePkts(pHcidevInfo
->pHCIDev
, &queue
);
215 #define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
216 (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
217 (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
218 static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle
,
219 HCI_TRANSPORT_PROPERTIES
*pProps
,
222 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
224 u32 address
, hci_uart_pwr_mgmt_params
;
225 // AR3K_CONFIG_INFO ar3kconfig;
227 pHcidevInfo
->pHCIDev
= HCIHandle
;
229 memcpy(&pHcidevInfo
->HCIProps
,pProps
,sizeof(*pProps
));
231 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE
,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n",
232 (unsigned long)HCIHandle
,
233 pHcidevInfo
->HCIProps
.HeadRoom
,
234 pHcidevInfo
->HCIProps
.TailRoom
,
235 pHcidevInfo
->HCIProps
.IOBlockPad
));
237 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
238 A_ASSERT((pProps
->HeadRoom
+ pProps
->TailRoom
) <= (struct net_device
*)(pHcidevInfo
->HCITransHdl
.netDevice
)->hard_header_len
);
240 A_ASSERT((pProps
->HeadRoom
+ pProps
->TailRoom
) <= pHcidevInfo
->ar
->arNetDev
->hard_header_len
);
243 /* provide buffers */
244 RefillRecvBuffers(pHcidevInfo
, HCI_ACL_TYPE
, MAX_ACL_RECV_BUFS
);
245 RefillRecvBuffers(pHcidevInfo
, HCI_EVENT_TYPE
, MAX_EVT_RECV_BUFS
);
248 /* start transport */
249 status
= HCI_TransportStart(pHcidevInfo
->pHCIDev
);
255 if (!pHcidevInfo
->HciNormalMode
) {
256 /* in test mode, no need to go any further */
260 // The delay is required when AR6K is driving the BT reset line
261 // where time is needed after the BT chip is out of reset (HCI_TransportStart)
262 // and before the first HCI command is issued (AR3KConfigure)
264 // The delay should be configurable and be only applied when AR6K driving the BT
265 // reset line. This could be done by some module parameter or based on some HW config
266 // info. For now apply 100ms delay blindly
269 A_MEMZERO(&ar3kconfig
,sizeof(ar3kconfig
));
270 ar3kconfig
.pHCIDev
= pHcidevInfo
->pHCIDev
;
271 ar3kconfig
.pHCIProps
= &pHcidevInfo
->HCIProps
;
272 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
273 ar3kconfig
.pHIFDevice
= (HIF_DEVICE
*)(pHcidevInfo
->HCITransHdl
.hifDevice
);
275 ar3kconfig
.pHIFDevice
= pHcidevInfo
->ar
->arHifDevice
;
277 ar3kconfig
.pBtStackHCIDev
= pHcidevInfo
->pBtStackHCIDev
;
279 if (ar3khcibaud
!= 0) {
280 /* user wants ar3k baud rate change */
281 ar3kconfig
.Flags
|= AR3K_CONFIG_FLAG_SET_AR3K_BAUD
;
282 ar3kconfig
.Flags
|= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY
;
283 ar3kconfig
.AR3KBaudRate
= ar3khcibaud
;
286 if ((hciuartscale
!= 0) || (hciuartstep
!= 0)) {
287 /* user wants to tune HCI bridge UART scale/step values */
288 ar3kconfig
.AR6KScale
= (u16
)hciuartscale
;
289 ar3kconfig
.AR6KStep
= (u16
)hciuartstep
;
290 ar3kconfig
.Flags
|= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP
;
293 /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
294 address
= TARG_VTOP(pHcidevInfo
->ar
->arTargetType
,
295 HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo
->ar
, hi_hci_uart_pwr_mgmt_params
));
296 status
= ar6000_ReadRegDiag(pHcidevInfo
->ar
->arHifDevice
, &address
, &hci_uart_pwr_mgmt_params
);
298 ar3kconfig
.PwrMgmtEnabled
= (hci_uart_pwr_mgmt_params
& 0x1);
299 ar3kconfig
.IdleTimeout
= (hci_uart_pwr_mgmt_params
& 0xFFFF0000) >> 16;
300 ar3kconfig
.WakeupTimeout
= (hci_uart_pwr_mgmt_params
& 0xFF00) >> 8;
302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
304 /* configure the AR3K device */
305 memcpy(ar3kconfig
.bdaddr
,pHcidevInfo
->ar
->bdaddr
,6);
306 status
= AR3KConfigure(&ar3kconfig
);
311 /* Make sure both AR6K and AR3K have power management enabled */
312 if (ar3kconfig
.PwrMgmtEnabled
) {
313 status
= HCI_TransportEnablePowerMgmt(pHcidevInfo
->pHCIDev
, true);
315 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
319 status
= bt_register_hci(pHcidevInfo
);
326 static void ar6000_hci_transport_failure(void *pContext
, int Status
)
328 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
330 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: transport failure! \n"));
332 if (pHcidevInfo
->HciNormalMode
) {
337 static void ar6000_hci_transport_removed(void *pContext
)
339 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
341 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE
, ("HCI Bridge: transport removed. \n"));
343 A_ASSERT(pHcidevInfo
->pHCIDev
!= NULL
);
345 HCI_TransportDetach(pHcidevInfo
->pHCIDev
);
346 bt_cleanup_hci(pHcidevInfo
);
347 pHcidevInfo
->pHCIDev
= NULL
;
350 static void ar6000_hci_send_complete(void *pContext
, HTC_PACKET
*pPacket
)
352 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
353 void *osbuf
= pPacket
->pPktContext
;
354 A_ASSERT(osbuf
!= NULL
);
355 A_ASSERT(pHcidevInfo
!= NULL
);
357 if (pPacket
->Status
) {
358 if ((pPacket
->Status
!= A_ECANCELED
) && (pPacket
->Status
!= A_NO_RESOURCE
)) {
359 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: Send Packet Failed: %d \n",pPacket
->Status
));
363 FreeHTCStruct(pHcidevInfo
,pPacket
);
364 FreeBtOsBuf(pHcidevInfo
,osbuf
);
368 static void ar6000_hci_pkt_recv(void *pContext
, HTC_PACKET
*pPacket
)
370 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
373 A_ASSERT(pHcidevInfo
!= NULL
);
374 skb
= (struct sk_buff
*)pPacket
->pPktContext
;
375 A_ASSERT(skb
!= NULL
);
379 if (pPacket
->Status
) {
383 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV
,
384 ("HCI Bridge, packet received type : %d len:%d \n",
385 HCI_GET_PACKET_TYPE(pPacket
),pPacket
->ActualLength
));
387 /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
388 * to fill the front of the buffer */
389 A_NETBUF_PUT(skb
,pPacket
->ActualLength
+ pHcidevInfo
->HCIProps
.HeadRoom
);
390 A_NETBUF_PULL(skb
,pHcidevInfo
->HCIProps
.HeadRoom
);
392 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP
)) {
393 AR_DEBUG_PRINTF(ATH_DEBUG_ANY
,("<<< Recv HCI %s packet len:%d \n",
394 (HCI_GET_PACKET_TYPE(pPacket
) == HCI_EVENT_TYPE
) ? "EVENT" : "ACL",
396 AR_DEBUG_PRINTBUF(skb
->data
, skb
->len
,"BT HCI RECV Packet Dump");
399 if (pHcidevInfo
->HciNormalMode
) {
400 /* indicate the packet */
401 if (bt_indicate_recv(pHcidevInfo
,HCI_GET_PACKET_TYPE(pPacket
),skb
)) {
402 /* bt stack accepted the packet */
408 /* for testing, indicate packet to the network stack */
409 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
410 skb
->dev
= (struct net_device
*)(pHcidevInfo
->HCITransHdl
.netDevice
);
411 if ((((struct net_device
*)pHcidevInfo
->HCITransHdl
.netDevice
)->flags
& IFF_UP
) == IFF_UP
) {
412 skb
->protocol
= eth_type_trans(skb
, (struct net_device
*)(pHcidevInfo
->HCITransHdl
.netDevice
));
414 skb
->dev
= pHcidevInfo
->ar
->arNetDev
;
415 if ((pHcidevInfo
->ar
->arNetDev
->flags
& IFF_UP
) == IFF_UP
) {
416 skb
->protocol
= eth_type_trans(skb
, pHcidevInfo
->ar
->arNetDev
);
424 FreeHTCStruct(pHcidevInfo
,pPacket
);
427 /* packet was not accepted, free it */
428 FreeBtOsBuf(pHcidevInfo
,skb
);
433 static void ar6000_hci_pkt_refill(void *pContext
, HCI_TRANSPORT_PACKET_TYPE Type
, int BuffersAvailable
)
435 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
438 if (Type
== HCI_ACL_TYPE
) {
439 refillCount
= MAX_ACL_RECV_BUFS
- BuffersAvailable
;
441 refillCount
= MAX_EVT_RECV_BUFS
- BuffersAvailable
;
444 if (refillCount
> 0) {
445 RefillRecvBuffers(pHcidevInfo
,Type
,refillCount
);
450 static HCI_SEND_FULL_ACTION
ar6000_hci_pkt_send_full(void *pContext
, HTC_PACKET
*pPacket
)
452 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)pContext
;
453 HCI_SEND_FULL_ACTION action
= HCI_SEND_FULL_KEEP
;
455 if (!pHcidevInfo
->HciNormalMode
) {
456 /* for epping testing, check packet tag, some epping packets are
457 * special and cannot be dropped */
458 if (HTC_GET_TAG_FROM_PKT(pPacket
) == AR6K_DATA_PKT_TAG
) {
459 action
= HCI_SEND_FULL_DROP
;
466 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
467 int ar6000_setup_hci(void *ar
)
469 int ar6000_setup_hci(AR_SOFTC_T
*ar
)
472 HCI_TRANSPORT_CONFIG_INFO config
;
476 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
;
481 pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO
));
483 if (NULL
== pHcidevInfo
) {
484 status
= A_NO_MEMORY
;
488 A_MEMZERO(pHcidevInfo
, sizeof(AR6K_HCI_BRIDGE_INFO
));
489 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
490 g_pHcidevInfo
= pHcidevInfo
;
491 pHcidevInfo
->HCITransHdl
= *(HCI_TRANSPORT_MISC_HANDLES
*)ar
;
493 ar
->hcidev_info
= pHcidevInfo
;
494 pHcidevInfo
->ar
= ar
;
496 spin_lock_init(&pHcidevInfo
->BridgeLock
);
497 INIT_HTC_PACKET_QUEUE(&pHcidevInfo
->HTCPacketStructHead
);
499 ar
->exitCallback
= AR3KConfigureExit
;
501 status
= bt_setup_hci(pHcidevInfo
);
506 if (pHcidevInfo
->HciNormalMode
) {
507 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE
, ("HCI Bridge: running in normal mode... \n"));
509 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE
, ("HCI Bridge: running in test mode... \n"));
512 pHcidevInfo
->pHTCStructAlloc
= (u8
*)A_MALLOC((sizeof(HTC_PACKET
)) * NUM_HTC_PACKET_STRUCTS
);
514 if (NULL
== pHcidevInfo
->pHTCStructAlloc
) {
515 status
= A_NO_MEMORY
;
519 pPacket
= (HTC_PACKET
*)pHcidevInfo
->pHTCStructAlloc
;
520 for (i
= 0; i
< NUM_HTC_PACKET_STRUCTS
; i
++,pPacket
++) {
521 FreeHTCStruct(pHcidevInfo
,pPacket
);
524 A_MEMZERO(&config
,sizeof(HCI_TRANSPORT_CONFIG_INFO
));
525 config
.ACLRecvBufferWaterMark
= MAX_ACL_RECV_BUFS
/ 2;
526 config
.EventRecvBufferWaterMark
= MAX_EVT_RECV_BUFS
/ 2;
527 config
.MaxSendQueueDepth
= MAX_HCI_WRITE_QUEUE_DEPTH
;
528 config
.pContext
= pHcidevInfo
;
529 config
.TransportFailure
= ar6000_hci_transport_failure
;
530 config
.TransportReady
= ar6000_hci_transport_ready
;
531 config
.TransportRemoved
= ar6000_hci_transport_removed
;
532 config
.pHCISendComplete
= ar6000_hci_send_complete
;
533 config
.pHCIPktRecv
= ar6000_hci_pkt_recv
;
534 config
.pHCIPktRecvRefill
= ar6000_hci_pkt_refill
;
535 config
.pHCISendFull
= ar6000_hci_pkt_send_full
;
537 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
538 pHcidevInfo
->pHCIDev
= HCI_TransportAttach(pHcidevInfo
->HCITransHdl
.htcHandle
, &config
);
540 pHcidevInfo
->pHCIDev
= HCI_TransportAttach(ar
->arHtcTarget
, &config
);
543 if (NULL
== pHcidevInfo
->pHCIDev
) {
550 if (pHcidevInfo
!= NULL
) {
551 if (NULL
== pHcidevInfo
->pHCIDev
) {
552 /* GMBOX may not be present in older chips */
553 /* just return success */
557 ar6000_cleanup_hci(ar
);
563 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
564 void ar6000_cleanup_hci(void *ar
)
566 void ar6000_cleanup_hci(AR_SOFTC_T
*ar
)
569 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
570 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= g_pHcidevInfo
;
572 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)ar
->hcidev_info
;
575 if (pHcidevInfo
!= NULL
) {
576 bt_cleanup_hci(pHcidevInfo
);
578 if (pHcidevInfo
->pHCIDev
!= NULL
) {
579 HCI_TransportStop(pHcidevInfo
->pHCIDev
);
580 HCI_TransportDetach(pHcidevInfo
->pHCIDev
);
581 pHcidevInfo
->pHCIDev
= NULL
;
584 if (pHcidevInfo
->pHTCStructAlloc
!= NULL
) {
585 A_FREE(pHcidevInfo
->pHTCStructAlloc
);
586 pHcidevInfo
->pHTCStructAlloc
= NULL
;
590 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
591 ar
->hcidev_info
= NULL
;
598 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
599 int hci_test_send(void *ar
, struct sk_buff
*skb
)
601 int hci_test_send(AR_SOFTC_T
*ar
, struct sk_buff
*skb
)
606 EPPING_HEADER
*pHeader
;
608 HTC_TX_TAG htc_tag
= AR6K_DATA_PKT_TAG
;
609 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
610 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= g_pHcidevInfo
;
612 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)ar
->hcidev_info
;
617 if (NULL
== pHcidevInfo
) {
622 if (NULL
== pHcidevInfo
->pHCIDev
) {
627 if (pHcidevInfo
->HciNormalMode
) {
628 /* this interface cannot run when normal WMI is running */
633 pHeader
= (EPPING_HEADER
*)A_NETBUF_DATA(skb
);
635 if (!IS_EPPING_PACKET(pHeader
)) {
640 if (IS_EPING_PACKET_NO_DROP(pHeader
)) {
641 htc_tag
= AR6K_CONTROL_PKT_TAG
;
644 length
= sizeof(EPPING_HEADER
) + pHeader
->DataLength
;
646 pPacket
= AllocHTCStruct(pHcidevInfo
);
647 if (NULL
== pPacket
) {
648 status
= A_NO_MEMORY
;
652 SET_HTC_PACKET_INFO_TX(pPacket
,
656 HCI_ACL_TYPE
, /* send every thing out as ACL */
659 HCI_TransportSendPkt(pHcidevInfo
->pHCIDev
,pPacket
,false);
667 void ar6000_set_default_ar3kconfig(AR_SOFTC_T
*ar
, void *ar3kconfig
)
669 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)ar
->hcidev_info
;
670 AR3K_CONFIG_INFO
*config
= (AR3K_CONFIG_INFO
*)ar3kconfig
;
672 config
->pHCIDev
= pHcidevInfo
->pHCIDev
;
673 config
->pHCIProps
= &pHcidevInfo
->HCIProps
;
674 config
->pHIFDevice
= ar
->arHifDevice
;
675 config
->pBtStackHCIDev
= pHcidevInfo
->pBtStackHCIDev
;
676 config
->Flags
|= AR3K_CONFIG_FLAG_SET_AR3K_BAUD
;
677 config
->AR3KBaudRate
= 115200;
680 #ifdef CONFIG_BLUEZ_HCI_BRIDGE
681 /*** BT Stack Entrypoints *******/
684 * bt_open - open a handle to the device
686 static int bt_open(struct hci_dev
*hdev
)
689 AR_DEBUG_PRINTF(ATH_DEBUG_TRC
, ("HCI Bridge: bt_open - enter - x\n"));
690 set_bit(HCI_RUNNING
, &hdev
->flags
);
691 set_bit(HCI_UP
, &hdev
->flags
);
692 set_bit(HCI_INIT
, &hdev
->flags
);
697 * bt_close - close handle to the device
699 static int bt_close(struct hci_dev
*hdev
)
701 AR_DEBUG_PRINTF(ATH_DEBUG_TRC
, ("HCI Bridge: bt_close - enter\n"));
702 clear_bit(HCI_RUNNING
, &hdev
->flags
);
707 * bt_send_frame - send data frames
709 static int bt_send_frame(struct sk_buff
*skb
)
711 struct hci_dev
*hdev
= (struct hci_dev
*)skb
->dev
;
712 HCI_TRANSPORT_PACKET_TYPE type
;
713 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
;
716 struct sk_buff
*txSkb
= NULL
;
719 AR_DEBUG_PRINTF(ATH_DEBUG_WARN
, ("HCI Bridge: bt_send_frame - no device\n"));
723 if (!test_bit(HCI_RUNNING
, &hdev
->flags
)) {
724 AR_DEBUG_PRINTF(ATH_DEBUG_TRC
, ("HCI Bridge: bt_send_frame - not open\n"));
728 pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)hdev
->driver_data
;
729 A_ASSERT(pHcidevInfo
!= NULL
);
731 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND
, ("+bt_send_frame type: %d \n",bt_cb(skb
)->pkt_type
));
732 type
= HCI_COMMAND_TYPE
;
734 switch (bt_cb(skb
)->pkt_type
) {
735 case HCI_COMMAND_PKT
:
736 type
= HCI_COMMAND_TYPE
;
740 case HCI_ACLDATA_PKT
:
745 case HCI_SCODATA_PKT
:
746 /* we don't support SCO over the bridge */
755 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP
)) {
756 AR_DEBUG_PRINTF(ATH_DEBUG_ANY
,(">>> Send HCI %s packet len: %d\n",
757 (type
== HCI_COMMAND_TYPE
) ? "COMMAND" : "ACL",
759 if (type
== HCI_COMMAND_TYPE
) {
760 u16 opcode
= HCI_GET_OP_CODE(skb
->data
);
761 AR_DEBUG_PRINTF(ATH_DEBUG_ANY
,(" HCI Command: OGF:0x%X OCF:0x%X \r\n",
762 opcode
>> 10, opcode
& 0x3FF));
764 AR_DEBUG_PRINTBUF(skb
->data
,skb
->len
,"BT HCI SEND Packet Dump");
769 txSkb
= bt_skb_alloc(TX_PACKET_RSV_OFFSET
+ pHcidevInfo
->HCIProps
.HeadRoom
+
770 pHcidevInfo
->HCIProps
.TailRoom
+ skb
->len
,
774 status
= A_NO_MEMORY
;
778 bt_cb(txSkb
)->pkt_type
= bt_cb(skb
)->pkt_type
;
779 txSkb
->dev
= (void *)pHcidevInfo
->pBtStackHCIDev
;
780 skb_reserve(txSkb
, TX_PACKET_RSV_OFFSET
+ pHcidevInfo
->HCIProps
.HeadRoom
);
781 memcpy(txSkb
->data
, skb
->data
, skb
->len
);
782 skb_put(txSkb
,skb
->len
);
784 pPacket
= AllocHTCStruct(pHcidevInfo
);
785 if (NULL
== pPacket
) {
786 status
= A_NO_MEMORY
;
790 /* HCI packet length here doesn't include the 1-byte transport header which
791 * will be handled by the HCI transport layer. Enough headroom has already
792 * been reserved above for the transport header
794 SET_HTC_PACKET_INFO_TX(pPacket
,
799 AR6K_CONTROL_PKT_TAG
); /* HCI packets cannot be dropped */
801 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND
, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb
));
802 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND
, ("HCI Bridge: type:%d, Total Length:%d Bytes \n",
805 status
= HCI_TransportSendPkt(pHcidevInfo
->pHCIDev
,pPacket
,false);
817 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND
, ("-bt_send_frame \n"));
822 * bt_ioctl - ioctl processing
824 static int bt_ioctl(struct hci_dev
*hdev
, unsigned int cmd
, unsigned long arg
)
826 AR_DEBUG_PRINTF(ATH_DEBUG_TRC
, ("HCI Bridge: bt_ioctl - enter\n"));
831 * bt_flush - flush outstandingbpackets
833 static int bt_flush(struct hci_dev
*hdev
)
835 AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
;
837 AR_DEBUG_PRINTF(ATH_DEBUG_TRC
, ("HCI Bridge: bt_flush - enter\n"));
839 pHcidevInfo
= (AR6K_HCI_BRIDGE_INFO
*)hdev
->driver_data
;
850 static void bt_destruct(struct hci_dev
*hdev
)
852 AR_DEBUG_PRINTF(ATH_DEBUG_TRC
, ("HCI Bridge: bt_destruct - enter\n"));
853 /* nothing to do here */
856 static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
859 struct hci_dev
*pHciDev
= NULL
;
860 HIF_DEVICE_OS_DEVICE_INFO osDevInfo
;
868 A_MEMZERO(&osDevInfo
,sizeof(osDevInfo
));
869 /* get the underlying OS device */
870 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
871 status
= ar6000_get_hif_dev((HIF_DEVICE
*)(pHcidevInfo
->HCITransHdl
.hifDevice
),
874 status
= HIFConfigureDevice(pHcidevInfo
->ar
->arHifDevice
,
875 HIF_DEVICE_GET_OS_DEVICE
,
881 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("Failed to OS device info from HIF\n"));
885 /* allocate a BT HCI struct for this device */
886 pHciDev
= hci_alloc_dev();
887 if (NULL
== pHciDev
) {
888 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge - failed to allocate bt struct \n"));
889 status
= A_NO_MEMORY
;
892 /* save the device, we'll register this later */
893 pHcidevInfo
->pBtStackHCIDev
= pHciDev
;
894 SET_HCIDEV_DEV(pHciDev
,osDevInfo
.pOSDevice
);
895 SET_HCI_BUS_TYPE(pHciDev
, HCI_VIRTUAL
, HCI_BREDR
);
896 pHciDev
->driver_data
= pHcidevInfo
;
897 pHciDev
->open
= bt_open
;
898 pHciDev
->close
= bt_close
;
899 pHciDev
->send
= bt_send_frame
;
900 pHciDev
->ioctl
= bt_ioctl
;
901 pHciDev
->flush
= bt_flush
;
902 pHciDev
->destruct
= bt_destruct
;
903 pHciDev
->owner
= THIS_MODULE
;
904 /* driver is running in normal BT mode */
905 pHcidevInfo
->HciNormalMode
= true;
910 bt_cleanup_hci(pHcidevInfo
);
916 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
920 if (pHcidevInfo
->HciRegistered
) {
921 pHcidevInfo
->HciRegistered
= false;
922 clear_bit(HCI_RUNNING
, &pHcidevInfo
->pBtStackHCIDev
->flags
);
923 clear_bit(HCI_UP
, &pHcidevInfo
->pBtStackHCIDev
->flags
);
924 clear_bit(HCI_INIT
, &pHcidevInfo
->pBtStackHCIDev
->flags
);
925 A_ASSERT(pHcidevInfo
->pBtStackHCIDev
!= NULL
);
927 if ((err
= hci_unregister_dev(pHcidevInfo
->pBtStackHCIDev
)) < 0) {
928 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: failed to unregister with bluetooth %d\n",err
));
932 if (pHcidevInfo
->pBtStackHCIDev
!= NULL
) {
933 kfree(pHcidevInfo
->pBtStackHCIDev
);
934 pHcidevInfo
->pBtStackHCIDev
= NULL
;
938 static int bt_register_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
944 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE
, ("HCI Bridge: registering HCI... \n"));
945 A_ASSERT(pHcidevInfo
->pBtStackHCIDev
!= NULL
);
946 /* mark that we are registered */
947 pHcidevInfo
->HciRegistered
= true;
948 if ((err
= hci_register_dev(pHcidevInfo
->pBtStackHCIDev
)) < 0) {
949 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: failed to register with bluetooth %d\n",err
));
950 pHcidevInfo
->HciRegistered
= false;
955 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE
, ("HCI Bridge: HCI registered \n"));
962 static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
,
963 HCI_TRANSPORT_PACKET_TYPE Type
,
968 bool success
= false;
969 BT_HCI_EVENT_HEADER
*pEvent
;
973 if (!test_bit(HCI_RUNNING
, &pHcidevInfo
->pBtStackHCIDev
->flags
)) {
974 AR_DEBUG_PRINTF(ATH_DEBUG_WARN
, ("HCI Bridge: bt_indicate_recv - not running\n"));
980 btType
= HCI_ACLDATA_PKT
;
983 btType
= HCI_EVENT_PKT
;
995 /* set the final type */
996 bt_cb(skb
)->pkt_type
= btType
;
998 skb
->dev
= (void *)pHcidevInfo
->pBtStackHCIDev
;
1001 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV
)) {
1002 if (bt_cb(skb
)->pkt_type
== HCI_EVENT_PKT
) {
1003 pEvent
= (BT_HCI_EVENT_HEADER
*)skb
->data
;
1004 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV
, ("BT HCI EventCode: %d, len:%d \n",
1005 pEvent
->EventCode
, pEvent
->ParamLength
));
1009 /* pass receive packet up the stack */
1010 if (hci_recv_frame(skb
) != 0) {
1011 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("HCI Bridge: hci_recv_frame failed \n"));
1014 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV
,
1015 ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType
,len
));
1025 static struct sk_buff
* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, int Length
)
1027 struct sk_buff
*skb
;
1028 /* in normal HCI mode we need to alloc from the bt core APIs */
1029 skb
= bt_skb_alloc(Length
, GFP_ATOMIC
);
1031 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("Failed to alloc bt sk_buff \n"));
1036 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, struct sk_buff
*skb
)
1041 #else // { CONFIG_BLUEZ_HCI_BRIDGE
1043 /* stubs when we only want to test the HCI bridging Interface without the HT stack */
1044 static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
1048 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
1052 static int bt_register_hci(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
)
1058 static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
,
1059 HCI_TRANSPORT_PACKET_TYPE Type
,
1060 struct sk_buff
*skb
)
1066 static struct sk_buff
* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, int Length
)
1071 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO
*pHcidevInfo
, struct sk_buff
*skb
)
1076 #endif // } CONFIG_BLUEZ_HCI_BRIDGE
1078 #else // { ATH_AR6K_ENABLE_GMBOX
1080 /* stubs when GMBOX support is not needed */
1082 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1083 int ar6000_setup_hci(void *ar
)
1085 int ar6000_setup_hci(AR_SOFTC_T
*ar
)
1091 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1092 void ar6000_cleanup_hci(void *ar
)
1094 void ar6000_cleanup_hci(AR_SOFTC_T
*ar
)
1100 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
1101 void ar6000_set_default_ar3kconfig(AR_SOFTC_T
*ar
, void *ar3kconfig
)
1107 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1108 int hci_test_send(void *ar
, struct sk_buff
*skb
)
1110 int hci_test_send(AR_SOFTC_T
*ar
, struct sk_buff
*skb
)
1116 #endif // } ATH_AR6K_ENABLE_GMBOX
1119 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1121 hcibridge_init_module(void)
1124 HCI_TRANSPORT_CALLBACKS hciTransCallbacks
;
1126 hciTransCallbacks
.setupTransport
= ar6000_setup_hci
;
1127 hciTransCallbacks
.cleanupTransport
= ar6000_cleanup_hci
;
1129 status
= ar6000_register_hci_transport(&hciTransCallbacks
);
1137 hcibridge_cleanup_module(void)
1141 module_init(hcibridge_init_module
);
1142 module_exit(hcibridge_cleanup_module
);
1143 MODULE_LICENSE("Dual BSD/GPL");